Browse Source

1.融合custom,windturbinenew,scada报警服务
2.预警产品用户编辑,用户注册添加密码强度校验,加密传输功能
3.feign升级为openfeign

wanghs 2 years ago
parent
commit
99ac860161
100 changed files with 6946 additions and 0 deletions
  1. 1 0
      .gitignore
  2. 33 0
      alarm/alarmstatistic/build.gradle
  3. 17 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/AlarmStatisticApplication.java
  4. 46 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/cache/AlarmStatisticCache.java
  5. 61 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/cache/FaultSnapCache.java
  6. 442 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/calculate/CalculateStatistic.java
  7. 68 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/config/ThreadPoolConfig.java
  8. 104 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/constant/Constants.java
  9. 67 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/enums/ResultCode.java
  10. 27 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/exception/AdviceException.java
  11. 46 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/response/ResponseWrapper.java
  12. 61 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/DateUtil.java
  13. 63 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/FileUtil.java
  14. 79 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/HttpUtil.java
  15. 126 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/controller/AlarmStatisticController.java
  16. 19 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmHistory.java
  17. 19 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmReal.java
  18. 119 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmSnap.java
  19. 30 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmStatistic.java
  20. 33 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/FaultSnap.java
  21. 18 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/FaultStatus.java
  22. 31 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/Records.java
  23. 147 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/ScheduleTask.java
  24. 30 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/TaskCallableFault.java
  25. 29 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/TaskCallableNormal.java
  26. 42 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/shardingclient/RemoteServiceBuilder.java
  27. 76 0
      alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/shardingclient/ShardingService.java
  28. 9 0
      alarm/alarmstatistic/src/main/resources/AGC测点
  29. 14 0
      alarm/alarmstatistic/src/main/resources/application.yaml
  30. 9 0
      alarm/alarmstatistic/src/main/resources/banner.txt
  31. 407 0
      alarm/alarmstatistic/src/main/resources/fjzt.txt
  32. 138 0
      alarm/alarmstatistic/src/main/resources/mappers/AlarmSnapMapper.xml
  33. 44 0
      alarm/custom/build.gradle
  34. 22 0
      alarm/custom/src/main/java/com/gyee/wisdom/Bootstrap.java
  35. 23 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/ApplicationReadyEventListener.java
  36. 225 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/CalculateServer.java
  37. 30 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/config/ConfigProperties.java
  38. 48 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/controller/ConfigController.java
  39. 41 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/cornjob/CacheRefreshJob.java
  40. 21 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/StationInfo.java
  41. 96 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/TagInfo.java
  42. 14 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/WindturbineGroup.java
  43. 26 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/WindturbineInfo.java
  44. 155 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunction.java
  45. 37 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionAVG.java
  46. 51 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionLastUpdateTime.java
  47. 114 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMAR.java
  48. 40 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMAX.java
  49. 95 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMR.java
  50. 95 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionRiseExceed.java
  51. 62 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionSustain.java
  52. 236 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmRule.java
  53. 39 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmScript.java
  54. 78 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlertSnapFactory.java
  55. 43 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/ScriptShell.java
  56. 6 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/ThingType.java
  57. 64 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/AlarmExpression.java
  58. 220 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/Analyzer.java
  59. 9 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/Token.java
  60. 12 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/TokenType.java
  61. 306 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/service/CacheService.java
  62. 162 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/service/SqlService.java
  63. 106 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/restful/RestfulClient.java
  64. 57 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/AlarmSnapService.java
  65. 34 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/RemoteServiceBuilder.java
  66. 19 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmHistory.java
  67. 41 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmHistoryInfo.java
  68. 33 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmSnap.java
  69. 49 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/ClientStompFrameHandler.java
  70. 34 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/ClientStompSessionHandler.java
  71. 35 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/RequestClient.java
  72. 86 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/StompClient.java
  73. 62 0
      alarm/custom/src/main/java/com/gyee/wisdom/alarm/util/SpringContextUtils.java
  74. 2 0
      alarm/custom/src/main/java/lombok.config
  75. BIN
      alarm/custom/src/main/lib/ojdbc6.jar
  76. 45 0
      alarm/custom/src/main/resources/application.yaml
  77. 9 0
      alarm/custom/src/main/resources/banner.txt
  78. 64 0
      alarm/custom/src/main/resources/log4j2.xml
  79. 86 0
      alarm/custom/src/test/java/TestScriptShell.java
  80. 80 0
      alarm/custom/src/test/java/TestThreadPool.java
  81. 41 0
      alarm/hrwindnew/build.gradle
  82. 15 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/HrwindNewApplication.java
  83. 24 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/ApplicationReadyEventListener.java
  84. 90 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/CalculateServer.java
  85. 41 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/SpringPhysicalNamingStrategy.java
  86. 35 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/Status8Properties.java
  87. 25 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/WindturbineConfig.java
  88. 25 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/model/TagInfo.java
  89. 6 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/model/ThingType.java
  90. 60 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/AlertSnapFactory.java
  91. 235 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/CacheService.java
  92. 124 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/SqlService.java
  93. 31 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/WarningrecordsFactory.java
  94. 338 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/restful/RestfulClient.java
  95. 63 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/AlarmSnapService.java
  96. 33 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/RemoteServiceBuilder.java
  97. 19 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmHistory.java
  98. 41 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmHistoryInfo.java
  99. 33 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmSnap.java
  100. 0 0
      alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/FaultSnap2.java

+ 1 - 0
.gitignore

@@ -28,6 +28,7 @@
 /alarm/sharding/build
 /alarm/alarmstatistic/build
 /alarm/sharding-mysql/build
+/alarm/sharding-mysql2/build
 /alarm/windturbinenew/build
 /calculate/feature/build
 /calculate/status8/build

+ 33 - 0
alarm/alarmstatistic/build.gradle

@@ -0,0 +1,33 @@
+buildscript {
+    repositories {
+        mavenLocal()
+        maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
+        mavenCentral()
+    }
+    dependencies {
+        classpath("$bootGroup:spring-boot-gradle-plugin:$springBootVersion")
+    }
+}
+
+apply plugin: "$bootGroup"
+apply plugin: 'io.spring.dependency-management'
+
+
+dependencies {
+    testCompile group: 'junit', name: 'junit', version: '4.12'
+
+    compile fileTree(dir: 'src/main/lib', include: '*.jar')
+    compile("$bootGroup:spring-boot-starter-web")
+    compile("$bootGroup:spring-boot-starter-websocket")
+    compile("$bootGroup:spring-boot-starter-undertow")
+    compile('org.apache.logging.log4j:log4j-core:2.15.0')
+    compile('org.apache.logging.log4j:log4j-jul:2.15.0')
+    compile('org.apache.logging.log4j:log4j-api:2.15.0')
+    compile('org.apache.logging.log4j:log4j-slf4j-impl:2.15.0')
+    compile 'com.alibaba:fastjson:1.2.17'
+    compile 'com.squareup.okhttp3:okhttp:3.4.1'
+    compile('com.fasterxml.jackson.datatype:jackson-datatype-jdk8')
+    compile("com.netflix.feign:feign-core:8.18.0")
+    compile("com.netflix.feign:feign-jackson:8.18.0")
+}
+

+ 17 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/AlarmStatisticApplication.java

@@ -0,0 +1,17 @@
+package com.gyee.wisdom;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@EnableAsync
+@EnableScheduling
+@SpringBootApplication
+public class AlarmStatisticApplication {
+
+	public static void main(String[] args) {
+		SpringApplication.run(AlarmStatisticApplication.class, args);
+	}
+
+}

+ 46 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/cache/AlarmStatisticCache.java

@@ -0,0 +1,46 @@
+package com.gyee.wisdom.alarm.statistic.common.cache;
+
+import com.gyee.wisdom.alarm.statistic.model.AlarmStatistic;
+
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ * 风机健康指数缓存
+ */
+public class AlarmStatisticCache {
+
+    // key:风机ID   value:AlarmStatistic的map对象:key:风机部件
+    public static HashMap<String, Map<String, AlarmStatistic>> statisticMap = new HashMap<>();
+
+    /**
+     * 获取结果
+     *
+     * @param wtId 风机ID
+     * @return
+     */
+    public static Map<String, AlarmStatistic> getMap(String wtId) {
+        if (statisticMap.containsKey(wtId))
+            return statisticMap.get(wtId);
+
+        return null;
+    }
+
+    /**
+     * put 风机指标
+     *
+     * @param wtId 风机ID
+     * @param map  风机部件的指标对象
+     */
+    public static void setMap(String wtId, Map<String, AlarmStatistic> map) {
+        if (statisticMap.containsKey(wtId))
+            statisticMap.replace(wtId, map);
+        else
+            statisticMap.put(wtId, map);
+    }
+
+    public static HashMap<String, Map<String, AlarmStatistic>> getAll(){
+        return statisticMap;
+    }
+}

+ 61 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/cache/FaultSnapCache.java

@@ -0,0 +1,61 @@
+package com.gyee.wisdom.alarm.statistic.common.cache;
+
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FaultSnapCache {
+
+
+    // key:风机ID  value:状态
+    public static Map<String, Integer> map = new HashMap<>();
+
+    /**
+     * 获取结果
+     *
+     * @param wtId 风机ID
+     * @return
+     */
+    public static boolean getWindturbine(String wtId) {
+        if (map.containsKey(wtId))
+            return true;
+
+        return false;
+    }
+
+    /**
+     * add 风机ID
+     *
+     * @param wtId 风机ID
+     */
+    public static void setMap(String wtId, Integer value) {
+        map.put(wtId, value);
+    }
+
+    /**
+     * 获取值
+     */
+    public static Integer getValue(String wtId) {
+        if (map.containsKey(wtId))
+            return map.get(wtId);
+
+        return -1;
+    }
+
+    /**
+     * 移除
+     * @param wtId
+     */
+    public static void removeValue(String wtId){
+        if (map.containsKey(wtId))
+            map.remove(wtId);
+    }
+
+    /**
+     * 清除
+     */
+    public static void clearMap() {
+        map.clear();
+    }
+
+}

+ 442 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/calculate/CalculateStatistic.java

@@ -0,0 +1,442 @@
+package com.gyee.wisdom.alarm.statistic.common.calculate;
+
+import com.gyee.wisdom.alarm.statistic.common.cache.FaultSnapCache;
+import com.gyee.wisdom.alarm.statistic.common.util.DateUtil;
+import com.gyee.wisdom.alarm.statistic.model.AlarmReal;
+import com.gyee.wisdom.alarm.statistic.model.AlarmSnap;
+import com.gyee.wisdom.alarm.statistic.model.AlarmStatistic;
+import com.gyee.wisdom.alarm.statistic.model.Records;
+import org.springframework.util.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 根据报警计算健康指数
+ */
+public class CalculateStatistic {
+
+    /**
+     * 按照风机部件过滤报警
+     *
+     * @param list
+     * @param widget 部件
+     * @return
+     */
+    public static List<AlarmReal> getRealTimeAlarm(List<AlarmSnap> list, String widget) {
+        List<AlarmReal> snaps = new ArrayList<>();
+
+        if (list == null || list.size() == 0)
+            return snaps;
+
+        // 部件不为空则按照部件过滤
+        if (StringUtils.hasText(widget)) {
+            for (AlarmSnap alarm : list) {
+                String category = null;
+                if (alarm.getCategory1().equals("windturbine") && alarm.getCategory2() != null)
+                    category = alarm.getCategory2();
+                if (alarm.getCategory1().equals("custom") && alarm.getCategory3() != null)
+                    category = alarm.getCategory3();
+
+                if (category != null && widget.toUpperCase().contains(category.toUpperCase()))
+                    snaps.add(new AlarmReal(alarm.getLastUpdateTime(), alarm.getAlertText(), alarm.getRankName()));
+            }
+        } else {
+            for (AlarmSnap alarm : list) {
+                snaps.add(new AlarmReal(alarm.getLastUpdateTime(), alarm.getAlertText(), alarm.getRankName()));
+            }
+        }
+
+        return snaps;
+    }
+
+
+    /**
+     * 计算正常风机健康指数
+     *
+     * @param list 报警历史数据
+     * @return
+     */
+    public static Map<String, AlarmStatistic> calculateNormal(List<Records> list, long interval) {
+
+        if (list == null || list.size() == 0) {
+            Map<String, AlarmStatistic> map = new HashMap<>();
+            AlarmStatistic statistic = new AlarmStatistic(4, 0, 0);
+            map.put("clx", statistic);
+            map.put("fdj", statistic);
+            map.put("bj", statistic);
+            map.put("ph", statistic);
+            map.put("yy", statistic);
+            map.put("other", statistic);
+
+            return map;
+        }
+
+        return filterNormal(list, interval);
+    }
+
+    /**
+     * 计算故障风机健康指数
+     * @param list
+     * @return
+     */
+    public static Map<String, AlarmStatistic> calculateFault(List<AlarmSnap> list) {
+
+        if (list == null || list.size() == 0) {
+            Map<String, AlarmStatistic> map = new HashMap<>();
+            AlarmStatistic statistic = new AlarmStatistic(1, 0, 0);
+
+            map.put("clx", statistic);
+            map.put("fdj", statistic);
+            map.put("bj", statistic);
+            map.put("ph", statistic);
+            map.put("yy", statistic);
+            map.put("other", statistic);
+
+            return map;
+        }
+
+        return filterFault(list);
+    }
+
+
+    /**
+     * 部件过滤
+     *
+     * @param list
+     * @param interval
+     * @return
+     */
+    private static Map<String, AlarmStatistic> filterNormal(List<Records> list, long interval) {
+        // 过滤后的集合 1-3级
+        List<Records> listCLX = new ArrayList<>();
+        List<Records> listFDJ = new ArrayList<>();
+        List<Records> listBJ = new ArrayList<>();
+        List<Records> listPH = new ArrayList<>();
+        List<Records> listYY = new ArrayList<>();
+        List<Records> listOther = new ArrayList<>();
+        // 过滤后的集合 4-5级
+        List<Records> listCLX2 = new ArrayList<>();
+        List<Records> listFDJ2 = new ArrayList<>();
+        List<Records> listBJ2 = new ArrayList<>();
+        List<Records> listPH2 = new ArrayList<>();
+        List<Records> listYY2 = new ArrayList<>();
+        List<Records> listOther2 = new ArrayList<>();
+        boolean fault = false;
+
+        for (Records records : list) {
+            String category = "";
+            if (FaultSnapCache.getWindturbine(records.getWindturbineId()))
+                fault = true;
+
+            int rank = records.getRank();
+            if (records.getCategory1().equals("windturbine") && records.getCategory2() != null)
+                category = records.getCategory2();
+            if (records.getCategory1().equals("custom") && records.getCategory3() != null)
+                category = records.getCategory3();
+
+            if (category.toUpperCase().contains("CLX")) {
+                if (rank <= 3)
+                    listCLX.add(records);
+                else
+                    listCLX2.add(records);
+            } else if (category.toUpperCase().contains("FDJ")) {
+                if (rank <= 3)
+                    listFDJ.add(records);
+                else
+                    listFDJ2.add(records);
+            } else if (category.toUpperCase().contains("PH")) {
+                if (rank <= 3)
+                    listPH.add(records);
+                else
+                    listPH2.add(records);
+            } else if (category.toUpperCase().contains("BJ")) {
+                if (rank <= 3)
+                    listBJ.add(records);
+                else
+                    listBJ2.add(records);
+            } else if (category.toUpperCase().contains("YY")) {
+                if (rank <= 3)
+                    listYY.add(records);
+                else
+                    listYY2.add(records);
+            } else {
+                if (rank <= 3)
+                    listOther.add(records);
+                else
+                    listOther2.add(records);
+            }
+        }
+
+
+        Map<String, AlarmStatistic> map = new HashMap<>();
+        map.put("clx", intervalFilter(listCLX, listCLX2, fault, interval));
+        map.put("fdj", intervalFilter(listFDJ, listFDJ2, fault, interval));
+        map.put("bj", intervalFilter(listBJ, listBJ2, fault, interval));
+        map.put("ph", intervalFilter(listPH, listPH2, fault, interval));
+        map.put("yy", intervalFilter(listYY, listYY2, fault, interval));
+        map.put("other", intervalFilter(listOther, listOther2, fault, interval));
+
+        return map;
+    }
+
+
+    /**
+     * 评级计算
+     *
+     * @param list
+     * @param list2
+     * @param fault    是否总故障
+     * @param interval
+     * @return
+     */
+    private static AlarmStatistic intervalFilter(List<Records> list, List<Records> list2, boolean fault, long interval) {
+
+        int star = 0;
+        // 计数器
+        int count = 0;
+        int count2 = 0;
+
+        for (int i = 0; i < list.size() - 1; i++) {
+            long ts1 = DateUtil.covertDateTimestamp(list.get(i).getAlertTime());
+            long ts2 = DateUtil.covertDateTimestamp(list.get(i + 1).getAlertTime());
+
+            if (Math.abs(ts2 - ts1) > interval) {
+                count += 1;
+            }
+        }
+
+        boolean rankFlag4 = false;
+        boolean rankFlag5 = false;
+        for (int i = 0; i < list2.size() - 1; i++) {
+            long ts1 = DateUtil.covertDateTimestamp(list2.get(i).getAlertTime());
+            long ts2 = DateUtil.covertDateTimestamp(list2.get(i + 1).getAlertTime());
+
+            if (Math.abs(ts2 - ts1) > interval) {
+                count2 += 1;
+            }
+            if (list2.get(i).getRank() == 4)
+                rankFlag4 = true;
+            if (list2.get(i).getRank() == 5)
+                rankFlag5 = true;
+        }
+
+
+        if (fault) {
+            star = 1;
+        } else {
+            if (count <= 10)
+                star = 4;
+            else
+                star = 3;
+
+            if (rankFlag4)
+                star = 2;
+            if (rankFlag5)
+                star = 1;
+        }
+
+        return new AlarmStatistic(star, count, count2);
+    }
+
+    /**
+     * 部件过滤
+     *
+     * @param list
+     * @return
+     */
+    private static Map<String, AlarmStatistic> filterFault(List<AlarmSnap> list) {
+        int lowCountCLX = 0;
+        int heightCountCLX = 0;
+        int lowCountFDJ = 0;
+        int heightCountFDJ = 0;
+        int lowCountBJ = 0;
+        int heightCountBJ = 0;
+        int lowCountPH = 0;
+        int heightCountPH = 0;
+        int lowCountYY = 0;
+        int heightCountYY = 0;
+        int lowCountOther = 0;
+        int heightCountOther = 0;
+        boolean rankCLX4 = false;
+        boolean rankFDJ4 = false;
+        boolean rankBJ4 = false;
+        boolean rankPH4 = false;
+        boolean rankYY4 = false;
+        boolean rankOther4 = false;
+        boolean rankCLX5 = false;
+        boolean rankFDJ5 = false;
+        boolean rankBJ5 = false;
+        boolean rankPH5 = false;
+        boolean rankYY5 = false;
+        boolean rankOther5 = false;
+        boolean fault = false;
+
+        for (AlarmSnap records : list) {
+            String category = "";
+            if (FaultSnapCache.getWindturbine(records.getWindturbineId()))
+                fault = true;
+
+            int rank = records.getRank();
+            if (records.getCategory1().equals("windturbine") && records.getCategory2() != null)
+                category = records.getCategory2();
+            if (records.getCategory1().equals("custom") && records.getCategory3() != null)
+                category = records.getCategory3();
+
+            if (category.toUpperCase().contains("CLX")) {
+                if (rank <= 3)
+                    lowCountCLX += 1;
+                else
+                    heightCountCLX += 1;
+                if (rank == 4)
+                    rankCLX4 = true;
+                if (rank == 5)
+                    rankCLX5 = true;
+            } else if (category.toUpperCase().contains("FDJ")) {
+                if (rank <= 3)
+                    lowCountFDJ += 1;
+                else
+                    heightCountFDJ += 1;
+                if (rank == 4)
+                    rankFDJ4 = true;
+                if (rank == 5)
+                    rankFDJ5 = true;
+            } else if (category.toUpperCase().contains("PH")) {
+                if (rank <= 3)
+                    lowCountPH += 1;
+                else
+                    heightCountPH += 1;
+                if (rank == 4)
+                    rankPH4 = true;
+                if (rank == 5)
+                    rankPH5 = true;
+            } else if (category.toUpperCase().contains("BJ")) {
+                if (rank <= 3)
+                    lowCountBJ += 1;
+                else
+                    heightCountBJ += 1;
+                if (rank == 4)
+                    rankBJ4 = true;
+                if (rank == 5)
+                    rankBJ5 = true;
+            } else if (category.toUpperCase().contains("YY")) {
+                if (rank <= 3)
+                    lowCountYY += 1;
+                else
+                    heightCountYY += 1;
+                if (rank == 4)
+                    rankYY4 = true;
+                if (rank == 5)
+                    rankYY5 = true;
+            } else {
+                if (rank <= 3)
+                    lowCountOther += 1;
+                else
+                    heightCountOther += 1;
+                if (rank == 4)
+                    rankOther4 = true;
+                if (rank == 5)
+                    rankOther5 = true;
+            }
+        }
+
+
+        Map<String, AlarmStatistic> map = new HashMap<>();
+        map.put("clx", countFilter(lowCountCLX, heightCountCLX, fault, rankCLX4, rankCLX5));
+        map.put("fdj", countFilter(lowCountFDJ, heightCountFDJ, fault, rankFDJ4, rankFDJ5));
+        map.put("bj", countFilter(lowCountBJ, heightCountBJ, fault, rankBJ4, rankBJ5));
+        map.put("ph", countFilter(lowCountPH, heightCountPH, fault, rankPH4, rankPH5));
+        map.put("yy", countFilter(lowCountYY, heightCountYY, fault, rankYY4, rankYY5));
+        map.put("other", countFilter(lowCountOther, heightCountOther, fault, rankOther4, rankOther5));
+
+        return map;
+    }
+
+    /**
+     * 故障风机将抗指数计算
+     *
+     * @param lowCount
+     * @param heightCount
+     * @param fault
+     * @return
+     */
+    private static AlarmStatistic countFilter(int lowCount, int heightCount, boolean fault, boolean rank4, boolean rank5) {
+        int star = 0;
+
+        if (fault) {
+            star = 1;
+        } else {
+            if (lowCount <= 10)
+                star = 4;
+            else
+                star = 3;
+            if (rank4)
+                star = 2;
+            if (rank5)
+                star = 1;
+        }
+
+        return new AlarmStatistic(star, lowCount, heightCount);
+    }
+
+
+    /**
+     * 正常风机健康指数计算和统计次数
+     *
+     * @param list
+     * @param list2
+     * @param fault
+     * @param interval
+     * @return
+     */
+    private static AlarmStatistic intervalFilter(List<Records> list, List<Records> list2, boolean fault, int interval) {
+
+        int star = 0;
+        // 计数器
+        int count = 0;
+        int count2 = 0;
+
+        for (int i = 0; i < list.size() - 1; ++i) {
+            long ts1 = DateUtil.covertDateTimestamp((list.get(i)).getAlertTime());
+            long ts2 = DateUtil.covertDateTimestamp((list.get(i + 1)).getAlertTime());
+            if (Math.abs(ts2 - ts1) > interval) {
+                count += 1;
+            }
+        }
+
+        boolean rankFlag4 = false;
+        boolean rankFlag5 = false;
+        for (int i = 0; i < list2.size() - 1; i++) {
+            long ts1 = DateUtil.covertDateTimestamp(list2.get(i).getAlertTime());
+            long ts2 = DateUtil.covertDateTimestamp(list2.get(i + 1).getAlertTime());
+
+            if (Math.abs(ts2 - ts1) > interval) {
+                count2 += 1;
+            }
+            if (list2.get(i).getRank() == 4)
+                rankFlag4 = true;
+            if (list2.get(i).getRank() == 5)
+                rankFlag5 = true;
+        }
+
+
+        if (fault) {
+            star = 1;
+        } else {
+            if (count <= 10)
+                star = 4;
+            else
+                star = 3;
+
+            if (rankFlag4)
+                star = 2;
+            if (rankFlag5)
+                star = 1;
+        }
+
+        return new AlarmStatistic(star, count, count2);
+    }
+}
+

+ 68 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/config/ThreadPoolConfig.java

@@ -0,0 +1,68 @@
+package com.gyee.wisdom.alarm.statistic.common.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+public class ThreadPoolConfig {
+
+    /**
+     *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
+     *	当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
+     *  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
+     */
+
+    /**
+     * 核心线程数(默认线程数)
+     */
+    private static final int corePoolSize = 40;
+    /**
+     * 最大线程数
+     */
+    private static final int maxPoolSize = 80;
+    /**
+     * 允许线程空闲时间(单位:默认为秒)
+     */
+    private static final int keepAliveTime = 60;
+    /**
+     * 缓冲队列大小
+     */
+    private static final int queueCapacity = 300;
+    /**
+     * 允许等待最长时间
+     */
+    private static final int awaitTime = 15;
+    /**
+     * 线程池名前缀
+     */
+    private static final String threadNamePrefix = "Alarm-Thread-";
+
+    private ThreadPoolTaskExecutor executor;
+
+    public ThreadPoolTaskExecutor getExecutor() {
+        if (executor == null)
+            executor = taskExecutor();
+
+        return executor;
+    }
+
+
+    private ThreadPoolTaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveTime);
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.setAwaitTerminationSeconds(awaitTime);
+
+        // 线程池对拒绝任务的处理策略
+        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+}

+ 104 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/constant/Constants.java

@@ -0,0 +1,104 @@
+package com.gyee.wisdom.alarm.statistic.common.constant;
+
+import com.gyee.wisdom.alarm.statistic.common.util.FileUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Component
+public class Constants {
+
+    /**
+     * 定时任务  轮询报警历史
+     */
+    public static final long FIXED_RATES = 10 * 60 * 1000;
+    /**
+     * 计算间隔
+     */
+    public static final long INTERVAL_MILL = 10 * 60 * 1000;
+
+    /**
+     * 风机的状态点          故障:5  维护:6
+     */
+    public static String WIND_TURBINE_STATUS_POINT = "";
+    public static final Integer FAULT_CODE = 5;
+    public static final Integer MAINTAIN_CODE = 6;
+
+    /**
+     * 风场AGC测点
+     */
+    public static final String AGC_MHS = "MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0296";
+    public static final String AGC_NSS = "NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1019";
+    public static final String AGC_XS = "XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0411";
+    public static final String AGC_SBQ = "SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818,SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818";
+    public static final String AGC_QS = "QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1281,SLAGC.NX_GD_QSF_DQ_P1_L1_001_AI0052";
+
+    /**
+     * 风电实时总功率
+     */
+    public static final String REAL_POWER = "JSFW.NX_GD_FDC_XX_XX_XXX_XXX_CI0135";
+
+    /**
+     * 所有场站风机集合
+     */
+    public static Map<String, List<String>> mapWindTurbine = new HashMap<>();
+
+
+    static {
+        List<String> listNSS = new ArrayList<>();
+        String nss = "NG01_";
+        for (int i = 1; i <= 99; i++) {
+            String t = i < 10 ? "0" + i : i + "";
+            listNSS.add(nss + t);
+        }
+
+        List<String> listMHS = new ArrayList<>();
+        String mhs = "MG01_";
+        for (int i = 1; i <= 43; i++) {
+            String t = i < 10 ? "0" + i : i + "";
+            listMHS.add(mhs + t);
+        }
+
+        List<String> listSBQ = new ArrayList<>();
+        String sbq = "SG01_";
+        for (int i = 1; i <= 116; i++) {
+            String t = i < 10 ? "0" + i : i + "";
+            listSBQ.add(sbq + t);
+        }
+
+        List<String> listXS = new ArrayList<>();
+        String xs = "XG01_";
+        for (int i = 1; i <= 58; i++) {
+            String t = i < 10 ? "0" + i : i + "";
+            listXS.add(xs + t);
+        }
+
+        List<String> listQS = new ArrayList<>();
+        String qs = "QG01_";
+        for (int i = 1; i <= 91; i++) {
+            String t = i < 10 ? "0" + i : i + "";
+            listQS.add(qs + t);
+        }
+
+        mapWindTurbine.put("NSS_FDC", listNSS);
+        mapWindTurbine.put("MHS_FDC", listMHS);
+        mapWindTurbine.put("SBQ_FDC", listSBQ);
+        mapWindTurbine.put("XS_FDC", listXS);
+        mapWindTurbine.put("QS_FDC", listQS);
+
+        /**
+         * 风机的状态点
+         */
+//        URL url = Thread.currentThread().getContextClassLoader().getResource("fjzt.txt");
+        WIND_TURBINE_STATUS_POINT = FileUtil.readFile("C:\\gyee\\alarm\\statistic\\fjzt.txt");
+//        WIND_TURBINE_STATUS_POINT = FileUtil.readFile(url.getFile());
+
+//        WIND_TURBINE_STATUS_POINT = FileUtil.readFile("fjzt.txt");
+    }
+}

+ 67 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/enums/ResultCode.java

@@ -0,0 +1,67 @@
+package com.gyee.wisdom.alarm.statistic.common.enums;
+
+public enum ResultCode {
+    /* 成功 */
+    SUCCESS(200, "成功"),
+
+    /* 默认失败 */
+    ERROR(4004, "失败"),
+    ERROR_DATA(4005, "数据查询失败"),
+
+    /* 参数错误:1000~1999 */
+    PARAM_NOT_VALID(1001, "参数无效"),
+    PARAM_IS_BLANK(1002, "参数为空"),
+    PARAM_TYPE_ERROR(1003, "参数类型错误"),
+    PARAM_NOT_COMPLETE(1004, "参数缺失"),
+
+    /* 用户错误 */
+    USER_NOT_LOGIN(2001, "用户未登录"),
+    USER_ACCOUNT_ERROR(2002, "账号或密码错误"),
+    USER_FAIL_LOGIN(2003, "登录失败"),
+
+    /* 业务错误 */
+    NO_PERMISSION(3001, "没有权限");
+
+    private Integer code;
+    private String message;
+
+    ResultCode(Integer code) {
+        this.code = code;
+    }
+
+    ResultCode(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    /**
+     * 根据code获取message
+     *
+     * @param code
+     * @return
+     */
+    public static String getMessageByCode(Integer code) {
+        for (ResultCode ele : values()) {
+            if (ele.getCode().equals(code)) {
+                return ele.getMessage();
+            }
+        }
+        return null;
+    }
+}

+ 27 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/exception/AdviceException.java

@@ -0,0 +1,27 @@
+package com.gyee.wisdom.alarm.statistic.common.exception;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.common.enums.ResultCode;
+import com.gyee.wisdom.alarm.statistic.common.response.ResponseWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+
+@Slf4j
+@RestControllerAdvice
+public class AdviceException {
+
+    @ExceptionHandler(Exception.class)
+    public JSONObject exception(ResultCode e) {
+        log.info(e.getMessage());
+        return ResponseWrapper.error(e);
+    }
+
+    @ExceptionHandler(RuntimeException.class)
+    public JSONObject runException(ResultCode e) {
+        log.info(e.getMessage());
+        return ResponseWrapper.error(ResultCode.ERROR);
+    }
+}

+ 46 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/response/ResponseWrapper.java

@@ -0,0 +1,46 @@
+package com.gyee.wisdom.alarm.statistic.common.response;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.common.enums.ResultCode;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.HashMap;
+
+@Data
+public class ResponseWrapper extends HashMap<String, Object> implements Serializable {
+
+    private Integer code;
+    private String message;
+    private Object data;
+    private ResultCode resultCode;
+
+    public static JSONObject error(ResultCode resultCode) {
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject error(int code, String message) {
+        JSONObject json = new JSONObject();
+        json.put("code", code);
+        json.put("msg", message);
+        return json;
+    }
+
+    public static JSONObject success(ResultCode resultCode) {
+        JSONObject json = new JSONObject();
+        json.put("code", resultCode.getCode());
+        json.put("msg", resultCode.getMessage());
+        return json;
+    }
+
+    public static JSONObject successData(Object value) {
+        JSONObject json = new JSONObject();
+        json.put("code", 200);
+        json.put("msg", "成功");
+        json.put("data", value);
+        return json;
+    }
+}

+ 61 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/DateUtil.java

@@ -0,0 +1,61 @@
+package com.gyee.wisdom.alarm.statistic.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+@Slf4j
+public class DateUtil {
+
+    /**
+     * 获取当前时间
+     *
+     * @return
+     */
+    public static String getCurrentDate() {
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+        String date = df.format(new Date());
+        return date;
+    }
+
+    /**
+     * 获取前 N 小时的时间
+     *
+     * @param hour
+     * @return
+     */
+    public static String getPreviousDate(int hour) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - hour);
+        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String date = df.format(calendar.getTime());
+        return date;
+    }
+
+    /**
+     * 字符串时间转时间戳
+     * @param time
+     * @return
+     */
+    public static Long covertDateTimestamp(String time){
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        long stamp = 0;
+        try {
+            stamp = sdf.parse(time).getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+
+        return stamp;
+    }
+
+
+    public static void main(String[] args) {
+        System.out.println(getCurrentDate());
+        System.out.println(getPreviousDate(3 * 360 * 24));
+//        System.out.println(covertDateTimestamp("2021-05-12 00:00:00"));
+    }
+}

+ 63 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/FileUtil.java

@@ -0,0 +1,63 @@
+package com.gyee.wisdom.alarm.statistic.common.util;
+
+import org.springframework.core.io.ClassPathResource;
+
+import java.io.*;
+import java.net.URL;
+import java.util.stream.Collectors;
+
+public class FileUtil {
+
+    public static String getFilePath(String name){
+        String result = "";
+
+        ClassPathResource classPathResource = new ClassPathResource(name);
+        InputStream is = null;
+        try {
+            is = classPathResource.getInputStream();
+            result = new BufferedReader(new InputStreamReader(is))
+                    .lines().collect(Collectors.joining(System.lineSeparator()));
+
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return result;
+    }
+
+
+    public static String readFile(String fileName){
+        File file = new File(fileName);
+        BufferedReader reader = null;
+        String result = "";
+        try {
+            reader = new BufferedReader(new FileReader(file));
+            String tempString;
+            // 一次读入一行,直到读入null为文件结束
+            while ((tempString = reader.readLine()) != null) {
+                // 显示行号
+                result += tempString;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            if(reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return result;
+    }
+}

+ 79 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/common/util/HttpUtil.java

@@ -0,0 +1,79 @@
+package com.gyee.wisdom.alarm.statistic.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+public class HttpUtil {
+
+    private HttpUtil() {
+    }
+
+    /**
+     * 发送get请求
+     *
+     * @param url    地址
+     * @param params 参数
+     * @return 请求结果
+     */
+    public static String get(String url, Map<String, Object> params) {
+        return request("get", url, params);
+    }
+
+    /**
+     * 发送post请求
+     *
+     * @param url    地址
+     * @param params 参数
+     * @return 请求结果
+     */
+    public static String post(String url, Map<String, Object> params) {
+        return request("post", url, params);
+    }
+
+    /**
+     * 发送http请求
+     *
+     * @param method 请求方法
+     * @param url    地址
+     * @param params 参数
+     * @return 请求结果
+     */
+    public static String request(String method, String url, Map<String, Object> params) {
+
+        if (method == null) {
+            throw new RuntimeException("请求方法不能为空");
+        }
+
+        if (url == null) {
+            throw new RuntimeException("url不能为空");
+        }
+
+        HttpUrl.Builder httpBuilder = HttpUrl.parse(url).newBuilder();
+
+        if (params != null) {
+            for (Map.Entry<String, Object> param : params.entrySet()) {
+                httpBuilder.addQueryParameter(param.getKey(), (String) param.getValue());
+            }
+        }
+
+        Request request = new Request.Builder()
+                .url(httpBuilder.build())
+                .method(method, new FormBody.Builder().build())
+                .build();
+
+        try {
+            OkHttpClient client = new OkHttpClient.Builder()
+                    .readTimeout(20, TimeUnit.SECONDS)
+                    .build();
+            Response response = client.newCall(request).execute();
+            return response.body().string();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+}

+ 126 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/controller/AlarmStatisticController.java

@@ -0,0 +1,126 @@
+package com.gyee.wisdom.alarm.statistic.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.common.cache.AlarmStatisticCache;
+import com.gyee.wisdom.alarm.statistic.common.cache.FaultSnapCache;
+import com.gyee.wisdom.alarm.statistic.common.constant.Constants;
+import com.gyee.wisdom.alarm.statistic.common.response.ResponseWrapper;
+import com.gyee.wisdom.alarm.statistic.common.calculate.CalculateStatistic;
+import com.gyee.wisdom.alarm.statistic.common.util.DateUtil;
+import com.gyee.wisdom.alarm.statistic.model.*;
+import com.gyee.wisdom.alarm.statistic.shardingclient.RemoteServiceBuilder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+
+@Slf4j
+@RestController
+@RequestMapping("/alarm")
+@CrossOrigin
+public class AlarmStatisticController {
+
+    @Autowired
+    protected RemoteServiceBuilder serviceBuilder;
+
+    /**
+     * 获取健康指标
+     *
+     * @param stId 场站ID
+     * @param wtId 风机ID
+     * @return
+     */
+    @GetMapping("/statistic")
+    public JSONObject getStatistic(
+            @RequestParam(value = "stId") String stId,
+            @RequestParam(value = "wtId") String wtId) {
+        if (AlarmStatisticCache.getMap(wtId) != null)
+            return ResponseWrapper.successData(AlarmStatisticCache.getMap(wtId));
+
+        Map<String, AlarmStatistic> map;
+        // 故障风机查询3年内的报警
+        if (FaultSnapCache.getWindturbine(wtId)) {
+            String start = DateUtil.getPreviousDate(3 * 360 * 24);
+            List<AlarmSnap> list = serviceBuilder.ShardingService().getRealTimeAlarm(
+                    stId, wtId, start, DateUtil.getCurrentDate());
+            map = CalculateStatistic.calculateFault(list);
+        }
+        else{
+            String start = DateUtil.getPreviousDate(24);
+            String end = DateUtil.getCurrentDate();
+            JSONObject json = serviceBuilder.ShardingService().getAlarmHistoryCount(stId, wtId, start, end);
+            AlarmHistory alarm = JSON.toJavaObject(json, AlarmHistory.class);
+            map = CalculateStatistic.calculateNormal(alarm.getRecords(), Constants.INTERVAL_MILL);
+        }
+
+
+        AlarmStatisticCache.setMap(wtId, map);
+
+        return ResponseWrapper.successData(map);
+    }
+
+
+    /**
+     * 按照部件查询活跃报警
+     *
+     * @param stId   场站ID
+     * @param wtId   风机ID
+     * @param widget 部件 eg:clx、fdj
+     * @return
+     */
+    @GetMapping("/list")
+    public JSONObject getWarningList(
+            @RequestParam(value = "stId") String stId,
+            @RequestParam(value = "wtId") String wtId,
+            @RequestParam(value = "widget", required = false) String widget) {
+
+        List<AlarmReal> realList = new ArrayList<>();
+        String start = DateUtil.getPreviousDate(3 * 360 * 24);
+        String end  = DateUtil.getCurrentDate();
+        List<AlarmSnap> list = serviceBuilder.ShardingService().getRealTimeAlarm(stId, wtId, start, end);
+        if (list != null && list.size() > 0) {
+            realList = CalculateStatistic.getRealTimeAlarm(list, widget);
+        }
+
+        return ResponseWrapper.successData(realList);
+    }
+
+    @GetMapping("/statistic/list")
+    public JSONObject getStatisticList(){
+        return ResponseWrapper.successData(AlarmStatisticCache.getAll());
+    }
+
+
+    @GetMapping("/test")
+    public String get() {
+//        JSONObject json = serviceBuilder.GoldenService().getFaultStatusFromGolden(Constants.WIND_TURBINE_STATUS_POINT);
+//
+//        List<WinTurbineStatus> list = new ArrayList<>();
+//
+//        for(Map.Entry<String, Object> entry : json.entrySet()){
+//            String key = entry.getKey();
+//            JSONObject jsonObject = json.getJSONObject(key);
+//            log.info(jsonObject.getInteger("doubleValue").toString());
+//            WinTurbineStatus status = new WinTurbineStatus();
+//            status.setWindTurbineId(key);
+//            status.setValue(obj.getIntValue("value"));
+//        }
+
+//        log.info(list.toString());
+//        JSONObject json = serviceBuilder.ShardingService().getAlarmHistoryCount(
+//                "NSS_FDC", "NG01_03",
+//                "2021-07-08 23:00:00", "2021-07-09 00:00:00");
+//        JSONArray records1 = json.getJSONArray("records");
+//        Records records = convertValue(json.get("records"), Records.class);
+//        AlarmHistory alarm = JSON.toJavaObject(json, AlarmHistory.class);
+//        Records r = (Records) records1.get(0);
+//        log.info(alarm.toString());
+        return "ss";
+    }
+
+}

+ 19 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmHistory.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class AlarmHistory {
+
+    private String total;
+    private String size;
+    private String current;
+    private Boolean searchCount;
+    private String pages;
+
+    private List<Records> records;
+
+}

+ 19 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmReal.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+
+import lombok.Data;
+
+
+@Data
+public class AlarmReal {
+
+    private String time;
+    private String alertText;
+    private String rankName;
+
+    public AlarmReal(String time, String alertText, String rankName) {
+        this.time = time;
+        this.alertText = alertText;
+        this.rankName = rankName;
+    }
+}

+ 119 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmSnap.java

@@ -0,0 +1,119 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmSnap implements Serializable {
+    private long id;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private int rank;
+    private int isOpened;
+    private Integer isConfirmed;
+    private Date confirmTime;
+    private String confirmPerson;
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private String lastUpdateTime;
+    private String lastUpdatePerson;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+    private String testingpointKey;
+    private String ifixPicture;
+    private String ifixTag;
+    private Date lastCloseTime;
+    private String lastClosePerson;
+    private String dataInfo;
+
+    public String getObjectId() {
+        if (category1.equals("custom")) {
+            switch (category2) {
+                case "1":
+                    return windturbineId;
+                case "2":
+                    return stationId;
+                case "3":
+                    return projectId;
+                case "4":
+                    return lineId;
+                case "5":
+                    return stationId;
+                default:
+                    return "";
+            }
+        } else if (category1.equals("windturbine"))
+            return windturbineId;
+        else
+            return stationId;
+    }
+
+    public String getObjectName() {
+        if (category1.equals("custom")) {
+            switch (category2) {
+                case "1":
+                    return windturbineName;
+                case "2":
+                    return stationName;
+                case "3":
+                    return projectName;
+                case "4":
+                    return lineName;
+                case "5":
+                    return stationName;
+                default:
+                    return "未知";
+            }
+        } else if (category1.equals("windturbine"))
+            return windturbineName;
+        else
+            return stationName;
+
+    }
+
+    public String getRankName() {
+
+        switch (this.rank) {
+            case 1:
+                return "低";
+            case 2:
+                return "中低";
+            case 3:
+                return "中";
+            case 4:
+                return "中高";
+            case 5:
+                return "高";
+            default:
+                return "低";
+        }
+    }
+
+    public String getCategoryName() {
+
+        switch (this.category1) {
+            case "custom":
+                return "自定义";
+            case "windturbine":
+                return "风机";
+            case "SYZ":
+                return "升压站";
+            case "GF":
+                return "光伏";
+            default:
+                return "未知";
+        }
+    }
+}

+ 30 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/AlarmStatistic.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+import lombok.Data;
+
+
+/**
+ * 风机健康指数统计
+ */
+@Data
+public class AlarmStatistic {
+    /**
+     * 几颗星
+     */
+    private Integer star;
+    /**
+     * 一般报警次数
+     */
+    private Integer lowCount;
+    /**
+     * 紧急报警次数
+     */
+    private Integer heightCount;
+
+
+    public AlarmStatistic(Integer star, Integer lowCount, Integer heightCount) {
+        this.star = star;
+        this.lowCount = lowCount;
+        this.heightCount = heightCount;
+    }
+}

+ 33 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/FaultSnap.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class FaultSnap implements Serializable {
+
+    private Long id;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    private int isOpened;
+    private String lastUpdateTime;
+    private String lastUpdatePerson;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+    private String testingpointKey;
+    private long alarmSnapId;
+    private String dataInfo;
+}

+ 18 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/FaultStatus.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+
+import lombok.Data;
+
+@Data
+public class FaultStatus {
+
+    // 风机
+    private String windTurbineId;
+
+    private Integer value;
+
+    public FaultStatus(String windTurbineId, Integer value) {
+        this.windTurbineId = windTurbineId;
+        this.value = value;
+    }
+}

+ 31 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/model/Records.java

@@ -0,0 +1,31 @@
+package com.gyee.wisdom.alarm.statistic.model;
+
+import lombok.Data;
+
+@Data
+public class Records {
+
+    private long id;
+    private String alertTime;
+    private int messageType;
+    private long snapId;
+    private String dataInfo;
+    private String alertTextLast;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private int rank;
+    private String lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+
+}

+ 147 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/ScheduleTask.java

@@ -0,0 +1,147 @@
+package com.gyee.wisdom.alarm.statistic.schedule;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.common.cache.AlarmStatisticCache;
+import com.gyee.wisdom.alarm.statistic.common.cache.FaultSnapCache;
+import com.gyee.wisdom.alarm.statistic.common.config.ThreadPoolConfig;
+import com.gyee.wisdom.alarm.statistic.common.constant.Constants;
+import com.gyee.wisdom.alarm.statistic.common.calculate.CalculateStatistic;
+import com.gyee.wisdom.alarm.statistic.common.util.DateUtil;
+import com.gyee.wisdom.alarm.statistic.model.AlarmHistory;
+import com.gyee.wisdom.alarm.statistic.model.AlarmSnap;
+import com.gyee.wisdom.alarm.statistic.model.AlarmStatistic;
+import com.gyee.wisdom.alarm.statistic.shardingclient.RemoteServiceBuilder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.Future;
+
+/**
+ * 定时任务
+ * 计算风机健康指标
+ */
+@Component
+@Slf4j
+public class ScheduleTask {
+
+    @Autowired
+    private ThreadPoolConfig config;
+    @Autowired
+    private RemoteServiceBuilder serviceBuilder;
+
+
+    /**
+     * 延时2分钟执行
+     * 查询风机24小时内报警并计算指标
+     */
+    @Scheduled(initialDelay = 30 * 1000, fixedRate = Constants.FIXED_RATES)
+    public void scheduledTaskStatistic() throws Exception {
+
+        String end = DateUtil.getCurrentDate();
+
+        for (Map.Entry<String, List<String>> entry : Constants.mapWindTurbine.entrySet()) {
+            //场站
+            String station = entry.getKey();
+            //风机
+            List<String> list = entry.getValue();
+
+            //存储线程的返回值
+            List<Future<JSONObject>> resultNormal = new LinkedList<>();
+            List<Future<List<AlarmSnap>>> resultFault = new LinkedList<>();
+
+            for (String wt : list) {
+                if (FaultSnapCache.getWindturbine(wt)) {
+                    // 故障风机
+                    String start = DateUtil.getPreviousDate(3 * 360 * 24);
+                    TaskCallableFault task = new TaskCallableFault(serviceBuilder, station, wt, start, end);
+                    Future<List<AlarmSnap>> submit = config.getExecutor().submit(task);
+
+                    resultFault.add(submit);
+                } else {
+                    // 正常风机
+                    String start = DateUtil.getPreviousDate(24);
+                    TaskCallableNormal task = new TaskCallableNormal(serviceBuilder, station, wt, start, end);
+                    Future<JSONObject> submit = config.getExecutor().submit(task);
+
+                    resultNormal.add(submit);
+                }
+            }
+
+            //返回结果
+            setStatisticNormal(resultNormal);
+            setStatisticFault(resultFault);
+
+            log.info("缓存风机数量:" + AlarmStatisticCache.statisticMap.size());
+        }
+    }
+
+
+    /**
+     * 查询故障风机
+     */
+    @Scheduled(fixedRate = 30 * 1000) //30s查询一次
+    public void scheduledTaskFaultSnap() {
+        JSONObject json = serviceBuilder.GoldenService().getFaultStatusFromGolden(Constants.WIND_TURBINE_STATUS_POINT);
+        Map<String, Integer> map = new HashMap<>();
+        for (Map.Entry<String, Object> entry : json.entrySet()) {
+            String key = entry.getKey();
+            String prefix = key.substring(0, 1) + "G01_";
+            int id = Integer.valueOf(key.substring(key.length() - 10, key.length() - 7));
+            JSONObject obj = json.getJSONObject(key);
+
+            String wtId = prefix + (id < 10 ? "0" + id : id + "");
+            Integer value = obj.getInteger("doubleValue");
+
+            if (FaultSnapCache.map.containsKey(wtId)) {
+                if (map.get(wtId) == Constants.FAULT_CODE && value == Constants.MAINTAIN_CODE)
+                    map.put(wtId, Constants.FAULT_CODE);
+                if (value == Constants.FAULT_CODE)
+                    map.put(wtId, value);
+            } else if (!map.containsKey(wtId) && value == Constants.FAULT_CODE) {
+                map.put(wtId, value);
+            }
+        }
+        FaultSnapCache.clearMap();
+        FaultSnapCache.map.putAll(map);
+        log.info("当前故障风机:" + FaultSnapCache.map.toString());
+    }
+
+
+    /**
+     * 计算健康指标
+     *
+     * @param results
+     */
+    private void setStatisticNormal(List<Future<JSONObject>> results) throws Exception {
+        //返回结果
+        if (results == null)
+            return;
+
+        for (int i = 0; i < results.size(); i++) {
+            JSONObject json = results.get(i).get();
+            AlarmHistory alarm = JSON.toJavaObject(json, AlarmHistory.class);
+            if (alarm != null && alarm.getRecords() != null && alarm.getRecords().size() > 0) {
+                Map<String, AlarmStatistic> map = CalculateStatistic.calculateNormal(alarm.getRecords(), Constants.INTERVAL_MILL);
+                AlarmStatisticCache.setMap(alarm.getRecords().get(0).getWindturbineId(), map);
+            }
+        }
+    }
+
+    private void setStatisticFault(List<Future<List<AlarmSnap>>> results) throws Exception {
+        //返回结果
+        if (results == null)
+            return;
+
+        for (int i = 0; i < results.size(); i++) {
+            List<AlarmSnap> list = results.get(i).get();
+            if (list != null && list.size() > 0) {
+                Map<String, AlarmStatistic> map = CalculateStatistic.calculateFault(list);
+                AlarmStatisticCache.setMap(list.get(0).getWindturbineId(), map);
+            }
+        }
+    }
+}

+ 30 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/TaskCallableFault.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.alarm.statistic.schedule;
+
+import com.gyee.wisdom.alarm.statistic.model.AlarmSnap;
+import com.gyee.wisdom.alarm.statistic.shardingclient.RemoteServiceBuilder;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+public class TaskCallableFault implements Callable<List<AlarmSnap>> {
+
+    private String stId;
+    private String wtId;
+    private String startTime;
+    private String endTime;
+    private RemoteServiceBuilder serviceBuilder;
+
+    public TaskCallableFault(RemoteServiceBuilder serviceBuilder, String stId, String wtId, String startTime, String endTime) {
+        this.stId = stId;
+        this.wtId = wtId;
+        this.startTime = startTime;
+        this.endTime = endTime;
+        this.serviceBuilder = serviceBuilder;
+    }
+
+
+    @Override
+    public List<AlarmSnap> call() throws Exception {
+        return this.serviceBuilder.ShardingService().getRealTimeAlarm(this.stId, this.wtId, this.startTime, this.endTime);
+    }
+}

+ 29 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/schedule/TaskCallableNormal.java

@@ -0,0 +1,29 @@
+package com.gyee.wisdom.alarm.statistic.schedule;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.shardingclient.RemoteServiceBuilder;
+
+import java.util.concurrent.Callable;
+
+public class TaskCallableNormal implements Callable<JSONObject> {
+
+    private String stId;
+    private String wtId;
+    private String startTime;
+    private String endTime;
+    private RemoteServiceBuilder serviceBuilder;
+
+    public TaskCallableNormal(RemoteServiceBuilder serviceBuilder, String stId, String wtId, String startTime, String endTime) {
+        this.stId = stId;
+        this.wtId = wtId;
+        this.startTime = startTime;
+        this.endTime = endTime;
+        this.serviceBuilder = serviceBuilder;
+    }
+
+
+    @Override
+    public JSONObject call() throws Exception {
+        return this.serviceBuilder.ShardingService().getAlarmHistoryCount(this.stId, this.wtId, this.startTime, this.endTime);
+    }
+}

+ 42 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/shardingclient/RemoteServiceBuilder.java

@@ -0,0 +1,42 @@
+package com.gyee.wisdom.alarm.statistic.shardingclient;
+
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Slf4j
+@Configuration
+public class RemoteServiceBuilder {
+
+    @Value("${shardingUrl:http://localhost:8075}")
+    private String shardingUrlString;
+    @Value("${goldenUrl:http://localhost:8011}")
+    private String goldenUrlString;
+
+    @Bean
+    public ShardingService ShardingService() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 10000))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(ShardingService.class, shardingUrlString);
+    }
+
+    @Bean
+    public ShardingService GoldenService() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 10000))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(ShardingService.class, goldenUrlString);
+    }
+}

+ 76 - 0
alarm/alarmstatistic/src/main/java/com/gyee/wisdom/alarm/statistic/shardingclient/ShardingService.java

@@ -0,0 +1,76 @@
+package com.gyee.wisdom.alarm.statistic.shardingclient;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.statistic.model.AlarmSnap;
+import com.gyee.wisdom.alarm.statistic.model.FaultSnap;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.List;
+
+public interface ShardingService {
+
+    /**
+     * 查询24小时内的报警
+     *
+     * @param stationid     场站ID
+     * @param windturbineid 风机ID
+     * @param category1     分类  --windturbine、custom
+     * @param category2     部件分类  custom对应都是1  windturbine部件名缩写
+     * @param rank          级别
+     * @param messageType   1--已解除 3--未解除
+     * @param starttime     开始时间  2021-07-08 00:00:00
+     * @param endtime       结束时间  2021-07-08 23:59:59
+     * @return
+     */
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /alarm/history/page?pagenum=1&pagesize=10000&stationid={stationid}" +
+            "&windturbineid={windturbineid}&messagetype=3&starttime={starttime}&endtime={endtime}")
+    JSONObject getAlarmHistoryCount(
+            @Param(value = "stationid") String stationid,
+            @Param(value = "windturbineid") String windturbineid,
+            @Param(value = "starttime") String starttime,
+            @Param(value = "endtime") String endtime
+    );
+
+
+    /**
+     * @param stationid
+     * @param windturbineid
+     * @param category2     部件缩写
+     *
+     * @param isopened      0:已解除   1:未解除
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /alarm/snap?pagenum=1&pagesize=10000&stationid={stationid}" +
+            "&windturbineid={windturbineid}&isopened=1&category1=windturbine" +
+            "&starttime={starttime}&endtime={endtime}")
+    List<AlarmSnap> getRealTimeAlarm(
+            @Param(value = "stationid") String stationid,
+            @Param(value = "windturbineid") String windturbineid,
+            @Param(value = "starttime") String starttime,
+            @Param(value = "endtime") String endtime
+    );
+
+    @Headers({"Content-Type: application/json", "Accept: application/json"})
+    @RequestLine("GET /fault/snap/list?category1=FJ&isOpened=1")
+    List<FaultSnap> getFaultSnap();
+
+
+    @RequestLine("GET /ts/latest?keys={points}")
+    JSONObject getFaultStatusFromGolden(@Param(value = "points") String points);
+
+
+    //获取最新实时报警2   websocketController getRealTimeAlertInfo()
+    @RequestLine("GET /alarm/snap/single?windturbineid={wtId}&alertvalue={alertValue}")
+    List<AlarmSnap> getRealTimeAlarmByObjectId(
+            @Param(value = "cateGory1") String cateGory1,
+            @Param(value = "objectId") String objectId,
+            @Param(value = "startTime") String startTime,
+            @Param(value = "isOpened") boolean isOpened //默认为1
+    );
+}

+ 9 - 0
alarm/alarmstatistic/src/main/resources/AGC测点

@@ -0,0 +1,9 @@
+麻黄山:           MHSDQ.NX_GD_MHSF_DQ_P1_L1_001_AI0296
+香山:             XSDQ.NX_GD_XSF_DQ_P1_L1_001_AI0411
+牛首山:           NSSDQN.NX_GD_NSSF_DQ_P1_L1_001_AI1019
+
+星能第六风电场:   SBQXLDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818
+牛首山第五风电场: SBQNWDQ.NX_GD_SBQF_DQ_P1_L1_001_AI0818
+
+青山:             QSDQ.NX_GD_QSF_DQ_P1_L1_001_AI1281
+宋堡第六风电场:   SLAGC.NX_GD_QSF_DQ_P1_L1_001_AI0052

+ 14 - 0
alarm/alarmstatistic/src/main/resources/application.yaml

@@ -0,0 +1,14 @@
+server:
+  port: 8070
+
+#本地
+#shardingUrl: http://localhost:8075
+#三区
+#shardingUrl: http://192.168.1.14:8075
+#一区
+shardingUrl: http://18.6.30.53:8075
+
+#三区
+#goldenUrl: http://10.155.32.4:8011
+#一区
+goldenUrl: http://18.6.30.53:8011

+ 9 - 0
alarm/alarmstatistic/src/main/resources/banner.txt

@@ -0,0 +1,9 @@
+          _                                      _                          _   _
+   __ _  | |   __ _   _ __   _ __ ___      ___  | |__     __ _   _ __    __| | (_)  _ __     __ _
+  / _` | | |  / _` | | '__| | '_ ` _ \    / __| | '_ \   / _` | | '__|  / _` | | | | '_ \   / _` |
+ | (_| | | | | (_| | | |    | | | | | |   \__ \ | | | | | (_| | | |    | (_| | | | | | | | | (_| |
+  \__,_| |_|  \__,_| |_|    |_| |_| |_|   |___/ |_| |_|  \__,_| |_|     \__,_| |_| |_| |_|  \__, |
+                                                                                            |___/
+
+
+ :: alarm-statistic ::                    version 1.0.0

+ 407 - 0
alarm/alarmstatistic/src/main/resources/fjzt.txt

@@ -0,0 +1,407 @@
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_067_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_068_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_080_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_075_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_069_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_078_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_070_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_076_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_082_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_009_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_010_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_011_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_012_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_013_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_014_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_015_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_016_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_017_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_018_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_019_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_020_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_021_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L2_022_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_023_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_024_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_025_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_026_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_027_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_028_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_029_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_030_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_031_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_032_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L3_033_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_034_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_035_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_036_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_037_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_038_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_039_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_040_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_041_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_042_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_043_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L4_044_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_045_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_046_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_047_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_048_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_049_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_050_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_051_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_052_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_053_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_054_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L5_055_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_056_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_057_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_058_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_059_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_060_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_061_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_062_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_063_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_064_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_065_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P2_L6_066_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_072_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_001_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_002_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_003_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_004_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_005_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_006_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_007_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P1_L1_008_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_079_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_077_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_087_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_073_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_085_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_090_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_088_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_074_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L7_071_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_091_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_081_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_083_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_084_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_086_CI0666,
+QSFJJSFW.NX_GD_QSF_FJ_P3_L8_089_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_001_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_002_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_003_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_004_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_005_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_006_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_007_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_008_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_009_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_010_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L1_011_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_012_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_013_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_014_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_015_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_016_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_017_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_018_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_019_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_020_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_021_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L2_022_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_023_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_024_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_025_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_026_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_027_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_028_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_029_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_030_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_031_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_032_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P1_L3_033_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_034_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_035_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_036_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_037_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_038_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_039_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_040_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_041_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_042_CI0666,
+MHSFJJSFW.NX_GD_MHSF_FJ_P2_L4_043_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_001_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_002_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_003_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_004_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_005_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_007_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_008_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_009_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_006_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_010_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_042_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_043_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_044_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_045_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_046_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_047_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_048_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_049_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_050_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_051_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_052_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_053_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_054_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L5_055_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_056_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_057_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_058_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_059_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_060_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_061_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_062_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_063_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_064_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_065_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L6_066_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_067_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_068_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_069_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_070_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_071_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_072_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_073_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_074_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_075_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_076_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_077_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L7_078_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_079_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_080_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_081_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_082_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_083_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_084_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_085_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_086_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_087_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_088_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_089_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_090_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P3_L8_091_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_101_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_102_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_103_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_104_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_105_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_106_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_107_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L10_108_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_109_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_110_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_111_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_112_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_113_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_114_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_115_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L11_116_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_092_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_093_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_094_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_095_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_096_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_097_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_098_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_099_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P4_L9_100_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_001_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_002_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_003_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_004_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_005_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_006_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_007_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_008_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_009_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_010_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L1_011_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_012_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_013_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_014_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_015_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_016_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_017_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_018_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_019_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_020_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_021_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_022_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_023_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_024_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P1_L2_025_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L1_011_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_012_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_013_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_014_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_015_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_016_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_017_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_018_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_019_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_020_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_021_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_022_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L2_023_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_045_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_046_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_047_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_048_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_049_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_050_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_051_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_052_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_053_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_054_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P1_L3_055_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_057_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_058_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_059_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_060_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_061_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_062_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_063_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_064_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_065_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_066_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_067_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L4_079_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_056_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_068_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_069_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_070_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_071_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_072_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_073_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_074_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_075_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_076_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_077_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L5_078_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_024_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_026_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_027_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_028_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_029_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_030_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_031_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_032_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_033_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_034_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_035_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_036_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_037_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_038_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_039_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_040_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_041_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L3_042_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_043_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_044_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_045_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_046_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_047_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_048_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_049_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_050_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_051_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_052_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_053_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_054_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_055_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_056_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_057_CI0666,
+XSFJJSFW.NX_GD_XSF_FJ_P2_L4_058_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_025_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_026_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_027_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_028_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_029_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_030_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_031_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_032_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P2_L6_033_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_034_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_035_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_036_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_037_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_038_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_039_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_040_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_041_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_042_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_043_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L7_044_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_090_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_091_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_092_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_093_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_094_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_095_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_096_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_097_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_098_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L8_099_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_080_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_081_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_082_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_083_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_084_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_085_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_086_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_087_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_088_CI0666,
+NSSFJJSFW.NX_GD_NSSF_FJ_P3_L9_089_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_001_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_002_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_003_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_004_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_005_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_006_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_007_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_008_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_009_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_010_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L1_011_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_012_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_013_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_014_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_015_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_016_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_017_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_018_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_019_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_020_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_021_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L2_022_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_023_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_024_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_025_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_026_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_027_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_028_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_029_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_030_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_031_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_032_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P1_L3_033_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_034_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_035_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_036_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_037_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_038_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_039_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_040_CI0666,
+SBQFJJSFW.NX_GD_SBQF_FJ_P2_L4_041_CI0666,

+ 138 - 0
alarm/alarmstatistic/src/main/resources/mappers/AlarmSnapMapper.xml

@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.gyee.wisdom.alarm.sharding.mapper.AlarmSnapMapper">
+
+    <select id="queryAll" parameterType="java.util.Map" resultType="com.gyee.wisdom.alarm.sharding.entity.AlarmSnap">
+        select * from  ALARMSNAP a
+        <where>
+            1=1
+            <if test="starttime !=null and endtime !=null">
+                and lastupdatetime &gt;= #{starttime,jdbcType=DATE} and lastupdatetime &lt;= #{endtime,jdbcType=DATE}
+            </if>
+            <if test="stid !=null and stid !=''">
+                and a.stationid=#{stid}
+            </if>
+            <if test="wtid !=null and wtid !=''">
+                and a.windturbineid=#{wtid}
+            </if>
+            <if test="category1 !=null and category1 !=''">
+                and a.category1=#{category1}
+            </if>
+            <if test="category2 !=null and category2 !=''">
+                and a.category2=#{category2}
+            </if>
+            <if test="rank !=null and rank !=''">
+                and a.rank=#{rank}
+            </if>
+            <if test="modelid !=null and modelid !=''">
+                and a.modelid=#{modelid}
+            </if>
+            <if test="isopened !=null ">
+                and a.isopened=#{isopened}
+            </if>
+            <if test="keyword !=null and keyword !=''">
+                and a.alerttext like #{keyword}
+            </if>
+        </where>
+        order by a.lastupdatetime  desc
+    </select>
+
+    <select id="pageQueryAll" parameterType="java.util.Map" resultType="com.gyee.wisdom.alarm.sharding.entity.AlarmSnap">
+        select * from  ALARMSNAP a
+        <where>
+            1=1
+            <if test="starttime !=null and endtime !=null">
+                and lastupdatetime &gt;= #{starttime,jdbcType=DATE} and lastupdatetime &lt;= #{endtime,jdbcType=DATE}
+            </if>
+            <if test="stid !=null and stid !=''">
+                and a.stationid=#{stid}
+            </if>
+            <if test="wtid !=null and wtid !=''">
+                and a.windturbineid=#{wtid}
+            </if>
+            <if test="category1 !=null and category1 !=''">
+                and a.category1=#{category1}
+            </if>
+            <if test="category2 !=null and category2 !=''">
+                and a.category2=#{category2}
+            </if>
+            <if test="rank !=null and rank !=''">
+                and a.rank=#{rank}
+            </if>
+            <if test="modelid !=null and modelid !=''">
+                and a.modelid=#{modelid}
+            </if>
+            <if test="isopened !=null ">
+                and a.isopened=#{isopened}
+            </if>
+            <if test="keyword !=null and keyword !=''">
+                and a.alerttext like #{keyword}
+            </if>
+        </where>
+        order by a.lastupdatetime  desc
+    </select>
+
+    <insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="false">
+        insert into alarmsnap ( ID, STATIONID, PROJECTID, LINEID, WINDTURBINEID, ALERTVALUE, CATEGORY1, CATEGORY2, CATEGORY3, RANK, ISOPENED, LASTUPDATETIME, STATIONNAME, PROJECTNAME, LINENAME, WINDTURBINENAME, ALERTTEXT, MODELID, TESTINGPOINTKEY, DATAINFO )
+        <foreach collection="list" item="item" index="index" separator="union all" >
+            ( select
+                #{item.id},#{item.stationId},#{item.projectId},#{item.lineId},#{item.windturbineId},
+                #{item.alertValue},#{item.category1},#{item.category2},#{item.category3},#{item.rank},
+                #{item.isOpened},#{item.lastUpdateTime},#{item.stationName},#{item.projectName},
+                #{item.lineName},#{item.windturbineName},#{item.alertText},#{item.modelId},
+                #{item.testingpointKey},#{item.dataInfo}
+            from dual )
+        </foreach>
+    </insert>
+
+
+    <!--<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="false">-->
+        <!--INSERT ALL-->
+        <!--<foreach item="item" index="index" collection="list">-->
+            <!--into alarmsnap ( ID, STATIONID, PROJECTID, LINEID, WINDTURBINEID, ALERTVALUE, CATEGORY1, CATEGORY2, CATEGORY3, RANK, ISOPENED, LASTUPDATETIME, STATIONNAME, PROJECTNAME, LINENAME, WINDTURBINENAME, ALERTTEXT, MODELID, TESTINGPOINTKEY, DATAINFO )-->
+            <!--values-->
+            <!--( #{item.id},#{item.stationId},#{item.projectId},#{item.lineId},#{item.windturbineId},-->
+            <!--#{item.alertValue},#{item.category1},#{item.category2},#{item.category3},#{item.rank},-->
+            <!--#{item.isOpened},#{item.lastUpdateTime},#{item.stationName},#{item.projectName},-->
+            <!--#{item.lineName},#{item.windturbineName},#{item.alertText},#{item.modelId},-->
+            <!--#{item.testingpointKey},#{item.dataInfo}  )-->
+        <!--</foreach>-->
+        <!--SELECT 1 FROM DUAL-->
+    <!--</insert>-->
+
+    <update id="batchUpdate" parameterType="java.util.List">
+        <foreach collection="list" item="item" index="index" open="begin" close=";end;" separator=";">
+            UPDATE alarmsnap
+            <set>
+                ISOPENED = #{item.isOpened},
+                LASTUPDATETIME = #{item.lastUpdateTime},
+                CATEGORY3=#{item.category3},
+                DATAINFO = #{item.dataInfo}
+            </set>
+            where id = #{item.id}
+        </foreach>
+    </update>
+
+    <select id="findByStationIdAndAlertValue" parameterType="java.util.Map" resultType="com.gyee.wisdom.alarm.sharding.entity.AlarmSnap">
+        select * from  ALARMSNAP a
+        <where>
+            a.stationid=#{stationid} and a.alertvalue = #{alertvalue} and rownum = 1
+        </where>
+    </select>
+
+    <select id="findByWindturbineIdAndAlertValue" parameterType="java.util.Map" resultType="com.gyee.wisdom.alarm.sharding.entity.AlarmSnap">
+        select * from  ALARMSNAP a
+        <where>
+            a.windturbineid=#{windturbineid} and a.alertvalue = #{alertvalue} and rownum = 1
+        </where>
+    </select>
+
+    <select id="findByTestingpointkey" parameterType="java.util.Map" resultType="com.gyee.wisdom.alarm.sharding.entity.AlarmSnap">
+        select * from  ALARMSNAP a
+        <where>
+            a.testingpointkey=#{testingpointkey}  and rownum = 1
+        </where>
+    </select>
+
+
+</mapper>

+ 44 - 0
alarm/custom/build.gradle

@@ -0,0 +1,44 @@
+buildscript {
+    repositories {
+        mavenLocal()
+        maven {
+            allowInsecureProtocol = true
+            url "http://maven.aliyun.com/nexus/content/groups/public" }
+        mavenCentral()
+    }
+    dependencies {
+        classpath("$bootGroup:spring-boot-gradle-plugin:$springBootVersion")
+    }
+}
+version = '1.0.02'
+apply plugin: "$bootGroup"
+apply plugin: 'io.spring.dependency-management'
+
+
+dependencies {
+
+    implementation project(":common:utils")
+    implementation project(":common:data")
+    implementation project(":dao:dao-interface")
+    implementation project(":dao:dao-sql")
+
+    implementation fileTree(dir: 'src/main/lib', include: '*.jar')
+
+    implementation("$bootGroup:spring-boot-starter-web")
+    implementation("$bootGroup:spring-boot-starter-undertow")
+    implementation("$bootGroup:spring-boot-starter-websocket")
+    implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
+    implementation("org.apache.logging.log4j:log4j-jul:$log4jVersion")
+    implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
+    implementation("org.apache.logging.log4j:log4j-slf4j-impl:$log4jVersion")
+    // compile 'mysql:mysql-connector-java:5.1.28'
+    implementation "com.alibaba:druid:$alibabaDruidVersion"
+    implementation "com.alibaba:fastjson:$fastjsonVersion"
+    implementation("org.codehaus.groovy:groovy-all:$groovyVersion")
+
+    testImplementation("$bootGroup:spring-boot-starter-test")
+    implementation("io.github.openfeign:feign-core:$openFeignVersion")
+    implementation("io.github.openfeign:feign-jackson:$openFeignVersion")
+
+}
+

+ 22 - 0
alarm/custom/src/main/java/com/gyee/wisdom/Bootstrap.java

@@ -0,0 +1,22 @@
+package com.gyee.wisdom;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * @author northriver
+ */
+@SpringBootApplication
+@ServletComponentScan
+@EnableScheduling
+public class Bootstrap {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Bootstrap.class, args);
+    }
+
+}
+
+

+ 23 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/ApplicationReadyEventListener.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.alarm;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationReadyEventListener implements
+        ApplicationListener<ApplicationReadyEvent> {
+
+    @Autowired
+    private CalculateServer calculateServer;
+
+    @Override
+    public void onApplicationEvent(ApplicationReadyEvent event) {
+        System.out.println("ApplicationReadyEvent  rised!");
+        System.out.println("listener: " + event.toString());
+        calculateServer.start();
+    }
+
+}

+ 225 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/CalculateServer.java

@@ -0,0 +1,225 @@
+package com.gyee.wisdom.alarm;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.gyee.wisdom.alarm.config.ConfigProperties;
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.model.WindturbineInfo;
+import com.gyee.wisdom.alarm.rule.AlarmRule;
+import com.gyee.wisdom.alarm.model.StationInfo;
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.transport.restful.RestfulClient;
+import com.gyee.wisdom.alarm.transport.shardingclient.RemoteServiceBuilder;
+import com.gyee.wisdom.alarm.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.alarm.transport.websocket.StompClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+//todo : 此处改造为抽象类,可扩展框架设计
+
+@Slf4j
+@Component
+public class CalculateServer {
+
+    @Autowired
+    private ConfigProperties configProperties;
+
+    @Autowired
+    private CacheService cacheService;
+
+    @Autowired
+    private RestfulClient restfulClient;
+    //private StompClient stompClient;
+
+    @Autowired
+    protected RemoteServiceBuilder remoteServiceBuilder;
+
+
+    private boolean serverStarted = false;
+    private boolean readThreadFlag = false;
+    private boolean calcThreadFlag = false;
+    //只有数据加载线程执行成功一次后,才开始执行计算线程
+    private boolean readRtdbSuccess = false;
+
+    private Map<String, StationInfo> stationInfoMap;
+    private Map<String, WindturbineInfo> windturbineInfoMap;
+    private List<AlarmRule> alarmRuleList;
+    private Map<String, TagInfo> tagInfoMap;
+
+    public boolean start() {
+
+        if (serverStarted) {
+            return true;
+        }
+        try {
+            //GlobalVar.config = configProperties;
+            log.warn("自定义报警计算服务启动...... ");
+            log.info("开始加载配置及测点数据......");
+            stationInfoMap = cacheService.getStationInfoMap();
+            windturbineInfoMap = cacheService.getWindturbineInfoMap();
+            alarmRuleList = cacheService.getAlarmRuleList();
+            tagInfoMap = cacheService.getTagMap();
+
+            //Map<String, ArrayList<String>> mm = cacheService.getUcWindturbineMap();
+            log.info("配置数据加载完成,场站数:" + stationInfoMap.size());
+
+            //stompClient = new StompClient(configProperties.getServiceUrl());
+            //stompClient.getLatest("NSSFJ.NX_GD_NSSF_FJ_P1_L1_010_AI0160,QSFJ.NX_GD_QSF_FJ_P1_L2_014_AI0002");
+
+            readThreadFlag = true;
+            getReadThread().start();
+            sleep(1000);
+            calcThreadFlag = true;
+            getCalcThread().start();
+
+            serverStarted = true;
+        } catch (Exception ex) {
+            serverStarted = false;
+            stop();
+            log.error(ex.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    public void stop() {
+        readThreadFlag = false;
+        calcThreadFlag = false;
+        serverStarted=false;
+        try {
+            Thread.sleep(5000);
+            //线程停止后,清空报警规则相关缓存
+            cacheService.clearCache();
+        } catch (Exception ex) {
+        }
+    }
+
+    public void restart() {
+    }
+
+    Thread getReadThread() {
+        return new Thread(new Runnable() {
+            public void run() {
+                log.info("数据加载线程启动...");
+                while (readThreadFlag) {
+                    try {
+                        ArrayList<String> keysList = cacheService.getKeysList();
+                        for (String keys : keysList) {
+                            restfulClient.getLatest(keys);
+                            System.out.print("*");
+                        }
+                        if (cacheService.getReadRtdbSuccess() == false) {
+                            sleep(configProperties.getCalcThreadInterval());
+                            continue;
+                        } else {
+                            if (readRtdbSuccess == false) {
+                                sleep(configProperties.getReadThreadInterval() * 3);
+                                readRtdbSuccess = true;
+                            }
+                        }
+                    } catch (Exception ex) {
+                        log.error(ex.getMessage());
+                    }
+                    sleep(configProperties.getReadThreadInterval());
+                }
+            }
+        });
+    }
+
+    Thread getCalcThread() {
+        return new Thread(new Runnable() {
+            public void run() {
+                log.info("状态计算线程启动...");
+
+                ExecutorService pool = Executors.newFixedThreadPool(configProperties.getMaxThreadCount());
+                ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
+                List<Task> tasks = getTaskList();
+
+                while (calcThreadFlag) {
+                    List<ListenableFuture<Integer>> futures = Lists.newArrayList();
+                    if (readRtdbSuccess == false) {
+                        sleep(configProperties.getCalcThreadInterval());
+                        continue;
+                    }
+
+                    try {
+                        if (tasks != null && tasks.size() > 0) {
+                            for (Task task : tasks) {
+                                futures.add(executorService.submit(task));
+                            }
+                        }
+
+                        final ListenableFuture<List<Integer>> resultsFuture = Futures.successfulAsList(futures);
+                        try {//所有都执行完毕
+                            resultsFuture.get();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        } finally {
+                            System.out.println("#");
+                        }
+                    } catch (Exception ex) {
+                        log.info(ex.getMessage());
+                    }
+                    System.out.println("#");
+                    sleep(configProperties.getCalcThreadInterval());
+                }
+
+                if (pool != null)
+                    pool.shutdown();
+            }
+        });
+    }
+
+    private void sleep(int milliseconds) {
+        try {
+            TimeUnit.MILLISECONDS.sleep(milliseconds);
+        } catch (Exception ex) {
+            log.info(ex.getMessage());
+        }
+    }
+
+    private List<Task> getTaskList() {
+        if (alarmRuleList != null) {
+            List<Task> result = new ArrayList<>(alarmRuleList.size());
+            for (AlarmRule ar : alarmRuleList) {
+                Task task = new Task(ar);
+                result.add(task);
+            }
+
+            return result;
+        }
+
+        return null;
+    }
+
+    /**
+     * 内部类,用于执行自定义报警规则解析任务
+     */
+    class Task implements Callable<Integer> {
+        private AlarmRule alarmRule;
+
+        public Task(AlarmRule rule) {
+            this.alarmRule = rule;
+        }
+
+        @Override
+        public Integer call() throws Exception {
+            alarmRule.run();
+            System.out.print('.');
+            return 1;
+        }
+    }
+
+
+}

+ 30 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/config/ConfigProperties.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.alarm.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+@Component
+@ConfigurationProperties("calculate.config")
+public class ConfigProperties {
+
+    //数据适配器websocket服务地址
+    private String serviceUrl;
+
+    //报警分表数据服务地址
+    private String shardingServiceUrl;
+
+    //扫描实时数据线程轮询时间间隔,单位毫秒
+    private int readThreadInterval = 1000;
+
+    //计算状态线程轮询时间间隔,单位毫秒
+    private int calcThreadInterval = 100;
+
+    //规则解析线程池大小
+    private int maxThreadCount = 4;
+
+}

+ 48 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/controller/ConfigController.java

@@ -0,0 +1,48 @@
+package com.gyee.wisdom.alarm.controller;
+
+import com.gyee.wisdom.alarm.CalculateServer;
+
+import com.gyee.wisdom.common.utils.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+@Slf4j
+@RestController
+@RequestMapping("/custom")
+@CrossOrigin
+public class ConfigController {
+
+
+    Logger logger = LogManager.getLogger(ConfigController.class);
+    @Autowired
+    private CalculateServer calculateServer;
+
+
+
+    @GetMapping(value = "/restart")
+    public void restartCalServer()
+    {
+        try {
+            log.warn("restart Calculate Server ......");
+            calculateServer.stop();
+            Thread.sleep(10000);
+            calculateServer.start();
+        } catch (Exception ex) {
+            System.out.println("定时任务异常-----------------");
+        }
+    }
+
+}
+
+
+
+

+ 41 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/cornjob/CacheRefreshJob.java

@@ -0,0 +1,41 @@
+package com.gyee.wisdom.alarm.cornjob;
+
+import com.gyee.wisdom.alarm.CalculateServer;
+import com.gyee.wisdom.alarm.service.CacheService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @descrition: 缓存刷新功能
+ * @author:Wanghs
+ * @date:2020-04-21
+ */
+@Component
+@Slf4j
+@EnableScheduling
+public class CacheRefreshJob {
+
+    @Autowired
+    private CalculateServer calculateServer;
+
+    @Autowired
+    private CacheService cacheService;
+
+    //报警规则重新加载--定时任务
+    @Scheduled(cron = "${calculate.cron.CacheRefresh}")
+    public void refreshAlarmRule() {
+        try {
+            log.warn("restart Calculate Server ......");
+            calculateServer.stop();
+            Thread.sleep(10000);
+            calculateServer.start();
+        } catch (Exception ex) {
+            System.out.println("定时任务异常-----------------");
+        }
+
+    }
+}

+ 21 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/StationInfo.java

@@ -0,0 +1,21 @@
+package com.gyee.wisdom.alarm.model;
+
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import lombok.Data;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Map;
+
+@Data
+public class StationInfo {
+
+//    private String stationName;
+//    private String stationId;
+
+    private PowerStation station;
+
+    //key: uniformCode
+    private Map<String, TagInfo> tagMap;
+
+
+}

+ 96 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/TagInfo.java

@@ -0,0 +1,96 @@
+package com.gyee.wisdom.alarm.model;
+
+import com.gyee.wisdom.common.data.timeseries.*;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+
+@Data
+public class TagInfo {
+
+    private TsPoint tsPoint;
+
+    private DoubleTsData doubleTsData;
+
+    private BooleanTsData booleanTsData;
+
+    private LongTsData longTsData;
+
+    //本地时间
+    private long localTs;
+
+    public TagInfo(TsPoint value) {
+        tsPoint = value;
+    }
+
+    public void UpdateTsData(HashMap<String, Object> hmp) {
+        long ts = Long.parseLong(hmp.get("ts").toString());
+        if (ts == 0) return;
+        if (ts <= getLastUpdateTime())
+            return;
+
+        short status = ((Integer) hmp.get("status")).shortValue();
+        //每次数据更新的时候,将本地当前时间赋值给localTs
+        long nowTs = new Date().getTime();
+        if (tsPoint.getTsDataType() == TsDataType.BOOLEAN) {
+            if (booleanTsData == null) {
+                Object objValue = hmp.get("booleanValue");
+                String valueStr = objValue.toString();
+                boolean value = "true".equals(valueStr) ? true : false;
+                booleanTsData = new BooleanTsData(ts, status, value);
+                localTs = nowTs;
+            } else {
+                Object objValue = hmp.get("booleanValue");
+                String valueStr = objValue.toString();
+                boolean value = "true".equals(valueStr) ? true : false;
+
+                if (booleanTsData.getBooleanValue() == value)
+                    return;
+                booleanTsData = new BooleanTsData(ts, status, value);
+                localTs = nowTs;
+            }
+
+        } else if (tsPoint.getTsDataType() == TsDataType.DOUBLE) {
+            if (doubleTsData == null){
+                doubleTsData = new DoubleTsData(ts, status, (double) hmp.get("doubleValue"));
+                localTs = nowTs;
+            }
+            else {
+                double value = (double) hmp.get("doubleValue");
+                if (doubleTsData.getDoubleValue() == value)
+                    return;
+                doubleTsData = new DoubleTsData(ts, status, value);
+                localTs = nowTs;
+            }
+        } else if (tsPoint.getTsDataType() == TsDataType.LONG) {
+            if (longTsData == null){
+                longTsData = new LongTsData(ts, status, Long.parseLong(hmp.get("longValue").toString()));
+                localTs = nowTs;
+            }
+
+            else {
+                long value = Long.parseLong(hmp.get("longValue").toString());
+                if (longTsData.getLongValue() == value)
+                    return;
+                longTsData = new LongTsData(ts, status, value);
+                localTs = nowTs;
+            }
+        }
+    }
+
+    public long getLastUpdateTime() {
+        if (tsPoint.getTsDataType() == TsDataType.BOOLEAN) {
+            return booleanTsData == null ? 0 : booleanTsData.getTs();
+        } else if (tsPoint.getTsDataType() == TsDataType.DOUBLE) {
+            return doubleTsData == null ? 0 : doubleTsData.getTs();
+        } else if (tsPoint.getTsDataType() == TsDataType.LONG) {
+            return longTsData == null ? 0 : longTsData.getTs();
+        }
+        return 0;
+    }
+
+    public long getLocalLastUpdateTime(){
+        return this.localTs;
+    }
+}

+ 14 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/WindturbineGroup.java

@@ -0,0 +1,14 @@
+package com.gyee.wisdom.alarm.model;
+
+import lombok.Data;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class WindturbineGroup {
+    private String station;
+    private String modelid;
+    private List<String> ucList;
+}

+ 26 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/model/WindturbineInfo.java

@@ -0,0 +1,26 @@
+package com.gyee.wisdom.alarm.model;
+
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.math.BigDecimal;
+import java.util.HashSet;
+import java.util.Map;
+
+@Data
+@Slf4j
+public class WindturbineInfo {
+
+//    private String name;
+//    private String id;
+//    private String modelId;
+
+    private Windturbine windturbine;
+
+    //key: varname
+    private Map<String, TagInfo> tagMap;
+
+    private HashSet uniformCodes;
+
+}

+ 155 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunction.java

@@ -0,0 +1,155 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.alarm.rule.expression.Analyzer;
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.util.SpringContextUtils;
+import com.gyee.wisdom.common.data.timeseries.TsDataType;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Data
+@NoArgsConstructor
+@Slf4j
+public class AlarmFunction {
+
+    private ThingType thingType;
+
+    private String thingId;
+
+    private AlarmExpression alarmExpression;
+
+    private List<AlarmFunction> children;
+
+    private AlarmFunction parent;
+
+    //key: uniformcode
+    private Map<String, TagInfo> tagMap;
+
+    private CacheService cacheService = SpringContextUtils.getBean(CacheService.class);
+
+    private long lastExplainTime = 0;
+
+    private long getLatestTsDataTs() {
+        long ts = 0;
+        if (alarmExpression.getVarList() != null && alarmExpression.getVarList().size() > 0) {
+            for (String varName : alarmExpression.getVarList()) {
+                if (varName.startsWith(Analyzer.FUNCODE))
+                    continue;
+                TagInfo tagInfo = getTagInfo(varName);
+                if (tagInfo != null && ts < tagInfo.getLastUpdateTime())
+                    ts = tagInfo.getLastUpdateTime();
+            }
+        }
+        if (children != null && children.size() > 0) {
+            for (AlarmFunction child : children) {
+                if (ts < child.getLatestTsDataTs())
+                    ts = child.getLatestTsDataTs();
+            }
+        }
+        return ts;
+    }
+
+    public Object explain() {
+        long ts1 = getLatestTsDataTs();
+        if (ts1 <= lastExplainTime) {
+            return "c";
+        } else {
+            lastExplainTime = ts1;
+        }
+
+        Map<String, Object> varMap = new HashMap<>();
+        if (alarmExpression.getVarList() != null && alarmExpression.getVarList().size() > 0) {
+            for (String varName : alarmExpression.getVarList()) {
+                if (varName.startsWith(Analyzer.FUNCODE))
+                    continue;
+                TagInfo tagInfo = getTagInfo(varName);
+                if (tagInfo == null) {
+                    log.warn("未找到标签点!ThingId=" + this.getThingId() + ", uc=" + varName + ",rule=" + alarmExpression.getRuleId());
+                    continue;
+                }
+                if (tagInfo.getTsPoint().getTsDataType() == TsDataType.BOOLEAN) {
+                    boolean varValue = tagInfo.getBooleanTsData().getBooleanValue();
+                    varMap.put(varName, varValue);
+                } else if (tagInfo.getTsPoint().getTsDataType() == TsDataType.LONG) {
+                    long varValue = tagInfo.getLongTsData().getLongValue();
+                    varMap.put(varName, varValue);
+                } else {
+                    double varValue = tagInfo.getDoubleTsData().getDoubleValue();
+                    varMap.put(varName, varValue);
+                }
+
+            }
+        }
+
+        if (children != null && children.size() > 0) {
+            for (AlarmFunction af : children) {
+                Object result = af.explain();
+                varMap.put(af.getAlarmExpression().getFunCode(), result);
+            }
+        }
+
+        return ScriptShell.parseExpr(alarmExpression.getExpression(), varMap);
+    }
+
+    public AlarmFunction(AlarmExpression aExpression, ThingType tType, String tId) {
+        thingType = tType;
+        thingId = tId;
+        alarmExpression = aExpression;
+        children = new ArrayList<>();
+        if (alarmExpression.getChildren() != null && alarmExpression.getChildren().size() > 0) {
+            for (AlarmExpression subExp : alarmExpression.getChildren()) {
+                AlarmFunction aFun = null;
+                if (subExp.getFunType() != null && subExp.getFunType().equals("RiseExceed")) {
+                    aFun = new AlarmFunctionRiseExceed(subExp, tType, tId);
+                } else if (subExp.getFunType() != null && subExp.getFunType().equals("LastUpdateTime")) {
+                    aFun = new AlarmFunctionLastUpdateTime(subExp, tType, tId);
+                } else if (subExp.getFunType() != null && subExp.getFunType().equals("Sustain")) {
+                    if (subExp.getExpression().startsWith("Sustain")) {
+                        String exp = subExp.getExpression();
+                        int offset = exp.lastIndexOf(',');
+                        String exp2 = exp.substring(8, offset);
+                        subExp.setExpression(exp2);
+                        String parms = exp.substring(offset + 1, exp.length() - 1);
+                        ArrayList<String> paramlist = new ArrayList<>();
+                        paramlist.add(parms);
+                        subExp.setFunParams(paramlist);
+                    }
+                    aFun = new AlarmFunctionSustain(subExp, tType, tId);
+                }
+                else if (subExp.getFunType() != null && subExp.getFunType().equals("MAX")) {
+                    aFun = new AlarmFunctionMAX(subExp, tType, tId);
+                }
+                else if (subExp.getFunType() != null && subExp.getFunType().equals("AVG")) {
+                    aFun = new AlarmFunctionAVG(subExp, tType, tId);
+                }
+                if (aFun == null) {
+                    aFun = new AlarmFunction(subExp, tType, tId);
+                }
+                aFun.setParent(this);
+                children.add(aFun);
+            }
+        }
+
+    }
+
+    protected TagInfo getTagInfo(String varName) {
+        if (tagMap == null) {
+            if (thingType == ThingType.WINDTURBINE) {
+                tagMap = cacheService.getWindturbineInfoMap().get(thingId).getTagMap();
+            } else {
+                tagMap = cacheService.getStationInfoMap().get(thingId).getTagMap();
+            }
+        }
+
+        return tagMap.get(varName);
+    }
+
+}

+ 37 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionAVG.java

@@ -0,0 +1,37 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @descrition:获取平均值,同一个风机传入多个测点(统一编码)
+ * @author:Wanghs
+ * @date:2020-04-07
+ */
+public class AlarmFunctionAVG  extends AlarmFunction{
+    public AlarmFunctionAVG(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return 0;
+
+        List<Double> valueList=new ArrayList<>();
+
+        for (int i = 0; i < this.getAlarmExpression().getVarList().size(); i++) {
+            TagInfo tagInfo = this.getTagInfo(this.getAlarmExpression().getVarList().get(i));
+           if(tagInfo!=null){
+               valueList.add(tagInfo.getDoubleTsData().getDoubleValue());
+           }
+        }
+
+        return valueList.stream().mapToDouble(Double::doubleValue).average().getAsDouble();
+    }
+
+}

+ 51 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionLastUpdateTime.java

@@ -0,0 +1,51 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.LinkedList;
+
+
+// 返回测点最近数据的时间
+// 应用场景: 判定离线,状态持续时间等
+// 函数原型: LastUpdateTime(测点名)
+@Data
+@NoArgsConstructor
+public class AlarmFunctionLastUpdateTime extends AlarmFunction {
+
+    public AlarmFunctionLastUpdateTime(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return 0;
+
+        String varName = this.getAlarmExpression().getVarList().get(0);
+        TagInfo tagInfo = this.getTagInfo(varName);
+      /*  if (tagInfo.getBooleanTsData() != null) {
+            if (tagInfo.getBooleanTsData().getBooleanValue() == false)
+                return 0;
+        }*/
+        // long ts = tagInfo.getLastUpdateTime();
+        if (tagInfo != null) {
+            //计算最后更新时间时,由原来的数据时间戳,改为数据更新时的本地时间
+            long ts = tagInfo.getLocalLastUpdateTime();
+            if (ts == 0)
+                return 0;
+            else {
+                long interval = new Date().getTime() - ts;
+                return Math.round(interval / 1000);
+            }
+        } else {
+            return 0;
+        }
+
+    }
+
+}

+ 114 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMAR.java

@@ -0,0 +1,114 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.TsDataType;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.LinkedList;
+
+
+// 均值极差:
+// 应用场景: 测点的均值极差计算
+// 函数原型: MAR(测点名,时间(秒))
+@Data
+@NoArgsConstructor
+public class AlarmFunctionMAR extends AlarmFunction {
+
+    private DoubleTsData lastUpdateTsData;
+    //数据缓存
+    private LinkedList<DoubleTsData> tsDataQueue = new LinkedList<DoubleTsData>();
+    private LinkedList<DoubleTsData> avgTsDataQueue = new LinkedList<>();
+    private long interval; //时间范围,单位秒
+
+    private double totalVal = 0;
+    private int count = 0;
+
+    public AlarmFunctionMAR(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+        String exp = alarmExpression.getExpression();
+        exp = exp.substring(3, exp.length() - 1);
+        String[] arr = exp.split(",");
+        interval = Long.valueOf(arr[1]);
+        //threshold = Double.valueOf(arr[2]);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return false;
+        String varName = this.getAlarmExpression().getVarList().get(0);
+        DoubleTsData tsData = getValue(varName);
+        if (tsData == null)
+            return 0;
+        if (lastUpdateTsData == null) {
+            lastUpdateTsData = tsData;
+            tsDataQueue.offer(tsData);
+            avgTsDataQueue.offer(tsData);
+            totalVal = tsData.getDoubleValue();
+            count = 1;
+            return 0;
+        }
+
+        //如果数据时间戳在变化,最新数据时间作为基准时间
+        //否则,认为数据已不更新,取系统时间和最新数据时间较大者为基准时间
+        long ts = new Date().getTime();
+        if (tsData.getTs() > lastUpdateTsData.getTs())
+            ts = tsData.getTs();
+        else if (tsData.getTs() > ts)
+            ts = tsData.getTs();
+
+
+        DoubleTsData headTsData = tsDataQueue.peek();
+
+        while (ts - headTsData.getTs() > interval * 1000 &&
+                tsDataQueue.size() > 0) {
+
+            headTsData = tsDataQueue.poll();
+            totalVal -= headTsData.getDoubleValue();
+            count--;
+        }
+
+        tsDataQueue.offer(tsData);
+        lastUpdateTsData = tsData;
+        totalVal += tsData.getDoubleValue();
+        count++;
+
+        long avgTs = new Date().getTime();
+        double avgVal = totalVal / count;
+        DoubleTsData avgTsData = new DoubleTsData(avgTs, (short)0, avgVal);
+        avgTsDataQueue.offer(avgTsData);
+
+        DoubleTsData headTsData2 = avgTsDataQueue.peek();
+        while (avgTs - headTsData2.getTs() > interval * 1000 &&
+                avgTsDataQueue.size() > 0) {
+            headTsData2 = avgTsDataQueue.poll();
+        }
+
+        DoubleTsData minTsData = avgTsData;
+        DoubleTsData maxTsData = avgTsData;
+
+        for (int i = 0; i < avgTsDataQueue.size(); i++) {
+            if (minTsData.getDoubleValue() >= avgTsDataQueue.get(i).getDoubleValue()) {
+                minTsData = avgTsDataQueue.get(i);
+            }
+            if (maxTsData.getDoubleValue() <=  avgTsDataQueue.get(i).getDoubleValue()) {
+                maxTsData = avgTsDataQueue.get(i);
+            }
+        }
+        return maxTsData.getDoubleValue() - minTsData.getDoubleValue();
+    }
+
+
+    public DoubleTsData getValue(String varName) {
+        TagInfo tagInfo = this.getTagInfo(varName);
+
+        if (tagInfo.getTsPoint().getTsDataType() == TsDataType.LONG && tagInfo.getLongTsData() != null) {
+            return new DoubleTsData(tagInfo.getLongTsData().getTs(), (short) 0, tagInfo.getLongTsData().getLongValue());
+        }
+        return tagInfo.getDoubleTsData();
+    }
+}

+ 40 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMAX.java

@@ -0,0 +1,40 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * @descrition:传入多个测点(统一编码)获取最大值
+ * @author:Wanghs
+ * @date:2020-04-07
+ */
+public class AlarmFunctionMAX extends AlarmFunction {
+    public AlarmFunctionMAX(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return 0;
+
+        Optional<Double> maxValue = Optional.empty();
+
+        for (int i = 0; i < this.getAlarmExpression().getVarList().size(); i++) {
+            TagInfo tagInfo = this.getTagInfo(this.getAlarmExpression().getVarList().get(i));
+            if (!maxValue.isPresent()) {
+                maxValue = Optional.of(tagInfo.getDoubleTsData().getDoubleValue());
+            } else {
+                if (maxValue.get() <= tagInfo.getDoubleTsData().getDoubleValue()) {
+                    maxValue = Optional.of(tagInfo.getDoubleTsData().getDoubleValue());
+                }
+            }
+        }
+
+        return maxValue.get().doubleValue();
+    }
+
+}

+ 95 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionMR.java

@@ -0,0 +1,95 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.TsDataType;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.LinkedList;
+
+
+// 移动极差:移动极差(Moving Range)是指两个或多个连续样本值中最大值与最小值之差。
+// 这种差是按这样方式计算的:每当得到一个额外的数据点时,就在样本中加上这个新的点,
+// 同时删除其中时间上“最老的”点,然后计算与这点有关的极差,因此每个极差的计算至少
+// 与前一个极差的计算共用一个点的值。
+// 一般说来,移动极差用于单值控制图,并且通常用两点(连续的点)来计算移动极差。
+// 应用场景: 测点的移动极差超限报警
+// 函数原型: MR(测点名,时间(秒))
+@Data
+@NoArgsConstructor
+public class AlarmFunctionMR extends AlarmFunction {
+
+    private DoubleTsData lastUpdateTsData;
+    //private DoubleTsData minTsData;
+    //数据缓存
+    private LinkedList<DoubleTsData> tsDataQueue = new LinkedList<DoubleTsData>();
+    private long interval; //时间范围,单位秒
+    //private double threshold; //阈值
+
+    public AlarmFunctionMR(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+        String exp = alarmExpression.getExpression();
+        exp = exp.substring(3, exp.length() - 1);
+        String[] arr = exp.split(",");
+        interval = Long.valueOf(arr[1]);
+        //threshold = Double.valueOf(arr[2]);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return false;
+        String varName = this.getAlarmExpression().getVarList().get(0);
+        DoubleTsData tsData = getValue(varName);
+        if (tsData == null)
+            return 0;
+        if (lastUpdateTsData == null) {
+            lastUpdateTsData = tsData;
+            tsDataQueue.offer(tsData);
+            return 0;
+        }
+
+        //如果数据时间戳在变化,最新数据时间作为基准时间
+        //否则,认为数据已不更新,取系统时间和最新数据时间较大者为基准时间
+        long ts = new Date().getTime();
+        if (tsData.getTs() > lastUpdateTsData.getTs())
+            ts = tsData.getTs();
+        else if (tsData.getTs() > ts)
+            ts = tsData.getTs();
+
+
+        DoubleTsData headTsData = tsDataQueue.peek();
+
+        while (ts - headTsData.getTs() > interval * 1000 &&
+                tsDataQueue.size() > 0) {
+            headTsData = tsDataQueue.poll();
+        }
+        tsDataQueue.offer(tsData);
+        lastUpdateTsData = tsData;
+        DoubleTsData minTsData = tsData;
+        DoubleTsData maxTsData = tsData;
+
+        for (int i = 0; i < tsDataQueue.size(); i++) {
+            if (minTsData.getDoubleValue() >= tsDataQueue.get(i).getDoubleValue()) {
+                minTsData = tsDataQueue.get(i);
+            }
+            if (maxTsData.getDoubleValue() <=  tsDataQueue.get(i).getDoubleValue()) {
+                maxTsData = tsDataQueue.get(i);
+            }
+        }
+        return maxTsData.getDoubleValue() - minTsData.getDoubleValue();
+    }
+
+
+    public DoubleTsData getValue(String varName) {
+        TagInfo tagInfo = this.getTagInfo(varName);
+
+        if (tagInfo.getTsPoint().getTsDataType() == TsDataType.LONG && tagInfo.getLongTsData() != null) {
+            return new DoubleTsData(tagInfo.getLongTsData().getTs(), (short) 0, tagInfo.getLongTsData().getLongValue());
+        }
+        return tagInfo.getDoubleTsData();
+    }
+}

+ 95 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionRiseExceed.java

@@ -0,0 +1,95 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.TsDataType;
+import com.gyee.wisdom.common.data.timeseries.TsPoint;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.*;
+
+
+// 取测点在给定的时间范围内数据上升的量是否超过阈值
+// 应用场景: 判断温升,测点值的上升速度过快等
+// 函数原型: RiseExceed(测点名,时间(秒),阈值)
+@Data
+@NoArgsConstructor
+public class AlarmFunctionRiseExceed extends AlarmFunction {
+
+    private DoubleTsData lastUpdateTsData;
+    //private DoubleTsData minTsData;
+    //数据缓存
+    private LinkedList<DoubleTsData> tsDataQueue = new LinkedList<DoubleTsData>();
+    private long interval; //时间范围,单位秒
+    private double threshold; //阈值
+
+
+    public AlarmFunctionRiseExceed(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+        String exp = alarmExpression.getExpression();
+        exp = exp.substring(11, exp.length() - 1);
+        String[] arr = exp.split(",");
+        interval = Long.valueOf(arr[1]);
+        threshold = Double.valueOf(arr[2]);
+    }
+
+    @Override
+    public Object explain() {
+        if (this.getAlarmExpression().getVarList() == null || this.getAlarmExpression().getVarList().size() < 1)
+            return false;
+        String varName = this.getAlarmExpression().getVarList().get(0);
+        DoubleTsData tsData = getValue(varName);
+        if (tsData == null)
+            return false;
+        if (lastUpdateTsData == null) {
+            lastUpdateTsData = tsData;
+            tsDataQueue.offer(tsData);
+            return false;
+        }
+
+        //如果数据时间戳在变化,最新数据时间作为基准时间
+        //否则,认为数据已不更新,取系统时间和最新数据时间较大者为基准时间
+        long ts = new Date().getTime();
+        if (tsData.getTs() > lastUpdateTsData.getTs())
+            ts = tsData.getTs();
+        else if (tsData.getTs() > ts)
+            ts = tsData.getTs();
+
+
+        DoubleTsData minTsData = tsDataQueue.peek();
+
+        while (ts - minTsData.getTs() > interval * 1000 &&
+                tsDataQueue.size() > 0) {
+            minTsData = tsDataQueue.poll();
+        }
+        tsDataQueue.offer(tsData);
+        for (int i = 0; i < tsDataQueue.size(); i++) {
+            if (minTsData.getDoubleValue() >= tsDataQueue.get(i).getDoubleValue()) {
+                minTsData = tsDataQueue.get(i);
+            }
+        }
+
+        while (tsDataQueue.size() > 0 &&
+                tsDataQueue.peek().getTs() < minTsData.getTs()) {
+            tsDataQueue.poll();
+        }
+
+        lastUpdateTsData = tsData;
+        if (tsData.getDoubleValue() - minTsData.getDoubleValue() > threshold) {
+            return true;
+        }
+        return false;
+    }
+
+
+    public DoubleTsData getValue(String varName) {
+        TagInfo tagInfo = this.getTagInfo(varName);
+
+        if (tagInfo.getTsPoint().getTsDataType() == TsDataType.LONG && tagInfo.getLongTsData() != null) {
+            return new DoubleTsData(tagInfo.getLongTsData().getTs(), (short) 0, tagInfo.getLongTsData().getLongValue());
+        }
+        return tagInfo.getDoubleTsData();
+    }
+}

+ 62 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmFunctionSustain.java

@@ -0,0 +1,62 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.LinkedList;
+
+
+// 判定状态(表达式成立)持续的时间是否超过给定的时间
+// 应用场景: 判断状态持续的时间
+// 函数原型: Sustain(expression,时间(秒))
+@Data
+@NoArgsConstructor
+public class AlarmFunctionSustain extends AlarmFunction {
+
+    private boolean lastUpdateStatus;
+    private long lastUpdateTs;
+    private long originalTs;
+    private long interval; //时间范围,单位秒
+
+    public AlarmFunctionSustain(AlarmExpression alarmExpression, ThingType tType, String tId) {
+        super(alarmExpression, tType, tId);
+        String val = alarmExpression.getFunParams().get(0);
+        interval = Long.valueOf(val);
+    }
+
+
+    @Override
+    public Object explain() {
+
+        long ts = new Date().getTime();
+        if (originalTs == 0)
+            originalTs = ts;
+
+        lastUpdateTs = ts;
+
+        Object obj = super.explain();
+        if (obj.equals(Boolean.TRUE)) {
+            if (lastUpdateStatus == false) {
+                originalTs = ts;
+                return false;
+            } else {
+                long tmp = lastUpdateTs - originalTs;
+                if (tmp > interval * 1000)
+                    return true;
+                else
+                    return false;
+            }
+        } else {
+            //originalTs = ts;
+            return false;
+        }
+    }
+
+
+    public DoubleTsData getValue(String varName) {
+        return null;
+    }
+}

+ 236 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmRule.java

@@ -0,0 +1,236 @@
+package com.gyee.wisdom.alarm.rule;
+
+import com.gyee.wisdom.alarm.model.StationInfo;
+import com.gyee.wisdom.alarm.model.WindturbineInfo;
+import com.gyee.wisdom.alarm.rule.expression.AlarmExpression;
+import com.gyee.wisdom.alarm.rule.expression.Analyzer;
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.service.SqlService;
+import com.gyee.wisdom.alarm.util.SpringContextUtils;
+import com.gyee.wisdom.common.data.alarm.AlertRule;
+import com.gyee.wisdom.alarm.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import com.gyee.wisdom.common.utils.StringUtil;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Data
+public class AlarmRule {
+
+    private AlertRule alertRule;
+
+    private AlarmExpression alarmExpression;
+
+    private List<AlarmFunction> funList;
+
+    private CacheService cacheService = SpringContextUtils.getBean(CacheService.class);
+
+    private SqlService sqlService = SpringContextUtils.getBean(SqlService.class);
+
+    public AlarmRule(AlertRule ar) {
+        this.alertRule = ar;
+        funList = new ArrayList<>();
+        try {
+            alarmExpression = Analyzer.getAlarmExpression(ar.getExpression());
+            alarmExpression.setRuleId(alertRule.getId());
+            ArrayList<String> ucs = alarmExpression.getAllUniformCodes();
+            //1-风机 2-风场 5-升压站
+            if ("1".equals(ar.getCategory()) ) {
+                //获取规则所对应的风机
+                List<Windturbine> lst = new ArrayList<>();
+                cacheService.getWindturbineInfoMap().values().stream()
+                        .filter((WindturbineInfo w) -> w.getWindturbine().getModelId().contains(ar.getModelId().trim())&&w.getWindturbine().getWindPowerStationId().equals(ar.getStation())).collect(Collectors.toList()).forEach(n -> lst.add(n.getWindturbine()));
+
+                //  String[] wtArray = ar.getWindturbine().split(",");
+                for (Windturbine wb : lst) {
+                    Map<String, WindturbineInfo> wtMap = cacheService.getWindturbineInfoMap();
+                    if (StringUtil.isNotBlank(wb.getId()) && wtMap.containsKey(wb.getId())) {
+                        AlarmFunction alarmFunction = new AlarmFunction(alarmExpression, ThingType.WINDTURBINE, wb.getId());
+                        if (funList.contains(alarmFunction)) {
+                            log.warn("重复的设备:" + wb.getId());
+                            continue;
+                        }
+                        funList.add(alarmFunction);
+                    }
+                }
+                //填充ucWindturbinelist
+                if (ucs.size() > 0) {
+                    for (String uc : ucs) {
+                        ArrayList<String> wtList = cacheService.getUcWindturbinelist(uc);
+                        for (Windturbine wb : lst) {
+                            if (wtList.contains(wb.getId()) == false)
+                                wtList.add(wb.getId());
+                        }
+                    }
+                }
+            }
+
+
+            if (("2".equals(ar.getCategory()) || "5".equals(ar.getCategory())) && ar.getStation() != null) {
+                String[] stArray = ar.getStation().split(",");
+                for (String stId : stArray) {
+                    Map<String, StationInfo> wtMap = cacheService.getStationInfoMap();
+                    if (StringUtil.isNotBlank(stId) && wtMap.containsKey(stId)) {
+                        AlarmFunction alarmFunction = new AlarmFunction(alarmExpression, ThingType.STATION, stId);
+                        if (funList.contains(alarmFunction)) {
+                            log.warn("重复的设备:" + stId);
+                            continue;
+                        }
+                        funList.add(alarmFunction);
+                    }
+                }
+
+                //填充ucStationlist
+                if (ucs.size() > 0) {
+                    for (String uc : ucs) {
+                        ArrayList<String> stList = cacheService.getUcStationlist(uc);
+                        for (String stId : stArray) {
+                            if (stList.contains(stId) == false)
+                                stList.add(stId);
+                        }
+                    }
+                }
+            }
+        } catch (Exception ex) {
+            log.error("生成自定义报警规则失败!规则id:" + ar.getId());
+        }
+    }
+
+    //缓存报警快照,减少数据库查询次数
+    //key: thingId
+    private HashMap<String, AlarmSnap> snapMap;
+
+    //用于批量更新数据库
+    private List<AlarmSnap> snapChangedList;
+
+    public void run() {
+        if (funList != null && funList.size() > 0) {
+
+            if (snapChangedList == null)
+                snapChangedList = new ArrayList<>();
+            else
+                snapChangedList.clear();
+
+            for (AlarmFunction fun : funList) {
+                try {
+
+                    Object obj = fun.explain();
+                    if (obj instanceof Boolean) {
+                        boolean writeHistory = true;
+                        AlarmSnap snap = getAlertSnap(fun.getThingId());
+                        if (true == (boolean) obj) {
+                            double interval = 0;
+//                            if (snap == null) {
+//                                snap = AlertSnapFactory.createAlertsnap(this.alertRule, fun.getThingId());
+//                                if (snap.getStationName() == null &&
+//                                        snap.getStationId() !=  null &&
+//                                        cacheService.getStationInfoMap().containsKey(snap.getStationId())) {
+//                                    StationInfo st = cacheService.getStationInfoMap().get(snap.getStationId());
+//                                    snap.setStationName(st.getStation().getStationName());
+//                                }
+//                            } else
+                            if (snap.getIsOpened() != 0) {
+                                long ts = (new Date()).getTime() - snap.getLastUpdateTime().getTime();
+                                //TimeSpan ts = DateTime.Now.Subtract((DateTime)snap.LastUpdateTime);
+                                interval = ts / (3600 * 1000);
+                            }
+
+                            if (snap.getIsOpened() == 0 || interval > 1) {
+                                snap.setIsOpened(1);
+                                //snap.DataInfo = CommonMethod.StringCopy(ari.DataInfo, 2000);
+                                //snap.setLastUpdatePerson("system");
+                                snap.setLastUpdateTime(new Date());
+//                                if (snap.getIsConfirmed() != 0 && interval > 8)
+//                                    snap.setIsConfirmed(0);
+
+                                //sqlService.saveAlertSnap(snap);
+                                snapChangedList.add(snap);
+
+
+                                //AlertSnapRepository.SaveAlertSnap(snap);
+                                //写实时库
+//                                string key = GetWindTurbineAlertPoint(windTurbine.Id);
+//                                logger.InfoFormat("写报警测点,key={0}, value={1}", key, ari.AlertRule.EdnaValue);
+//                                eDos.SendSinglePoint(key, ari.AlertRule.EdnaValue);
+                                log.info(String.format("触发报警!%s,规则:%s", fun.getThingId(), alertRule.getName()+"--"+alertRule.getExpression()));
+                            }
+                        } else {
+                            //解除报警
+                            if (snap != null && snap.getIsOpened() != 0) {
+                                snap.setIsOpened(0);
+                                //snap.DataInfo = CommonMethod.StringCopy(ari.DataInfo, 2000);
+//                                snap.setIsConfirmed(0);
+//                                snap.setLastClosePerson("system");
+//                                snap.setLastCloseTime(new Date());
+                                snap.setLastUpdateTime(new Date());
+                                //sqlService.saveAlertSnap(snap);
+                                snapChangedList.add(snap);
+                                log.info(String.format("解除报警!%s,规则:%s",
+                                        fun.getThingId(), alertRule.getId()));
+                            }
+                        }
+                    } else {
+                        System.out.print(obj.toString());
+                    }
+                } catch (Exception ex) {
+                    log.error("自定义报警规则执行时出错!"+fun.getThingId()+"--"+this.alertRule.getId()+"----"+this.alertRule.getName()+"------" + ex.getMessage());
+                }
+            }
+
+            if (snapChangedList.size() > 0)
+              sqlService.saveAlertSnaps(snapChangedList);
+        }
+    }
+
+    private AlarmSnap getAlertSnap(String thingId) {
+        if (snapMap == null)
+            snapMap = new HashMap<>();
+        if (snapMap.containsKey(thingId)) {
+            return snapMap.get(thingId);
+        } else {
+            AlarmSnap alertsnap = findAlertSnap(thingId, this.alertRule.getEdnaValue());
+            if (alertsnap == null) {
+                alertsnap = AlertSnapFactory.createAlertsnap(this.alertRule, thingId);
+                if (alertsnap.getStationName() == null &&
+                        alertsnap.getStationId() != null &&
+                        cacheService.getStationInfoMap().containsKey(alertsnap.getStationId())) {
+                    StationInfo st = cacheService.getStationInfoMap().get(alertsnap.getStationId());
+                    alertsnap.setStationName(st.getStation().getStationName());
+                }
+            }
+            if (alertsnap.getId() != null)
+                snapMap.put(thingId, alertsnap);
+            if(StringUtils.isBlank(alertsnap.getCategory3()))
+            {
+                //如果风机报警的category3字段为空,则说明报警没有关联到相关部件,取报警规则中的Relatedparts进行赋值
+                if(StringUtils.isNotBlank(this.alertRule.getRelatedParts())){
+                    alertsnap.setCategory3(this.alertRule.getRelatedParts());
+                }
+            }
+            return alertsnap;
+        }
+    }
+
+    private AlarmSnap findAlertSnap(String thingId, int alertValue) {
+        try {
+            if ("1".equals(this.alertRule.getCategory())) {
+                return sqlService.getAlertSnap(ThingType.WINDTURBINE, thingId, alertValue);
+            }
+
+            return sqlService.getAlertSnap(ThingType.STATION, thingId, alertValue);
+        } catch (Exception ex) {
+            log.warn(String.format("thingId=%s, alertValue=%d", thingId, alertValue));
+            log.error(ex.getMessage(), ex);
+            return null;
+        }
+
+    }
+
+
+}

+ 39 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlarmScript.java

@@ -0,0 +1,39 @@
+package com.gyee.wisdom.alarm.rule;
+
+import groovy.lang.Script;
+
+public class AlarmScript extends Script {
+
+    @Override
+    public Object run() {
+        return null;
+    }
+
+    public double dataSub(double d1, double d2) {
+        return d1 - d2;
+    }
+
+    /**
+     * 数据有变化就报警
+     * @return
+     */
+//    public boolean IsChanged() {
+//        long entityId = (long)getBinding().getVariable(ScriptShell.entityIdName);
+//        String variable = (String)getBinding().getVariable(ScriptShell.variableName);
+//        TsData currentData = (TsData)getBinding().getVariable(ScriptShell.tsDataName);
+//        TsData preData = ScriptShell.getPreTsData(entityId,variable);
+//        if (preData == null) {
+//            return  true;   //如果没有前值,直接触发报警?
+//        }
+//        if (preData.getTs() >= currentData.getTs()) {
+//            return false;   //过期的数据,不触发报警
+//        }
+//        if (preData.getValue().equals(currentData.getValue())) {
+//            return false;
+//        } else {
+//            return true;    //当前值与前值不一样,触发报警
+//        }
+//
+//    }
+//
+}

+ 78 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/AlertSnapFactory.java

@@ -0,0 +1,78 @@
+package com.gyee.wisdom.alarm.rule;
+
+
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.util.SpringContextUtils;
+import com.gyee.wisdom.common.data.alarm.AlertRule;
+import com.gyee.wisdom.common.data.alarm.Alerthistory;
+import com.gyee.wisdom.alarm.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import com.gyee.wisdom.common.utils.StringUtil;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+
+public class AlertSnapFactory {
+    public static AlarmSnap createAlertsnap(AlertRule ar) {
+        AlarmSnap snap = new AlarmSnap();
+        //snap.setId(StringUtil.getUUID());
+        snap.setAlertText(ar.getName().trim());
+        snap.setAlertValue((int) ar.getEdnaValue());
+        snap.setProjectId(ar.getProject());
+        snap.setCategory1("custom");
+        snap.setCategory2(ar.getCategory());
+        //如果报警规则的关联部件不为空
+        if(StringUtils.isNotBlank(ar.getRelatedParts())){
+            snap.setCategory3(ar.getRelatedParts());
+        }
+        snap.setRank(ar.getRank());
+        snap.setLastUpdateTime(new Date());
+        return snap;
+    }
+
+    public static AlarmSnap createAlertsnap(AlertRule ar, PowerStation wps) {
+        AlarmSnap snap = createAlertsnap(ar);
+        snap.setStationId(wps.getId());
+        snap.setStationName(wps.getStationName());
+
+        return snap;
+    }
+
+
+    public static AlarmSnap createAlertsnap(AlertRule ar, Windturbine obj) {
+        AlarmSnap snap = createAlertsnap(ar);
+        snap.setWindturbineId(obj.getId());
+        snap.setWindturbineName(obj.getCodeToName());
+        snap.setLineId(obj.getLineId());
+        snap.setModelId(obj.getModelId());
+//        Line ln = DataCache.Instance.GetLinesByID(obj.LineId);
+//        if (ln != null)
+//            snap.LineName = ln.Name;
+//        snap.ProjectId = obj.ProjectId;
+//        Project prj = DataCache.Instance.GetProjectsByID(obj.ProjectId);
+//        if (prj != null)
+//            snap.ProjectName = prj.Name;
+        snap.setStationId(obj.getWindPowerStationId());
+//        WindPowerStation wps = DataCache.Instance.GetWindPowerStationByID(prj.WindPowerStationId);
+//        if (wps != null)
+//            snap.StationName = wps.Name;
+
+        return snap;
+    }
+
+
+    public static AlarmSnap createAlertsnap(AlertRule ar, String thingId) {
+        CacheService cacheService = SpringContextUtils.getBean(CacheService.class);
+        if ("1".equals(ar.getCategory())) {
+            Windturbine wt = cacheService.getWindturbineInfoMap().get(thingId).getWindturbine();
+            return createAlertsnap(ar, wt);
+        } else {
+            PowerStation st = cacheService.getStationInfoMap().get(thingId).getStation();
+            return createAlertsnap(ar, st);
+        }
+    }
+
+
+}
+

+ 43 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/ScriptShell.java

@@ -0,0 +1,43 @@
+package com.gyee.wisdom.alarm.rule;
+
+import groovy.lang.Binding;
+import groovy.lang.GroovyShell;
+import groovy.lang.Script;
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ScriptShell {
+    private static final GroovyShell shell;
+    private static ConcurrentHashMap<String, Script> cache = new ConcurrentHashMap<String, Script>();
+
+    static {
+        CompilerConfiguration cfg = new CompilerConfiguration();
+        cfg.setScriptBaseClass(AlarmScript.class.getName());
+        shell = new GroovyShell(cfg);
+    }
+
+    public static Object parseExpr(String expr) {
+        Script s = getScriptFromCache(expr);
+        return s.run();
+    }
+
+    public static Object parseExpr(String expr, Map<String, Object> map) {
+        Binding binding = new Binding(map);
+        Script script = getScriptFromCache(expr);
+        script.setBinding(binding);
+        return script.run();
+    }
+
+    private static Script getScriptFromCache(String expr) {
+        if (cache.containsKey(expr)) {
+            return cache.get(expr);
+        }
+        Script script = shell.parse(expr);
+        cache.put(expr, script);
+        return script;
+    }
+
+
+}

+ 6 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/ThingType.java

@@ -0,0 +1,6 @@
+package com.gyee.wisdom.alarm.rule;
+
+public enum ThingType {
+    WINDTURBINE,  //风机
+    STATION, //风场
+}

+ 64 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/AlarmExpression.java

@@ -0,0 +1,64 @@
+package com.gyee.wisdom.alarm.rule.expression;
+
+import lombok.Data;
+import lombok.ToString;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Data
+public class AlarmExpression {
+
+    private String funCode;
+
+    private String funType;
+
+    private String originalExpression;
+
+    private String expression;
+
+    private List<String> varList;
+
+    private List<AlarmExpression> children;
+
+    private AlarmExpression parent;
+
+    private String ruleId;
+
+    private ArrayList<String> funParams;
+
+//    private boolean isOpened;
+
+//    public AlarmExpression(String exp) {
+//
+//    }
+
+    public ArrayList<String> getAllUniformCodes() {
+        ArrayList<String> result = new ArrayList<>();
+        if (varList != null && varList.size() > 0) {
+            for (String var : varList) {
+                if (var.startsWith(Analyzer.FUNCODE) == false)
+                    result.add(var);
+            }
+        }
+
+        if (children != null && children.size() > 0) {
+            for (AlarmExpression subExp : children) {
+                ArrayList<String> r2 = subExp.getAllUniformCodes();
+                if (r2.size() > 0) {
+                    for (String svar : r2) {
+                        if (svar.startsWith(Analyzer.FUNCODE) == false)
+                            result.add(svar);
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return expression;
+    }
+}

+ 220 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/Analyzer.java

@@ -0,0 +1,220 @@
+package com.gyee.wisdom.alarm.rule.expression;
+
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+
+public class Analyzer {
+
+    public static final String FUNCODE = "Function";
+
+    //自定义函数名集合
+    public static final HashSet<String> CUSTOM_FUNS = new HashSet<String>() {{
+        add("RiseExceed");
+        add("LastUpdateTime");
+        add("Sustain");
+        add("MR");
+        add("MAR");
+        add("MAX");
+        add("AVG");
+    }};
+
+    public static AlarmExpression getAlarmExpression(String exp) {
+        ArrayList<Token> tokens = getTokens(exp);
+        return createAlarmExpression(tokens);
+    }
+
+    public static ArrayList<Token> getTokens(String exp) {
+        ArrayList<Token> tokens = new ArrayList<>();
+        int expIndex = 0;
+        int tokenIndex = 0;
+        while (expIndex < exp.length()) {
+            char currentChar = exp.charAt(expIndex);
+            //如果当前字符是一个分隔符,则认为这是一个分隔符标记
+            //给当前标记和标记类型赋值,并将指针后移
+            if (isDelim(currentChar)) {
+                Token token = new Token();
+                token.setValue(currentChar + "");
+                if (currentChar == '(') {
+                    token.setTokenType(TokenType.PARENTHESISL);
+                    //识别出函数名
+                    if (tokens.size() > 0) {
+                        Token preToken = tokens.get(tokens.size() - 1);
+                        if (preToken.getTokenType() == TokenType.VARIABE &&
+                                CUSTOM_FUNS.contains(preToken.getValue())) {
+                            preToken.setTokenType(TokenType.CUSTOMFUN);
+                        } else {
+                            preToken.setTokenType(TokenType.SYSFUN);
+                        }
+                    }
+                } else if (currentChar == ')')
+                    token.setTokenType(TokenType.PARENTHESISR);
+                else
+                    token.setTokenType(TokenType.OTHER);
+
+                if (currentChar != ' ')
+                    tokens.add(token);
+                tokenIndex = 0;
+            } else if (isVariable(currentChar)) {
+                if (tokenIndex == 0) {
+                    Token token = new Token();
+                    token.setValue(currentChar + "");
+                    if (currentChar >= '0' && currentChar <= '9')
+                        token.setTokenType(TokenType.CONST);
+                    else
+                        token.setTokenType(TokenType.VARIABE);
+                    tokens.add(token);
+                } else {
+                    Token token = tokens.get(tokens.size() - 1);
+                    token.setValue(token.getValue() + currentChar);
+                }
+                tokenIndex++;
+            } else {
+                //其他字符,忽略
+            }
+            expIndex++;
+        }
+
+        return tokens;
+    }
+
+    //判断一个字符是否为分隔符
+    public static boolean isDelim(char c) {
+        if (("+-*/><=&|! ,()".indexOf(c) != -1))
+            return true;
+        return false;
+    }
+
+    //判断一个字符是否为字母数字或小数点
+    public static boolean isVariable(char c) {
+        if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '.' || c == '_')
+            return true;
+
+        return false;
+    }
+
+    public static AlarmExpression createAlarmExpression(ArrayList<Token> tokens) {
+        AlarmExpression alarmExpression = new AlarmExpression();
+        alarmExpression.setFunCode("ROOT");
+
+        List<AlarmExpression> subFun = new ArrayList<>();
+        int funCnt = 0;
+        List<String> varList = new ArrayList<>();
+        StringBuilder sbExp = new StringBuilder();
+
+        int tokenIndex = 0;
+        while (tokenIndex < tokens.size()) {
+            Token token = tokens.get(tokenIndex);
+            if (token.getTokenType() == TokenType.VARIABE) {
+                if (varList.contains(token.getValue()) == false)
+                    varList.add(token.getValue());
+                sbExp.append(token.getValue());
+            } else if (token.getTokenType() == TokenType.CUSTOMFUN) {
+                ArrayList<Token> subTokens = getFunTokens(tokens, tokenIndex);
+                AlarmExpression subExp = createCustomFunExpression(subTokens);
+                String subFunCode = FUNCODE + funCnt++;
+                subExp.setFunCode(subFunCode);
+                subExp.setParent(alarmExpression);
+                subFun.add(subExp);
+                varList.add(subFunCode);
+                sbExp.append(subFunCode);
+
+                tokenIndex += subTokens.size();
+                continue;
+            } else {
+                sbExp.append(token.getValue());
+            }
+
+            tokenIndex++;
+        }
+
+        alarmExpression.setVarList(varList);
+        alarmExpression.setExpression(sbExp.toString());
+        alarmExpression.setChildren(subFun);
+
+        return alarmExpression;
+    }
+
+    private static AlarmExpression createCustomFunExpression(ArrayList<Token> tokens) {
+        AlarmExpression alarmExpression = new AlarmExpression();
+
+        List<AlarmExpression> subExps = new ArrayList<>();
+        int funCnt = 0;
+        List<String> varList = new ArrayList<>();
+        List<String> paramList = new ArrayList<>();
+        StringBuilder sbExp = new StringBuilder();
+        alarmExpression.setFunType(tokens.get(0).getValue());
+        sbExp.append(tokens.get(0).getValue());
+
+        int tokenIndex = 1;
+        while (tokenIndex < tokens.size()) {
+            Token token = tokens.get(tokenIndex);
+            if (token.getTokenType() == TokenType.VARIABE) {
+                if (varList.contains(token.getValue()) == false)
+                    varList.add(token.getValue());
+                sbExp.append(token.getValue());
+            } else if (token.getTokenType() == TokenType.CUSTOMFUN) {
+                ArrayList<Token> subTokens = getFunTokens(tokens, tokenIndex);
+                AlarmExpression subExp = createCustomFunExpression(subTokens);
+                subExp.setParent(alarmExpression);
+                String subFunCode = FUNCODE + funCnt++;
+                subExp.setFunCode(subFunCode);
+                subExps.add(subExp);
+                varList.add(subFunCode);
+                sbExp.append(subFunCode);
+                tokenIndex += subTokens.size();
+                continue;
+            } else {
+                sbExp.append(token.getValue());
+            }
+
+            tokenIndex++;
+        }
+
+        alarmExpression.setVarList(varList);
+        alarmExpression.setExpression(sbExp.toString());
+        alarmExpression.setChildren(subExps);
+
+        return alarmExpression;
+    }
+
+    private static ArrayList<Token> getFunTokens(ArrayList<Token> tokens, int startIndex) {
+        ArrayList<Token> result = new ArrayList<>();
+        int cntL = 0;
+        int cntR = 0;
+        while (startIndex < tokens.size()) {
+            Token token = tokens.get(startIndex);
+            result.add(token);
+            if (token.getTokenType() == TokenType.PARENTHESISL) {
+                cntL++;
+            } else if (token.getTokenType() == TokenType.PARENTHESISR) {
+                if (++cntR == cntL) {
+                    break;
+                }
+            }
+            startIndex++;
+        }
+
+        return result;
+    }
+
+
+    public static void main(String[] args) {
+        //String exp = "AI041>80 && AI_FJZT!=3";
+        //String exp = "LastUpdateTime(AI03229)>=1800 && LastUpdateTime(AI03101)>=1800 && LastUpdateTime(DI07893)>=1800 && LastUpdateTime(DI07436)>=1800 && LastUpdateTime(DI07822)>=1800";
+
+        //String exp = "Sustain(AI022 > 4.5 && AI_FJZT==0,Math.Abs(600-100),60)";
+
+        String exp = "Sustain(FJAI022 > 4.5 && FCAI_FJZT==0 && LastUpdateTime(AI03229)>=1800 && LastUpdateTime(AI03101)>=1800 ,Math.Abs(600-100),60)";
+
+        ArrayList<Token> tokens = getTokens(exp);
+        for (Token token : tokens) {
+            System.out.println(token.getValue() + "----" + token.getTokenType());
+        }
+
+        AlarmExpression alarmExpression = createAlarmExpression(tokens);
+        System.out.println(alarmExpression.getFunType());
+
+    }
+}

+ 9 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/Token.java

@@ -0,0 +1,9 @@
+package com.gyee.wisdom.alarm.rule.expression;
+
+import lombok.Data;
+
+@Data
+public class Token {
+    private String value;
+    private TokenType tokenType;
+}

+ 12 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/rule/expression/TokenType.java

@@ -0,0 +1,12 @@
+package com.gyee.wisdom.alarm.rule.expression;
+
+public enum TokenType {
+    EMPTY,  //空,未赋值
+    VARIABE, //变量
+    CONST,  //常量
+    CUSTOMFUN, //自定义函数
+    SYSFUN, //标准库函数
+    PARENTHESISL, //圆括号左边
+    PARENTHESISR,  //圆括号右边
+    OTHER //其他符号,包括运算符,逗号等
+}

+ 306 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/service/CacheService.java

@@ -0,0 +1,306 @@
+package com.gyee.wisdom.alarm.service;
+
+import com.gyee.wisdom.alarm.config.ConfigProperties;
+import com.gyee.wisdom.alarm.rule.AlarmRule;
+import com.gyee.wisdom.alarm.model.*;
+import com.gyee.wisdom.common.data.alarm.AlertRule;
+import com.gyee.wisdom.common.data.timeseries.TsDataType;
+import com.gyee.wisdom.common.data.timeseries.TsPoint;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.security.KeyStore;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Slf4j
+@Service
+public class CacheService {
+
+    //keyid: stationId
+    private Map<String, StationInfo> stationInfoMap;
+    //keyid: windturibneId
+    private Map<String, WindturbineInfo> windturbineInfoMap;
+    //keyid: pointId
+    private Map<String, TagInfo> tagMap;
+    //点名串分组,防止串超长
+    private ArrayList<String> keysList;
+    //keyid: uniformCode, 俺统一编码整理风机
+    private Map<String, ArrayList<String>> ucWindturbineMap;
+    //keyid: uniformCode, 俺统一编码整理风场
+    private Map<String, ArrayList<String>> ucStationMap;
+
+    private List<AlarmRule> alarmRuleList;
+    //标示读取实时数据的线程是否取得到了数据
+    private boolean readRtdbSuccess;
+
+    @Autowired
+    private ConfigProperties configProperties;
+    @Autowired
+    private SqlService sqlService;
+
+    public List<AlarmRule> getAlarmRuleList() {
+        if (alarmRuleList == null)
+            alarmRuleList = createAlarmRuleList();
+
+        return alarmRuleList;
+    }
+
+    private List<AlarmRule> createAlarmRuleList() {
+        List<AlarmRule> result = new ArrayList<>();
+
+        log.info("加载自定义报警规则...");
+        List<AlertRule> lstAr = sqlService.getAllAlertRules();
+        for (AlertRule ar : lstAr) {
+            log.info(ar.getId());
+            AlarmRule amr = new AlarmRule(ar);
+            result.add(amr);
+        }
+        return result;
+    }
+
+    public Map<String, StationInfo> getStationInfoMap() {
+        if (stationInfoMap == null)
+            stationInfoMap = createStationInfoMap();
+
+        return stationInfoMap;
+    }
+
+    private Map<String, StationInfo> createStationInfoMap() {
+        Map<String, StationInfo> result = new HashMap<>();
+
+        log.info("加载场站数据...");
+        List<PowerStation> lstAr = sqlService.getStationList();
+        for (PowerStation ar : lstAr) {
+            if (ar.getId().endsWith("_FDC")) {
+                StationInfo amr = new StationInfo();
+//                amr.setStationId(ar.getId());
+//                amr.setStationName(ar.getStationName());
+                amr.setStation(ar);
+
+                result.put(ar.getId(), amr);
+            }
+        }
+        return result;
+    }
+
+    public Map<String, WindturbineInfo> getWindturbineInfoMap() {
+        if (windturbineInfoMap == null)
+            windturbineInfoMap = createWindturbineInfoMap();
+
+        return windturbineInfoMap;
+    }
+
+    private Map<String, WindturbineInfo> createWindturbineInfoMap() {
+        Map<String, WindturbineInfo> result = new HashMap<>();
+
+        log.info("加载风机数据...");
+        List<Windturbine> lstAr = sqlService.getAllWindturbine();
+        for (Windturbine wt : lstAr) {
+            if (wt.getWindPowerStationId().endsWith("_FDC")) {
+                WindturbineInfo wtInfo = new WindturbineInfo();
+//                wtInfo.setId(wt.getId());
+//                wtInfo.setModelId(wt.getModelId());
+//                wtInfo.setName(wt.getModelId());
+                wtInfo.setWindturbine(wt);
+
+                result.put(wt.getId(), wtInfo);
+            }
+        }
+        return result;
+    }
+
+
+    public Map<String, ArrayList<String>> getUcWindturbineMap() {
+        if (ucWindturbineMap == null) {
+            ucWindturbineMap = new HashMap<>();
+        }
+        return ucWindturbineMap;
+    }
+
+    public Map<String, ArrayList<String>> getUcStationMap() {
+        if (ucStationMap == null) {
+            ucStationMap = new HashMap<>();
+        }
+        return ucStationMap;
+    }
+
+    public ArrayList<String> getUcWindturbinelist(String uc) {
+        if (ucWindturbineMap == null) {
+            ucWindturbineMap = new HashMap<>();
+        }
+
+        if (ucWindturbineMap.containsKey(uc) == false) {
+            ArrayList<String> wtList = new ArrayList<>();
+            ucWindturbineMap.put(uc, wtList);
+        }
+
+        return ucWindturbineMap.get(uc);
+    }
+
+    public ArrayList<String> getUcStationlist(String uc) {
+        if (ucStationMap == null) {
+            ucStationMap = new HashMap<>();
+        }
+
+        if (ucStationMap.containsKey(uc) == false) {
+            ArrayList<String> stList = new ArrayList<>();
+            ucStationMap.put(uc, stList);
+        }
+
+        return ucStationMap.get(uc);
+    }
+
+    public Map<String, TagInfo> getTagMap() {
+        if (tagMap == null)
+            tagMap = createTagMap();
+
+        return tagMap;
+    }
+
+    private Map<String, TagInfo> createTagMap() {
+        Map<String, TagInfo> result = new HashMap<>();
+
+        Map<String, ArrayList<String>> ucWtMap = getUcWindturbineMap();
+        for (Map.Entry<String, ArrayList<String>> entry : ucWtMap.entrySet()) {
+            String uc = entry.getKey();
+            ArrayList<String> wtList = entry.getValue();
+            String[] wtArray = new String[wtList.size()];
+            wtList.toArray(wtArray);
+
+            List<TsPoint> tsPointList = sqlService.getTsPointByThingIds("windturbine", uc, wtArray);
+            for (TsPoint tp : tsPointList) {
+                if (result.containsKey(tp.getId()) == false) {
+                    TagInfo tagInfo = new TagInfo(tp);
+                    result.put(tp.getId(), tagInfo);
+                    String wtId = tp.getThingId();
+                    if (windturbineInfoMap == null)
+                        windturbineInfoMap = createWindturbineInfoMap();
+                    if (windturbineInfoMap.containsKey(wtId)) {
+                        WindturbineInfo wInfo = windturbineInfoMap.get(wtId);
+                        if (wInfo.getTagMap() == null)
+                            wInfo.setTagMap(new HashMap<>());
+                        if (wInfo.getTagMap().containsKey(tp.getUniformCode()) == false) {
+                            wInfo.getTagMap().put(tp.getUniformCode(), tagInfo);
+                        }
+                    }
+                }
+            }
+        }
+
+        Map<String, ArrayList<String>> ucStMap = getUcStationMap();
+        for (Map.Entry<String, ArrayList<String>> entry : ucStMap.entrySet()) {
+            String uc = entry.getKey();
+            ArrayList<String> stList = entry.getValue();
+            String[] stArray = new String[stList.size()];
+            stList.toArray(stArray);
+
+            List<TsPoint> tsPointList = sqlService.getTsPointByThingIds("station", uc, stArray);
+            for (TsPoint tp : tsPointList) {
+                if (result.containsKey(tp.getId()) == false) {
+                    TagInfo tagInfo = new TagInfo(tp);
+                    result.put(tp.getId(), tagInfo);
+                    String stId = tp.getThingId();
+                    if (stationInfoMap == null)
+                        stationInfoMap = createStationInfoMap();
+                    if (stationInfoMap.containsKey(stId)) {
+                        StationInfo info = stationInfoMap.get(stId);
+                        if (info.getTagMap() == null)
+                            info.setTagMap(new HashMap<>());
+                        if (info.getTagMap().containsKey(tp.getUniformCode()) == false) {
+                            info.getTagMap().put(tp.getUniformCode(), tagInfo);
+                        }
+                    }
+                }
+            }
+        }
+
+        return result;
+    }
+
+
+    public ArrayList<String> getKeysList() {
+        if (keysList == null)
+            keysList = createKeysList();
+
+        return keysList;
+    }
+
+    private ArrayList<String> createKeysList() {
+        ArrayList<String> result = new ArrayList<>();
+        Map<String, TagInfo> tm = getTagMap();
+        StringBuilder sbDouble = new StringBuilder();
+        StringBuilder sbBoolean = new StringBuilder();
+        StringBuilder sbLong = new StringBuilder();
+
+        int cntDouble = 0;
+        int cntBoolean = 0;
+        int cntLong = 0;
+
+        for (Map.Entry<String, TagInfo> entry : tm.entrySet()) {
+            String tagId = entry.getKey();
+            TagInfo tagInfo = entry.getValue();
+            if (tagInfo.getTsPoint().getTsDataType() == TsDataType.DOUBLE) {
+                sbDouble.append(tagId);
+                sbDouble.append(",");
+                cntDouble++;
+                if (cntDouble % 1000 == 0) {
+                    result.add(sbDouble.toString());
+                    sbDouble.delete(0, sbDouble.length());
+                }
+            } else if (tagInfo.getTsPoint().getTsDataType() == TsDataType.BOOLEAN) {
+                sbBoolean.append(tagId);
+                sbBoolean.append(",");
+                cntBoolean++;
+                if (cntBoolean % 1000 == 0) {
+                    result.add(sbBoolean.toString());
+                    sbBoolean.delete(0, sbBoolean.length());
+                }
+            } else if (tagInfo.getTsPoint().getTsDataType() == TsDataType.LONG) {
+                sbLong.append(tagId);
+                sbLong.append(",");
+                cntLong++;
+                if (cntLong % 1000 == 0) {
+                    result.add(sbLong.toString());
+                    sbLong.delete(0, sbLong.length());
+                }
+            }
+        }
+
+        if (sbDouble.length() > 0)
+            result.add(sbDouble.toString());
+        if (sbBoolean.length() > 0)
+            result.add(sbBoolean.toString());
+        if (sbLong.length() > 0)
+            result.add(sbLong.toString());
+
+        return result;
+    }
+
+
+    public boolean getReadRtdbSuccess() {
+        return readRtdbSuccess;
+    }
+
+    public void setReadRtdbSuccess(boolean value) {
+        readRtdbSuccess = value;
+    }
+
+    public void clearCache() {
+        this.stationInfoMap = null;
+        this.windturbineInfoMap = null;
+        this.tagMap = null;
+        this.keysList = null;
+        this.ucWindturbineMap = null;
+        this.ucStationMap = null;
+        this.alarmRuleList = null;
+        this.readRtdbSuccess = false;
+        log.warn("缓存数据清空!");
+    }
+
+}

+ 162 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/service/SqlService.java

@@ -0,0 +1,162 @@
+package com.gyee.wisdom.alarm.service;
+
+import com.gyee.wisdom.alarm.rule.ThingType;
+import com.gyee.wisdom.alarm.transport.shardingclient.RemoteServiceBuilder;
+import com.gyee.wisdom.alarm.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.common.data.alarm.AlertRule;
+import com.gyee.wisdom.common.data.power.WindturbinePowerCurvefitting;
+import com.gyee.wisdom.common.data.timeseries.TsPoint;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import com.gyee.wisdom.dao.alarm.AlarmhistoryDao;
+import com.gyee.wisdom.dao.alarm.AlarmsnapDao;
+import com.gyee.wisdom.dao.alarm.AlertRuleDao;
+import com.gyee.wisdom.dao.power.IWindturbinePowerCurvefittingDao;
+import com.gyee.wisdom.dao.things.IThingsPointDao;
+import com.gyee.wisdom.dao.windturbine.IPowerStationDao;
+import com.gyee.wisdom.dao.windturbine.IWindturbineDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@Service
+public class SqlService {
+
+    @Autowired
+    protected IPowerStationDao stationDao;
+
+    @Autowired
+    protected IWindturbineDao windturbineDao;
+
+    @Autowired
+    private IThingsPointDao thingsPointDao;
+
+    @Autowired
+    private IWindturbinePowerCurvefittingDao powerCurvefittingDao;
+
+    @Autowired
+    private AlarmsnapDao alarmsnapDao;
+
+    @Autowired
+    private AlarmhistoryDao alarmhistoryDao;
+
+    @Autowired
+    private AlertRuleDao alertRuleDao;
+
+    @Autowired
+    protected RemoteServiceBuilder remoteServiceBuilder;
+
+    public List<PowerStation> getStationList() {
+        return stationDao.getAll();
+    }
+
+    public List<Windturbine> findByStationId(String stationId) {
+        return windturbineDao.findByStationId(stationId);
+    }
+
+    public List<Windturbine> getAllWindturbine() {
+        return windturbineDao.find();
+    }
+
+    public List<AlertRule> getAllAlertRules() {
+        return alertRuleDao.findByEnabled(true);
+    }
+
+    public List<TsPoint> getTsPointByUniformCodes(String thingsType, String thingsId, String... uniformCodes) {
+
+        List<TsPoint> selectList = new ArrayList<>();
+        if (uniformCodes.length > 1000) {
+
+            int selectCount = uniformCodes.length / 1000;
+            int remainder = uniformCodes.length % 1000;
+
+            if (remainder == 0) {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] uniformCodeArr = Arrays.copyOfRange(uniformCodes, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByUnformCodes(thingsType, thingsId, uniformCodeArr);
+                    selectList.addAll(subList);
+                }
+            } else {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] uniformCodeArr = Arrays.copyOfRange(uniformCodes, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByUnformCodes(thingsType, thingsId, uniformCodeArr);
+                    selectList.addAll(subList);
+                }
+                //将数组剩余元素进行查询
+                String[] lastUniformCode = Arrays.copyOfRange(uniformCodes, uniformCodes.length - remainder, uniformCodes.length);
+                List<TsPoint> lastSubList = thingsPointDao.findTsPointByUnformCodes(thingsType, thingsId, lastUniformCode);
+                selectList.addAll(lastSubList);
+            }
+        } else {
+            selectList = thingsPointDao.findTsPointByUnformCodes(thingsType, thingsId, uniformCodes);
+        }
+        return selectList;
+
+    }
+
+
+    //todo: 按顺序整理
+
+    public List<TsPoint> getTsPointByThingIds(String thingsType, String uniformCode, String... thingIds) {
+
+        List<TsPoint> selectList = new ArrayList<>();
+        if (thingIds.length > 1000) {
+
+            int selectCount = thingIds.length / 1000;
+            int remainder = thingIds.length % 1000;
+
+            if (remainder == 0) {
+
+                for (int i = 0; i < selectCount; i++) {
+                    String[] thingsIdArr = Arrays.copyOfRange(thingIds, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByThingIds(thingsType, uniformCode, thingsIdArr);
+                    selectList.addAll(subList);
+                }
+            } else {
+                for (int i = 0; i < selectCount; i++) {
+                    String[] thingsIdArr = Arrays.copyOfRange(thingIds, 1000 * i, 1000 * (i + 1));
+                    List<TsPoint> subList = thingsPointDao.findTsPointByThingIds(thingsType, uniformCode, thingsIdArr);
+                    selectList.addAll(subList);
+                }
+                //将数组剩余元素进行查询
+                String[] lastThingId = Arrays.copyOfRange(thingIds, thingIds.length - remainder, thingIds.length);
+                List<TsPoint> lastSubList = thingsPointDao.findTsPointByThingIds(thingsType, uniformCode, lastThingId);
+                selectList.addAll(lastSubList);
+            }
+        } else {
+            selectList = thingsPointDao.findTsPointByThingIds(thingsType, uniformCode, thingIds);
+        }
+        return selectList;
+
+    }
+
+    public List<WindturbinePowerCurvefitting> getPowerCurvefittingByWindturbineId(String windturbineId) {
+        return powerCurvefittingDao.findByWindturbineId(windturbineId);
+    }
+
+
+    public AlarmSnap getAlertSnap(ThingType thingType, String thingId, int alertvalue) {
+
+        if (thingType == ThingType.WINDTURBINE)
+            return remoteServiceBuilder.alarmSnapService().queryOneByWtId(thingId, alertvalue);
+        else if (thingType == ThingType.STATION)
+            return remoteServiceBuilder.alarmSnapService().queryOneByStId(thingId, alertvalue);
+
+        return null;
+    }
+
+    public void saveAlertSnap(AlarmSnap snap) {
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnap(snap);
+    }
+
+    public void saveAlertSnaps(List<AlarmSnap> snaps) {
+
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnaps(snaps);
+    }
+
+}

+ 106 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/restful/RestfulClient.java

@@ -0,0 +1,106 @@
+package com.gyee.wisdom.alarm.transport.restful;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.config.ConfigProperties;
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.util.SpringContextUtils;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.TsPointData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import javax.swing.text.html.HTML;
+import java.util.*;
+
+@Service
+@Slf4j
+public class RestfulClient {
+
+    @Autowired
+    private ConfigProperties configProperties;
+
+    @Autowired
+    private CacheService cacheService;
+
+    private Map<String, TagInfo> tagInfoMap;
+
+    private RestTemplate restTemplate;
+
+    private String adpUrl;
+
+    private String getAdpUrl() {
+        if (adpUrl == null) {
+            adpUrl = configProperties.getServiceUrl();
+        }
+
+        return adpUrl;
+    }
+
+    private String adpLatestUrl;
+
+    private String getAdpLatestUrl() {
+        if (adpLatestUrl == null) {
+            adpLatestUrl = getAdpUrl() + "/latest?keys=";
+        }
+        return adpLatestUrl;
+    }
+
+    private RestTemplate getRestTemplate() {
+        if (restTemplate == null) {
+            //复杂构造函数的使用
+            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
+            requestFactory.setConnectTimeout(10000);// 设置超时
+            requestFactory.setReadTimeout(10000);
+            restTemplate = new RestTemplate(requestFactory);
+        }
+
+        return restTemplate;
+    }
+
+    private Map<String, TagInfo> getTagInfoMap() {
+        return cacheService.getTagMap();
+    }
+
+    public void getLatest(String keys) throws Exception {
+
+        String url = getAdpLatestUrl() + keys;
+        ResponseEntity<Object> resp = getRestTemplate().getForEntity(url, Object.class);
+        if (resp.getStatusCode() == HttpStatus.OK) {
+            HashMap<String, HashMap<String, Object>> map = (HashMap<String, HashMap<String, Object>>) resp.getBody();
+            if (map != null && map.size() > 0) {
+                for (Map.Entry<String, HashMap<String, Object>> entry : map.entrySet()) {
+                    try {
+                        String tagId = entry.getKey();
+                        TagInfo tagInfo = getTagInfoMap().get(tagId);
+                        tagInfo.UpdateTsData(entry.getValue());
+                    } catch (Exception ex) {
+                        log.error(ex.getMessage());
+                        //System.out.println(ex.getMessage());
+                    }
+                }
+            }
+
+            //已成功取得数据,通知计算线程可以开始运算了
+            if (cacheService.getReadRtdbSuccess() == false)
+                cacheService.setReadRtdbSuccess(true);
+        } else {
+            log.error(resp.getStatusCodeValue() + "");
+        }
+
+
+    }
+
+    public void writeLatestPointList(List<TsPointData> writeList) throws Exception {
+        String url = configProperties.getServiceUrl() + "/latest/batch";
+        restTemplate.postForObject(url, writeList, String.class);
+    }
+
+
+}

+ 57 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/AlarmSnapService.java

@@ -0,0 +1,57 @@
+package com.gyee.wisdom.alarm.transport.shardingclient;
+
+import com.gyee.wisdom.alarm.transport.shardingclient.dto.AlarmSnap;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+import org.springframework.web.bind.annotation.RequestParam;
+
+import java.util.List;
+import java.util.Map;
+
+public interface AlarmSnapService {
+
+	@RequestLine("GET /alarm/snap/{snapId}")
+	AlarmSnap queryById(@Param(value = "snapId") long snapId);
+
+	@RequestLine("GET /alarm/snap/single?windturbineid={wtId}&alertvalue={alertValue}")
+	AlarmSnap queryOneByWtId(
+			@Param(value = "wtId") String wtId,
+			@Param(value = "alertValue") Integer alertValue
+	);
+
+	@RequestLine("GET /alarm/snap/single?alertvalue={alertValue}&stationid={stId}")
+	AlarmSnap queryOneByStId(
+			@Param(value = "stId") String stId,
+			@Param(value = "alertValue") Integer alertValue
+	);
+
+	@RequestLine("GET /alarm/snap/single?testingpointkey={tagId}")
+	AlarmSnap queryOneByTagId( @Param(value = "tagId") String tagId );
+
+	@RequestLine("GET /alarm/snap?stationid={stationid}&windturbineid={windturbineid}&category1={category1}&" +
+			"category2={category2}&rank={rank}&modelid={modelid}&isopened={isopened}&" +
+			"keyword={keyword}&starttime={starttime}&endtime={endtime}")
+	public List<AlarmSnap> queryAll(
+            @Param(value = "stationid") String stId,
+            @Param(value = "windturbineid") String wtId,
+            @Param(value = "category1") String category1,
+            @Param(value = "category2") String category2,
+            @Param(value = "rank") String rank,
+            @Param(value = "modelid") String modelId,
+            @Param(value = "isopened") Integer isOpened,
+            @Param(value = "keyword") String keyWord,
+            @Param(value = "starttime") String startTime,
+            @Param(value = "endtime") String endTime
+    );
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap")
+	void saveAlarmSnap(AlarmSnap alarmSnap);
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap/batch")
+	void saveAlarmSnaps(List<AlarmSnap> alarmSnaps);
+
+
+}

+ 34 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/RemoteServiceBuilder.java

@@ -0,0 +1,34 @@
+package com.gyee.wisdom.alarm.transport.shardingclient;
+
+import com.gyee.wisdom.alarm.config.ConfigProperties;
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class RemoteServiceBuilder {
+
+    @Autowired
+    private ConfigProperties configProperties;
+//    public String shardingSevice = "http://localhost:8075";
+
+    @Bean
+    public AlarmSnapService alarmSnapService() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 3500))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(AlarmSnapService.class, configProperties.getShardingServiceUrl());
+    }
+
+
+
+}

+ 19 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmHistory.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.alarm.transport.shardingclient.dto;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmHistory implements Serializable{
+
+    private Long id;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date alertTime;
+    private int messageType;
+    private Long snapId;
+    private String dataInfo;
+}

+ 41 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmHistoryInfo.java

@@ -0,0 +1,41 @@
+package com.gyee.wisdom.alarm.transport.shardingclient.dto;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+@Data
+public class AlarmHistoryInfo implements Serializable {
+
+    private static final long serialVersionUID = 0L;
+
+    private Long id;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date alertTime;
+    private int messageType;
+    private Long snapId;
+    private String dataInfo;
+
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+
+}

+ 33 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/shardingclient/dto/AlarmSnap.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.alarm.transport.shardingclient.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmSnap implements Serializable{
+
+    private Long id;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    private int isOpened;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+    private String testingpointKey;
+    private String dataInfo;
+}

+ 49 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/ClientStompFrameHandler.java

@@ -0,0 +1,49 @@
+package com.gyee.wisdom.alarm.transport.websocket;
+
+import com.gyee.wisdom.alarm.model.TagInfo;
+import com.gyee.wisdom.alarm.service.CacheService;
+import com.gyee.wisdom.alarm.util.SpringContextUtils;
+import org.springframework.messaging.simp.stomp.StompFrameHandler;
+import org.springframework.messaging.simp.stomp.StompHeaders;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+
+public class ClientStompFrameHandler implements StompFrameHandler {
+
+    private CacheService cacheService = SpringContextUtils.getBean(CacheService.class);
+
+    private Map<String, TagInfo> tagInfoMap = cacheService.getTagMap();
+
+    public Type getPayloadType(StompHeaders headers) {
+        //Map<String, BasicTsData> map = new HashMap<>();
+        return HashMap.class;
+    }
+
+    public void handleFrame(StompHeaders headers, Object payload) {
+        System.out.print(".");
+
+        HashMap<String, HashMap<String, Object>> map = (HashMap<String, HashMap<String, Object>>) payload;
+        if (map.size() > 0) {
+            for (Map.Entry<String, HashMap<String, Object>> entry : map.entrySet()) {
+                try {
+                    String tagId = entry.getKey();
+                    TagInfo tagInfo = tagInfoMap.get(tagId);
+                    tagInfo.UpdateTsData(entry.getValue());
+                } catch (Exception ex) {
+                    System.out.println(ex.getMessage());
+                }
+            }
+        }
+
+        //已成功取得数据,通知计算线程可以开始运算了
+        if (cacheService.getReadRtdbSuccess() == false)
+            cacheService.setReadRtdbSuccess(true);
+    }
+
+
+}

+ 34 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/ClientStompSessionHandler.java

@@ -0,0 +1,34 @@
+package com.gyee.wisdom.alarm.transport.websocket;
+
+import org.springframework.messaging.simp.stomp.StompCommand;
+import org.springframework.messaging.simp.stomp.StompHeaders;
+import org.springframework.messaging.simp.stomp.StompSession;
+import org.springframework.messaging.simp.stomp.StompSessionHandlerAdapter;
+
+public class ClientStompSessionHandler extends StompSessionHandlerAdapter {
+
+    public boolean connect = false;
+
+    @Override
+    public void handleFrame(StompHeaders headers, Object payload) {
+        System.out.println(headers.toString());
+        System.out.println(payload);
+    }
+
+    @Override
+    public void handleException(StompSession s, StompCommand c, StompHeaders h, byte[] p, Throwable ex) {
+        System.out.println(ex.getMessage());
+    }
+
+    @Override
+    public void handleTransportError(StompSession session, Throwable ex) {
+        System.out.println(ex.getMessage());
+    }
+
+    @Override
+    public void afterConnected(final StompSession session, StompHeaders connectedHeaders) {
+        System.out.println("websocket连接成功");
+    }
+
+
+}

+ 35 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/RequestClient.java

@@ -0,0 +1,35 @@
+package com.gyee.wisdom.alarm.transport.websocket;
+
+
+import java.util.concurrent.TimeUnit;
+
+public class RequestClient {
+
+    public static void main(String[] args) {
+
+        StompClient client = new StompClient("ws://localhost:8011/wisdom");
+
+        for (int i = 0; i < 10; i++) {
+            client.getLatest("NSSFJ.NX_GD_NSSF_FJ_P1_L1_001_AI0005,NSSFJ.NX_GD_NSSF_FJ_P1_L1_001_AI0006");
+        }
+        client.getLatest("NSSFJ.NX_GD_NSSF_FJ_P1_L1_001_AI0005888,NSSFJ.NX_GD_NSSF_FJ_P1_L1_001_AI0006888");
+
+        //request.writeLatestBatch();
+        //request.writeLatest();
+
+        sleep(5000);
+
+        try {
+            System.in.read();
+        } catch (Exception ex) {
+        }
+    }
+
+    private static void sleep(int milliseconds) {
+        try {
+            TimeUnit.MILLISECONDS.sleep(milliseconds);
+        } catch (Exception ex) {
+            System.out.println(ex.getMessage());
+        }
+    }
+}

+ 86 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/transport/websocket/StompClient.java

@@ -0,0 +1,86 @@
+package com.gyee.wisdom.alarm.transport.websocket;
+
+
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.messaging.converter.MappingJackson2MessageConverter;
+import org.springframework.messaging.simp.stomp.StompFrameHandler;
+import org.springframework.messaging.simp.stomp.StompHeaders;
+import org.springframework.messaging.simp.stomp.StompSession;
+import org.springframework.messaging.simp.stomp.StompSessionHandler;
+import org.springframework.web.socket.WebSocketHttpHeaders;
+import org.springframework.web.socket.client.standard.StandardWebSocketClient;
+import org.springframework.web.socket.messaging.WebSocketStompClient;
+import org.springframework.web.socket.sockjs.client.SockJsClient;
+import org.springframework.web.socket.sockjs.client.Transport;
+import org.springframework.web.socket.sockjs.client.WebSocketTransport;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
+
+@Slf4j
+public class StompClient {
+
+    private String serviceUrl;
+    private SockJsClient sockJsClient;
+    private WebSocketStompClient wsStompClient;
+    private StompSession stompSession;
+    //private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
+    private ClientStompSessionHandler stompSessionHandler;
+    private ClientStompFrameHandler stompFrameHandler;
+
+    public StompClient(String url) {
+        this.serviceUrl = url;
+        List<Transport> transports = new ArrayList<>();
+        transports.add(new WebSocketTransport(new StandardWebSocketClient()));
+        this.sockJsClient = new SockJsClient(transports);
+        this.wsStompClient = new WebSocketStompClient(sockJsClient);
+        this.wsStompClient.setInboundMessageSizeLimit(9999999);
+        this.wsStompClient.setMessageConverter(new MappingJackson2MessageConverter());
+        stompSessionHandler = new ClientStompSessionHandler();
+        stompFrameHandler = new ClientStompFrameHandler();
+    }
+
+
+    public void connect() {
+        if (stompSession != null && stompSession.isConnected())
+            return;
+        try {
+            stompSession = wsStompClient.connect(serviceUrl, new WebSocketHttpHeaders(), stompSessionHandler).get();
+            log.info("连接成功!url=" + serviceUrl);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+        }
+    }
+
+    public void disContenct() {
+        if (stompSession != null) {
+            stompSession.disconnect();
+            System.out.println("websocket已断开");
+        }
+    }
+
+    public void sendRequest(StompHeaders headers) {
+        connect();
+        if (!stompSession.isConnected()) {
+            log.error("未能建立与数据适配器的websocke连接!url=" + serviceUrl);
+        }
+
+        stompSession.subscribe(headers, stompFrameHandler);
+    }
+
+    public void getLatest(String keyStr) {
+
+        StompHeaders headers = new StompHeaders();
+        headers.setDestination("/app/latest");
+        headers.add("keyStr", keyStr);
+
+        sendRequest(headers);
+    }
+
+}

+ 62 - 0
alarm/custom/src/main/java/com/gyee/wisdom/alarm/util/SpringContextUtils.java

@@ -0,0 +1,62 @@
+package com.gyee.wisdom.alarm.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringContextUtils implements ApplicationContextAware {
+
+    /**
+     * 上下文对象实例
+     */
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        this.applicationContext = applicationContext;
+    }
+
+    /**
+     * 获取applicationContext
+     *
+     * @return
+     */
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+
+    /**
+     * 通过name获取 Bean.
+     *
+     * @param name
+     * @return
+     */
+    public static Object getBean(String name) {
+        return getApplicationContext().getBean(name);
+    }
+
+    /**
+     * 通过class获取Bean.
+     *
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+
+    /**
+     * 通过name,以及Clazz返回指定的Bean
+     *
+     * @param name
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T getBean(String name, Class<T> clazz) {
+        return getApplicationContext().getBean(name, clazz);
+    }
+}

+ 2 - 0
alarm/custom/src/main/java/lombok.config

@@ -0,0 +1,2 @@
+config.stopBubbling=true
+lombok.equalsAndHashCode.callSuper=call

BIN
alarm/custom/src/main/lib/ojdbc6.jar


+ 45 - 0
alarm/custom/src/main/resources/application.yaml

@@ -0,0 +1,45 @@
+server:
+  port: 8060
+
+spring:
+  application:
+    name: alarm-custom
+  jpa:
+    show-sql: false
+  datasource:
+    driver-class-name: oracle.jdbc.OracleDriver
+    url: jdbc:oracle:thin:@123.60.213.70:1521:gdnxfd
+    username: nxfdprod
+    password: gdnxfd123
+#    driver-class-name: com.mysql.jdbc.Driver
+#    url: jdbc:mysql://127.0.0.1/wisdom_cs?useUnicode=true&characterEncoding=UTF-8
+#    username: root
+#    password: 123
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      max-active: 20
+      initial-size: 1
+      min-idle: 3
+      max-wait: 60000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+calculate:
+  config:
+    #服务地址  ws://localhost:8011/wisdom
+    serviceUrl: http://127.0.0.1:8011/ts
+    #服务地址  ws://localhost:8011/wisdom
+    shardingServiceUrl: http://192.168.100.204:8075
+    #扫描线程轮询时间(单位:毫秒)
+    readThreadInterval: 1000
+    #计算线程轮询时间(单位:毫秒)
+    calcThreadInterval: 1000
+    #规则解析线程池大小
+    maxThreadCount: 4
+  cron:
+   #每天2点0分进行报警规则重新加载
+   CacheRefresh: 0 0 2 ? * *
+
+

+ 9 - 0
alarm/custom/src/main/resources/banner.txt

@@ -0,0 +1,9 @@
+       _                                       _
+      | |                                     | |
+  __ _| | __ _ _ __ _ __ ___     ___ _   _ ___| |_ ___  _ __ ___
+ / _` | |/ _` | '__| '_ ` _ \   / __| | | / __| __/ _ \| '_ ` _ \
+| (_| | | (_| | |  | | | | | | | (__| |_| \__ \ || (_) | | | | | |
+ \__,_|_|\__,_|_|  |_| |_| |_|  \___|\__,_|___/\__\___/|_| |_| |_|
+
+
+ :: alarm-custom ::                    version 1.0.0

+ 64 - 0
alarm/custom/src/main/resources/log4j2.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+    <Properties>
+        <Property name="Pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %t %M(%F:%L) %m%n</Property>
+    </Properties>
+    <Filter type="ThresholdFilter" level="INFO"/>
+
+    <Appenders>
+        <Console name="Console" target="SYSTEM_OUT">
+            <PatternLayout pattern="${Pattern}"/>
+        </Console>
+        <RollingFile name="RollingFileInfo" fileName="logs/info.log"
+                     filePattern="logs/%d{yyyy-MM}/info-%d{yyyy-MM-dd}.%i.log">
+            <PatternLayout pattern="${Pattern}"/>
+            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy>
+                <Delete basePath="${baseDir}" maxDepth="2">
+                    <IfFileName glob="*/*.log" />
+                    <IfLastModified age="24H" />
+                </Delete>
+            </DefaultRolloverStrategy>
+        </RollingFile>
+        <RollingFile name="RollingFileWarn" fileName="logs/warn.log"
+                     filePattern="logs/%d{yyyy-MM}/warn-%d{yyyy-MM-dd}.%i.log">
+            <PatternLayout pattern="${Pattern}"/>
+            <ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy>
+                <Delete basePath="${baseDir}" maxDepth="2">
+                    <IfFileName glob="*/*.log" />
+                    <IfLastModified age="24H" />
+                </Delete>
+            </DefaultRolloverStrategy>
+        </RollingFile>
+        <RollingFile name="RollingFileError" fileName="logs/error.log"
+                     filePattern="logs/%d{yyyy-MM}/error-%d{yyyy-MM-dd}.%i.log">
+            <PatternLayout pattern="${Pattern}"/>
+            <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
+            <Policies>
+                <TimeBasedTriggeringPolicy/>
+            </Policies>
+            <DefaultRolloverStrategy>
+                <Delete basePath="${baseDir}" maxDepth="2">
+                    <IfFileName glob="*/*.log" />
+                    <IfLastModified age="24H" />
+                </Delete>
+            </DefaultRolloverStrategy>
+        </RollingFile>
+    </Appenders>
+
+    <Loggers>
+        <Root level="INFO">
+            <AppenderRef ref="Console"/>
+         <!-- <appender-ref ref="RollingFileInfo"/>
+            <appender-ref ref="RollingFileWarn"/>-->
+            <appender-ref ref="RollingFileError"/>
+        </Root>
+    </Loggers>
+</Configuration>

+ 86 - 0
alarm/custom/src/test/java/TestScriptShell.java

@@ -0,0 +1,86 @@
+import com.gyee.wisdom.alarm.rule.AlarmScript;
+import groovy.lang.Binding;
+import groovy.lang.GroovyShell;
+import groovy.lang.Script;
+import org.codehaus.groovy.control.CompilerConfiguration;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class TestScriptShell {
+
+    private static final GroovyShell shell;
+
+    private static ConcurrentHashMap<String, Script> cache = new ConcurrentHashMap<String, Script>();
+
+    static {
+        CompilerConfiguration cfg = new CompilerConfiguration();
+        cfg.setScriptBaseClass(AlarmScript.class.getName());
+
+        shell = new GroovyShell(cfg);
+    }
+
+    public static final String entityIdName = "entityId";
+    public static final String variableName = "variable";
+    public static final String tsDataName = "tsData";
+
+    //   private static ConcurrentHashMap<Long,ConcurrentHashMap<String, TsData>> tsDataCache = new ConcurrentHashMap<Long,ConcurrentHashMap<String, TsData>>();
+
+    public static Object parseExpr(String expr) {
+        Script s = getScriptFromCache(expr);
+        return s.run();
+    }
+
+    public static Object parseExpr(String expr, Map<String, Object> map) {
+        Binding binding = new Binding(map);
+        Script script = getScriptFromCache(expr);
+        script.setBinding(binding);
+        return script.run();
+    }
+
+    private static Script getScriptFromCache(String expr) {
+        if (cache.containsKey(expr)) {
+            return cache.get(expr);
+        }
+        Script script = shell.parse(expr);
+        cache.put(expr, script);
+        return script;
+    }
+
+
+    public static void main(String[] args) {
+        Map<String, Object> row = new HashMap<String, Object>();
+        row.put("ai1", 13);
+        row.put("ai2", 2.1);
+        row.put("di1", false);
+
+//        DoubleTsData tsd = new DoubleTsData(1,(short)1,335.98);
+//        row.put("AI128", tsd);
+
+        //double a = Math.max()
+
+//        Object obj = parseExpr("AI128",row);
+//        System.out.println(obj);
+        Object obj1 = parseExpr("Math.max(ai1, ai2)", row);
+        System.out.println(obj1);
+        Object obj2 = parseExpr("ai1 > ai2 && di1", row);
+        System.out.println(obj2);
+        Object obj3 = parseExpr("dataSub(ai1,ai2)", row);
+        System.out.println(obj3);
+        Object obj4 = parseExpr("dataSub(ai2,ai1)", row);
+        System.out.println(obj4);
+    }
+
+    //eg1: fun1(var1)
+    //eg2: fun2(var1+var2*var3,const1)
+    //eg3: fun3(Math.fun(exp1, exp2...), exp)
+    //eg4: fun4(fun3, fun2,fun1)
+    //eg5: fun5(fun4, fun3)
+
+    //ar: varlist,funlist, scriptMap
+    // 函数内变量全部用引号括起
+    //wt: arlist, taglist
+    //tagInfo:
+
+}

+ 80 - 0
alarm/custom/src/test/java/TestThreadPool.java

@@ -0,0 +1,80 @@
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+
+public class TestThreadPool {
+
+    public static void main(String[] args) throws InterruptedException {
+
+        sellTicket();
+
+    }
+
+    /**
+     * 生产车票
+     *
+     * @return
+     */
+    public static List<String> createTickets() {
+        List<String> list = new ArrayList<>();
+        for (int i = 0; i < 100; i++) {
+            list.add("车票" + i);
+        }
+        return list;
+    }
+
+    public static void sellTicket() {
+        List<String> list = createTickets();//获取车票
+
+        List<ListenableFuture<Integer>> futures = Lists.newArrayList();
+        ExecutorService pool = Executors.newFixedThreadPool(10);//定义线程数
+        ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
+        for (int i = 0; i < list.size(); i++) {
+            futures.add(executorService.submit(new Task(list.get(i))));
+        }
+
+        final ListenableFuture<List<Integer>> resultsFuture = Futures.successfulAsList(futures);
+        try {//所有都执行完毕
+            resultsFuture.get();
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            System.out.println("操作完毕");
+            pool.shutdown();
+        }
+    }
+}
+
+/**
+ * 内部类,用于处理售票
+ */
+class Task implements Callable<Integer> {
+    private String ticket;
+
+    /**
+     * 构造方法,用于参数传递
+     *
+     * @param ticket
+     */
+    public Task(String ticket) {
+        this.ticket = ticket;
+    }
+
+    @Override
+    public Integer call() throws Exception {
+        System.out.println("已卖" + ticket);//执行卖票过程
+        return 1;
+    }
+}
+

+ 41 - 0
alarm/hrwindnew/build.gradle

@@ -0,0 +1,41 @@
+buildscript {
+    repositories {
+        mavenLocal()
+        maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
+        mavenCentral()
+    }
+    dependencies {
+        classpath("$bootGroup:spring-boot-gradle-plugin:$springBootVersion")
+    }
+}
+
+apply plugin: "$bootGroup"
+apply plugin: 'io.spring.dependency-management'
+
+
+dependencies {
+
+    compile project(":common:utils")
+    compile project(":common:data")
+    compile project(":dao:dao-interface")
+    compile project(":dao:dao-sql")
+
+    compile fileTree(dir: 'src/main/lib', include: '*.jar')
+
+    compile("$bootGroup:spring-boot-starter-web")
+    compile("$bootGroup:spring-boot-starter-undertow")
+    compile("$bootGroup:spring-boot-starter-websocket")
+    compile('org.apache.logging.log4j:log4j-core:2.15.0')
+    compile('org.apache.logging.log4j:log4j-jul:2.15.0')
+    compile('org.apache.logging.log4j:log4j-api:2.15.0')
+    compile('org.apache.logging.log4j:log4j-slf4j-impl:2.15.0')
+    //compile 'mysql:mysql-connector-java:5.1.28'
+    compile 'com.alibaba:druid:1.0.25'
+    compile 'com.alibaba:fastjson:1.2.17'
+    compile('org.codehaus.groovy:groovy-all:2.4.15')
+
+    testCompile("$bootGroup:spring-boot-starter-test")
+    compile("com.netflix.feign:feign-core:8.18.0")
+    compile("com.netflix.feign:feign-jackson:8.18.0")
+}
+

+ 15 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/HrwindNewApplication.java

@@ -0,0 +1,15 @@
+package com.gyee.wisdom;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+
+@SpringBootApplication
+@ServletComponentScan
+public class HrwindNewApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(HrwindNewApplication.class, args);
+    }
+
+}

+ 24 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/ApplicationReadyEventListener.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.alarm.hrwind;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class ApplicationReadyEventListener implements ApplicationListener<ApplicationReadyEvent> {
+
+    @Autowired
+    private CalculateServer calculateServer;
+
+    @Override
+    public void onApplicationEvent(ApplicationReadyEvent event) {
+        log.info("ApplicationReadyEvent  rised!");
+        log.info("listener: " + event.toString());
+        calculateServer.start();
+    }
+
+}

+ 90 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/CalculateServer.java

@@ -0,0 +1,90 @@
+package com.gyee.wisdom.alarm.hrwind;
+import com.gyee.wisdom.alarm.hrwind.config.Status8Properties;
+import com.gyee.wisdom.alarm.hrwind.service.CacheService;
+import com.gyee.wisdom.alarm.hrwind.transport.restful.RestfulClient;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+@Slf4j
+@Component
+public class CalculateServer {
+
+    @Autowired
+    private Status8Properties configProperties;
+    @Autowired
+    private CacheService cacheService;
+    @Autowired
+    private RestfulClient restfulClient;
+    private boolean serverStarted = false;
+    private boolean readThreadFlag = false;
+
+    //只有数据加载线程执行成功一次后,才开始执行计算线程
+    public boolean start() {
+        if (serverStarted) {
+            return true;
+        }
+        try {
+            log.info("风机报警监视服务启动.......开始加载配置及测点数据......");
+            cacheService.getTagMap();
+            log.info("测点加载完成,测点数量:" + cacheService.getTagMap().size());
+            readThreadFlag = true;
+            getReadThread().start();
+            serverStarted = true;
+        } catch (Exception ex) {
+            serverStarted = false;
+            stop();
+            log.error(ex.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    Thread getReadThread() {
+        return new Thread(new Runnable() {
+            @Override
+            public void run() {
+                log.info("数据加载线程启动...");
+                while (readThreadFlag) {
+                    try {
+                        //todo: 此处应修改为数据订阅方式
+                        Map<String,ArrayList<String>> keysList = cacheService.getKeysList();
+                        keysList.forEach((k,v)->{
+                            for (String keys : v) {
+                                System.out.print("*");
+                                //log.info("-----windturbine.keys------{},{}", keys.split(",").length, keys);
+                                restfulClient.getLatest(k,keys);
+                            }
+                        });
+                    } catch (Exception ex) {
+                        log.error(ex.getMessage());
+                    }
+                    sleep(configProperties.getReadThreadInterval());
+                }
+            }
+        });
+    }
+
+    public void stop() {
+        readThreadFlag = false;
+        try {
+            Thread.sleep(5000);
+        } catch (Exception ex) {
+            log.info(ex.getMessage());
+        }
+    }
+
+    private void sleep(int milliseconds) {
+        try {
+            TimeUnit.MILLISECONDS.sleep(milliseconds);
+        } catch (Exception ex) {
+            log.info(ex.getMessage());
+        }
+    }
+
+
+}

+ 41 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/SpringPhysicalNamingStrategy.java

@@ -0,0 +1,41 @@
+package com.gyee.wisdom.alarm.hrwind.config;
+
+import org.hibernate.boot.model.naming.Identifier;
+import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
+import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @author xysn
+ */
+@Component
+public class SpringPhysicalNamingStrategy extends PhysicalNamingStrategyStandardImpl {
+
+    @Resource
+    private Environment environment;
+
+    @Override
+    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
+        String nm = name.getText().trim();
+        if (nm.startsWith("${")) {
+            nm = nm.substring(2, nm.length() - 1);
+            String[] nms = nm.split(":");
+            String nam = nms[0].trim();
+            if ("".equals(nam)) {
+                return super.toPhysicalTableName(name, jdbcEnvironment);
+            }
+            String val = environment.getProperty(nam);
+            if (val == null || "".equals(val)) {
+                if (nms.length < 2 || nms[1] == null || "".equals(nms[1].trim())) {
+                    return super.toPhysicalTableName(name, jdbcEnvironment);
+                }
+                return Identifier.toIdentifier(nms[1].trim());
+            }
+            return Identifier.toIdentifier(val);
+        }
+        return super.toPhysicalTableName(name, jdbcEnvironment);
+    }
+}

+ 35 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/Status8Properties.java

@@ -0,0 +1,35 @@
+package com.gyee.wisdom.alarm.hrwind.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties("calculate.status8")
+public class Status8Properties {
+
+    //数据适配器websocket服务地址
+    private String serviceUrl;
+
+    //报警分表数据服务地址
+    private String shardingServiceUrl;
+
+    //离线判定时间间隔,单位毫秒
+    private long offlineInterval = 600000;
+
+    //扫描实时数据线程轮询时间间隔,单位毫秒
+    private int readThreadInterval = 1000;
+
+    //计算状态线程轮询时间间隔,单位毫秒
+    private int calcThreadInterval = 1000;
+
+    public long getOfflineInterval() {
+        return offlineInterval;
+    }
+
+    public void setOfflineInterval(long value) {
+        this.offlineInterval = value * 1000;
+    }
+
+}

+ 25 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/config/WindturbineConfig.java

@@ -0,0 +1,25 @@
+package com.gyee.wisdom.alarm.hrwind.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+@Component
+@ConfigurationProperties("windturbine")
+public class WindturbineConfig {
+    private String station;
+    private List<Map<String, String>> models;
+    private boolean fjgl;
+    private String fjgljx;
+    public String[] getAllModels(){
+        String[] s = new String[models.size()];
+        for (int i = 0; i < models.size(); i++) {
+            s[i] = models.get(i).get("model");
+        }
+        return s;
+    }
+}

+ 25 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/model/TagInfo.java

@@ -0,0 +1,25 @@
+package com.gyee.wisdom.alarm.hrwind.model;
+
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.FaultSnap2;
+import com.gyee.wisdom.common.data.alarm.ScadaFault;
+import com.gyee.wisdom.common.data.alarm.Warning;
+import com.gyee.wisdom.common.data.alarm.WindturbineTestingpointAi;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.IntegerTsData;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import lombok.Data;
+
+@Data
+public class TagInfo {
+    private String id;
+    private String uniformCode;
+    private PowerStation st;
+    private Windturbine wt;
+    private Warning warning;
+    private boolean isTJ;
+    private ScadaFault scadaFault;
+    private FaultSnap2 snap;
+    private IntegerTsData lastTsData;
+    private DoubleTsData lastTsDatad;
+}

+ 6 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/model/ThingType.java

@@ -0,0 +1,6 @@
+package com.gyee.wisdom.alarm.hrwind.model;
+
+public enum ThingType {
+    WINDTURBINE,  //风机
+    STATION, //风场
+}

+ 60 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/AlertSnapFactory.java

@@ -0,0 +1,60 @@
+package com.gyee.wisdom.alarm.hrwind.service;
+
+
+import com.gyee.wisdom.alarm.hrwind.model.TagInfo;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.FaultSnap2;
+import com.gyee.wisdom.common.utils.StringUtil;
+
+import java.util.Date;
+
+public class AlertSnapFactory {
+    public static FaultSnap2 createFaultSnap(TagInfo tagInfo) {
+        FaultSnap2 snap = new FaultSnap2();
+        snap.setAlertText(tagInfo.getScadaFault().getDescription().trim());
+        snap.setCategory1(tagInfo.getScadaFault().getCategory1());
+        snap.setCategory2(tagInfo.getScadaFault().getCategory2());
+        snap.setCategory3(tagInfo.getScadaFault().getCategory3());
+        snap.setRank(tagInfo.getScadaFault().getRank());
+        snap.setLastUpdatePerson("system");
+        snap.setLastUpdateTime(new Date());
+        snap.setStationName(tagInfo.getSt().getStationName());
+        snap.setStationId(tagInfo.getSt().getId());
+        snap.setTestingpointKey(tagInfo.getId());
+        if (tagInfo.getWt() != null) {
+            snap.setWindturbineId(tagInfo.getWt().getId());
+            snap.setWindturbineName(tagInfo.getWt().getCodeToName());
+            snap.setModelId(tagInfo.getWt().getModelId());
+            snap.setProjectId(tagInfo.getWt().getProjectId());
+            snap.setLineId(tagInfo.getWt().getLineId());
+        }
+
+        return snap;
+    }
+
+    public static AlarmSnap createAlertsnapNew(TagInfo tagInfo) {
+        AlarmSnap snap = new AlarmSnap();
+        snap.setAlertText(tagInfo.getWarning().getChineseText());
+        snap.setAlertValue(tagInfo.getWarning().getEdnaValue());
+        snap.setCategory1("windturbine");
+        snap.setCategory2(tagInfo.getWarning().getWarningClassifyId());
+        //如果warning表中关联部件字段不为空,则alarmSnap中category4字段赋值为关联部件
+        if (StringUtil.isNotBlank(tagInfo.getWarning().getRelatedParts())) {
+            snap.setCategory3(tagInfo.getWarning().getRelatedParts());
+        }
+        snap.setRank("3");
+        snap.setLastUpdateTime(new Date());
+        snap.setStationName(tagInfo.getSt().getStationName());
+        snap.setStationId(tagInfo.getSt().getId());
+        snap.setModelId(tagInfo.getWarning().getModelId());
+        snap.setWindturbineName(tagInfo.getWt().getName());
+        snap.setWindturbineId(tagInfo.getWt().getId());
+        snap.setTestingpointKey(tagInfo.getId());
+        snap.setLineId(tagInfo.getWt().getLineId());
+        snap.setProjectId(tagInfo.getWt().getProjectId());
+        return snap;
+    }
+
+
+}
+

+ 235 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/CacheService.java

@@ -0,0 +1,235 @@
+package com.gyee.wisdom.alarm.hrwind.service;
+
+import com.gyee.wisdom.alarm.hrwind.config.WindturbineConfig;
+import com.gyee.wisdom.common.data.alarm.ScadaFault;
+import com.gyee.wisdom.common.data.alarm.Warning;
+import com.gyee.wisdom.common.data.alarm.WindturbineTestingpointAi;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import com.gyee.wisdom.alarm.hrwind.model.TagInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+@Slf4j
+@Service
+public class CacheService {
+    //keyid: stationId
+    private Map<String, PowerStation> stationInfoMap;
+    //keyid: windturibneId
+    private Map<String, Windturbine> windturbineInfoMap;
+    //key1:机型-故障还是告警,key2: pointId
+    private Map<String, Map<String, TagInfo>> tagMap;
+
+    //key1: modelid, key2:uniformcode
+    private Map<String, Map<Integer, Warning>> warningMap;
+
+    //点名串分组,防止串超长
+    private Map<String,ArrayList<String>> keysList;
+
+    @Autowired
+    private SqlService sqlService;
+    @Autowired
+    private WindturbineConfig windturbineConfig;
+
+    public Map<String, PowerStation> getStationInfoMap() {
+        if (stationInfoMap == null) {
+            stationInfoMap = createStationInfoMap();
+        }
+        return stationInfoMap;
+    }
+
+    private Map<String, PowerStation> createStationInfoMap() {
+        Map<String, PowerStation> result = new HashMap<>();
+        log.info("加载场站数据...");
+        List<PowerStation> pwst = sqlService.getStationByIdIn(windturbineConfig.getStation().split(","));
+        for (PowerStation ps : pwst) {
+            if(ps != null){
+                result.put(ps.getId(), ps);
+            }
+        }
+        return result;
+    }
+
+    public Map<String, Windturbine> getWindturbineInfoMap() {
+        if (windturbineInfoMap == null) {
+            windturbineInfoMap = createWindturbineInfoMap();
+        }
+        return windturbineInfoMap;
+    }
+
+    private Map<String, Windturbine> createWindturbineInfoMap() {
+        Map<String, Windturbine> result = new HashMap<>();
+
+        log.info("加载风机数据...");
+        String[] models = windturbineConfig.getFjgljx().split(",");
+        List<Windturbine> lstAr = sqlService.findWindturbineByModelIdIn(models);
+        for (Windturbine wt : lstAr) {
+            result.put(wt.getId(), wt);
+
+        }
+        return result;
+    }
+
+    public Map<String, Map<Integer, Warning>> getWarningMap() {
+        if (warningMap == null) {
+            warningMap = createWarningMap();
+        }
+        return warningMap;
+    }
+
+    private Map<String, Map<Integer, Warning>> createWarningMap() {
+        Map<String, Map<Integer, Warning>> result = new HashMap<>();
+        log.info("加载warning数据...");
+        List<Warning> lstAr = sqlService.findByModelIdIn(windturbineConfig.getAllModels());
+        for (Warning wt : lstAr) {
+            String modelid = wt.getLevelId()+"-"+wt.getModelId();
+            Integer uniformCode =0;
+            if (wt.getEdnaValue() == 0) {
+                continue;
+            }
+            uniformCode = wt.getEdnaValue();
+            if (result.containsKey(modelid) == false) {
+                Map<Integer, Warning> ucMap = new HashMap<>();
+                result.put(modelid, ucMap);
+            }
+            Map<Integer, Warning> uMap = result.get(modelid);
+            if (uMap.containsKey(uniformCode) == false) {
+                uMap.put(uniformCode, wt);
+            }
+        }
+        return result;
+    }
+
+    public Map<String, Map<String, TagInfo>> getTagMap() {
+        if (tagMap == null) {
+            tagMap = createTagMapBJ();
+        }
+        return tagMap;
+    }
+
+    private Map<String, Map<String, TagInfo>> createTagMapBJ() {
+        Map<String, Map<String, TagInfo>> result = new HashMap<>();
+        Map<String, TagInfo> resultAiGZ = new HashMap<>();
+        //场站
+        Map<String, PowerStation> stMap = getStationInfoMap();
+        //场站风机信息
+        Map<String, Windturbine> wtMap = getWindturbineInfoMap();
+        //风机报警点配置
+        Map<String, Map<Integer, Warning>> warnMap = getWarningMap();
+        //风场测点配置故障
+        List<WindturbineTestingpointAi> lstDisGz = new ArrayList<>();
+        //风场测点配置告警
+        List<WindturbineTestingpointAi> lstDisGj = new ArrayList<>();
+        //状态点是AI点-报弹窗-故障停机状态
+        List<ScadaFault> lstAisGz = new ArrayList<>();
+
+        if(windturbineConfig.isFjgl()){
+            lstAisGz = sqlService.getScadaFaultByCategory4Not("TJ");
+            for (ScadaFault ai : lstAisGz) {
+                TagInfo tagInfo = new TagInfo();
+                tagInfo.setId(ai.getPointkey());
+                //UniformCode里填上机型
+                tagInfo.setUniformCode(ai.getCategory4());
+                if (stMap.containsKey(ai.getStationId())) {
+                    tagInfo.setSt(stMap.get(ai.getStationId()));
+                } else {
+                    continue;
+                }
+                if (wtMap.containsKey(ai.getDeviceId())) {
+                    tagInfo.setWt(wtMap.get(ai.getDeviceId()));
+                } else {
+                    continue;
+                }
+                tagInfo.setScadaFault(ai);
+                resultAiGZ.put(tagInfo.getId(), tagInfo);
+            }
+            result.put("ZTAI_BJ", resultAiGZ);
+        }
+        for (Map<String, String> modelMap : windturbineConfig.getModels()) {
+            Map<String, TagInfo> resultGz = new HashMap<>();
+            Map<String, TagInfo> resultGj = new HashMap<>();
+            if(!modelMap.get("uniformcodeGZ").equals("")){
+                lstDisGz = sqlService.getWindturbinetestingpointAiByModelAndUniformcodeIn(modelMap.get("model"),modelMap.get("uniformcodeGZ").split(","));
+            }
+            if(!modelMap.get("uniformcodeGJ").equals("")){
+                lstDisGj = sqlService.getWindturbinetestingpointAiByModelAndUniformcodeIn(modelMap.get("model"),modelMap.get("uniformcodeGJ").split(","));
+            }
+            log.info("----windturbineTestingpointDi----记录:{}", modelMap.get("model")+","+lstDisGz.size()+","+lstDisGj.size());
+            for (WindturbineTestingpointAi ai : lstDisGz) {
+                TagInfo tagInfo = new TagInfo();
+                tagInfo.setId(ai.getId());
+                tagInfo.setUniformCode(ai.getUniformcode());
+                if (stMap.containsKey(ai.getWindpowerstationid())) {
+                    tagInfo.setSt(stMap.get(ai.getWindpowerstationid()));
+                } else {
+                    continue;
+                }
+                if (wtMap.containsKey(ai.getWindturbineid())) {
+                    tagInfo.setWt(wtMap.get(ai.getWindturbineid()));
+                } else {
+                    continue;
+                }
+                resultGz.put(tagInfo.getId(), tagInfo);
+            }
+            for (WindturbineTestingpointAi ai : lstDisGj) {
+                TagInfo tagInfo = new TagInfo();
+                tagInfo.setId(ai.getId());
+                tagInfo.setUniformCode(ai.getUniformcode());
+                if (stMap.containsKey(ai.getWindpowerstationid())) {
+                    tagInfo.setSt(stMap.get(ai.getWindpowerstationid()));
+                } else {
+                    continue;
+                }
+                if (wtMap.containsKey(ai.getWindturbineid())) {
+                    tagInfo.setWt(wtMap.get(ai.getWindturbineid()));
+                } else {
+                    continue;
+                }
+                resultGj.put(tagInfo.getId(), tagInfo);
+            }
+
+            result.put("GZ_BJ-"+modelMap.get("model"), resultGz);
+            result.put("YJ_BJ-"+modelMap.get("model"), resultGj);
+            log.info("----createTagMapBJ------{}", modelMap.get("model")+","+resultGz.size()+","+resultGj.size());
+        }
+        return result;
+    }
+
+    public Map<String,ArrayList<String>> getKeysList() {
+        if (keysList == null) {
+            keysList = createKeysList();
+        }
+        return keysList;
+    }
+
+    private Map<String,ArrayList<String>> createKeysList() {
+        Map<String, ArrayList<String>> mapkl = new HashMap<>();
+        ArrayList<String> result = new ArrayList<>();
+        Map<String, Map<String, TagInfo>> tm = getTagMap();
+        StringBuilder sbBoolean = new StringBuilder();
+        AtomicInteger cntBoolean = new AtomicInteger();
+        tm.forEach((tmkey,tmvalues)->{
+            tmvalues.forEach((tmvk,tmvv)->{
+                String tagId =tmvk;
+                sbBoolean.append(tagId);
+                sbBoolean.append(",");
+                cntBoolean.getAndIncrement();
+                if (cntBoolean.get() % 1000 == 0) {
+                    result.add(sbBoolean.toString());
+                    sbBoolean.delete(0, sbBoolean.length());
+                }
+            });
+            if (sbBoolean.length() > 0) {
+                result.add(sbBoolean.toString());
+                sbBoolean.delete(0, sbBoolean.length());
+            }
+            mapkl.put(tmkey, (ArrayList<String>)result.clone());
+            result.clear();
+        });
+        return mapkl;
+    }
+}

+ 124 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/SqlService.java

@@ -0,0 +1,124 @@
+package com.gyee.wisdom.alarm.hrwind.service;
+
+import com.gyee.wisdom.alarm.hrwind.model.ThingType;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.RemoteServiceBuilder;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.FaultSnap2;
+import com.gyee.wisdom.common.data.alarm.*;
+import com.gyee.wisdom.common.data.windturbine.PowerStation;
+import com.gyee.wisdom.common.data.windturbine.Windturbine;
+import com.gyee.wisdom.dao.alarm.*;
+import com.gyee.wisdom.dao.windturbine.IPowerStationDao;
+import com.gyee.wisdom.dao.windturbine.IWindturbineDao;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+@Service
+public class SqlService {
+
+    @Autowired
+    private IPowerStationDao powerstationDao;
+
+    @Autowired
+    private IWindturbineDao windturbineDao;
+    @Autowired
+    private ScadaFaultDao scadaFaultDao;
+
+    @Autowired
+    private AlarmhistoryNewDao alarmhistoryNewDao;
+
+    @Autowired
+    private WarningDao warningDao;
+
+    @Autowired
+    private WarningrecordsDao warningrecordsDao;
+
+    @Autowired
+    private WindturbinetestingpointAiDao windturbinetestingpointAiDao;
+
+    @Autowired
+    private RemoteServiceBuilder remoteServiceBuilder;
+
+
+    public PowerStation getStationById(String id){
+        return powerstationDao.getStationById(id);
+    }
+    public List<PowerStation> getStationByIdIn(String[] ids){
+        return powerstationDao.getStationByIdIn(ids);
+    }
+
+
+    public List<Windturbine> findByStationId(String stationId) {
+        return windturbineDao.findByStationId(stationId);
+    }
+
+    public List<Windturbine> findWindturbineByModelId(String modelId) {
+        return windturbineDao.findByModelId(modelId);
+    }
+    public List<Windturbine> findWindturbineByModelIdIn(String[] modelId) {
+        return windturbineDao.findByModelIdIn(modelId);
+    }
+
+
+    public List<WindturbineTestingpointAi> getWindturbinetestingpointAiByModelAndUniformcode(String  model, String  uniformcode){
+        return windturbinetestingpointAiDao.getWindturbinetestingpointAiByModelAndUniformcode(model,uniformcode);
+    }
+    public List<WindturbineTestingpointAi> getWindturbinetestingpointAiByModelAndUniformcodeIn(String model, String[] uniformcodes) {
+        return windturbinetestingpointAiDao.getWindturbinetestingpointAiByModelAndUniformcodeIn(model,uniformcodes);
+    }
+    public List<ScadaFault> getScadaFaultByCategory4Not(String c4) {
+        return scadaFaultDao.getScadaFaultByCategory4Not(c4);
+    }
+
+    public  List<Warning> findByModelId(String modelid){
+        return warningDao.findByModelId(modelid);
+    }
+    public  List<Warning> findByModelIdIn(String[] modelids){
+        return warningDao.findByModelIdIn(modelids);
+    }
+
+    public AlarmSnap getAlertSnap(ThingType thingType, String thingId, int alertvalue) {
+        if(alertvalue==-1){
+            return remoteServiceBuilder.alarmSnapService().queryOneByTagId(thingId);
+        }
+        if (thingType == ThingType.WINDTURBINE) {
+            return remoteServiceBuilder.alarmSnapService().queryOneByWtId(thingId, alertvalue);
+        } else if (thingType == ThingType.STATION) {
+            return remoteServiceBuilder.alarmSnapService().queryOneByStId(thingId, alertvalue);
+        }
+        return null;
+    }
+
+    @Transactional(rollbackFor = RuntimeException.class)
+    public void saveAlertSnapNew(AlarmSnap snaps) {
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnap(snaps);
+
+    }
+
+    @Transactional(rollbackFor = RuntimeException.class)
+    public void saveAlarmSnaps(List<AlarmSnap> snaps) {
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnaps(snaps);
+
+    }
+
+    @Transactional(rollbackFor = RuntimeException.class)
+    public void saveWarningrecordsList(List<Warningrecords> snaps) {
+        warningrecordsDao.batchSave(snaps);
+    }
+
+    public void saveWarningrecords(Warningrecords warningrecords) {
+        warningrecordsDao.saveList(warningrecords);
+    }
+
+
+    public FaultSnap2 findByTestingpointkey(String testingpointkey) {
+        return remoteServiceBuilder.alarmSnapService().queryOneByTagId2(testingpointkey);
+    }
+
+    public void saveFaultSnap(List<FaultSnap2> snaps) {
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnaps2(snaps);
+    }
+}

+ 31 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/service/WarningrecordsFactory.java

@@ -0,0 +1,31 @@
+package com.gyee.wisdom.alarm.hrwind.service;
+
+import com.gyee.wisdom.alarm.hrwind.model.TagInfo;
+import com.gyee.wisdom.common.data.alarm.Warningrecords;
+import java.util.Date;
+
+/**
+ * @Auther: ruyuan
+ * @Date: 2019-05-06 14:29
+ * @Description:
+ */
+public class WarningrecordsFactory {
+
+    public static Warningrecords createWarningrecords(TagInfo tagInfo) {
+        Warningrecords warningrecords = new Warningrecords();
+        warningrecords.setWindpowerstationid(tagInfo.getSt().getId());
+        warningrecords.setWindturbineid(tagInfo.getWt().getId());
+        warningrecords.setWarningid(tagInfo.getWarning().getId());
+        warningrecords.setWarningtime(new Date(tagInfo.getLastTsData().getTs()));
+        warningrecords.setIsconfirm("0");
+        warningrecords.setIshandle("");
+        warningrecords.setHandle("");
+        warningrecords.setShutdowneventid("");
+        warningrecords.setLevelid(tagInfo.getWarning().getLevelId());
+        warningrecords.setWtaiid(tagInfo.getId());
+        warningrecords.setDurationhour("");
+        warningrecords.setIsfilter("0");
+        return warningrecords;
+    }
+
+}

+ 338 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/restful/RestfulClient.java

@@ -0,0 +1,338 @@
+package com.gyee.wisdom.alarm.hrwind.transport.restful;
+
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.hrwind.config.WindturbineConfig;
+import com.gyee.wisdom.alarm.hrwind.service.CacheService;
+import com.gyee.wisdom.alarm.hrwind.service.SqlService;
+import com.gyee.wisdom.alarm.hrwind.model.ThingType;
+import com.gyee.wisdom.alarm.hrwind.service.AlertSnapFactory;
+
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.FaultSnap2;
+import com.gyee.wisdom.common.data.alarm.Warning;
+import com.gyee.wisdom.common.data.timeseries.BooleanTsData;
+import com.gyee.wisdom.common.data.timeseries.DoubleTsData;
+import com.gyee.wisdom.common.data.timeseries.IntegerTsData;
+import com.gyee.wisdom.alarm.hrwind.config.Status8Properties;
+import com.gyee.wisdom.alarm.hrwind.model.TagInfo;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Slf4j
+public class RestfulClient {
+
+    @Autowired
+    private Status8Properties configProperties;
+
+    @Autowired
+    private CacheService cacheService;
+
+    private Map<String, Map<String, TagInfo>> tagInfoMap;
+
+    private RestTemplate restTemplate;
+
+    private String adpUrl;
+    @Autowired
+    private SqlService sqlService;
+    @Autowired
+    private WindturbineConfig windturbineConfig;
+
+    private String adpLatestUrl;
+
+    private String getAdpUrl() {
+        if (adpUrl == null) {
+            adpUrl = configProperties.getServiceUrl();
+        }
+        return adpUrl;
+    }
+
+    private String getAdpLatestUrl() {
+        if (adpLatestUrl == null) {
+            adpLatestUrl = getAdpUrl() + "/latest?keys=";
+        }
+        return adpLatestUrl;
+    }
+
+    private RestTemplate getRestTemplate() {
+        if (restTemplate == null) {
+            //复杂构造函数的使用
+            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
+            requestFactory.setConnectTimeout(10000);// 设置超时
+            requestFactory.setReadTimeout(10000);
+            restTemplate = new RestTemplate(requestFactory);
+        }
+        return restTemplate;
+    }
+
+    private Map<String, Map<String, TagInfo>> getTagInfoMap() {
+        if (tagInfoMap == null) {
+            tagInfoMap = cacheService.getTagMap();
+        }
+        return tagInfoMap;
+    }
+
+    private HashMap<String, Integer> codeMap = new HashMap<>();
+
+
+    public void getLatest(String gzorgj, String keys) {
+        String url = getAdpLatestUrl() + keys;
+        if (gzorgj.equals("ZTAI_BJ")) {
+            ResponseEntity<JSONObject> resp = getRestTemplate().getForEntity(url, JSONObject.class);
+            if (resp.getStatusCode() == HttpStatus.OK) {
+                JSONObject jsonObject = resp.getBody();
+                Map<String, DoubleTsData> result = new HashMap<>();
+
+                Iterator<String> sIterator = jsonObject.keySet().iterator();
+                while (sIterator.hasNext()) {
+                    // 获得key
+                    String key = sIterator.next();
+                    // 根据key获得value, value也可以是JSONObject,JSONArray,使用对应的参数接收即可
+                    JSONObject jsonData = jsonObject.getJSONObject(key);
+                    Long ts = jsonData.getLong("ts");
+                    double dValue = 0;
+                    if (jsonData.containsKey("doubleValue")) {
+                        dValue = jsonData.getDoubleValue("doubleValue");
+                    } else if (jsonData.containsKey("booleanValue")) {
+                        dValue = jsonData.getBooleanValue("booleanValue") ? 1 : 0;
+                    } else if (jsonData.containsKey("longValue")) {
+                        dValue = jsonData.getDoubleValue("longValue");
+                    } else if (jsonData.containsKey("stringValue")) {
+                        dValue = jsonData.getDoubleValue("stringValue");
+                    }
+                    DoubleTsData tsData = new DoubleTsData(ts, (short) 0, dValue);
+                    result.put(key, tsData);
+                }
+                List<FaultSnap2> snapList = new ArrayList<>();
+                try {
+                    for (Map.Entry<String, DoubleTsData> entry : result.entrySet()) {
+                        String tagId = entry.getKey();
+                        TagInfo tagInfo = getTagInfoMap().get("ZTAI_BJ").get(tagId);
+                        DoubleTsData tsData = entry.getValue();
+                        if (tsData == null || tsData.getTs() == 0) {
+                            continue;
+                        }
+                        tagInfo.setLastTsDatad(tsData);
+                        FaultSnap2 snap = tagInfo.getSnap();
+                        String modelId = tagInfo.getUniformCode();
+                        int value = (int) tsData.getDoubleValue();
+                        //风机的8种原始状态:0-停机、 1-上电、2-待机、3-启动、4-并网、5-故障、6-维护、7-离线
+                        if ("GW77-1500".equals(modelId) || "GW82-1500".equals(modelId) || "GW109-2500".equals(modelId)) {
+                            //0	初始化 1停机过程 2停机状态 3待机状态 4启机状态 6维护状态 5发电状态 8自检状态 9维护状态
+                            if (value == 5) {
+                                if (snap == null) {
+                                    snap = sqlService.findByTestingpointkey(tagInfo.getId());
+                                    if (snap != null)
+                                        tagInfo.setSnap(snap);
+                                    else
+                                        snap = AlertSnapFactory.createFaultSnap(tagInfo);
+                                }
+
+                                if (snap.getIsOpened() == 0) {
+                                    snap.setIsOpened(1);
+                                    snap.setLastUpdateTime(new Date());
+                                    snapList.add(snap);
+                                }
+                            } else {
+                                if (snap != null && snap.getIsOpened() == 1) {
+                                    snap.setIsOpened(0);
+                                    snap.setLastUpdateTime(new Date(tsData.getTs()));
+                                    snapList.add(snap);
+                                }
+                            }
+
+                        } else if ("UP2000-105s".equals(modelId) || "UP2000-96".equals(modelId) || "UP2000-121S".equals(modelId) || "UP2000-130S".equals(modelId)
+                                || "UP3000-146S".equals(modelId) || "UP2000-115s".equals(modelId) || "UP3000-120".equals(modelId)) {
+                            //0是通讯中断,1是故障,2是维护,3是待机,4是启动,5是并网,6是正常停机
+                            if (value == 1) {
+                                if (snap == null) {
+                                    snap = sqlService.findByTestingpointkey(tagInfo.getId());
+                                    if (snap != null)
+                                        tagInfo.setSnap(snap);
+                                    else
+                                        snap = AlertSnapFactory.createFaultSnap(tagInfo);
+                                }
+
+                                if (snap.getIsOpened() == 0) {
+                                    snap.setIsOpened(1);
+                                    snap.setLastUpdateTime(new Date());
+                                    snapList.add(snap);
+                                }
+                            } else {
+                                if (snap != null && snap.getIsOpened() == 1) {
+                                    snap.setIsOpened(0);
+                                    snap.setLastUpdateTime(new Date(tsData.getTs()));
+                                    snapList.add(snap);
+                                }
+                            }
+
+                        } else if ("MY-1.5se".equals(modelId)) {
+                            //2、200 启动 也算待机  4 、5是故障,7、8是停机,9、10是待机,11故障,12、13 停机   3 并网。
+                            if (value == 11 || value == 4 || value == 5) {
+                                if (snap == null) {
+                                    snap = sqlService.findByTestingpointkey(tagInfo.getId());
+                                    if (snap != null)
+                                        tagInfo.setSnap(snap);
+                                    else
+                                        snap = AlertSnapFactory.createFaultSnap(tagInfo);
+                                }
+
+                                if (snap.getIsOpened() == 0) {
+                                    snap.setIsOpened(1);
+                                    snap.setLastUpdateTime(new Date());
+                                    snapList.add(snap);
+                                }
+                            } else {
+                                if (snap != null && snap.getIsOpened() == 1) {
+                                    snap.setIsOpened(0);
+                                    snap.setLastUpdateTime(new Date(tsData.getTs()));
+                                    snapList.add(snap);
+                                }
+                            }
+
+                        }
+                    }
+                } catch (Exception ex) {
+                    log.error("--------创建报警信息报错--------{}", ex.getMessage());
+                }
+
+                if (snapList.size() > 0) {
+                    sqlService.saveFaultSnap(snapList);
+                }
+            } else {
+                log.error(resp.getStatusCodeValue() + "");
+            }
+
+        } else {
+            ResponseEntity<Object> resp = getRestTemplate().getForEntity(url, Object.class);
+            if (resp.getStatusCode() == HttpStatus.OK) {
+                Map<String, HashMap<String, Object>> map = (HashMap<String, HashMap<String, Object>>) resp.getBody();
+
+                Map<String, Map<Integer, Warning>> warnMap = cacheService.getWarningMap();
+                Map<Integer, Warning> ucMap = new HashMap<>();
+                ucMap = warnMap.entrySet().stream().filter(um -> um.getKey().equals(gzorgj)).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)).get(gzorgj);
+            /*Optional<Map.Entry<String, Map<Integer, Warning>>> first = warnMap.entrySet().stream().filter(m -> m.getKey().equals(gzorgj)).findFirst();
+            if(first.isPresent()){
+                ucMap=first.get().getValue();
+            }*/
+                if (map != null && map.size() > 0 && ucMap.size() > 0) {
+                    try {
+                        List<AlarmSnap> alarmSnapList = new ArrayList<>();
+
+                        for (Map.Entry<String, HashMap<String, Object>> entry : map.entrySet()) {
+                            String tagId = entry.getKey();
+                            TagInfo tagInfo = getTagInfoMap().get(gzorgj).get(tagId);
+                            IntegerTsData tsData = getTsData(entry.getValue());
+                            if (tsData == null || tsData.getTs() == 0) {
+                                continue;
+                            }
+                            tagInfo.setLastTsData(tsData);
+                            // 变化存
+                            String wtId = tagInfo.getId();
+                            Integer value = tagInfo.getLastTsData().getIntegerValue();
+
+                            if (value == null || !codeMap.containsKey(wtId)) {
+                                codeMap.put(wtId, value);
+                                continue;
+                            } else if (value.equals(codeMap.get(wtId))) {
+                                continue;
+                            } else {
+                                codeMap.put(wtId, value);
+                                log.info(tagInfo.getWt().getId() + " , " + value);
+                            }
+
+                        /*if (value != null && codeMap.containsKey(wtId) && value.equals(codeMap.get(wtId)) ) {
+                            continue;
+                        } else {
+                            codeMap.put(wtId, value);
+                            log.info(tagInfo.getWt().getId() + " , " + value);
+                        }*/
+
+                            if (ucMap.containsKey(value)) {
+                                tagInfo.setWarning(ucMap.get(tagInfo.getLastTsData().getIntegerValue()));
+                                AlarmSnap snap = findAlertSnap(tagInfo.getWt().getId(), tagInfo.getWarning().getEdnaValue());
+                                if (snap == null) {
+                                    snap = AlertSnapFactory.createAlertsnapNew(tagInfo);
+                                } else if (snap.getLastUpdateTime().getTime() >= tsData.getTs()) {
+                                    log.info("time error");
+                                    continue;
+                                }
+
+                                snap.setIsOpened(1);
+                                snap.setDataInfo("" + value);
+                                //snap.setIsConfirmed(0);
+                                snap.setLastUpdateTime(new Date(tsData.getTs()));
+                                alarmSnapList.add(snap);
+                                log.info(tagInfo.getWt().getId() + " , " + value + ",,,add");
+                                //sqlService.saveAlertSnapNew(snap);
+                                //Warningrecords warningrecords= WarningrecordsFactory.createWarningrecords(tagInfo);
+                                // warningrecordsList.add(warningrecords);
+
+                            } else if (value == 0) {
+                                AlarmSnap snap = findAlertSnap(tagInfo.getId(), -1);
+                                if (snap == null) {
+                                    continue;
+                                } else if (snap.getLastUpdateTime().getTime() >= tsData.getTs()) {
+                                    log.info("time error");
+                                    continue;
+                                }
+                                snap.setIsOpened(0);
+                                snap.setDataInfo("0");
+                                snap.setLastUpdateTime(new Date(tsData.getTs()));
+                                alarmSnapList.add(snap);
+                                log.info(tagInfo.getWt().getId() + " , " + value + ",,,add");
+                            }else {
+                                log.info(gzorgj + "未能识别的错误码:" + value + ", 风机号:" + tagInfo.getWt().getId());
+                            }
+                        }
+                        if (alarmSnapList.size() > 0) {
+                            System.out.println("保存报警记录" + alarmSnapList.size() + "条!");
+                            sqlService.saveAlarmSnaps(alarmSnapList);
+                            //log.info("save return!");
+                            alarmSnapList.clear();
+                        }
+
+                        //if (warningrecordsList.size() > 1) {
+                        // sqlService.saveWarningrecordsList(warningrecordsList);
+                        // warningrecordsList.clear();
+                        // }
+
+                    } catch (Exception ex) {
+                        log.error("\n创建报警失败----------------{}", ex.getMessage());
+                    }
+
+
+                }
+
+            } else {
+                log.error(resp.getStatusCodeValue() + "");
+            }
+        }
+
+    }
+
+    public IntegerTsData getTsData(HashMap<String, Object> hmp) {
+        try {
+            long ts = Long.parseLong(hmp.get("ts").toString());
+            short status = ((Integer) hmp.get("status")).shortValue();
+            return new IntegerTsData(ts, status, ((Double) hmp.get("doubleValue")).intValue());
+        } catch (Exception ex) {
+            log.info("------------{}", ex.getMessage());
+        }
+        return null;
+    }
+
+    private AlarmSnap findAlertSnap(String thingId, int alertValue) {
+
+        return sqlService.getAlertSnap(ThingType.WINDTURBINE, thingId, alertValue);
+    }
+
+}

+ 63 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/AlarmSnapService.java

@@ -0,0 +1,63 @@
+package com.gyee.wisdom.alarm.hrwind.transport.shardingclient;
+
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.AlarmSnap;
+import com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto.FaultSnap2;
+import com.gyee.wisdom.common.data.alarm.FaultSnap;
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.List;
+
+public interface AlarmSnapService {
+
+	@RequestLine("GET /alarm/snap/{snapId}")
+    AlarmSnap queryById(@Param(value = "snapId") long snapId);
+
+	@RequestLine("GET /alarm/snap/single?windturbineid={wtId}&alertvalue={alertValue}")
+	AlarmSnap queryOneByWtId(
+            @Param(value = "wtId") String wtId,
+            @Param(value = "alertValue") Integer alertValue
+    );
+
+	@RequestLine("GET /alarm/snap/single?alertvalue={alertValue}&stationid={stId}")
+	AlarmSnap queryOneByStId(
+            @Param(value = "stId") String stId,
+            @Param(value = "alertValue") Integer alertValue
+    );
+
+	@RequestLine("GET /alarm/snap/single?testingpointkey={tagId}")
+	AlarmSnap queryOneByTagId(@Param(value = "tagId") String tagId);
+
+	@RequestLine("GET /alarm/snap?stationid={stationid}&windturbineid={windturbineid}&category1={category1}&" +
+			"category2={category2}&rank={rank}&modelid={modelid}&isopened={isopened}&" +
+			"keyword={keyword}&starttime={starttime}&endtime={endtime}")
+	List<AlarmSnap> queryAll(
+            @Param(value = "stationid") String stId,
+            @Param(value = "windturbineid") String wtId,
+            @Param(value = "category1") String category1,
+            @Param(value = "category2") String category2,
+            @Param(value = "rank") String rank,
+            @Param(value = "modelid") String modelId,
+            @Param(value = "isopened") Integer isOpened,
+            @Param(value = "keyword") String keyWord,
+            @Param(value = "starttime") String startTime,
+            @Param(value = "endtime") String endTime
+    );
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap")
+	void saveAlarmSnap(AlarmSnap alarmSnap);
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap/batch")
+	void saveAlarmSnaps(List<AlarmSnap> alarmSnaps);
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /fault/snap/batch")
+	void saveAlarmSnaps2(List<FaultSnap2> faultSnap2s);
+
+
+	@RequestLine("GET /fault/snap/single?tagId={tagId}")
+	FaultSnap2 queryOneByTagId2(@Param(value = "tagId") String tagId);
+}

+ 33 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/RemoteServiceBuilder.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.alarm.hrwind.transport.shardingclient;
+
+import com.gyee.wisdom.alarm.hrwind.config.Status8Properties;
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class RemoteServiceBuilder {
+
+    @Autowired
+    private Status8Properties configProperties;
+//    public String shardingSevice = "http://localhost:8075";
+
+    @Bean
+    public AlarmSnapService alarmSnapService() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 3500))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(AlarmSnapService.class, configProperties.getShardingServiceUrl());
+    }
+
+
+
+}

+ 19 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmHistory.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmHistory implements Serializable{
+
+    private Long id;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date alertTime;
+    private int messageType;
+    private Long snapId;
+    private String dataInfo;
+}

+ 41 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmHistoryInfo.java

@@ -0,0 +1,41 @@
+package com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto;
+
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+@Data
+public class AlarmHistoryInfo implements Serializable {
+
+    private static final long serialVersionUID = 0L;
+
+    private Long id;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date alertTime;
+    private int messageType;
+    private Long snapId;
+    private String dataInfo;
+
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+
+}

+ 33 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/AlarmSnap.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.alarm.hrwind.transport.shardingclient.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmSnap implements Serializable{
+
+    private Long id;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    private int isOpened;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+    private String testingpointKey;
+    private String dataInfo;
+}

+ 0 - 0
alarm/hrwindnew/src/main/java/com/gyee/wisdom/alarm/hrwind/transport/shardingclient/dto/FaultSnap2.java


Some files were not shown because too many files changed in this diff