zy 2 mesi fa
commit
24769621bc
100 ha cambiato i file con 8292 aggiunte e 0 eliminazioni
  1. 223 0
      ipfcst/D5000-web/pom.xml
  2. 34 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000DelimiterHandler.java
  3. 20 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Exception.java
  4. 28 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Iec104SlaverBuilder.java
  5. 121 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Operation.java
  6. 169 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Utils.java
  7. 168 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Apdu.java
  8. 93 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Asdu.java
  9. 54 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Vsq.java
  10. 29 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000information/D5000DataInfo.java
  11. 294 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000information/D5000FixedValue.java
  12. 201 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/MasterRequestSocket.java
  13. 59 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/receive/InfoAnswerType.java
  14. 171 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/sandandrevice/RequestDataType.java
  15. 105 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/sandandrevice/ReturnDataType.java
  16. 56 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/BinaryInformationType.java
  17. 56 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/ChangePasswordType.java
  18. 109 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/UploadDataType.java
  19. 17 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/D5000WebApplication.java
  20. 25 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/JarPathUtil.java
  21. 20 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/CollectedDailyPower.java
  22. 426 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/DailyPower.java
  23. 26 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/FailedDualRequest.java
  24. 59 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/Gather104TCPChannel.java
  25. 119 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/OperatingCapacity.java
  26. 64 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/OperationStatus.java
  27. 27 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/SampleDailyPower.java
  28. 24 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/SampleInfo.java
  29. 18 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedDailyPower.java
  30. 16 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedOperatingCapacity.java
  31. 15 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedOperationStatus.java
  32. 19 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UsernameAndPassword.java
  33. 65 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/D5000CommConfigBean.java
  34. 50 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/GatherConfigBean.java
  35. 60 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/SpringContextUtil.java
  36. 134 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/DownloadAndUploadExcelController.java
  37. 37 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/FailedDualRequestController.java
  38. 58 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/Gather104TcpChannelController.java
  39. 168 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/JumpPageController.java
  40. 61 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/OperationStatusController.java
  41. 279 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/QueryDataController.java
  42. 61 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/SampleInfoController.java
  43. 49 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/SamplePowerController.java
  44. 47 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/ShortForecastPowerController.java
  45. 48 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UploadDataController.java
  46. 83 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UploadStatusController.java
  47. 51 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UsernamePasswordController.java
  48. 103 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controllerutil/ControllerAOP.java
  49. 58 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controllerutil/ResultBean.java
  50. 163 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/GetSampleFileDataJob.java
  51. 143 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/GetShortForecastDataJob.java
  52. 149 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/ReportFileReceiveAndUploadStatusJob.java
  53. 91 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/SynchronizeDataTasks.java
  54. 55 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/TaskSchedulingCenter.java
  55. 66 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadOperatingCapacityJob.java
  56. 69 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadOperationStatusJob.java
  57. 99 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadSampleDataJob.java
  58. 118 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadShortForecastDataJob.java
  59. 39 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/CollectedDailyPowerMapper.java
  60. 21 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/FailedDualRequestMapper.java
  61. 26 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/Gather104TcpChannelMapper.java
  62. 14 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/OperatingCapacityMapper.java
  63. 21 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/OperationStatusMapper.java
  64. 36 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/SampleDailyPowerMapper.java
  65. 23 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/SampleInfoMapper.java
  66. 27 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedDailyPowerMapper.java
  67. 23 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedOperatingCapacityMapper.java
  68. 17 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedOperationStatusMapper.java
  69. 18 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UsernameAndPasswordMapper.java
  70. 105 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/CollectedDailyPowerService.java
  71. 48 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/CollectedStatusService.java
  72. 34 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/FailedDualRequestService.java
  73. 67 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/Gather104TcpChannelService.java
  74. 73 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/GzipUtil.java
  75. 24 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/OperatingCapacityService.java
  76. 37 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/OperationStatusService.java
  77. 201 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/QueryDataService.java
  78. 130 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RequestOtherService.java
  79. 36 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RunAfterStart.java
  80. 60 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RunAfterStarted.java
  81. 157 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/SampleDailyPowerService.java
  82. 45 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/SampleInfoService.java
  83. 129 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/TimeUtils.java
  84. 109 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/Upload2D5000Service.java
  85. 57 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadStatusService.java
  86. 67 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedDailyPowerService.java
  87. 40 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedOperatingCapacityService.java
  88. 57 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedOperationStatusService.java
  89. 76 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UsernamePasswordService.java
  90. 8 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/BaseProtocolTunnel.java
  91. 124 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/Gather104tcpClient.java
  92. 80 0
      ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/HandleShortFloat.java
  93. 2 0
      ipfcst/D5000-web/src/main/resources/IEC104.properties
  94. 26 0
      ipfcst/D5000-web/src/main/resources/config/dev/application-D5000.yml
  95. 17 0
      ipfcst/D5000-web/src/main/resources/config/dev/application.properties
  96. 637 0
      ipfcst/D5000-web/src/main/resources/create.sql
  97. BIN
      ipfcst/D5000-web/src/main/resources/ipfcst.keystore
  98. 86 0
      ipfcst/D5000-web/src/main/resources/logback.xml
  99. 246 0
      ipfcst/D5000-web/src/main/resources/mapper/CollectedDailyPowerMapper.xml
  100. 19 0
      ipfcst/D5000-web/src/main/resources/mapper/FailedDualRequestMapper.xml

+ 223 - 0
ipfcst/D5000-web/pom.xml

@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>2.2.1.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+    <groupId>com.jiayue.ipfcst.d5000</groupId>
+    <artifactId>ipfcst-d5000-web</artifactId>
+    <version>1.16.0</version>
+    <name>d5000-web</name>
+    <description>D5000全(页面,逻辑,通讯)</description>
+    <repositories>
+        <repository>
+            <id>jiayue-releases</id>
+            <name>嘉越云仓库</name>
+            <url>http://49.4.68.219:8888/repository/jiayue-releases/</url>
+        </repository>
+    </repositories>
+    <properties>
+        <java.version>1.8</java.version>
+        <skipTests>true</skipTests>
+    </properties>
+    <profiles>
+        <profile>
+            <id>dev</id>
+            <properties>
+                <profiles.active>dev</profiles.active>
+            </properties>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+        </profile>
+        <profile>
+            <id>pro</id>
+            <properties>
+                <profiles.active>pro</profiles.active>
+            </properties>
+        </profile>
+    </profiles>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-quartz</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-thymeleaf</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.16</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.ftpserver</groupId>
+            <artifactId>ftpserver-core</artifactId>
+            <version>1.1.1</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.jdom/jdom -->
+        <dependency>
+            <groupId>org.jdom</groupId>
+            <artifactId>jdom</artifactId>
+            <version>2.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <scope>runtime</scope>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.16</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.14</version>
+        </dependency>
+        <!-- 处理excel和上面功能是一样的-->
+        <dependency>
+            <groupId>net.sourceforge.jexcelapi</groupId>
+            <artifactId>jxl</artifactId>
+            <version>2.6.10</version>
+        </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-http</artifactId>
+            <version>5.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>com.h2database</groupId>
+            <artifactId>h2</artifactId>
+            <version>1.4.199</version>
+        </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+            <version>1.3.1</version>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.1.6.Final</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/org.reflections/reflections -->
+        <dependency>
+            <groupId>org.reflections</groupId>
+            <artifactId>reflections</artifactId>
+            <version>0.9.10</version>
+        </dependency>
+
+
+        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>1.7.25</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+        <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core -->
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+            <version>1.2.47</version>
+        </dependency>
+
+        <dependency>
+            <groupId>wei.yigulu</groupId>
+            <artifactId>protocol-iec104</artifactId>
+            <version>2.4.23</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.junit.vintage</groupId>
+                    <artifactId>junit-vintage-engine</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+
+        </plugins>
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <filtering>false</filtering>
+                <excludes>
+                    <exclude>config/**</exclude>
+                </excludes>
+            </resource>
+            <resource>
+                <directory>src/main/resources/config/${profiles.active}</directory>
+            </resource>
+        </resources>
+    </build>
+
+</project>

+ 34 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000DelimiterHandler.java

@@ -0,0 +1,34 @@
+package com.jiayue.ipfcst.d5000;
+
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+/**
+ * 自定义拆包处理器
+ *
+ * @author 修唯xiuwei
+ * @create 2019-01-31 13:10
+ * @Email 524710549@qq.com
+ **/
+@Slf4j
+public class D5000DelimiterHandler extends ByteToMessageDecoder {
+
+    @Override
+    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
+        int s=in.readableBytes();
+        int n=0;
+        int l = in.indexOf(1, s, (byte) 0x68);
+        for (; l != -1; ) {
+            out.add(in.readBytes(l-n));
+            n=l;
+            l = in.indexOf(l+1, s, (byte) 0x68);
+        }
+        out.add(in.readBytes(in.readableBytes()));
+    }
+}
+

+ 20 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Exception.java

@@ -0,0 +1,20 @@
+package com.jiayue.ipfcst.d5000;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * D5000异常
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-13 上午1:00
+ * @Email 524710549@qq.com
+ **/
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class D5000Exception extends Exception {
+    private int code;
+    private String message;
+}

+ 28 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Iec104SlaverBuilder.java

@@ -0,0 +1,28 @@
+package com.jiayue.ipfcst.d5000;
+
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Apdu;
+import io.netty.channel.socket.SocketChannel;
+import wei.yigulu.iec104.nettyconfig.AllCustomDelimiterHandler;
+import wei.yigulu.iec104.nettyconfig.Iec104SlaverBuilder;
+import wei.yigulu.iec104.nettyconfig.Slave104Handle;
+import wei.yigulu.netty.ProtocolChannelInitializer;
+
+public class D5000Iec104SlaverBuilder extends  Iec104SlaverBuilder   {
+
+
+    public D5000Iec104SlaverBuilder(int port) {
+        super(port);
+    }
+
+    @Override
+    protected ProtocolChannelInitializer getOrCreateChannelInitializer() {
+        return new ProtocolChannelInitializer<SocketChannel>(this) {
+            @Override
+            protected void initChannel(SocketChannel ch) throws Exception {
+                ch.pipeline().addLast(new D5000DelimiterHandler());
+                ch.pipeline().addLast(new Slave104Handle((Iec104SlaverBuilder) builder, D5000Apdu.class));
+            }
+
+        };
+    }
+}

+ 121 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Operation.java

@@ -0,0 +1,121 @@
+package com.jiayue.ipfcst.d5000;
+
+
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Apdu;
+import com.jiayue.ipfcst.d5000.d5000dataframe.receive.InfoAnswerType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice.RequestDataType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice.ReturnDataType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.ChangePasswordType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.UploadDataType;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.AbstractDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.utils.DataConvertor;
+
+
+import java.util.List;
+
+/**
+ * 所有关于D5000的操作
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-13 上午12:13
+ * @Email 524710549@qq.com
+ **/
+@Slf4j
+public class D5000Operation {
+
+    //部分一     请求各种数据
+
+    /**
+     * 请求数据
+     *
+     * @param requestDataType
+     * @return
+     * @throws Exception
+     */
+    public static List reqData(RequestDataType requestDataType) throws Exception {
+        Asdu asdu = requestDataType.generateBack();
+        D5000Apdu apdu = new D5000Apdu();
+        apdu.setAsdu(asdu);
+        byte[] bb = apdu.encode();
+        log.info("发送数据帧:" + DataConvertor.Byte2String(bb));
+        D5000Apdu apdu1 = MasterRequestSocket.getInstance().writeToSocket(bb);
+        log.info(JSON.toJSONString(apdu1));
+        if (apdu1 == null) {
+            throw new D5000Exception(404, "请求没有响应");
+        }
+        AbstractDataFrameType dataFrame = apdu1.getAsdu().getDataFrame();
+        if (dataFrame != null) {
+            if (dataFrame instanceof ReturnDataType) {
+                return ((ReturnDataType) dataFrame).getData();
+            }else if(dataFrame instanceof InfoAnswerType){
+                D5000Utils.validateInfoNum((InfoAnswerType) dataFrame);
+            }
+        }
+        return null;
+    }
+
+    //部分二  上报各种数据,短期风功率预测,项目运行状态,样板机功率,日预测运行容量
+
+    /**
+     * 上报各种数据
+     *
+     * @param uploadDataType
+     * @return boolean
+     * @throws Exception
+     */
+    public static boolean uploadData(UploadDataType uploadDataType) throws Exception {
+        boolean f = false;
+        Asdu asdu = uploadDataType.generateBack();
+        D5000Apdu apdu = new D5000Apdu();
+        apdu.setAsdu(asdu);
+        byte[] bb = apdu.encode();
+        log.info("发送数据帧:" + DataConvertor.Byte2String(bb));
+        D5000Apdu apdu1 = MasterRequestSocket.getInstance().writeToSocket(bb);
+        if (apdu1 != null && apdu1.getApciType() == Apdu.ApciType.I_FORMAT) {
+            InformationBodyAddress informationBodyAddress = D5000Utils.validateInfoNum((InfoAnswerType) (apdu1.getAsdu().getDataFrame()));
+            log.info("发送地址位:" + uploadDataType.getAddress().toString());
+            log.info("接收地址位:" + informationBodyAddress.toString());
+            if (informationBodyAddress != null) {
+                f = true;
+            }
+        } else {
+            log.error("请求没有响应");
+            throw new D5000Exception(404, "请求没有响应");
+        }
+        return f;
+    }
+
+
+    /**
+     * 修改密码
+     *
+     * @param changePasswordType
+     * @return boolean
+     * @throws Exception
+     */
+    public static boolean changePassword(ChangePasswordType changePasswordType) throws Exception {
+        boolean f = false;
+        Asdu asdu = changePasswordType.generateBack();
+        D5000Apdu apdu = new D5000Apdu();
+        apdu.setAsdu(asdu);
+        byte[] bb = apdu.encode();
+        log.info("发送数据帧:" + DataConvertor.Byte2String(bb));
+        D5000Apdu apdu1 = MasterRequestSocket.getInstance().writeToSocket(bb);
+        if (apdu1 != null && apdu1.getApciType() == Apdu.ApciType.I_FORMAT) {
+            InformationBodyAddress informationBodyAddress = D5000Utils.validateInfoNum((InfoAnswerType) (apdu1.getAsdu().getDataFrame()));
+            if (informationBodyAddress != null) {
+                log.info("修改后的新密码:" + DataConvertor.Byte2String(changePasswordType.getNewPassword()));
+                f = true;
+            }
+        } else {
+            throw new D5000Exception(404, "请求没有响应");
+        }
+        return f;
+    }
+
+}

+ 169 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000Utils.java

@@ -0,0 +1,169 @@
+package com.jiayue.ipfcst.d5000;
+
+
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Vsq;
+import com.jiayue.ipfcst.d5000.D5000information.D5000DataInfo;
+import com.jiayue.ipfcst.d5000.D5000information.D5000FixedValue;
+import com.jiayue.ipfcst.d5000.d5000dataframe.receive.InfoAnswerType;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * D5000中用到的工具类
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-09 下午10:27
+ * @Email 524710549@qq.com
+ **/
+@Slf4j
+public class D5000Utils {
+
+    private static Map<Integer, D5000DataInfo> dataInfoMap = new HashMap<>();
+
+    /**
+     * 数据i帧除去数据的长度
+     */
+    private static final int OTHERLEN = 14;
+
+    /**
+     * 根据年份大小而改变的数值
+     */
+    private static final int YEARDAYS = 365;
+
+    static {
+        Class<?> clz = D5000FixedValue.class;
+        Field[] fields = clz.getDeclaredFields();
+        for (Field f : fields) {
+            if (D5000DataInfo.class.equals(f.getGenericType())) {
+                f.setAccessible(true);
+                try {
+                    D5000DataInfo info = (D5000DataInfo) f.get(null);
+                    dataInfoMap.put(info.getAddress(), info);
+                } catch (IllegalAccessException e) {
+                    e.printStackTrace();
+                }
+
+            }
+        }
+    }
+
+    public static Map<Integer, D5000DataInfo> getDataInfoMap() {
+        return dataInfoMap;
+    }
+
+    public static void appendByteList(List<Byte> buffer, byte[] bytes) {
+        for (byte b : bytes) {
+            buffer.add(b);
+        }
+    }
+
+    public static D5000DataInfo analyzeDataType(int address) {
+        return dataInfoMap.get(address);
+    }
+
+    /**
+     * 验证数据个数是否正确
+     *
+     * @param dataInfo
+     * @param vsq
+     * @return
+     */
+    public static int validateDataNum(D5000DataInfo dataInfo, D5000Vsq vsq) {
+        int dataNum = 0;
+        int num = (vsq.getTotLen() - 14) / 4;
+        if (dataInfo.getPointNum() == YEARDAYS) {
+            if (num == YEARDAYS || num == YEARDAYS + 1) {
+                dataNum = num;
+            }
+        } else {
+            if (num == dataInfo.getPointNum()) {
+                dataNum = num;
+            }
+        }
+        return dataNum;
+    }
+
+
+    /**
+     * 判断返回的InfoAnswerType 类型信息所代表的意义
+     *
+     * @param infoAnswerType
+     * @return
+     */
+    public static InformationBodyAddress validateInfoNum(InfoAnswerType infoAnswerType) throws D5000Exception {
+        switch (infoAnswerType.getResultCode()) {
+            case 0:
+                throw new D5000Exception(0, "账户名或密码错误");
+            case 1:
+                throw new D5000Exception(1, "修改密码失败");
+            case 2:
+                return new InformationBodyAddress((byte) 0X02, (byte) 0X50, (byte) 0X00);
+            case 10:
+                return new InformationBodyAddress(0XFFE001);
+            case 11:
+                throw new D5000Exception(11, "计划值申报超过规定时间");
+            case 12:
+                throw new D5000Exception(12, "计划值申报超过规定时间");
+            case 13:
+                throw new D5000Exception(13, "计划值申报错误,请检查电场ID或数据点数");
+            case 20:
+                return new InformationBodyAddress(0XFFD001);
+            case 21:
+                throw new D5000Exception(21, "项目运行状态申报超过规定时间");
+            case 22:
+                throw new D5000Exception(22, "项目运行状态申报超过规定时间");
+            case 23:
+                throw new D5000Exception(23, "项目运行状态申报错误,请检查电场ID或数据点数");
+            case 30:
+                return new InformationBodyAddress(0XFFC001);
+            case 31:
+                throw new D5000Exception(31, "样板机申报超过规定时间");
+            case 32:
+                throw new D5000Exception(32, "样板机申报超过规定时间");
+            case 33:
+                throw new D5000Exception(33, "样板机申报错误,请检查电场ID或数据点数");
+            default:
+                throw new D5000Exception(34, "应答报文回应码错误");
+        }
+    }
+
+
+    /**
+     * 把由数字组成的string 拆成一个个数字后添加入byte数组中
+     * 数组头开始添加
+     *
+     * @param s
+     * @param bs
+     * @return
+     */
+    public static int stringAdd2ByteArray(String s, byte[] bs) {
+        if (s.matches("^[0-9]*$") && s.length() <= bs.length) {
+            char[] chars = s.toCharArray();
+            int len = chars.length;
+            for (int i = 0; i < len; i++) {
+                bs[i] = (byte) (chars[i] - 48);
+            }
+            return len;
+        }else{
+            log.info("字串不是纯数字,文本为:"+s);
+        }
+        return 0;
+    }
+
+
+    public static int byteArrayAdd2ByteArray(byte[] bs1, byte[] bs2) {
+        if (bs1.length <= bs2.length) {
+            for (int i = 0; i < bs1.length; i++) {
+                bs2[i] = bs1[i];
+            }
+            return bs1.length;
+        }
+        return 0;
+    }
+}

+ 168 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Apdu.java

@@ -0,0 +1,168 @@
+package com.jiayue.ipfcst.d5000.D5000framestructure;
+
+
+import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.exception.Iec104Exception;
+import wei.yigulu.iec104.util.SendAndReceiveNumUtil;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * D5000的apdu
+ * 由于d5000的报文长度较长且长度解析有异于常规104
+ * 故需重写
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-09 上午12:45
+ * @Email 524710549@qq.com
+ **/
+
+@Slf4j
+@Data
+@AllArgsConstructor
+public class D5000Apdu extends Apdu {
+
+
+    public static final byte[] TESTBACK = new byte[]{0x68, 0x0e, (byte) 0x83, 0x00, 0x00, 0x00, (byte) 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+    /**
+     * 读取字节流 将数据帧转化为APDU
+     *
+     * @param dis
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public D5000Apdu loadByteBuf(ByteBuf dis) throws Exception {
+        this.channel = channel;
+        int start = dis.readByte() & 0xff;
+        int len = dis.readByte() & 0xff;
+        log.debug("APDU长度:" + len);
+        byte[] controlFields = new byte[4];
+        if (start != 104) {
+            new Iec104Exception("起始字符错误" + start);
+        } else {
+            //读4字节控制域
+            dis.readBytes(controlFields);
+            //第一比特=0  ===》I格式
+            if ((controlFields[0] & 0x01) == 0) {
+                //I帧
+                this.apciType = ApciType.I_FORMAT;
+                //发送序列号  先是最低有效位 ,接下来是最高有效位,最高有效位拿到后面,最低有效位后面补0,LSB 0;MSB
+                sendSeqNum = ((controlFields[0] & 0xfe) >> 1) + ((controlFields[1] & 0xff) << 7);
+                //接收序列号 原理同发送序列号
+                receiveSeqNum = ((controlFields[2] & 0xfe) >> 1) + ((controlFields[3] & 0xff) << 7);
+                log.debug("I帧,发送序列号:" + sendSeqNum + ",接收序列号:" + receiveSeqNum);
+                if (channel != null) {
+                    SendAndReceiveNumUtil.receiveIFrame(this, this.channel.id());
+                }
+                //第一比特=1  第二比特=0 ===》S格式
+                //构建数据单元
+                this.asdu = new D5000Asdu();
+                ((D5000Asdu) this.asdu).getVsq().setApduLen((byte) len);
+                this.asdu.loadByteBuf(dis);
+            } else if ((controlFields[0] & 0x03) == 1) {
+                //S帧
+                this.apciType = ApciType.S_FORMAT;
+                receiveSeqNum = ((controlFields[2] & 0xfe) >> 1) + ((controlFields[3] & 0xff) << 7);
+                log.debug("S帧,接收序列号:" + receiveSeqNum);
+                //第一比特=1  第二比特=1 ===》S格式
+            } else if ((controlFields[0] & 0x03) == 3) {
+                //U帧
+                switch (controlFields[0]) {
+                    case 0x07:
+                        this.apciType = ApciType.STARTDT_ACT;
+                        log.debug("U帧,启动命令");
+                        break;
+                    case 0x0B:
+                        this.apciType = ApciType.STARTDT_CON;
+                        log.debug("U帧启动确认");
+                        break;
+                    case 0x13:
+                        this.apciType = ApciType.STOPDT_ACT;
+                        log.debug("U帧停止命令");
+                        break;
+                    case 0x23:
+                        this.apciType = ApciType.STOPDT_CON;
+                        log.debug("U帧停止确认");
+                        break;
+                    case 0x43:
+                        this.apciType = ApciType.TESTFR_ACT;
+                        log.debug("U帧测试命令");
+                        break;
+                    case (byte) 0x83:
+                        this.apciType = ApciType.TESTFR_CON;
+                        log.debug("U帧测试确认");
+                        break;
+                    default:
+                        log.debug("U帧类型异常");
+                        break;
+                }
+            }
+        }
+        return this;
+    }
+
+
+    /**
+     * APDU编码由当前的apdu编码成数据帧
+     *
+     * @return
+     */
+    @Override
+    public byte[] encode() throws Exception {
+        List<Byte> buffer = new ArrayList<>();
+        buffer.add((byte) 0x68);
+        buffer.add((byte) 0x00);
+        if (apciType == ApciType.I_FORMAT) {
+            buffer.add((byte) (sendSeqNum << 1));
+            buffer.add((byte) (sendSeqNum >> 7));
+            buffer.add((byte) (receiveSeqNum << 1));
+            buffer.add((byte) (receiveSeqNum >> 7));
+            asdu.encode(buffer);
+        } else if (apciType == ApciType.STARTDT_ACT) {
+            buffer.add((byte) 0x07);
+            buffer.add((byte) 0x00);
+            buffer.add((byte) 0x00);
+            buffer.add((byte) 0x00);
+        } else if (apciType == ApciType.STARTDT_CON) {
+            buffer.add((byte) 0x0b);
+            buffer.add((byte) 0x00);
+            buffer.add((byte) 0x00);
+            buffer.add((byte) 0x00);
+        } else if (apciType == ApciType.S_FORMAT) {
+            buffer.add((byte) 0x01);
+            buffer.add((byte) 0x00);
+            buffer.add((byte) (receiveSeqNum << 1));
+            buffer.add((byte) (receiveSeqNum >> 7));
+        }
+        buffer.set(1, (byte) buffer.size());
+        buffer.set(7, (byte) (buffer.size() >> 8));
+        byte[] bs = new byte[buffer.size()];
+        for (int i = 0; i < buffer.size(); i++) {
+            bs[i] = buffer.get(i);
+        }
+        return bs;
+    }
+
+    /**
+     * U帧的应答措施
+     *
+     * @return
+     */
+    @Override
+    public byte[][] uHandleAndAnswer() throws Iec104Exception {
+        byte[][] bb;
+        bb = new byte[1][];
+        bb[0] = TESTBACK;
+        return bb;
+    }
+
+
+}

+ 93 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Asdu.java

@@ -0,0 +1,93 @@
+package com.jiayue.ipfcst.d5000.D5000framestructure;
+
+
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.apdumodel.Cot;
+import wei.yigulu.iec104.asdudataframe.AbstractDataFrameType;
+import wei.yigulu.iec104.container.AsduTypeAnnotationContainer;
+import wei.yigulu.iec104.container.DataTypeClasses;
+import wei.yigulu.utils.DataConvertor;
+
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * D5000asdu
+ *由于d5000的asdu 较正常104缺少源地址故重写
+ * ASDU采用与标准104相同的报文结构。
+ * 报文域从前到后分别为类型标识1个字节、
+ * 可变结构限定词域1个字节、
+ * 传送原因域1个字节、
+ * 应用服务数据单元公共地址域2个字节、
+ * 信息对象地址3个字节
+ * 和信息对象值。
+ * @author 修唯xiuwei
+ * @create 2019-04-09 上午12:47
+ * @Email 524710549@qq.com
+ **/
+@Slf4j
+@NoArgsConstructor
+@Data
+public class D5000Asdu extends Asdu {
+
+    D5000Vsq vsq=new D5000Vsq();
+
+    /**
+     * @param dataInputStream
+     * @throws Exception
+     */
+    @Override
+    public Asdu loadByteBuf(ByteBuf dataInputStream) throws Exception {
+        //获取类型表示配置文件
+        this.typeId = dataInputStream.readByte() & 0xff;
+
+        vsq.readByte(dataInputStream.readByte());
+        cot = new Cot().readByte(dataInputStream.readByte());
+        //公共地址
+        byte[] commAddress = new byte[2];
+        dataInputStream.readBytes(commAddress);
+        commonAddress =commAddress[0]+((commAddress[1]&0xff)<<8);
+        //信息体
+        if (typeId < 145) {
+            Map<Integer, DataTypeClasses> map= AsduTypeAnnotationContainer.getInstance().getDataTypes();
+            if(map.containsKey(typeId)){
+                dataFrame = (AbstractDataFrameType)(map.get(typeId).getTypeClass().newInstance());
+                Method load = map.get(typeId).getLoad();
+                load.invoke(dataFrame, dataInputStream, this.getVsq());
+            }else{
+                byte[] unknown = new byte[dataInputStream.readableBytes()];
+                dataInputStream.readBytes(unknown);
+                System.out.println(DataConvertor.Byte2String(unknown));
+                throw new IOException("无法转换信息对象,由于类型标识未知: " + typeId);
+            }
+            log.debug(dataFrame.toString());
+            privateInformation = null;
+        } else {
+            log.debug("");
+        }
+        return this;
+    }
+
+    @Override
+    public void encode(List<Byte> buffer) {
+
+        buffer.add((byte) typeId);
+
+        vsq.encode(buffer);
+
+        cot.encode(buffer);
+
+        buffer.add((byte) commonAddress);
+
+        buffer.add((byte) (commonAddress >> 8));
+
+        dataFrame.encode(buffer);
+    }
+}

+ 54 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000framestructure/D5000Vsq.java

@@ -0,0 +1,54 @@
+package com.jiayue.ipfcst.d5000.D5000framestructure;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import wei.yigulu.iec104.apdumodel.Vsq;
+
+
+import java.util.List;
+
+/**
+ * D5000重写的Vsq
+ * 因为部分报文的长度超过255个字节,
+ * 所以对原来长度域进行了扩展,通过两个字节来标识报文的长度。
+ * 长度同时包括起始域(0X68)和长度域自身。
+ * 把可变结构限定词域作为长度的高字节部分,原来长度域作为长度的低字节部分。
+ * 即APDU的第二个字节和ASDU的第二个字节联合表示报文的长度。
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-09 下午6:38
+ * @Email 524710549@qq.com
+ **/
+
+
+
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class D5000Vsq extends Vsq {
+
+    @Override
+    public D5000Vsq readByte(Byte value) {
+        super.setOriginal(value);
+        super.setSq(1);
+        this.setTotLen(((super.getOriginal()&0xff)<<8)|(this.getApduLen()&0xff));
+        return  this;
+    }
+
+
+    /**
+     *
+     * @param
+     */
+   byte apduLen=0;
+
+   int  totLen;
+
+    @Override
+    public void encode(List<Byte> buffer) {
+            buffer.add((byte)0x00);
+    }
+
+
+}

+ 29 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000information/D5000DataInfo.java

@@ -0,0 +1,29 @@
+package com.jiayue.ipfcst.d5000.D5000information;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * D5000不同类型信息的地址位对应关系
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-09 下午11:26
+ * @Email 524710549@qq.com
+ **/
+@AllArgsConstructor
+@Data
+public class D5000DataInfo {
+    int address;
+    String describe;
+    DataType dataType;
+    DateFormat dateFormat;
+    int pointNum;
+
+    public enum DataType {
+        INT, FLOAT
+    }
+
+    public enum DateFormat {
+        YMD, Y
+    }
+}

+ 294 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/D5000information/D5000FixedValue.java

@@ -0,0 +1,294 @@
+package com.jiayue.ipfcst.d5000.D5000information;
+
+
+/**
+ * D5000定义的一些定值
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-04 16:00
+ * @Email 524710549@qq.com
+ **/
+public class D5000FixedValue {
+
+
+    /**
+     * 0X6001---日实际功率---float---yyyy-MM-dd---96点
+     */
+    public static final D5000DataInfo RSJGL=new D5000DataInfo(0x6001,"日实际功率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+    /**
+     * 0X7001---日申报功率---float---yyyy-MM-dd---96点
+     */
+    public static final D5000DataInfo RSBGL=new D5000DataInfo(0X7001,"日申报功率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+    /**
+     * 0X8001---日考核指定---D5000DataInfo---yyyy-MM-dd---96点
+     */
+    public static final D5000DataInfo RKHZD=new D5000DataInfo(0X8001,"日考核指定", D5000DataInfo.DataType.INT, D5000DataInfo.DateFormat.YMD,96);
+
+    /**
+     * 0X9001---年预测准确率---float
+     */
+    public static final D5000DataInfo NYCZQL=new D5000DataInfo(0X9001,"年预测准确率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,365);
+
+
+    /**
+     * 0XA001---年预测合格率---float---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NYCHGL=new D5000DataInfo(0XA001,"年预测合格率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,365);
+
+    /**
+     *0XB001---年预测传送率---float---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NYCCSL=new D5000DataInfo(0XB001,"年预测传送率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,365);
+
+    /**
+     * 0XC001---年预测考核结果---float---yyyy---日历天数(12)
+     */
+    public static final D5000DataInfo NYCKHJG=new D5000DataInfo(0XC001,"年预测考核结果", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     * 0XD001---年弃风排序---D5000DataInfo---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NQFPX=new D5000DataInfo(0XD001,"年弃风排序", D5000DataInfo.DataType.INT, D5000DataInfo.DateFormat.Y,365);
+
+    /**
+     * 0XE001---日预测准确率---float---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RYCZQL=new D5000DataInfo(0XE001,"日预测准确率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,1);
+
+
+    /**
+     * 0XF001---日预测合格率---float---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RYCHGL=new D5000DataInfo(0XF001,"日预测合格率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,1);
+
+
+    /**
+     * 0X10001---日预测传送率---float---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RYCCSL=new D5000DataInfo(0X10001,"日预测传送率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,1);
+
+
+
+    /**
+     * 0X11001---日弃风排序---D5000DataInfo---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RQFPX=new D5000DataInfo(0X11001,"日弃风排序", D5000DataInfo.DataType.INT, D5000DataInfo.DateFormat.YMD,1);
+
+
+    /**
+     * 0X12001---日弃风发电比---float---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RQFFDB=new D5000DataInfo(0X12001,"日弃风发电比", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,1);
+
+    /**
+     * 0X13001---年弃风发电比---float---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NQFFDB=new D5000DataInfo(0X13001,"年弃风发电比", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,365);
+
+    /**
+     * 0X14001---日反措级别---D5000DataInfo---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RFCJB=new D5000DataInfo(0X14001,"日反措级别", D5000DataInfo.DataType.INT, D5000DataInfo.DateFormat.YMD,1);
+
+
+    /**
+     * 0X15001---年反措级别---D5000DataInfo---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NFCJB=new D5000DataInfo(0X15001,"年反措级别", D5000DataInfo.DataType.INT, D5000DataInfo.DateFormat.Y,365);
+
+
+    /**
+     * 0X16001---年交易电量---float---yyyy---日历天数(365或366)
+     */
+    public static final D5000DataInfo NJYDL=new D5000DataInfo(0X16001,"年交易电量", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,365);
+
+
+    /**
+     * 0X17001---日交易电量---float---yyyy-MM-dd---1点
+     */
+    public static final D5000DataInfo RJYDL=new D5000DataInfo(0X17001,"日交易电量", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,1);
+
+
+    /**
+     * 0X18001---月AGC服务---float---yyyy---12点
+     */
+    public static final D5000DataInfo YAGCFW=new D5000DataInfo(0X18001,"月AGC服务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+
+    /**
+     * 0X19001---月安全管理---float---yyyy---12点
+     */
+    public static final D5000DataInfo YAQGL=new D5000DataInfo(0X19001,"月安全管理", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     * 0X1A001---月调度业务---float---yyyy---12点
+     */
+    public static final D5000DataInfo YDDFU=new D5000DataInfo(0X1A001,"月调度业务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     * 0X1B001---月曲线违约考核---float---yyyy---12点
+     */
+    public static final D5000DataInfo YQXWYKH=new D5000DataInfo(0X1B001,"月曲线违约考核", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     * 0X1C001---月非计划停机考核---float---yyyy---12点
+     */
+    public static final D5000DataInfo YFTJKH=new D5000DataInfo(0X1C001,"月非计划停机考核", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     * 0X1D001---月调峰服务---float---yyyy---12点
+     */
+    public static final D5000DataInfo YTFKH=new D5000DataInfo(0X1D001,"月调峰服务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     * 0X1E001---月继电保护---float---yyyy---12点
+     */
+    public static final D5000DataInfo YJDBH=new D5000DataInfo(0X1E001,"月继电保护", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     * 0X1F001---月风电预测考核---float---yyyy---12点
+     */
+    public static final D5000DataInfo YFDYCKH=new D5000DataInfo(0X1F001,"月风电预测考核", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     * 0X20001---月机组检修---float---yyyy---12点
+     */
+    public static final D5000DataInfo YJZJX=new D5000DataInfo(0X20001,"月机组检修", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X21001---月水库调度---float---yyyy---12点
+     */
+    public static final D5000DataInfo YSKDD=new D5000DataInfo(0X21001,"月水库调度", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X22001---月通信---float---yyyy---12点
+     */
+    public static final D5000DataInfo YTX=new D5000DataInfo(0X22001,"月通信", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X23001---月电厂高压侧电气设备---float
+     */
+    public static final D5000DataInfo YDCGYCDQSB=new D5000DataInfo(0X23001,"月电厂高压侧电气设备", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X24001---月黑启动服务---float
+     */
+    public static final D5000DataInfo YHQDFW=new D5000DataInfo(0X24001,"月黑启动服务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X25001---月励磁和PSS装置管理---float
+     */
+    public static final D5000DataInfo YLCHPSSZZGL=new D5000DataInfo(0X25001,"月励磁和PSS装置管理", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+
+    /**
+     *0X26001---月无功调节服务---float
+     */
+    public static final D5000DataInfo YWGTJFW=new D5000DataInfo(0X26001,"月无功调节服务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+
+    /**
+     *0X27001---月一次调频服务---float
+     */
+    public static final D5000DataInfo YYCTPFW=new D5000DataInfo(0X27001,"月一次调频服务", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X28001---月自动化---float
+     */
+    public static final D5000DataInfo YZDH=new D5000DataInfo(0X28001,"月自动化", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X29001---月运行调峰结算费用---float
+     */
+    public static final D5000DataInfo YYXTFJSFY=new D5000DataInfo(0X29001,"月运行调峰结算费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X2A001---月AGC费用---float
+     */
+    public static final D5000DataInfo YAGCFY=new D5000DataInfo(0X2A001,"月AGC费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X2B001---月开停调峰费用---float
+     */
+    public static final D5000DataInfo YKTTFFY=new D5000DataInfo(0X2B001,"月开停调峰费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+    /**
+     *0X2C001---月黑启动调峰费用---float
+     */
+    public static final D5000DataInfo YHQDTFFY=new D5000DataInfo(0X2C001,"月黑启动调峰费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X2D001---月无功补充费用---float
+     */
+    public static final D5000DataInfo YWGBCFY=new D5000DataInfo(0X2D001,"月无功补充费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X2E001---月旋转备用费用---float
+     */
+    public static final D5000DataInfo YXZBCFY=new D5000DataInfo(0X2E001,"月旋转备用费用", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.Y,12);
+
+
+    /**
+     *0X2F001---发电计划---float
+     */
+    public static final D5000DataInfo FDJH=new D5000DataInfo(0X2F001,"发电计划", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+    /**
+     *0X30001---电场项目运行状态---float
+     */
+    public static final D5000DataInfo DCXMYXZT=new D5000DataInfo(0X30001,"电场项目运行状态", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,4);
+
+    /**
+     *0X31001---日样板机申报功率---float
+     */
+    public static final D5000DataInfo RYBJSBGL=new D5000DataInfo(0X31001,"日样板机申报功率", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+    /**
+     *0XFFF001---短期风功率预测收取---float
+     */
+    public static final D5000DataInfo DQFGLYCSQ=new D5000DataInfo(0XFFF001,"短期风功率预测收取", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+    /**
+     *0XFFE001---短期风功率预测上报---float
+     */
+    public static final D5000DataInfo DQFGLYCSB=new D5000DataInfo(0XFFE001,"短期风功率预测上报", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+    /**
+     *0XFFD001---项目运行状态上报---float
+     */
+    public static final D5000DataInfo XMYXZTSB=new D5000DataInfo(0XFFD001,"项目运行状态上报", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,4);
+
+
+    /**
+     *0XFFC001---样板机功率上报---float
+     */
+    public static final D5000DataInfo YBJGLSB=new D5000DataInfo(0XFFC001,"样板机功率上报", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+    /**
+     *0XFFB001---日预测运行容量上报---loat
+     */
+    public static final D5000DataInfo RYCYXRLSB=new D5000DataInfo(0XFFB001,"日预测运行容量", D5000DataInfo.DataType.FLOAT, D5000DataInfo.DateFormat.YMD,96);
+
+
+}

+ 201 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/MasterRequestSocket.java

@@ -0,0 +1,201 @@
+package com.jiayue.ipfcst.d5000;
+
+
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Apdu;
+import io.netty.buffer.Unpooled;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.experimental.Accessors;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import wei.yigulu.utils.DataConvertor;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+
+/**
+ * 创建一个socket客户端并向服务端发送一条数据
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-17 10:49
+ * @Email 524710549@qq.com
+ **/
+@Slf4j
+@Getter
+public class MasterRequestSocket {
+
+
+    private static class LazyHolder {
+        private static final MasterRequestSocket INSTANCE = new MasterRequestSocket();
+    }
+
+    private MasterRequestSocket() {
+    }
+
+    public static final MasterRequestSocket getInstance() {
+        return LazyHolder.INSTANCE;
+    }
+
+    private int nowPort;
+
+    private int start;
+
+    private int end;
+
+    @Setter
+    @Accessors(chain = true)
+    private String masterIp ;
+
+    @Setter
+    @Accessors(chain = true)
+    private String masterSpareIp;
+
+    @Setter
+    @Accessors(chain = true)
+    private String selfIp;
+
+    @Setter
+    @Accessors(chain = true)
+    private int masterPort =2404;
+
+    @Setter
+    @Accessors(chain = true)
+    private int socketRetryNum = 5;
+
+    @Setter
+    @Accessors(chain = true)
+    private int selfServerPort = 2404;
+
+    @Setter
+    @Accessors(chain = true)
+    String selfPortRange = "2400-2500";
+
+
+    public int getNextPort() {
+        if (nowPort == 0) {
+            String[] ss = this.selfPortRange.split("-");
+            this.start = Integer.parseInt(ss[0]);
+            this.end = Integer.parseInt(ss[1]);
+            nowPort = start;
+        } else if (nowPort == end) {
+            nowPort = start;
+        } else if (nowPort == (this.selfServerPort - 1)) {
+            nowPort += 2;
+        } else {
+            nowPort++;
+        }
+        return nowPort;
+    }
+
+
+    public Socket createSocket(int retryNum,String ip) {
+        Socket socket = null;
+        if(retryNum>0) {
+            try {
+                socket = new Socket(InetAddress.getByName(ip), masterPort, InetAddress.getByName(selfIp), getNextPort());
+                socket.setSoTimeout(3000);
+            } catch (UnknownHostException e) {
+                log.error("创建socket通道时发生异常",e);
+            } catch (IOException e) {
+                log.error("socket未创建成功",e);
+                try {
+                    socket.close();
+                } catch (IOException | NullPointerException e1) {
+                   log.error("socket未关闭成功",e);
+                }
+                try {
+                    Thread.sleep(200L);
+                } catch (InterruptedException e1) {
+                    e1.printStackTrace();
+                }
+                log.info("重试创建socket连接");
+                createSocket(--retryNum,ip);
+            }
+        }
+        return socket;
+
+    }
+
+    public synchronized D5000Apdu writeToSocket(byte[] bb) throws D5000Exception {
+        Socket socket = createSocket(socketRetryNum,masterIp);
+        if(socket==null){
+            socket=createSocket(  socketRetryNum,masterSpareIp);
+        }
+        OutputStream outputStream = null;
+        InputStream inputStream = null;
+        D5000Apdu apdu = null;
+        if(socket==null){
+            throw new D5000Exception(10404,"创建Socket连接失败");
+        }
+        try {
+            while (!socket.isConnected()) {
+                Thread.sleep(200L);
+            }
+            outputStream = socket.getOutputStream();
+            inputStream = socket.getInputStream();
+            outputStream.write(bb);
+            outputStream.flush();
+            // this.sendNum++;
+            apdu = readAndParse(inputStream);
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            closeAll(socket, outputStream, inputStream);
+
+        }
+        return apdu;
+    }
+
+
+
+    public D5000Apdu readAndParse(InputStream inputStream) throws IOException, InterruptedException {
+        byte[] re = new byte[2048];
+        int len;
+        long end = new DateTime().getMillis() + 10000L;
+        D5000Apdu apdu=null;
+        while ((len = inputStream.read(re)) <= 0 && new DateTime().getMillis() < end) {
+            Thread.sleep(20L);
+        }
+        if (len != 0&&len!=-1) {
+            byte[] res = Arrays.copyOf(re, len);
+            log.info("接收到数据帧:" + DataConvertor.Byte2String(res));
+            try {
+                apdu=new D5000Apdu().loadByteBuf(Unpooled.copiedBuffer(res));
+               // this.receiveNum++;
+            } catch (Exception e) {
+                e.printStackTrace();
+               log.error("数据帧解析失败");
+            }
+        } else {
+            log.error("未接收到数据帧");
+        }
+        return apdu;
+    }
+
+    private void closeAll(Socket socket, OutputStream outputStream, InputStream inputStream) {
+        try {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+            if (outputStream != null) {
+                outputStream.close();
+            }
+            socket.close();
+        } catch (IOException e1) {
+            e1.printStackTrace();
+        }
+        log.info("关闭请求socket连接");
+    }
+
+
+}
+
+
+
+

+ 59 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/receive/InfoAnswerType.java

@@ -0,0 +1,59 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.receive;
+
+
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+import lombok.SneakyThrows;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Vsq;
+import wei.yigulu.iec104.asdudataframe.SimpleDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+
+/**
+ * D5000新增报文类型 info应答
+ * <p>
+ * info.0=登陆失败,请检查用户名和口令
+ * info.1=修改密码失败,请检查原用户名和密码及密码要求
+ * info.2=修改密码成功
+ * info.9=查询失败,请检查报文格式
+ * info.10=计划值申报成功
+ * info.11=计划值申报超过规定时间
+ * info.12=计划值申报错误,请检查数据点数
+ * info.13=计划值申报错误,请检查电场ID或数据点数
+ * info.20=项目运行状态申报成功
+ * info.21=项目运行状态申报超过规定时间
+ * info.22=项目运行状态申报错误,请检查数据点数
+ * info.23=项目运行状态申报错误,请检查项目ID或数据点数
+ * info.30=样板机申报成功
+ * info.31=样板机申报超过规定时间
+ * info.32=样板机申报错误,请检查数据点数
+ * info.33=样板机申报错误,请检查样板机ID或数据点数
+ * nfo应答报文可以对请求数据报文、修改密码报文、上传数据报文、二进制报文进行回复。类型码为137。
+ * 因为报文的总长度为15,可变结构限定词为0X00,长度域为0X0F。传送原因为7。
+ * 应用服务数据单元公共地址为0X01 0X00,信息对象地址为0X03 0X50 0X00,结果码为1个字节。
+ * 后面未定义部分用于扩展。
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:31
+ * @Email 524710549@qq.com
+ **/
+@AsduType
+@Data
+public class InfoAnswerType extends SimpleDataFrameType {
+
+    public static final int TYPEID = 137;
+
+    public static final InformationBodyAddress ADDRESS = new InformationBodyAddress((byte) 0x03, (byte) 0x50, (byte) 0x00);
+
+    public int resultCode;
+
+    @SneakyThrows
+    @Override
+    public void loadByteBuf(ByteBuf is, Vsq vsq) {
+        InformationBodyAddress informationBodyAddress = new InformationBodyAddress(is);
+        if (informationBodyAddress.equals(ADDRESS)) {
+            this.resultCode = is.readByte()&0xff;
+        }
+    }
+
+}

+ 171 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/sandandrevice/RequestDataType.java

@@ -0,0 +1,171 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice;
+
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Apdu;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Asdu;
+import com.jiayue.ipfcst.d5000.D5000information.D5000DataInfo;
+import com.jiayue.ipfcst.d5000.D5000information.D5000FixedValue;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.UploadDataType;
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.config.SpringContextUtil;
+import com.jiayue.ipfcst.d5000web.service.CollectedDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.UsernamePasswordService;
+import io.netty.buffer.ByteBuf;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.apdumodel.Vsq;
+import wei.yigulu.iec104.asdudataframe.AbstractDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.exception.Iec104Exception;
+import wei.yigulu.utils.DataConvertor;
+
+
+import java.util.List;
+
+/**
+ * D5000新增报文类型-请求数据类型
+ * 请求报文的报文类型码为138。
+ * 因为报文长度为58,所以可变结构限定词为0x00,
+ * 长度字段为0x3A。日期数据占用4个字节,年使用两个字节表达,
+ * 低位在前(请求年数据时月和日域为0,2016年03月21日编码为0XE0 0X07 0X03 0X15)。
+ * 传送原因为6,应用服务数据单元公共地址为0X01 X00。
+ * 信息对象地址为请求的数据的点的起始地址,地址编码如下:
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:34
+ * @Email 524710549@qq.com
+ **/
+
+@AsduType
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@Slf4j
+public class RequestDataType extends AbstractDataFrameType {
+
+    public RequestDataType(DateTime date, String ids, D5000DataInfo dataInfo) {
+        this.address = new InformationBodyAddress(dataInfo.getAddress());
+        if (dataInfo.getDateFormat() == D5000DataInfo.DateFormat.YMD) {
+            this.year = date.getYear();
+            this.month = date.getMonthOfYear();
+            this.day = date.getDayOfMonth();
+        } else {
+            this.year = date.getYear();
+            this.month = 0;
+            this.day = 0;
+        }
+        D5000Utils.stringAdd2ByteArray(ids, this.dataId);
+    }
+
+    InformationBodyAddress address = new InformationBodyAddress();
+
+    byte[] userName = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+    byte[] password = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+    int year;
+
+    int month;
+
+    int day;
+
+    byte[] dataId = new byte[]{(byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+            (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff};
+
+    public static final int TYPEID = 138;
+
+    @Override
+    public void loadByteBuf(ByteBuf is, Vsq vsq) {
+        try {
+            address = new InformationBodyAddress(is);
+        } catch (Iec104Exception e) {
+            e.printStackTrace();
+        }
+        userName = new byte[10];
+        is.readBytes(userName);
+        password = new byte[10];
+        is.readBytes(password);
+        year = ((is.readByte() & 0xff) | ((is.readByte() & 0xff) << 8));
+        month = (is.readByte() & 0xff);
+        day = (is.readByte() & 0xff);
+        dataId = new byte[20];
+        is.readBytes(dataId);
+    }
+
+    @Override
+    public void encode(List<Byte> buffer) {
+        this.address.encode(buffer);
+        D5000Utils.appendByteList(buffer, this.userName);
+        D5000Utils.appendByteList(buffer, this.password);
+        buffer.add((byte) this.year);
+        buffer.add((byte) (this.year >> 8));
+        buffer.add((byte) (this.month & 0xff));
+        buffer.add((byte) (this.day & 0xff));
+        D5000Utils.appendByteList(buffer, this.dataId);
+    }
+
+    @Override
+    public Asdu generateBack() {
+        D5000Asdu asdu = new D5000Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.setCommonAddress(1);
+        asdu.setNot(6);
+        return asdu;
+    }
+
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) {
+        log.info("--------响应D5000主站召唤--------");
+        byte[][] bbs = new byte[0][];
+        RequestDataType requestDataType = (RequestDataType) apdu.getAsdu().getDataFrame();
+        if (requestDataType.getAddress().getAddress() == D5000FixedValue.DQFGLYCSQ.getAddress()) {
+            //响应ReturnDataType
+            requestDataType.getYear();
+            String months = requestDataType.getMonth() < 10 ? "0" + requestDataType.getMonth() : requestDataType.getMonth() + "";
+            String days = requestDataType.getDay() < 10 ? "0" + requestDataType.getDay() : requestDataType.getDay() + "";
+            //发送这天的 短期风功率预测
+            String day = requestDataType.getYear() + "-" + months + "-" + days;
+            log.info("主站请求{}的短期数据", day);
+            CollectedDailyPower collectedDailyPower = new CollectedDailyPower();
+            collectedDailyPower.setIsManual(null);
+            collectedDailyPower.setDate(day);
+            //响应ReturnDataType
+            UsernamePasswordService usernamePasswordService = SpringContextUtil.getBean(UsernamePasswordService.class);
+            try {
+                List<CollectedDailyPower> collectedDailyPowers = SpringContextUtil.getBean(CollectedDailyPowerService.class).get(collectedDailyPower);
+                if (collectedDailyPowers.size() > 0) {
+                    UploadDataType uploadDataType = new UploadDataType(DateTime.parse(collectedDailyPowers.get(0).getDate()), usernamePasswordService.getUserName(), D5000FixedValue.DQFGLYCSB, collectedDailyPowers.get(0).convert2List());
+                    usernamePasswordService.setUserNameAndPassword(uploadDataType);
+                    Asdu asdu = uploadDataType.generateBack();
+                    D5000Apdu dapdu = new D5000Apdu();
+                    dapdu.setAsdu(asdu);
+                    byte[] bb = dapdu.encode();
+                    bbs = new byte[1][];
+                    bbs[0] = bb;
+                    log.info("发送数据帧:" + DataConvertor.Byte2String(bb));
+                    log.info("响应D5000主站召唤上传预测数据成功");
+                } else {
+                    log.info("响应D5000主站召唤上传预测数据失败,没有该日期数据");
+                }
+            } catch (Exception e) {
+                log.error("响应D5000主站召唤上传预测数据失败");
+                log.error(e.toString());
+                e.printStackTrace();
+            }
+        }
+        return bbs;
+    }
+
+}

+ 105 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/sandandrevice/ReturnDataType.java

@@ -0,0 +1,105 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice;
+
+
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Asdu;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Vsq;
+import com.jiayue.ipfcst.d5000.D5000information.D5000DataInfo;
+import io.netty.buffer.ByteBuf;
+import lombok.Data;
+import lombok.SneakyThrows;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.apdumodel.Vsq;
+import wei.yigulu.iec104.asdudataframe.AbstractDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeFourByteInteger;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeShortFloat;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.exception.Iec104Exception;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * D5000新增报文类型-返回数据类型
+ * 请求数据返回报文的类型码为139,可变结构限定词在下面给出计算方法。
+ * 传送原因为7。应用服务数据单元公共地址为0X01 0X00,
+ * 信息对象地址为请求数据时的点的地址。
+ * 返回数据INT类型和FLOAT类型都使用4各字节表示一个数据。
+ * float遵从的是IEEE R32.24 。Int使用4字节补码表示。
+ * 并且使用小端序(低字节在前)。
+ * 如果请求的是2014年的弃风排序数据,因为2014为平年,
+ * 所以会有365个int数据,每个int数据占用4个字节,
+ * 故数据长度为365*4,整个报文的长度为14+365*4=1475。
+ * 所以长度域为1475%256=195=0XC3,可变限定词域为1475/256=5=0X05。
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:40
+ * @Email 524710549@qq.com
+ **/
+
+@AsduType
+@Data
+public class ReturnDataType extends AbstractDataFrameType {
+
+
+    InformationBodyAddress address = new InformationBodyAddress();
+
+    List data;
+
+    public static final int TYPEID = 139;
+
+    @SneakyThrows
+    @Override
+    public void loadByteBuf(ByteBuf is, Vsq vsq) {
+        try {
+            address = new InformationBodyAddress(is);
+        } catch (Iec104Exception e) {
+            e.printStackTrace();
+        }
+        D5000DataInfo info = D5000Utils.analyzeDataType(address.getAddress());
+        int dataNum = D5000Utils.validateDataNum(info, (D5000Vsq) vsq);
+        if (dataNum != 0) {
+            if (info.getDataType() == D5000DataInfo.DataType.INT) {
+                data = new ArrayList<Integer>(dataNum);
+                for (int i = 0; i < dataNum; i++) {
+                    data.add(new IeFourByteInteger(is).getValue());
+                }
+            } else {
+                data = new ArrayList<Float>(dataNum);
+                for (int i = 0; i < dataNum; i++) {
+                    data.add(new IeShortFloat(is).getValue());
+                }
+            }
+        }
+    }
+
+    @Override
+    public void encode(List<Byte> buffer) {
+        address.encode(buffer);
+        for(Object o :this.data){
+            if(o instanceof  Integer){
+                new IeFourByteInteger(((Integer)o).longValue()).encode(buffer);
+            }else if(o instanceof  Float){
+                new IeShortFloat((Float)o).encode(buffer);
+            }
+        }
+    }
+
+    @Override
+    public Asdu generateBack() {
+        D5000Asdu asdu=new D5000Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.setCommonAddress(1);
+        asdu.setNot(7);
+        return asdu;
+    }
+
+
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) throws Exception {
+        return new byte[0][];
+    }
+}

+ 56 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/BinaryInformationType.java

@@ -0,0 +1,56 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.send;
+
+
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Asdu;
+
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.SimpleDataFrameType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * D5000 新增数据类型 -二进制数据信息
+ * 类型标识为142,两个方向都可发送。
+ * 可以传送任何的二进制数据,数据长度不固定,
+ * 由长度字段和可变结构限定词判定。
+ * 如果使用此报文传递文本,文本使用Utf-8编码。
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:51
+ * @Email 524710549@qq.com
+ **/
+@AsduType
+public class BinaryInformationType extends SimpleDataFrameType {
+
+
+    public static final int TYPEID = 142;
+
+    byte[] userName=new byte[10];
+
+    byte[] password=new byte[10];
+
+    List<Byte> binaryData=new ArrayList<>();
+
+
+
+    @Override
+    public void encode(List<Byte> buffer) {
+        D5000Utils.appendByteList(buffer,userName);
+        D5000Utils.appendByteList(buffer,password);
+        buffer.addAll(binaryData);
+    }
+
+    @Override
+    public Asdu generateBack() {
+        D5000Asdu asdu=new D5000Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.setCommonAddress(1);
+        asdu.setNot(6);
+        return asdu;
+    }
+
+}

+ 56 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/ChangePasswordType.java

@@ -0,0 +1,56 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.send;
+
+
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Asdu;
+import lombok.Data;
+
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.SimpleDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+
+import java.util.List;
+
+/**
+ * D5000新增报文类型-修改密码
+ * 修改密码报文类型标识为140,本报文为从站向主站发送的报文。信息对象地址为0X02 0X50 0X00,数据域
+ * 长度字段为0X2C,可变地址限定词为0X00。
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:46
+ * @Email 524710549@qq.com
+ **/
+@AsduType
+@Data
+public class ChangePasswordType extends SimpleDataFrameType {
+
+
+    public static final int TYPEID = 140;
+
+    InformationBodyAddress address=new InformationBodyAddress((byte)0x02,(byte)0x50,(byte)0x00);
+
+    byte[] userName=new byte[10];
+
+    byte[] oldPassword =new byte[10];
+
+    byte[] newPassword=new byte[10];
+
+    @Override
+    public void encode(List<Byte> buffer) {
+        address.encode(buffer);
+        D5000Utils.appendByteList(buffer,userName);
+        D5000Utils.appendByteList(buffer,oldPassword);
+        D5000Utils.appendByteList(buffer,newPassword);
+    }
+
+    @Override
+    public Asdu generateBack() {
+        D5000Asdu asdu=new D5000Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.setCommonAddress(1);
+        return asdu;
+    }
+
+}

+ 109 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000/d5000dataframe/send/UploadDataType.java

@@ -0,0 +1,109 @@
+package com.jiayue.ipfcst.d5000.d5000dataframe.send;
+
+
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.D5000framestructure.D5000Asdu;
+import com.jiayue.ipfcst.d5000.D5000information.D5000DataInfo;
+import lombok.Data;
+import org.joda.time.DateTime;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.SimpleDataFrameType;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeShortFloat;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.exception.Iec104Exception;
+import wei.yigulu.iec104.asdudataframe.typemodel.IeFourByteInteger;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * D5000 新增报文类型 -上传数据
+ * 类型标识为141,本报文为从站向主站发送的报文。因为数据的长度不固定,
+ * 所以长度和可变结构限定词根据数据的长度变化。数据部分包括上传数据的用户和密码,
+ * 数据的日期,数据的ID和数据值。上报报文信息对象地址与含义对应关系如下:
+ * 信息地址---数据意义---数据类型---日期---数据长度
+ * 0XFFE001---短期风功率预测上报---float---yyyy-MM-dd---96点
+ * 0XFFD001---项目运行状态上报---float---yyyy-MM-dd---4点
+ * 0XFFC001---样板机功率上报---float---yyyy-MM-dd---96点
+ * 0XFFB001---日预测运行容量---float---yyyy-MM-dd---96点
+ *
+ * @author 修唯xiuwei
+ * @create 2019-04-08 下午11:49
+ * @Email 524710549@qq.com
+ **/
+@AsduType
+@Data
+public class UploadDataType extends SimpleDataFrameType {
+
+
+    public UploadDataType (DateTime date, String  ids, D5000DataInfo dataInfo, List data) throws Iec104Exception {
+        this.address=new InformationBodyAddress(dataInfo.getAddress());
+        if(dataInfo.getDateFormat()== D5000DataInfo.DateFormat.YMD){
+            this.year=date.getYear();
+            this.month=date.getMonthOfYear();
+            this.day=date.getDayOfMonth();
+        }else{
+            this.year=date.getYear();
+            this.month=0;
+            this.day=0;
+        }
+        D5000Utils.stringAdd2ByteArray(ids,this.dataId);
+        this.data=data;
+    }
+
+
+    public static final int TYPEID = 141;
+
+    InformationBodyAddress address ;
+
+    byte[] userName=new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
+            (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
+
+    byte[] password=new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
+            (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
+
+    int year;
+
+    int month;
+
+    int day;
+
+    byte[]  dataId=new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
+            (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
+            (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
+            (byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
+
+    List data=new ArrayList();
+
+
+    @Override
+    public void encode(List<Byte> buffer) {
+        address.encode(buffer);
+        D5000Utils.appendByteList(buffer,userName);
+        D5000Utils.appendByteList(buffer,password);
+        buffer.add((byte) year);
+        buffer.add((byte) ( year>>8));
+        buffer.add((byte) (month&0xff));
+        buffer.add((byte) (day&0xff));
+        D5000Utils.appendByteList(buffer,dataId);
+        for(Object o :data){
+            if(o instanceof  Integer){
+                new IeFourByteInteger(((Integer)o).longValue()).encode(buffer);
+            }else if(o instanceof  Float){
+                new IeShortFloat((Float)o).encode(buffer);
+            }
+        }
+    }
+
+    @Override
+    public Asdu generateBack() {
+        D5000Asdu asdu=new D5000Asdu();
+        asdu.setTypeId(TYPEID);
+        asdu.setDataFrame(this);
+        asdu.setCommonAddress(1);
+        asdu.setNot(6);
+        return asdu;
+    }
+}
+
+

+ 17 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/D5000WebApplication.java

@@ -0,0 +1,17 @@
+package com.jiayue.ipfcst.d5000web;
+
+import org.apache.ftpserver.usermanager.impl.BaseUser;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @author xiuwei
+ */
+@MapperScan("com.jiayue.ipfcst.d5000web.mapper")
+@SpringBootApplication
+public class D5000WebApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(D5000WebApplication.class, args);
+    }
+}

+ 25 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/JarPathUtil.java

@@ -0,0 +1,25 @@
+package com.jiayue.ipfcst.d5000web;
+
+/**
+ * 获取jar包路径的工具
+ *
+ * @author: xiuwei
+ * @version:
+ */
+public class JarPathUtil {
+
+	public static String getPath() {
+		String path = JarPathUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+		if (System.getProperty("os.name").contains("dows")) {
+			path=path.replaceFirst("file:","");
+			path = path.substring(1, path.length());
+		}
+		if (path.contains("jar")) {
+			path=path.replaceFirst("file:","");
+			path = path.substring(0, path.lastIndexOf("."));
+			return path.substring(0, path.lastIndexOf("/"));
+		}
+
+		return path.replace("target/classes/", "");
+	}
+}

+ 20 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/CollectedDailyPower.java

@@ -0,0 +1,20 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 采集到的日功率
+ * @author: xiuwei
+ * @create: 2020-04-09 18:50
+ */
+@Data
+public class CollectedDailyPower  extends DailyPower {
+
+    Integer id;
+
+    String updateDate;
+
+    Boolean isManual=false;
+
+}

+ 426 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/DailyPower.java

@@ -0,0 +1,426 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 每日的功率
+ * @author: xiuwei
+ * @create: 2020-04-09 16:00
+ */
+@Data
+public class DailyPower {
+
+    String date;
+
+    Double p1;
+    Double p2;
+    Double p3;
+    Double p4;
+    Double p5;
+    Double p6;
+    Double p7;
+    Double p8;
+    Double p9;
+    Double p10;
+    Double p11;
+    Double p12;
+    Double p13;
+    Double p14;
+    Double p15;
+    Double p16;
+    Double p17;
+    Double p18;
+    Double p19;
+    Double p20;
+    Double p21;
+    Double p22;
+    Double p23;
+    Double p24;
+    Double p25;
+    Double p26;
+    Double p27;
+    Double p28;
+    Double p29;
+    Double p30;
+    Double p31;
+    Double p32;
+    Double p33;
+    Double p34;
+    Double p35;
+    Double p36;
+    Double p37;
+    Double p38;
+    Double p39;
+    Double p40;
+    Double p41;
+    Double p42;
+    Double p43;
+    Double p44;
+    Double p45;
+    Double p46;
+    Double p47;
+    Double p48;
+    Double p49;
+    Double p50;
+    Double p51;
+    Double p52;
+    Double p53;
+    Double p54;
+    Double p55;
+    Double p56;
+    Double p57;
+    Double p58;
+    Double p59;
+    Double p60;
+    Double p61;
+    Double p62;
+    Double p63;
+    Double p64;
+    Double p65;
+    Double p66;
+    Double p67;
+    Double p68;
+    Double p69;
+    Double p70;
+    Double p71;
+    Double p72;
+    Double p73;
+    Double p74;
+    Double p75;
+    Double p76;
+    Double p77;
+    Double p78;
+    Double p79;
+    Double p80;
+    Double p81;
+    Double p82;
+    Double p83;
+    Double p84;
+    Double p85;
+    Double p86;
+    Double p87;
+    Double p88;
+    Double p89;
+    Double p90;
+    Double p91;
+    Double p92;
+    Double p93;
+    Double p94;
+    Double p95;
+    Double p96;
+
+    public List<Float> convert2List(){
+        List list=new ArrayList();
+        list.add( p1.floatValue());
+        list.add( p2.floatValue());
+        list.add( p3.floatValue());
+        list.add( p4.floatValue());
+        list.add( p5.floatValue());
+        list.add( p6.floatValue());
+        list.add( p7.floatValue());
+        list.add( p8.floatValue());
+        list.add( p9.floatValue());
+        list.add( p10.floatValue());
+        list.add( p11.floatValue());
+        list.add( p12.floatValue());
+        list.add( p13.floatValue());
+        list.add( p14.floatValue());
+        list.add( p15.floatValue());
+        list.add( p16.floatValue());
+        list.add( p17.floatValue());
+        list.add( p18.floatValue());
+        list.add( p19.floatValue());
+        list.add( p20.floatValue());
+        list.add( p21.floatValue());
+        list.add( p22.floatValue());
+        list.add( p23.floatValue());
+        list.add( p24.floatValue());
+        list.add( p25.floatValue());
+        list.add( p26.floatValue());
+        list.add( p27.floatValue());
+        list.add( p28.floatValue());
+        list.add( p29.floatValue());
+        list.add( p30.floatValue());
+        list.add( p31.floatValue());
+        list.add( p32.floatValue());
+        list.add( p33.floatValue());
+        list.add( p34.floatValue());
+        list.add( p35.floatValue());
+        list.add( p36.floatValue());
+        list.add( p37.floatValue());
+        list.add( p38.floatValue());
+        list.add( p39.floatValue());
+        list.add( p40.floatValue());
+        list.add( p41.floatValue());
+        list.add( p42.floatValue());
+        list.add( p43.floatValue());
+        list.add( p44.floatValue());
+        list.add( p45.floatValue());
+        list.add( p46.floatValue());
+        list.add( p47.floatValue());
+        list.add( p48.floatValue());
+        list.add( p49.floatValue());
+        list.add( p50.floatValue());
+        list.add( p51.floatValue());
+        list.add( p52.floatValue());
+        list.add( p53.floatValue());
+        list.add( p54.floatValue());
+        list.add( p55.floatValue());
+        list.add( p56.floatValue());
+        list.add( p57.floatValue());
+        list.add( p58.floatValue());
+        list.add( p59.floatValue());
+        list.add( p60.floatValue());
+        list.add( p61.floatValue());
+        list.add( p62.floatValue());
+        list.add( p63.floatValue());
+        list.add( p64.floatValue());
+        list.add( p65.floatValue());
+        list.add( p66.floatValue());
+        list.add( p67.floatValue());
+        list.add( p68.floatValue());
+        list.add( p69.floatValue());
+        list.add( p70.floatValue());
+        list.add( p71.floatValue());
+        list.add( p72.floatValue());
+        list.add( p73.floatValue());
+        list.add( p74.floatValue());
+        list.add( p75.floatValue());
+        list.add( p76.floatValue());
+        list.add( p77.floatValue());
+        list.add( p78.floatValue());
+        list.add( p79.floatValue());
+        list.add( p80.floatValue());
+        list.add( p81.floatValue());
+        list.add( p82.floatValue());
+        list.add( p83.floatValue());
+        list.add( p84.floatValue());
+        list.add( p85.floatValue());
+        list.add( p86.floatValue());
+        list.add( p87.floatValue());
+        list.add( p88.floatValue());
+        list.add( p89.floatValue());
+        list.add( p90.floatValue());
+        list.add( p91.floatValue());
+        list.add( p92.floatValue());
+        list.add( p93.floatValue());
+        list.add( p94.floatValue());
+        list.add( p95.floatValue());
+        list.add( p96.floatValue());
+        return list;
+    }
+
+    public DailyPower setFormList(List<Double> Doubles){
+        if(Doubles.size()>=96){
+            this.p1=Doubles.get(0);
+            this.p2=Doubles.get(1);
+            this.p3=Doubles.get(2);
+            this.p4=Doubles.get(3);
+            this.p5=Doubles.get(4);
+            this.p6=Doubles.get(5);
+            this.p7=Doubles.get(6);
+            this.p8=Doubles.get(7);
+            this.p9=Doubles.get(8);
+            this.p10=Doubles.get(9);
+            this.p11=Doubles.get(10);
+            this.p12=Doubles.get(11);
+            this.p13=Doubles.get(12);
+            this.p14=Doubles.get(13);
+            this.p15=Doubles.get(14);
+            this.p16=Doubles.get(15);
+            this.p17=Doubles.get(16);
+            this.p18=Doubles.get(17);
+            this.p19=Doubles.get(18);
+            this.p20=Doubles.get(19);
+            this.p21=Doubles.get(20);
+            this.p22=Doubles.get(21);
+            this.p23=Doubles.get(22);
+            this.p24=Doubles.get(23);
+            this.p25=Doubles.get(24);
+            this.p26=Doubles.get(25);
+            this.p27=Doubles.get(26);
+            this.p28=Doubles.get(27);
+            this.p29=Doubles.get(28);
+            this.p30=Doubles.get(29);
+            this.p31=Doubles.get(30);
+            this.p32=Doubles.get(31);
+            this.p33=Doubles.get(32);
+            this.p34=Doubles.get(33);
+            this.p35=Doubles.get(34);
+            this.p36=Doubles.get(35);
+            this.p37=Doubles.get(36);
+            this.p38=Doubles.get(37);
+            this.p39=Doubles.get(38);
+            this.p40=Doubles.get(39);
+            this.p41=Doubles.get(40);
+            this.p42=Doubles.get(41);
+            this.p43=Doubles.get(42);
+            this.p44=Doubles.get(43);
+            this.p45=Doubles.get(44);
+            this.p46=Doubles.get(45);
+            this.p47=Doubles.get(46);
+            this.p48=Doubles.get(47);
+            this.p49=Doubles.get(48);
+            this.p50=Doubles.get(49);
+            this.p51=Doubles.get(50);
+            this.p52=Doubles.get(51);
+            this.p53=Doubles.get(52);
+            this.p54=Doubles.get(53);
+            this.p55=Doubles.get(54);
+            this.p56=Doubles.get(55);
+            this.p57=Doubles.get(56);
+            this.p58=Doubles.get(57);
+            this.p59=Doubles.get(58);
+            this.p60=Doubles.get(59);
+            this.p61=Doubles.get(60);
+            this.p62=Doubles.get(61);
+            this.p63=Doubles.get(62);
+            this.p64=Doubles.get(63);
+            this.p65=Doubles.get(64);
+            this.p66=Doubles.get(65);
+            this.p67=Doubles.get(66);
+            this.p68=Doubles.get(67);
+            this.p69=Doubles.get(68);
+            this.p70=Doubles.get(69);
+            this.p71=Doubles.get(70);
+            this.p72=Doubles.get(71);
+            this.p73=Doubles.get(72);
+            this.p74=Doubles.get(73);
+            this.p75=Doubles.get(74);
+            this.p76=Doubles.get(75);
+            this.p77=Doubles.get(76);
+            this.p78=Doubles.get(77);
+            this.p79=Doubles.get(78);
+            this.p80=Doubles.get(79);
+            this.p81=Doubles.get(80);
+            this.p82=Doubles.get(81);
+            this.p83=Doubles.get(82);
+            this.p84=Doubles.get(83);
+            this.p85=Doubles.get(84);
+            this.p86=Doubles.get(85);
+            this.p87=Doubles.get(86);
+            this.p88=Doubles.get(87);
+            this.p89=Doubles.get(88);
+            this.p90=Doubles.get(89);
+            this.p91=Doubles.get(90);
+            this.p92=Doubles.get(91);
+            this.p93=Doubles.get(92);
+            this.p94=Doubles.get(93);
+            this.p95=Doubles.get(94);
+            this.p96=Doubles.get(95);
+        }else{
+            throw new RuntimeException("List 内值数量小于96个");
+        }
+        return this;
+    }
+
+
+    public DailyPower setFormDailyPower(DailyPower dailyPower){
+        this.date=dailyPower.getDate();
+        this.p1=dailyPower.getP1();
+        this.p2=dailyPower.getP2();
+        this.p3=dailyPower.getP3();
+        this.p4=dailyPower.getP4();
+        this.p5=dailyPower.getP5();
+        this.p6=dailyPower.getP6();
+        this.p7=dailyPower.getP7();
+        this.p8=dailyPower.getP8();
+        this.p9=dailyPower.getP9();
+        this.p10=dailyPower.getP10();
+        this.p11=dailyPower.getP11();
+        this.p12=dailyPower.getP12();
+        this.p13=dailyPower.getP13();
+        this.p14=dailyPower.getP14();
+        this.p15=dailyPower.getP15();
+        this.p16=dailyPower.getP16();
+        this.p17=dailyPower.getP17();
+        this.p18=dailyPower.getP18();
+        this.p19=dailyPower.getP19();
+        this.p20=dailyPower.getP20();
+        this.p21=dailyPower.getP21();
+        this.p22=dailyPower.getP22();
+        this.p23=dailyPower.getP23();
+        this.p24=dailyPower.getP24();
+        this.p25=dailyPower.getP25();
+        this.p26=dailyPower.getP26();
+        this.p27=dailyPower.getP27();
+        this.p28=dailyPower.getP28();
+        this.p29=dailyPower.getP29();
+        this.p30=dailyPower.getP30();
+        this.p31=dailyPower.getP31();
+        this.p32=dailyPower.getP32();
+        this.p33=dailyPower.getP33();
+        this.p34=dailyPower.getP34();
+        this.p35=dailyPower.getP35();
+        this.p36=dailyPower.getP36();
+        this.p37=dailyPower.getP37();
+        this.p38=dailyPower.getP38();
+        this.p39=dailyPower.getP39();
+        this.p40=dailyPower.getP40();
+        this.p41=dailyPower.getP41();
+        this.p42=dailyPower.getP42();
+        this.p43=dailyPower.getP43();
+        this.p44=dailyPower.getP44();
+        this.p45=dailyPower.getP45();
+        this.p46=dailyPower.getP46();
+        this.p47=dailyPower.getP47();
+        this.p48=dailyPower.getP48();
+        this.p49=dailyPower.getP49();
+        this.p50=dailyPower.getP50();
+        this.p51=dailyPower.getP51();
+        this.p52=dailyPower.getP52();
+        this.p53=dailyPower.getP53();
+        this.p54=dailyPower.getP54();
+        this.p55=dailyPower.getP55();
+        this.p56=dailyPower.getP56();
+        this.p57=dailyPower.getP57();
+        this.p58=dailyPower.getP58();
+        this.p59=dailyPower.getP59();
+        this.p60=dailyPower.getP60();
+        this.p61=dailyPower.getP61();
+        this.p62=dailyPower.getP62();
+        this.p63=dailyPower.getP63();
+        this.p64=dailyPower.getP64();
+        this.p65=dailyPower.getP65();
+        this.p66=dailyPower.getP66();
+        this.p67=dailyPower.getP67();
+        this.p68=dailyPower.getP68();
+        this.p69=dailyPower.getP69();
+        this.p70=dailyPower.getP70();
+        this.p71=dailyPower.getP71();
+        this.p72=dailyPower.getP72();
+        this.p73=dailyPower.getP73();
+        this.p74=dailyPower.getP74();
+        this.p75=dailyPower.getP75();
+        this.p76=dailyPower.getP76();
+        this.p77=dailyPower.getP77();
+        this.p78=dailyPower.getP78();
+        this.p79=dailyPower.getP79();
+        this.p80=dailyPower.getP80();
+        this.p81=dailyPower.getP81();
+        this.p82=dailyPower.getP82();
+        this.p83=dailyPower.getP83();
+        this.p84=dailyPower.getP84();
+        this.p85=dailyPower.getP85();
+        this.p86=dailyPower.getP86();
+        this.p87=dailyPower.getP87();
+        this.p88=dailyPower.getP88();
+        this.p89=dailyPower.getP89();
+        this.p90=dailyPower.getP90();
+        this.p91=dailyPower.getP91();
+        this.p92=dailyPower.getP92();
+        this.p93=dailyPower.getP93();
+        this.p94=dailyPower.getP94();
+        this.p95=dailyPower.getP95();
+        this.p96=dailyPower.getP96();
+        return this;
+    }
+
+
+
+
+}

+ 26 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/FailedDualRequest.java

@@ -0,0 +1,26 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 同步请求失败记录
+ * @author: xiuwei
+ * @create: 2020-04-22 16:39
+ */
+@Data
+public class FailedDualRequest {
+
+    Integer id;
+
+    Integer requestType;
+
+    String requestUrl;
+
+    String requestJson;
+
+    Long insertTime;
+
+    Boolean isRead;
+
+}

+ 59 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/Gather104TCPChannel.java

@@ -0,0 +1,59 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 104采集通道信息
+ * @author: tangle
+ * @create: 2023-02-06 14:05
+ */
+@Data
+public class Gather104TCPChannel {
+
+
+    Integer id;
+
+    /**
+     * 通道编号
+     */
+    private Integer cid;
+
+    /**
+     * 通道名称
+     */
+    private String channelName;
+
+
+    /**
+     * 远端ip
+     */
+    private String remoteIp;
+
+
+    /**
+     * 远端端口
+     */
+    private Integer remotePort;
+
+
+    /**
+     * 远端备用端口
+     */
+    private Integer remoteSparePort;
+
+    /**
+     * 本地ip
+     */
+    private String localIp;
+
+    /**
+     * 本地端口
+     */
+    private Integer localPort;
+
+    /**
+     * 公共地址位
+     */
+    private Integer publicAddress = 1;
+}

+ 119 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/OperatingCapacity.java

@@ -0,0 +1,119 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @program: d5000-web
+ * @description: 预测运行容量
+ * @author: xiuwei
+ * @create: 2020-04-09 14:46
+ */
+@Data
+@NoArgsConstructor
+public class OperatingCapacity extends DailyPower {
+
+    public OperatingCapacity(Double capacity){
+        this.p1=capacity;
+        this.p2=capacity;
+        this.p3=capacity;
+        this.p4=capacity;
+        this.p5=capacity;
+        this.p6=capacity;
+        this.p7=capacity;
+        this.p8=capacity;
+        this.p9=capacity;
+        this.p10=capacity;
+        this.p11=capacity;
+        this.p12=capacity;
+        this.p13=capacity;
+        this.p14=capacity;
+        this.p15=capacity;
+        this.p16=capacity;
+        this.p17=capacity;
+        this.p18=capacity;
+        this.p19=capacity;
+        this.p20=capacity;
+        this.p21=capacity;
+        this.p22=capacity;
+        this.p23=capacity;
+        this.p24=capacity;
+        this.p25=capacity;
+        this.p26=capacity;
+        this.p27=capacity;
+        this.p28=capacity;
+        this.p29=capacity;
+        this.p30=capacity;
+        this.p31=capacity;
+        this.p32=capacity;
+        this.p33=capacity;
+        this.p34=capacity;
+        this.p35=capacity;
+        this.p36=capacity;
+        this.p37=capacity;
+        this.p38=capacity;
+        this.p39=capacity;
+        this.p40=capacity;
+        this.p41=capacity;
+        this.p42=capacity;
+        this.p43=capacity;
+        this.p44=capacity;
+        this.p45=capacity;
+        this.p46=capacity;
+        this.p47=capacity;
+        this.p48=capacity;
+        this.p49=capacity;
+        this.p50=capacity;
+        this.p51=capacity;
+        this.p52=capacity;
+        this.p53=capacity;
+        this.p54=capacity;
+        this.p55=capacity;
+        this.p56=capacity;
+        this.p57=capacity;
+        this.p58=capacity;
+        this.p59=capacity;
+        this.p60=capacity;
+        this.p61=capacity;
+        this.p62=capacity;
+        this.p63=capacity;
+        this.p64=capacity;
+        this.p65=capacity;
+        this.p66=capacity;
+        this.p67=capacity;
+        this.p68=capacity;
+        this.p69=capacity;
+        this.p70=capacity;
+        this.p71=capacity;
+        this.p72=capacity;
+        this.p73=capacity;
+        this.p74=capacity;
+        this.p75=capacity;
+        this.p76=capacity;
+        this.p77=capacity;
+        this.p78=capacity;
+        this.p79=capacity;
+        this.p80=capacity;
+        this.p81=capacity;
+        this.p82=capacity;
+        this.p83=capacity;
+        this.p84=capacity;
+        this.p85=capacity;
+        this.p86=capacity;
+        this.p87=capacity;
+        this.p88=capacity;
+        this.p89=capacity;
+        this.p90=capacity;
+        this.p91=capacity;
+        this.p92=capacity;
+        this.p93=capacity;
+        this.p94=capacity;
+        this.p95=capacity;
+        this.p96=capacity;
+    }
+
+    Integer id;
+
+    Long updateTime;
+
+}

+ 64 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/OperationStatus.java

@@ -0,0 +1,64 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 项目运行状态
+ * @author: xiuwei
+ * @create: 2020-04-16 13:15
+ */
+@Data
+public class OperationStatus {
+
+
+    Integer id;
+
+    String name;
+
+    /**
+     * 关联D5000的ID
+     */
+    String did;
+
+    /**
+     * 并网容量
+     */
+    Double gridConnCapacity;
+
+    /**
+     * 运行容量
+     */
+    Double operatingCapacity;
+
+    /**
+     * 检修容量
+     */
+    Double maintenanceCapacity;
+
+
+    /**
+     * 运行机组台数
+     */
+    Integer operatingUnitsNum;
+
+
+    /**
+     * 最后的修改时间
+     */
+    Long updateTime;
+
+
+   public List<Float> covert2List(){
+       List<Float> floats=new ArrayList<>();
+       floats.add(this.getGridConnCapacity().floatValue());
+       floats.add(this.getMaintenanceCapacity().floatValue());
+       floats.add(this.getOperatingCapacity().floatValue());
+       floats.add(this.getOperatingUnitsNum().floatValue());
+       return floats;
+   }
+
+}

+ 27 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/SampleDailyPower.java

@@ -0,0 +1,27 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机功率
+ * @author: xiuwei
+ * @create: 2020-04-14 19:31
+ */
+@Data
+public class SampleDailyPower extends DailyPower {
+
+    Integer id;
+
+    String uploadDate;
+
+    String sampleId;
+
+    String updateTime;
+
+    /**
+     * 是否是系统自动灌入
+     */
+    String isAuto;
+
+}

+ 24 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/SampleInfo.java

@@ -0,0 +1,24 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机信息
+ * @author: xiuwei
+ * @create: 2020-04-15 18:52
+ */
+@Data
+public class SampleInfo {
+
+    Integer id;
+    String name;
+    String did;
+
+    Integer channelId;
+
+    Integer point;
+
+    Double multiplier;
+
+}

+ 18 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedDailyPower.java

@@ -0,0 +1,18 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 上传过的日功率
+ * @author: xiuwei
+ * @create: 2020-04-09 18:51
+ */
+@Data
+public class UploadedDailyPower extends CollectedDailyPower {
+
+    String uploadDate;
+
+
+
+}

+ 16 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedOperatingCapacity.java

@@ -0,0 +1,16 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 上传过的运行容量
+ * @author: xiuwei
+ * @create: 2020-04-16 16:24
+ */
+@Data
+public class UploadedOperatingCapacity extends OperatingCapacity {
+
+    String uploadDate;
+
+}

+ 15 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UploadedOperationStatus.java

@@ -0,0 +1,15 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 上传过的项目运行状态
+ * @author: xiuwei
+ * @create: 2020-04-16 16:25
+ */
+@Data
+public class UploadedOperationStatus extends OperationStatus {
+
+    String uploadDate;
+}

+ 19 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/bean/UsernameAndPassword.java

@@ -0,0 +1,19 @@
+package com.jiayue.ipfcst.d5000web.bean;
+
+import lombok.Data;
+
+/**
+ * @program: d5000-web
+ * @description: 用户名密码
+ * @author: xiuwei
+ * @create: 2020-04-13 09:01
+ */
+@Data
+public class UsernameAndPassword {
+
+    String username;
+
+    String password;
+
+
+}

+ 65 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/D5000CommConfigBean.java

@@ -0,0 +1,65 @@
+package com.jiayue.ipfcst.d5000web.config;
+
+import com.jiayue.ipfcst.d5000.D5000Iec104SlaverBuilder;
+import com.jiayue.ipfcst.d5000.MasterRequestSocket;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.util.StringUtils;
+
+/**
+ * @program: d5000-web
+ * @description: 返回配置类
+ * @author: xiuwei
+ * @create: 2020-04-10 18:45
+ */
+@Configuration
+@ConfigurationProperties(prefix = "d5000")
+@Data
+public class D5000CommConfigBean {
+
+    private String username;
+
+    private String password;
+    private String masterIp;
+    private String masterSpareIp;
+    private Integer masterPort;
+    private String selfIp;
+    private String selfPortRange;
+    private Integer selfServerPort;
+    private String filePath;
+
+
+    @Bean
+    public MasterRequestSocket getMasterRequestSocket() {
+        MasterRequestSocket masterRequestSocket = MasterRequestSocket.getInstance();
+        if (!StringUtils.isEmpty(this.masterIp)) {
+            masterRequestSocket.setMasterIp(this.masterIp);
+        }
+        if (!StringUtils.isEmpty(this.masterSpareIp)) {
+            masterRequestSocket.setMasterSpareIp(this.masterSpareIp);
+        }
+        if (this.masterPort != null) {
+            masterRequestSocket.setMasterPort(this.masterPort);
+        }
+        if (!StringUtils.isEmpty(this.selfIp)) {
+            masterRequestSocket.setSelfIp(this.selfIp);
+        }
+        if (!StringUtils.isEmpty(this.selfPortRange)) {
+            masterRequestSocket.setSelfPortRange(this.selfPortRange);
+        }
+        if (this.selfServerPort != null) {
+            masterRequestSocket.setSelfServerPort(this.selfServerPort);
+        }
+        new Thread(() -> {
+            try {
+                new D5000Iec104SlaverBuilder(getSelfServerPort()).create();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }).start();
+        return masterRequestSocket;
+    }
+
+}

+ 50 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/GatherConfigBean.java

@@ -0,0 +1,50 @@
+package com.jiayue.ipfcst.d5000web.config;
+
+import com.jiayue.ipfcst.d5000.D5000Iec104SlaverBuilder;
+import com.jiayue.ipfcst.d5000.MasterRequestSocket;
+import com.jiayue.ipfcst.d5000web.service.Gather104TcpChannelService;
+import com.jiayue.ipfcst.gather.Gather104tcpClient;
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.util.StringUtils;
+import wei.yigulu.iec104.nettyconfig.Iec104HSMasterBuilder;
+
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+
+/**
+ * @program: d5000-web
+ * @description: 返回配置类
+ * @author: xiuwei
+ * @create: 2020-04-10 18:45
+ */
+@Configuration
+@EnableScheduling
+@Data
+public class GatherConfigBean {
+
+
+    @Bean
+    public void initGather() {
+        try {
+            Gather104tcpClient.getInstance().run();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Scheduled(fixedDelay = 60000l)
+    public void qq() {
+        Gather104tcpClient.getInstance().pbSendTotalSummonFrame();
+    }
+
+
+
+
+
+}

+ 60 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/config/SpringContextUtil.java

@@ -0,0 +1,60 @@
+package com.jiayue.ipfcst.d5000web.config;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+
+/**
+ * spring管理环境中获取bean
+ *
+ * @author yangzz
+ */
+@Service("springContextUtil")
+public class SpringContextUtil implements ApplicationContextAware
+{
+    // Spring应用上下文环境
+    private static ApplicationContext applicationContext;
+
+    /**
+     * 实现ApplicationContextAware接口的回调方法,设置上下文环境
+     *
+     * @param applicationContext
+     */
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext)
+    {
+        SpringContextUtil.applicationContext = applicationContext;
+    }
+
+    /**
+     * @return ApplicationContext
+     */
+    public static ApplicationContext getApplicationContext()
+    {
+        return applicationContext;
+    }
+
+    /**
+     * 获取对象
+     *
+     * @param name
+     * @return Object
+     * @throws BeansException
+     */
+    public static Object getBean(String name) throws BeansException
+    {
+        return applicationContext.getBean(name);
+    }
+
+    /**
+     * 通过class获取Bean.
+     *
+     * @param clazz
+     * @param <T>
+     * @return
+     */
+    public static <T> T getBean(Class<T> clazz) {
+        return getApplicationContext().getBean(clazz);
+    }
+}

+ 134 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/DownloadAndUploadExcelController.java

@@ -0,0 +1,134 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.io.resource.ClassPathResource;
+import com.jiayue.ipfcst.d5000.D5000Exception;
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import jxl.Sheet;
+import jxl.Workbook;
+import jxl.read.biff.BiffException;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 上传和下载Excel文件的接口
+ * @author: xiuwei
+ * @create: 2020-04-15 08:55
+ */
+@Controller
+@RequestMapping("/file")
+public class DownloadAndUploadExcelController {
+
+
+    @GetMapping("getSampleModel")
+    public void downSampleModel(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        download(request,response,"样板机模版");
+    }
+
+    @GetMapping("getShortPowerModel")
+    public void downShortPowerModel(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        download(request,response,"短期预测数据模版");
+    }
+
+    @GetMapping("getOperatingCapacityModel")
+    public void downOperatingCapacityModel(HttpServletRequest request, HttpServletResponse response) throws IOException {
+        download(request,response,"预测运行容量模版");
+    }
+
+    @PostMapping(value = "/uploadShortPowerModel")
+    @ResponseBody
+    public ResultBean UploadShortPowerModel(@RequestParam("date") String date, @RequestParam("file") MultipartFile file) throws Exception {
+        List<Double> list = parseUploadFile(file);
+        CollectedDailyPower collectedDailyPower=new CollectedDailyPower();
+        collectedDailyPower.setFormList(list);
+        collectedDailyPower.setDate(date);
+        collectedDailyPower.setUpdateDate(DateTime.now().toString("yyyy-MM-dd"));
+        collectedDailyPower.setIsManual(true);
+        return new ResultBean(collectedDailyPower);
+    }
+
+    @PostMapping(value = "/uploadSampleModel")
+    @ResponseBody
+    public ResultBean UploadSampleModel(@RequestParam("date") String date,@RequestParam("sampleId") String sampleId,@RequestParam("file") MultipartFile file) throws Exception {
+        List<Double> list = parseUploadFile(file);
+        SampleDailyPower sampleDailyPower=new SampleDailyPower();
+        sampleDailyPower.setFormList(list);
+        sampleDailyPower.setDate(date);
+        sampleDailyPower.setSampleId(sampleId);
+        return new ResultBean(sampleDailyPower);
+    }
+
+    @PostMapping(value = "/uploadOperatingCapacityModel")
+    @ResponseBody
+    public ResultBean UploadOperatingCapacityModel(@RequestParam("file") MultipartFile file) throws Exception {
+        return new ResultBean();
+    }
+
+
+
+
+    public void download( HttpServletRequest request, HttpServletResponse response,String fileName) throws IOException {
+        response.setCharacterEncoding(request.getCharacterEncoding());
+        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
+        response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''"+ URLEncoder.encode(fileName+".xls","UTF-8"));
+        response.setHeader("Pragma", "no-cache");
+        response.setHeader("Cache-Control", "no-cache");
+        response.setDateHeader("Expires", 0);
+        FileInputStream fis = null;
+        try {
+            ClassPathResource classPathResource = new ClassPathResource("static/model/powerModel.xls");
+            InputStream inputStream = classPathResource.getStream();
+            try {
+                IOUtils.copy(inputStream, response.getOutputStream());
+                response.flushBuffer();
+            } finally {
+                IOUtils.closeQuietly(inputStream);
+            }
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+
+    public List<Double> parseUploadFile(MultipartFile file) throws IOException, BiffException, D5000Exception {
+        List<Double> doubles=new ArrayList<>();
+        InputStream is = file.getInputStream();
+        Workbook wb = Workbook.getWorkbook(is);
+        Sheet sheet = wb.getSheet(0);
+        for (int i = 1; i <=96; i++) {
+            try {
+                doubles.add(Double.parseDouble(sheet.getCell(1, i).getContents()));
+            }catch (Exception e){
+                throw  new D5000Exception(101,"第"+(i+1)+"行功率填写错误");
+            }
+        }
+        return  doubles;
+    }
+
+
+}

+ 37 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/FailedDualRequestController.java

@@ -0,0 +1,37 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.FailedDualRequest;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.FailedDualRequestService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 备机请求失败的记录
+ * @author: xiuwei
+ * @create: 2020-04-22 18:40
+ */
+@Controller
+@RequestMapping("/failedDualRequest")
+public class FailedDualRequestController {
+
+    @Autowired
+    FailedDualRequestService failedDualRequestService;
+
+    @GetMapping("")
+    @ResponseBody
+    public ResultBean getNotHandled(){
+        List<FailedDualRequest> list = failedDualRequestService.getNotHandled();
+        for(FailedDualRequest  f:list){
+            failedDualRequestService.toBeRead(f.getId());
+        }
+        return new ResultBean(list);
+    }
+
+}

+ 58 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/Gather104TcpChannelController.java

@@ -0,0 +1,58 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.Gather104TCPChannel;
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.Gather104TcpChannelService;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import com.jiayue.ipfcst.d5000web.service.SampleInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机信息对外接口
+ * @author: xiuwei
+ * @create: 2020-04-15 19:29
+ */
+@Controller
+@RequestMapping("")
+public class Gather104TcpChannelController {
+
+    @Autowired
+    Gather104TcpChannelService gather104TcpChannelService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @GetMapping("gather104TCPChannel")
+    @ResponseBody
+    public ResultBean get() {
+        return new ResultBean(gather104TcpChannelService.get());
+    }
+    @PostMapping("gather104TCPChannel")
+    @ResponseBody
+    public ResultBean add(Gather104TCPChannel gather104TCPChannel) {
+        return new ResultBean(gather104TcpChannelService.add(gather104TCPChannel));
+    }
+    @DeleteMapping("gather104TCPChannel")
+    @ResponseBody
+    public  ResultBean delete(Gather104TCPChannel gather104TCPChannel) {
+
+        return new ResultBean(gather104TcpChannelService.delete(gather104TCPChannel.getId()));
+    }
+
+    @PutMapping("gather104TCPChannel")
+    @ResponseBody
+    public ResultBean update(Gather104TCPChannel gather104TCPChannel) {
+        if(gather104TCPChannel.getId()!=null) {
+            return new ResultBean(gather104TcpChannelService.update(gather104TCPChannel));
+        }else{
+            return new ResultBean(gather104TcpChannelService.add(gather104TCPChannel));
+        }
+    }
+
+
+
+}

+ 168 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/JumpPageController.java

@@ -0,0 +1,168 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.web.bind.annotation.GetMapping;
+
+/**
+ * 文件上传状态的页面跳转  首页
+ *
+ * @author 修唯xiuwei
+ * @create 2020-04-08 18:03
+ * @Email 524710549@qq.com
+ **/
+@Controller
+public class JumpPageController {
+
+    @Value("${dual.isDual: false}")
+    Boolean isDual;
+    @Value("${powerStationType: 1}")
+    Integer powerStationType;
+
+    @Value("${uploadShortForecastDays: 10}")
+    Integer uploadShortForecastDays = 7;
+
+    @GetMapping("")
+    public String jumpIndex(Model model) {
+        model.addAttribute("powerStationType",powerStationType);
+        return "index";
+    }
+
+    @GetMapping("uploadStatus")
+    public String jumpUploadStatus(Model model) {
+        model.addAttribute("isDual",isDual);
+        model.addAttribute("isDual",isDual);
+        model.addAttribute("uploadShortForecastDays",uploadShortForecastDays);
+        return "uploadStatus";
+    }
+
+
+    @GetMapping("queryActualPower")
+    public String jumpDailyPower(Model model) {
+        model.addAttribute("surl", "actualPower");
+        model.addAttribute("title", "实际功率");
+        model.addAttribute("isSample", false);
+        return "queryDailyPower";
+    }
+
+
+    @GetMapping("querySample")
+    public String jumpSample(Model model) {
+        model.addAttribute("surl", "samplePower");
+        model.addAttribute("title", "样板机功率");
+        model.addAttribute("isSample", true);
+        return "queryDailyPower";
+    }
+
+    @GetMapping("queryShort")
+    public String jumpShort(Model model) {
+        model.addAttribute("surl", "shortForecastPower");
+        model.addAttribute("title", "短期预测");
+        model.addAttribute("isSample", false);
+        return "queryDailyPower";
+    }
+
+    @GetMapping("uploadShort")
+    public String jumpUploadShort(Model model) {
+        model.addAttribute("isSample", false);
+        model.addAttribute("type", "短期");
+        model.addAttribute("downloadFileUrl","getShortPowerModel");
+        model.addAttribute("url","shortForecastPower");
+        return "uploadPower";
+    }
+
+    @GetMapping("uploadSample")
+    public String jumpUploadSample(Model model) {
+        model.addAttribute("isSample", true);
+        model.addAttribute("type", "样板机");
+        model.addAttribute("downloadFileUrl","getSampleModel");
+        model.addAttribute("url","sample");
+        return "uploadPower";
+    }
+
+
+    /**
+     * 日弃风排序页面
+     * @param model
+     * @return
+     */
+    @GetMapping("dailyAbandonSort")
+    public String jumpDailyAbandonSort(Model model) {
+        model.addAttribute("title", "日弃电排序");
+        model.addAttribute("surl","dailyAbandonSort");
+        return "d1page";
+    }
+
+    /**
+     * 日弃风比率页面
+     * @param model
+     * @return
+     */
+    @GetMapping("dailyAbandonRatio")
+    public String jumpDailyAbandonRatio(Model model) {
+        model.addAttribute("title", "日弃电率");
+        model.addAttribute("surl","dailyAbandonRatio");
+        return "d1page";
+    }
+
+
+    /**
+     * 日弃风排序页面
+     * @param model
+     * @return
+     */
+    @GetMapping("yearAbandonSort")
+    public String jumpYearAbandonSort(Model model) {
+        model.addAttribute("title", "年弃电排序");
+        model.addAttribute("surl","yearAbandonSort");
+        return "d365page";
+    }
+
+    /**
+     * 日弃风比率页面
+     * @param model
+     * @return
+     */
+    @GetMapping("yearAbandonRatio")
+    public String jumpYearAbandonRatio(Model model) {
+        model.addAttribute("title", "年弃电率");
+        model.addAttribute("surl","yearAbandonRatio");
+        return "d365page";
+    }
+
+
+
+    @GetMapping("dailyThreeRate")
+    public String jumpDailyThreeRate(Model model) {
+        return "dailyThreeRate";
+    }
+
+    @GetMapping("yearThreeRate")
+    public String jumpYearThreeRate(Model model) {
+        return "yearThreeRate";
+    }
+
+    @GetMapping("configOperationStatus")
+    public String jumpConfigOperationStatus(Model model) {
+        return "configOperationStatus";
+    }
+
+    @GetMapping("queryOperationStatus")
+    public String jumpQueryOperationStatus(Model model) {
+        return "queryOperationStatus";
+    }
+
+    @GetMapping("configSample")
+    public String jumpConfigSample(Model model) {
+        return "configSample";
+    }
+
+
+    @GetMapping("channelInfo")
+    public String jumpChannelInfo(Model model) {
+        return "channelInfo";
+    }
+
+
+}

+ 61 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/OperationStatusController.java

@@ -0,0 +1,61 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.OperationStatus;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.OperationStatusService;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: d5000-web
+ * @description: 项目运行状态对外接口
+ * @author: xiuwei
+ * @create: 2020-04-16 13:55
+ */
+@Controller
+@RequestMapping("/operationStatus")
+public class OperationStatusController {
+
+
+
+    @Autowired
+    OperationStatusService operationStatusService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @GetMapping("")
+    @ResponseBody
+    public ResultBean get(OperationStatus operationStatus) {
+        return new ResultBean(operationStatusService.get(operationStatus));
+    }
+
+    @PutMapping("")
+    @ResponseBody
+    public ResultBean addOrUpdate(OperationStatus operationStatus, @RequestParam(value = "dual",required = false) Boolean dual) {
+        operationStatus.setUpdateTime(DateTime.now().getMillis());
+        if (dual == null || !dual) {
+            requestOtherService.put("/operationStatus?dual=true", operationStatus);
+        }
+        if (operationStatus.getId() == null) {
+            return new ResultBean(operationStatusService.add(operationStatus));
+        } else {
+            return new ResultBean(operationStatusService.update(operationStatus));
+        }
+    }
+
+
+    @DeleteMapping("")
+    @ResponseBody
+    public ResultBean delete(OperationStatus operationStatus,@RequestParam(value = "dual",required = false) Boolean dual) {
+        if (dual == null || !dual) {
+            requestOtherService.delete("/operationStatus?dual=true", operationStatus);
+        }
+        return new ResultBean(operationStatusService.delete(operationStatus));
+    }
+
+
+}

+ 279 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/QueryDataController.java

@@ -0,0 +1,279 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000.D5000information.D5000FixedValue;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.QueryDataService;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 查询数据相关操作
+ *
+ * @author 修唯xiuwei
+ * @create 2020-04-08 18:17
+ * @Email 524710549@qq.com
+ **/
+@Controller
+@RequestMapping("/query")
+public class QueryDataController {
+
+
+    @Autowired
+    QueryDataService queryDataService;
+
+    DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd");
+
+    DateTimeFormatter yearFormatter = DateTimeFormat.forPattern("yyyy");
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日实际功率
+     * @Date 2020/4/10 19:54
+     * @Param date
+     **/
+    @GetMapping("actualPower")
+    @ResponseBody
+    public ResultBean queryActualPower(String  date) throws Exception {
+        return  new ResultBean(queryDataService.queryActualPower(dateTimeFormatter.parseDateTime(date)));
+    }
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日申报功率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("shortForecastPower")
+    @ResponseBody
+    public ResultBean queryShortForecastPower(String date) throws Exception {
+        return  new ResultBean(queryDataService.queryShortForecastPower(dateTimeFormatter.parseDateTime(date)));
+    }
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日样板机功率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("samplePower")
+    @ResponseBody
+    public ResultBean querySamplePower(String date, String ids) throws Exception {
+        return  new ResultBean(queryDataService.querySamplePower(dateTimeFormatter.parseDateTime(date),ids));
+    }
+
+
+    /**
+     * @return List<Integer>
+     * @Author 修唯
+     * @Description 查询日考核指定的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("dayEvaluation")
+    @ResponseBody
+    public ResultBean queryDEvaluation(String date) throws Exception {
+        return   new ResultBean(queryDataService.queryDEvaluation(dateTimeFormatter.parseDateTime(date)));
+    }
+
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日准确率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("dayAccuracyRate")
+    @ResponseBody
+    public ResultBean queryDAccuracyRate(String date) throws Exception {
+        return   new ResultBean(queryDataService.queryDAccuracyRate(dateTimeFormatter.parseDateTime(date)));
+    }
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日合格率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("dayPassRate")
+    @ResponseBody
+    public ResultBean queryDPassRate(String date) throws Exception {
+        return   new ResultBean(queryDataService.queryDPassRate(dateTimeFormatter.parseDateTime(date)));
+    }
+
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询日传送率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("dayTransmissionRate")
+    @ResponseBody
+    public ResultBean queryDTransmissionRate(String date) throws Exception {
+
+        return   new ResultBean(queryDataService.queryDTransmissionRate(dateTimeFormatter.parseDateTime(date)));
+    }
+
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询年考核结果
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("yearEvaluation")
+    @ResponseBody
+    public ResultBean queryYEvaluation(String date) throws Exception {
+        DateTime dateTime = yearFormatter.parseDateTime(date);
+        List<Float> list = queryDataService.queryYEvaluation(dateTime);
+        return new ResultBean(divideByMonth(list, dateTime));
+    }
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询年准确率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("yearAccuracyRate")
+    @ResponseBody
+    public ResultBean queryYAccuracyRate(String date) throws Exception {
+        DateTime dateTime=yearFormatter.parseDateTime(date);
+        List<Float> list = queryDataService.queryYAccuracyRate(dateTime);
+        return   new ResultBean(divideByMonth(list,dateTime));
+    }
+
+    /**
+     * @return  ResultBean
+     * @Author 修唯
+     * @Description 查询年合格率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("yearPassRate")
+    @ResponseBody
+    public ResultBean queryYPassRate(String date) throws Exception {
+        DateTime dateTime=yearFormatter.parseDateTime(date);
+        List<Float> list = queryDataService.queryYPassRate(dateTime);
+        return  new ResultBean(divideByMonth(list,dateTime));
+    }
+
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询年传送率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("yearTransmissionRate")
+    @ResponseBody
+    public ResultBean queryYTransmissionRate(String date) throws Exception {
+        DateTime dateTime = yearFormatter.parseDateTime(date);
+        List<Float> list = queryDataService.queryYTransmissionRate(dateTime);
+        return new ResultBean(divideByMonth(list,dateTime));
+    }
+
+
+    /**
+     * @return ResultBean
+     * @Author 修唯
+     * @Description 查询项目运行状态
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    @GetMapping("operationStatus")
+    @ResponseBody
+    public ResultBean queryOperationStatus(String date,String ids) throws Exception {
+        return new ResultBean(queryDataService.queryOperationStatus(dateTimeFormatter.parseDateTime(date),ids));
+    }
+
+
+    /**
+     * 查询日弃风排序
+     * @return ResultBean
+     * @param date 查询日期
+     **/
+    @GetMapping("dailyAbandonSort")
+    @ResponseBody
+    public ResultBean queryDailyAbandonSort(String date) throws Exception {
+        return new ResultBean(queryDataService.queryNoIds(dateTimeFormatter.parseDateTime(date), D5000FixedValue.RQFPX));
+    }
+
+
+    /**
+     * 查询年弃风排序
+     * @return ResultBean
+     * @param date 查询日期
+     **/
+    @GetMapping("yearAbandonSort")
+    @ResponseBody
+    public ResultBean queryYearAbandonSort(String date) throws Exception {
+        DateTime dateTime = yearFormatter.parseDateTime(date);
+        List  list = queryDataService.queryNoIds(dateTime, D5000FixedValue.NQFPX);
+        return new ResultBean(divideByMonth(list,dateTime));
+    }
+
+
+
+    /**
+     * 查询日弃风比
+     * @return ResultBean
+     * @param date 查询日期
+     **/
+    @GetMapping("dailyAbandonRatio")
+    @ResponseBody
+    public ResultBean queryDailyAbandonRatio(String date) throws Exception {
+        return new ResultBean(queryDataService.queryNoIds(dateTimeFormatter.parseDateTime(date), D5000FixedValue.RQFFDB));
+    }
+
+
+    /**
+     * 查询年弃风比
+     * @return ResultBean
+     * @param date 查询日期
+     **/
+    @GetMapping("yearAbandonRatio")
+    @ResponseBody
+    public ResultBean queryYearAbandonRatio(String date) throws Exception {
+        DateTime dateTime = yearFormatter.parseDateTime(date);
+        List  list = queryDataService.queryNoIds(dateTime, D5000FixedValue.NQFFDB);
+        return new ResultBean(divideByMonth(list,dateTime));
+
+    }
+
+    /**
+     * 将一年的数据按月份划分
+     * @param list
+     * @return
+     */
+    private Map<Integer,List> divideByMonth(List  list,DateTime year){
+        Map<Integer, List> map = new HashMap<>();
+         for (int i = 1; i <= 12; i++) {
+            map.put(i, new ArrayList());
+        }
+        for (int i = 0; i < list.size(); i++) {
+            map.get(year.plusDays(i).getMonthOfYear()).add(list.get(i));
+        }
+        return map;
+    }
+
+}

+ 61 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/SampleInfoController.java

@@ -0,0 +1,61 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import com.jiayue.ipfcst.d5000web.service.SampleInfoService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机信息对外接口
+ * @author: xiuwei
+ * @create: 2020-04-15 19:29
+ */
+@Controller
+@RequestMapping("")
+public class SampleInfoController {
+
+    @Autowired
+    SampleInfoService sampleInfoService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @GetMapping("sampleInfo")
+    @ResponseBody
+    public ResultBean get(SampleInfo sampleInfo) {
+        return new ResultBean(sampleInfoService.get(sampleInfo));
+    }
+    @PostMapping("sampleInfo")
+    @ResponseBody
+    public ResultBean add(SampleInfo sampleInfo) {
+        return new ResultBean(sampleInfoService.add(sampleInfo));
+    }
+    @DeleteMapping("sampleInfo")
+    @ResponseBody
+    public  ResultBean delete(SampleInfo sampleInfo,@RequestParam(value = "dual",required = false) Boolean dual) {
+        if (dual == null || !dual) {
+            requestOtherService.delete("/sampleInfo?dual=true", sampleInfo);
+        }
+        return new ResultBean(sampleInfoService.delete(sampleInfo));
+    }
+
+    @PutMapping("sampleInfo")
+    @ResponseBody
+    public ResultBean update(SampleInfo sampleInfo,@RequestParam(value = "dual",required = false) Boolean dual) {
+        if (dual == null || !dual) {
+        requestOtherService.put("/sampleInfo?dual=true",sampleInfo);
+        }
+        if(sampleInfo.getId()!=null) {
+            return new ResultBean(sampleInfoService.update(sampleInfo));
+        }else{
+            return new ResultBean(sampleInfoService.add(sampleInfo));
+        }
+    }
+
+
+
+}

+ 49 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/SamplePowerController.java

@@ -0,0 +1,49 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import com.jiayue.ipfcst.d5000web.service.SampleDailyPowerService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机功率对外接口
+ * @author: xiuwei
+ * @create: 2020-04-15 16:49
+ */
+@Controller
+@RequestMapping("/sample")
+public class SamplePowerController {
+
+    @Autowired
+    SampleDailyPowerService sampleDailyPowerService;
+
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+
+    @PutMapping("")
+    @ResponseBody
+    public ResultBean addOrUpdate(SampleDailyPower sampleDailyPower, @RequestParam(value = "dual", required = false) Boolean dual) {
+        sampleDailyPower.setIsAuto("N");
+        sampleDailyPowerService.add(sampleDailyPower);
+        if (dual == null || !dual) {
+            requestOtherService.put("/sample?dual=true", sampleDailyPower);
+        }
+        return new ResultBean(sampleDailyPower);
+    }
+
+    ;
+
+    @GetMapping("")
+    @ResponseBody
+    public ResultBean get(SampleDailyPower sampleDailyPower) {
+        sampleDailyPower.setIsAuto("N");
+        return new ResultBean(sampleDailyPowerService.get(sampleDailyPower));
+    }
+
+}

+ 47 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/ShortForecastPowerController.java

@@ -0,0 +1,47 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.CollectedDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @program: d5000-web
+ * @description: 短期预测文件的接口
+ * @author: xiuwei
+ * @create: 2020-04-15 14:47
+ */
+@Controller
+@RequestMapping("/shortForecastPower")
+public class ShortForecastPowerController {
+
+    @Autowired
+    CollectedDailyPowerService collectedDailyPowerService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @PutMapping("")
+    @ResponseBody
+    public ResultBean saveOrUpdate(CollectedDailyPower collectedDailyPower, @RequestParam(value = "dual", required = false) Boolean dual) {
+        collectedDailyPower.setIsManual(true);
+        collectedDailyPower.setUpdateDate(DateTime.now().toString("yyyy-MM-dd"));
+        collectedDailyPowerService.add(collectedDailyPower);
+        if (dual == null || !dual) {
+            requestOtherService.put("/shortForecastPower?dual=true", collectedDailyPower);
+        }
+        return new ResultBean(collectedDailyPower);
+    }
+
+    @GetMapping("")
+    @ResponseBody
+    public ResultBean get(CollectedDailyPower collectedDailyPower) {
+        return new ResultBean(collectedDailyPowerService.get(collectedDailyPower));
+    }
+
+
+}

+ 48 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UploadDataController.java

@@ -0,0 +1,48 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.bean.OperatingCapacity;
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.Upload2D5000Service;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+/**
+ * @program: d5000-web
+ * @description: 将数据传输至D5000
+ * @author: xiuwei
+ * @create: 2020-04-20 14:02
+ */
+@Controller
+@RequestMapping("upload")
+public class UploadDataController {
+
+    @Autowired
+    Upload2D5000Service upload2D5000Service;
+
+    @PostMapping("/shortForecastPower")
+    @ResponseBody
+    public ResultBean shortForecast(CollectedDailyPower collectedDailyPower) throws Exception {
+        upload2D5000Service.uploadShortForecast(collectedDailyPower);
+        return new ResultBean();
+    }
+
+
+    @PostMapping("/sample")
+    @ResponseBody
+    public ResultBean sample(SampleDailyPower sampleDailyPower) throws Exception {
+        upload2D5000Service.uploadSamplePower(sampleDailyPower);
+        return new ResultBean();
+    }
+
+    @PostMapping("/operatingCapacity")
+    @ResponseBody
+    public ResultBean operatingCapacity(OperatingCapacity operatingCapacity) throws Exception {
+        upload2D5000Service.uploadOperatingCapacity(operatingCapacity);
+        return new ResultBean();
+    }
+}

+ 83 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UploadStatusController.java

@@ -0,0 +1,83 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000web.config.D5000CommConfigBean;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.CollectedStatusService;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import com.jiayue.ipfcst.d5000web.service.UploadStatusService;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 文件上传获取状态获取接口
+ *
+ * @author 修唯xiuwei
+ * @create 2020-04-08 18:23
+ * @Email 524710549@qq.com
+ **/
+@Controller
+public class UploadStatusController {
+
+    @Autowired
+    UploadStatusService uploadLocalStatus;
+    @Autowired
+    CollectedStatusService collectedStatusService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @Autowired
+    D5000CommConfigBean d5000CommConfigBean;
+
+
+    @ResponseBody
+    @GetMapping("localStatus")
+    public ResultBean getLocalStatus() {
+        Map<String, Map> map = new HashMap<>();
+        map.put("upload", uploadLocalStatus.uploadLocalStatus());
+        map.put("get", collectedStatusService.getLocalStatus());
+        return new ResultBean(map);
+    }
+
+
+    @ResponseBody
+    @GetMapping("serverTime")
+    public ResultBean getServerTime() {
+        Map<String, String> map = new HashMap<>();
+        map.put("time", DateTime.now().toString("yyyy-MM-dd HH:mm"));
+        return new ResultBean(map);
+    }
+
+    @ResponseBody
+    @GetMapping("otherStatus")
+    public ResultBean getOtherStatus() {
+        String re = requestOtherService.get("/localStatus");
+        Object object = JSON.parse(re);
+        if (re != null) {
+            return new ResultBean(object);
+        }
+        return new ResultBean();
+    }
+
+    @ResponseBody
+    @GetMapping("getQrCodeContent")
+    public ResultBean getQrCodeContent() {
+        Map<String, Object> content = new HashMap<>();
+        content.put("masterIp", d5000CommConfigBean.getMasterIp());
+        content.put("masterSpareIp", d5000CommConfigBean.getMasterSpareIp());
+        content.put("masterPort", d5000CommConfigBean.getMasterPort());
+        content.put("selfIp", d5000CommConfigBean.getSelfIp());
+        content.put("selfServerPort", d5000CommConfigBean.getSelfServerPort());
+        content.put("filePath", d5000CommConfigBean.getFilePath());
+        return new ResultBean(content);
+    }
+
+
+}

+ 51 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controller/UsernamePasswordController.java

@@ -0,0 +1,51 @@
+package com.jiayue.ipfcst.d5000web.controller;
+
+import com.jiayue.ipfcst.d5000.D5000Operation;
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.ChangePasswordType;
+import com.jiayue.ipfcst.d5000web.controllerutil.ResultBean;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import com.jiayue.ipfcst.d5000web.service.UsernamePasswordService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 用户名密码对外接口
+ * @author: xiuwei
+ * @create: 2020-04-15 18:32
+ */
+@Controller
+@RequestMapping("/usernamePassword")
+public class UsernamePasswordController {
+
+    @Autowired
+    UsernamePasswordService usernamePasswordService;
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @RequestMapping("/update")
+    @ResponseBody
+    public ResultBean update(String newPassword, @RequestParam(value = "dual", required = false) Boolean dual) throws Exception {
+        Map<String, Object> jsonObject = new HashMap<>();
+        jsonObject.put("newPassword", newPassword);
+        ChangePasswordType changePasswordType = new ChangePasswordType();
+        usernamePasswordService.setUserNameAndPassword(changePasswordType);
+        D5000Utils.stringAdd2ByteArray(newPassword, changePasswordType.getNewPassword());
+        D5000Operation.changePassword(changePasswordType);
+        usernamePasswordService.updatePassword(newPassword);
+        if (dual == null || !dual) {
+            requestOtherService.post("/usernamePassword/update?dual=true", jsonObject);
+        }
+        return new ResultBean();
+    }
+
+
+}

+ 103 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controllerutil/ControllerAOP.java

@@ -0,0 +1,103 @@
+package com.jiayue.ipfcst.d5000web.controllerutil;
+
+
+import com.alibaba.fastjson.JSON;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.Arrays;
+
+
+@Aspect
+@Component
+/**
+ *  该类为aop切面类,主要是对所有返回值为resultbean的方法进行入参监控,以及异常处理
+ * @author 修唯
+ * @creation 2017年11月27日
+ */
+public class ControllerAOP {
+    private static final Logger logger = LoggerFactory.getLogger(ControllerAOP.class);
+
+    @Pointcut("execution(public com.jiayue.ipfcst.d5000web.controllerutil.ResultBean *(..))")
+    public void webLog() {
+    }
+
+    @Around("webLog()")
+    /**
+     * 对返回值为resultbean的方法进行切面,获取其入参
+     * @param pjp
+     * @return
+     */
+    public Object handlerControllerMethod(ProceedingJoinPoint pjp) {
+
+        long startTime = System.currentTimeMillis();
+        ResultBean<?> result;
+        try {
+            result = (ResultBean<?>) pjp.proceed();
+            logger.info(pjp.getSignature() + "use time:" + (System.currentTimeMillis() - startTime));
+            // 接收到请求,记录请求内容
+            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
+                    .getRequestAttributes();
+            HttpServletRequest request = attributes.getRequest();
+            // 记录下请求内容
+            logger.info("URL : " + request.getRequestURL().toString());
+            logger.info("HTTP_METHOD : " + request.getMethod());
+            logger.info("IP : " + request.getRemoteAddr());
+            logger.info("CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName());
+            logger.info("ARGS : " + Arrays.toString(pjp.getArgs()));
+        } catch (Throwable e) {
+            result = handlerException(pjp, e);
+        }
+        return result;
+
+    }
+
+    @AfterReturning(returning = "ret", pointcut = "webLog()")
+    /**
+     * 对切面方法进行返回值处理
+     * @param ret
+     * @throws Throwable
+     */
+    public void doAfterReturning(Object ret) throws Throwable {
+        // 处理完请求,返回内容
+        logger.info("RESPONSE : " + JSON.toJSONString(ret));
+    }
+
+    @SuppressWarnings("rawtypes")
+    /**
+     * 对切面方法进行异常捕获处理
+     * @param pjp
+     * @param e
+     * @return
+     */
+    private ResultBean<?> handlerException(ProceedingJoinPoint pjp, Throwable e) {
+
+        ResultBean<?> result = new ResultBean();
+        // 已知异常
+        if (e instanceof IllegalStateException) {
+            result.setMsg(e.getLocalizedMessage() + "非法文件格式");
+            result.setCode(ResultBean.FAIL);
+        } else if (e instanceof IOException) {
+            result.setMsg(e.getLocalizedMessage() + "找不到文件夹");
+            result.setCode(ResultBean.FAIL);
+        } else {
+            logger.error(pjp.getSignature() + " 后台接口 exception ", e);
+            result.setMsg(pjp.getSignature() + e.toString());
+            result.setCode(ResultBean.FAIL);
+            // 未知异常是应该重点关注的,这里可以做其他操作,如通知邮件,单独写到某个文件等等。
+        }
+        return result;
+
+    }
+
+}

+ 58 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/controllerutil/ResultBean.java

@@ -0,0 +1,58 @@
+package com.jiayue.ipfcst.d5000web.controllerutil;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 统一返回值类
+ * @author 修唯
+ * @creation 2017年11月27日
+ */
+@Data
+public class ResultBean<T> implements Serializable{
+
+		private static final long serialVersionUID = 1L;
+
+		/**
+		 * 成功标识
+		 */
+		public static final int SUCCESS = 0;
+		/**
+		 * 失败标识
+		 */
+		public static final int FAIL = 1;
+		/**
+		 * 没有权限
+		 */
+		public static final int NO_PERMISSION = 2;
+		/**
+		 * 输出消息
+		 */
+		private String msg = "success";
+		/**
+		 * 输出状态
+		 */
+		private int code = SUCCESS;
+		/**
+		 * 输出JavaBean
+		 */
+		private T data;
+
+		public ResultBean() {
+			super();
+		}
+
+		public ResultBean(T data) {
+			super();
+			this.data = data;
+		}
+
+		public ResultBean(Throwable e) {
+			super();
+			this.msg = e.toString();
+			this.code = FAIL;
+		}
+
+
+}

+ 163 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/GetSampleFileDataJob.java

@@ -0,0 +1,163 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000web.JarPathUtil;
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.service.SampleDailyPowerService;
+import lombok.extern.slf4j.Slf4j;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.input.SAXBuilder;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * @program: d5000-web
+ * @description: 短期预测数据采集任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Slf4j
+@Component
+public class GetSampleFileDataJob implements Job {
+
+	private static final String JOBNAME = "GetSampleFileData";
+
+	@Value("${trigger.getSampleFileData:0 10/15 0,1 * * ? *}")
+	String triggerCron;
+
+	@Value("${d5000.filePath}")
+	String sampleFilePath;
+
+	Pattern expr = Pattern.compile("20[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])");
+
+	DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyyMMdd");
+
+
+	@Autowired
+	SampleDailyPowerService sampleDailyPowerService;
+
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+		log.info("开始执行获取样板机数据文件定时任务");
+		log.info("查找" + sampleFilePath + "文件夹下文件");
+		try {
+			SAXBuilder saxBuilder = new SAXBuilder();
+			File files = new File(sampleFilePath);
+			InputStream is;
+			Document document;
+			Element rootElement;
+			List<Element> children;
+			File[] files1 = new File[0];
+			String moveUrl;
+			SampleDailyPower sampleDailyPower;
+			String date;
+			if (files.isDirectory()) {
+				files1 = files.listFiles();
+				log.info("文件夹下有" + files1.length + "个文件");
+			}
+			for (File f : files1) {
+				log.info("解析文件:" + f.getName());
+				Matcher matcher = expr.matcher(f.getName());
+				if (matcher.find() && f.getName().contains("YBJ")) {
+					try {
+						date = dateTimeFormatter.parseDateTime(matcher.group()).toString("yyyy-MM-dd");
+						is = new FileInputStream(f);
+						document = saxBuilder.build(is);
+						rootElement = document.getRootElement();
+						children = rootElement.getChildren();
+						for (Element child : children) {
+							if (!"Row".equals(child.getName())) {
+								continue;
+							}
+							sampleDailyPower = new SampleDailyPower();
+							List<Element> childrenList = child.getChildren();
+							for (Element o : childrenList) {
+								try {
+									log.info("获取到文件内容:"+o.getName()+":"+o.getValue());
+									sampleDailyPower.setDate(date);
+									if ("YBJNO".equals(o.getName())) {
+										sampleDailyPower.setSampleId(o.getValue());
+									}
+									if ("YG".equals(o.getName())) {
+										sampleDailyPower.setFormList(string2DoubleList(o.getValue()));
+									}
+								} catch (Exception e) {
+									log.error("读取样板机数据文件解析时发生异常", e);
+								}
+							}
+							sampleDailyPower.setIsAuto("N");
+							sampleDailyPowerService.add(sampleDailyPower);
+							log.info("获取到,并存储样板机数据" + JSON.toJSONString(sampleDailyPower));
+						}
+					} catch (Exception e) {
+						moveUrl = JarPathUtil.getPath() + "/fail/" + DateTime.now().toString("yyyyMMdd") + "/";
+						File file = new File(moveUrl);
+						if (!file.exists()) {
+							file.mkdirs();
+						}
+						log.info("移动文件" + f.getName() + "至失败文件夹:" + moveUrl);
+						FileUtil.move(f, new File(moveUrl + f.getName()), true);
+						continue;
+					}
+					moveUrl = JarPathUtil.getPath() + "/success/" + DateTime.now().toString("yyyyMMdd") + "/";
+					File file = new File(moveUrl);
+					if (!file.exists()) {
+						file.mkdirs();
+					}
+					log.info("移动文件" + f.getName() + "至成功文件夹:" + moveUrl);
+					FileUtil.move(f, new File(moveUrl + f.getName()), true);
+				} else {
+					log.warn("解析文件名不符合样板机文件:" + f.getName());
+				}
+			}
+		} catch (Exception e) {
+			log.error("采集样板机数据任务发生异常:", e);
+		}
+		log.info("获取样板机数据定时任务执行完毕");
+	}
+
+	public JobDetail getJobDetail() {
+		return JobBuilder.newJob(this.getClass())
+				.withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+				.build();
+
+	}
+
+	public Trigger getTrigger() {
+		return TriggerBuilder.newTrigger()
+				.withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+				.startNow()
+				.withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+				.build();
+	}
+
+
+	private List<Double> string2DoubleList(String nums) {
+		String[] numArr = nums.split(",");
+		List<Double> doubleList = new ArrayList<>();
+		for (String s : numArr) {
+			doubleList.add(Double.parseDouble(s));
+		}
+		return doubleList;
+	}
+
+
+}

+ 143 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/GetShortForecastDataJob.java

@@ -0,0 +1,143 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000web.JarPathUtil;
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.service.CollectedDailyPowerService;
+import lombok.extern.slf4j.Slf4j;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.input.SAXBuilder;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @program: d5000-web
+ * @description: 短期预测数据采集任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Slf4j
+@Component
+public class GetShortForecastDataJob implements Job {
+
+	private static final String JOBNAME = "GetShortForecastData";
+
+	@Value("${trigger.getShortForecastData}")
+	String triggerCron;
+
+	@Value("${d5000.filePath}")
+	String forecastFilePath;
+
+	Pattern expr = Pattern.compile("20[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])");
+
+	DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyyMMdd");
+
+
+	@Autowired
+	CollectedDailyPowerService collectedDailyPowerService;
+
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+		log.info("开始执行获取短期数据定时任务");
+		log.info("查找" + forecastFilePath + "文件夹下文件");
+		try {
+			SAXBuilder saxBuilder = new SAXBuilder();
+			File files = new File(forecastFilePath);
+			InputStream is;
+			Document document;
+			Element rootElement;
+			List<Element> children;
+			File[] files1 = new File[0];
+			List<Double> valueList;
+			String moveUrl;
+			CollectedDailyPower collectedDailyPower;
+			if (files.isDirectory()) {
+				files1 = files.listFiles();
+				log.info("文件夹下有" + files1.length + "个文件");
+			}
+			for (File f : files1) {
+				collectedDailyPower = new CollectedDailyPower();
+				log.info("解析文件:" + f.getName());
+				Matcher matcher = expr.matcher(f.getName());
+				if (matcher.find()  && !f.getName().contains("YBJ")) {
+					try {
+						collectedDailyPower.setDate(dateTimeFormatter.parseDateTime(matcher.group()).toString("yyyy-MM-dd"));
+						collectedDailyPower.setUpdateDate(DateTime.now().toString("yyyy-MM-dd"));
+						is = new FileInputStream(f);
+						document = saxBuilder.build(is);
+						rootElement = document.getRootElement();
+						children = rootElement.getChildren();
+						valueList = new ArrayList<>();
+						for (Element child : children) {
+							List<Element> childrenList = child.getChildren();
+							for (Element o : childrenList) {
+								if ("YG".equals(o.getName())) {
+									valueList.add(Double.parseDouble(o.getValue()));
+								}
+							}
+						}
+						collectedDailyPower.setFormList(valueList);
+						log.info("获取,并存储短期数据" + JSON.toJSONString(collectedDailyPower));
+						collectedDailyPowerService.add(collectedDailyPower);
+					} catch (Exception e) {
+						moveUrl= JarPathUtil.getPath()+"/fail/"+DateTime.now().toString("yyyyMMdd")+"/" ;
+						File file=new File(moveUrl);
+						if (!file.exists()) {
+							file.mkdirs();
+						}
+						log.info("移动文件" + f.getName() + "至失败文件夹:"+moveUrl);
+						FileUtil.move(f,new File(moveUrl+ f.getName()),true);
+						continue;
+					}
+					moveUrl=JarPathUtil.getPath()+"/success/"+DateTime.now().toString("yyyyMMdd")+"/" ;
+					File file=new File(moveUrl);
+					if (!file.exists()) {
+						file.mkdirs();
+					}
+					log.info("移动文件" + f.getName() + "至成功文件夹:"+moveUrl);
+					FileUtil.move(f,new File(moveUrl+ f.getName()),true);
+				} else {
+					log.warn("解析文件名不符合预测文件:" + f.getName());
+				}
+			}
+		} catch (Exception e) {
+			log.error("采集短期预测数据任务发生异常:", e);
+		}
+		log.info("获取短期数据定时任务执行完毕");
+	}
+
+	public JobDetail getJobDetail() {
+		return JobBuilder.newJob(this.getClass())
+				.withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+				.build();
+
+	}
+
+	public Trigger getTrigger() {
+		return TriggerBuilder.newTrigger()
+				.withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+				.startNow()
+				.withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+				.build();
+	}
+
+
+
+
+}

+ 149 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/ReportFileReceiveAndUploadStatusJob.java

@@ -0,0 +1,149 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+
+import com.jiayue.ipfcst.d5000web.JarPathUtil;
+import com.jiayue.ipfcst.d5000web.bean.UploadedDailyPower;
+import com.jiayue.ipfcst.d5000web.service.SampleDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.UploadedDailyPowerService;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import org.joda.time.format.DateTimeFormat;
+import org.joda.time.format.DateTimeFormatter;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.io.File;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @program: d5000-web
+ * @description: 上报短期文件上传状态至功率预测定时任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Slf4j
+@Component
+public class ReportFileReceiveAndUploadStatusJob implements Job {
+
+
+	private static final String JOBNAME = "ReportFileReceiveAndUploadStatus";
+
+
+	@Value("${trigger.reportFileReceiveAndUploadStatus:0 0/5 * * * ?}")
+	String triggerCron;
+
+	@Value("${forecastServerIpAndPort:}")
+	String forecastServerIpAndPort;
+
+	@Value("${ipOfThisServer:}")
+	String ipOfThisServer;
+
+	Pattern expr = Pattern.compile("20[0-9]{2}(0[1-9]|1[0-2])(0[1-9]|[1-2][0-9]|3[0-1])");
+
+	DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyyMMdd");
+
+
+	@Autowired
+	UploadedDailyPowerService uploadedDailyPowerService;
+
+	@Autowired
+	SampleDailyPowerService sampleDailyPowerService;
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+		System.out.println("forecastServerIpAndPort" + forecastServerIpAndPort);
+		System.out.println("ipOfThisServer" + ipOfThisServer);
+		if (StringUtils.isEmpty(forecastServerIpAndPort) || StringUtils.isEmpty(ipOfThisServer)) {
+			return;
+		}
+		log.info("开始执行上报短期文件上传状态至功率预测定时任务");
+		String filePath= JarPathUtil.getPath() + "/success/" + DateTime.now().toString("yyyyMMdd") + "/";
+		log.info("查找"+filePath+"下的文件");
+		File dir = new File(filePath);
+		File[] files;
+		List<UploadedDailyPower> list;
+		UploadedDailyPower uploadedDailyPower = new UploadedDailyPower();
+		if (dir.isDirectory()) {
+			files = dir.listFiles();
+			log.info("[成功文件]文件夹下有" + files.length + "个文件");
+			if (files.length > 0) {
+				for (File f : files) {
+					try {
+						Matcher matcher = expr.matcher(f.getName());
+						if (matcher.find()) {
+							if (f.getName().contains("YBJ")) {
+								List<String> l = sampleDailyPowerService.uploadFailedSample();
+								if(l.size()>0){
+									log.info(f.getName() + "文件上报失败,向功率预测汇报该状态");
+									HttpResponse re = HttpRequest.get("https://" + forecastServerIpAndPort + "/uploadFileOpenInterface/updateD5000FileStatus/" + ipOfThisServer + "/" + f.getName() + "/0").execute();
+									if (re != null) {
+										log.info("上报结果" + re.body());
+									} else {
+										log.info("上报结果为空");
+									}
+								}else{
+									log.info(f.getName() + "文件上报成功,向功率预测汇报该状态");
+									HttpResponse re = HttpRequest.get("https://" + forecastServerIpAndPort + "/uploadFileOpenInterface/updateD5000FileStatus/" + ipOfThisServer + "/" + f.getName() + "/1").execute();
+									if (re != null) {
+										log.info("上报结果" + re.body());
+									} else {
+										log.info("上报结果为空");
+									}
+								}
+							} else {
+								uploadedDailyPower.setDate(dateTimeFormatter.parseDateTime(matcher.group()).toString("yyyy-MM-dd"));
+								uploadedDailyPower.setUploadDate(DateTime.now().toString("yyyy-MM-dd"));
+								list = uploadedDailyPowerService.get(uploadedDailyPower);
+								if (list.size() > 0) {
+									log.info(f.getName() + "文件上报成功,向功率预测汇报该状态");
+									HttpResponse re = HttpRequest.get("https://" + forecastServerIpAndPort + "/uploadFileOpenInterface/updateD5000FileStatus/" + ipOfThisServer + "/" + f.getName() + "/1").execute();
+									if (re != null) {
+										log.info("上报结果" + re.body());
+									} else {
+										log.info("上报结果为空");
+									}
+								} else {
+									log.info(f.getName() + "文件上报失败,向功率预测汇报该状态");
+									HttpResponse re = HttpRequest.get("https://" + forecastServerIpAndPort + "/uploadFileOpenInterface/updateD5000FileStatus/" + ipOfThisServer + "/" + f.getName() + "/0").execute();
+									if (re != null) {
+										log.info("上报结果" + re.body());
+									} else {
+										log.info("上报结果为空");
+									}
+								}
+							}
+						}
+					} catch (Exception e) {
+						log.info("上报功率预测状态发生异常",e);
+						e.printStackTrace();
+					}
+				}
+			}
+		}
+		log.info("上报文件上传状态至功率预测定时任务执行完毕");
+	}
+
+	public JobDetail getJobDetail() {
+		return JobBuilder.newJob(this.getClass())
+				.withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+				.build();
+
+	}
+
+	public Trigger getTrigger() {
+		return TriggerBuilder.newTrigger()
+				.withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+				.startNow()
+				.withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+				.build();
+	}
+
+
+}

+ 91 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/SynchronizeDataTasks.java

@@ -0,0 +1,91 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000web.bean.FailedDualRequest;
+import com.jiayue.ipfcst.d5000web.service.FailedDualRequestService;
+import com.jiayue.ipfcst.d5000web.service.RequestOtherService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 同步数据库
+ * @author: xiuwei
+ * @create: 2020-04-22 18:54
+ */
+@Component
+@Slf4j
+public class SynchronizeDataTasks implements Job {
+
+    private static  final  String JOBNAME="SynchronizeDataTasks";
+
+    @Autowired
+    RequestOtherService requestOtherService;
+
+    @Autowired
+    FailedDualRequestService failedDualRequestService;
+
+    @Value("${dual.isDual}")
+    Boolean isDual;
+
+    @Value("${server.port}")
+    Integer selfPort;
+
+    @Value("${trigger.synchronizeDataTasks}")
+    String triggerCron;
+
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        if(isDual) {
+            log.info("开始执行同步数据定时任务");
+            try {
+                String jsonObject = requestOtherService.get("/failedDualRequest");
+                System.out.println(jsonObject);
+                if (jsonObject != null) {
+                    List<FailedDualRequest> failedDualRequests = JSON.parseArray(jsonObject, FailedDualRequest.class);
+                    for (FailedDualRequest f : failedDualRequests) {
+                        failedDualRequestService.toBeRead(f.getId());
+                        switch (f.getRequestType()) {
+                            case 0:
+                                HttpRequest.put("http://localhost:" + selfPort + f.getRequestUrl()).form(JSON.parseObject(f.getRequestJson(), Map.class)).setConnectionTimeout(500).execute().body();
+                                break;
+                            case 1:
+                                HttpRequest.post("http://localhost:" + selfPort + f.getRequestUrl()).form(JSON.parseObject(f.getRequestJson(), Map.class)).setConnectionTimeout(500).execute().body();
+                                break;
+                            case 2:
+                                HttpRequest.delete("http://localhost:" + selfPort + f.getRequestUrl()).form(JSON.parseObject(f.getRequestJson(), Map.class)).setConnectionTimeout(500).execute().body();
+                                break;
+                        }
+                    }
+                }
+                ;
+            } catch (Exception e) {
+                log.error("执行同步数据任务发生异常:", e);
+            }
+            log.info("同步数据定时任务执行完毕");
+        }
+    }
+
+    public JobDetail getJobDetail(){
+        return JobBuilder.newJob(this.getClass())
+                .withIdentity(JOBNAME+"Job", "D5000TasksAndTriggers")
+                .build();
+
+    }
+
+    public Trigger getTrigger(){
+        return TriggerBuilder.newTrigger()
+                .withIdentity(JOBNAME+"Trigger", "D5000TasksAndTriggers")
+                .startNow()
+                .withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+                .build();
+    }
+}

+ 55 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/TaskSchedulingCenter.java

@@ -0,0 +1,55 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+import org.quartz.Scheduler;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: d5000-web
+ * @description: 任务调度启动
+ * @author: xiuwei
+ * @create: 2020-04-14 15:46
+ */
+@Component
+public class TaskSchedulingCenter implements ApplicationRunner {
+
+    @Autowired
+    Scheduler scheduler;
+
+    @Autowired
+    GetShortForecastDataJob getShortForecastDataJob;
+
+    @Autowired
+    UploadShortForecastDataJob uploadShortForecastDataJob;
+
+    @Autowired
+    UploadSampleDataJob uploadSampleDataJob;
+
+    @Autowired
+    UploadOperatingCapacityJob uploadOperatingCapacityJob;
+
+    @Autowired
+    UploadOperationStatusJob UploadOperationStatusJob;
+    @Autowired
+    SynchronizeDataTasks synchronizeDataTasks;
+
+    @Autowired
+    ReportFileReceiveAndUploadStatusJob reportFileReceiveAndUploadStatusJob;
+
+    @Autowired
+    GetSampleFileDataJob getSampleFileDataJob;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        scheduler.scheduleJob(getShortForecastDataJob.getJobDetail(),getShortForecastDataJob.getTrigger());
+        scheduler.scheduleJob(uploadShortForecastDataJob.getJobDetail(),uploadShortForecastDataJob.getTrigger());
+        scheduler.scheduleJob(uploadSampleDataJob.getJobDetail(),uploadSampleDataJob.getTrigger());
+        scheduler.scheduleJob(uploadOperatingCapacityJob.getJobDetail(),uploadOperatingCapacityJob.getTrigger());
+        scheduler.scheduleJob(UploadOperationStatusJob.getJobDetail(),UploadOperationStatusJob.getTrigger());
+        scheduler.scheduleJob(synchronizeDataTasks.getJobDetail(),synchronizeDataTasks.getTrigger());
+        scheduler.scheduleJob(reportFileReceiveAndUploadStatusJob.getJobDetail(),reportFileReceiveAndUploadStatusJob.getTrigger());
+        scheduler.scheduleJob(getSampleFileDataJob.getJobDetail(),getSampleFileDataJob.getTrigger());
+    }
+}

+ 66 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadOperatingCapacityJob.java

@@ -0,0 +1,66 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+
+import com.jiayue.ipfcst.d5000web.service.OperatingCapacityService;
+import com.jiayue.ipfcst.d5000web.service.Upload2D5000Service;
+import com.jiayue.ipfcst.d5000web.service.UploadedOperatingCapacityService;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * @program: d5000-web
+ * @description: 上传项目运行状态任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Component
+@Slf4j
+public class UploadOperatingCapacityJob implements Job {
+
+    private static  final  String JOBNAME="UploadOperatingCapacityJob";
+
+    @Value("${trigger.uploadOperatingCapacity}")
+    String triggerCron;
+
+    @Autowired
+    OperatingCapacityService operatingCapacityService;
+
+    @Autowired
+    UploadedOperatingCapacityService uploadedOperatingCapacityService;
+
+    @Autowired
+    Upload2D5000Service upload2D5000Service;
+
+
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        log.info("开始执行上传运行容量的定时任务");
+        try {
+            upload2D5000Service.uploadOperatingCapacity(operatingCapacityService.get());
+        }catch (Exception e){
+            log.error("上传运行容量任务发生异常:",e);
+        }
+        log.info("上传运行容量的定时任务执行完毕");
+    }
+
+    public  JobDetail getJobDetail(){
+        return JobBuilder.newJob(this.getClass())
+                .withIdentity(JOBNAME+"Job", "D5000TasksAndTriggers")
+                .build();
+
+    }
+
+    public Trigger getTrigger(){
+        return TriggerBuilder.newTrigger()
+                .withIdentity(JOBNAME+"Trigger", "D5000TasksAndTriggers")
+                .startNow()
+                .withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+                .build();
+    }
+
+
+}

+ 69 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadOperationStatusJob.java

@@ -0,0 +1,69 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+
+import com.jiayue.ipfcst.d5000web.bean.OperationStatus;
+import com.jiayue.ipfcst.d5000web.service.OperationStatusService;
+import com.jiayue.ipfcst.d5000web.service.Upload2D5000Service;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 上传项目运行状态任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Component
+@Slf4j
+public class UploadOperationStatusJob implements Job {
+
+	private static final String JOBNAME = "UploadOperationStatusJob";
+
+	@Value("${trigger.uploadOperationStatus}")
+	String triggerCron;
+
+
+	@Autowired
+	OperationStatusService operationStatusService;
+
+	@Autowired
+	Upload2D5000Service upload2D5000Service;
+
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+		log.info("开始执行上传项目运行状态的定时任务");
+
+		List<OperationStatus> operationStatuses = operationStatusService.get(null);
+		for (OperationStatus o : operationStatuses) {
+			try {
+				upload2D5000Service.uploadOperationStatus(o);
+			} catch (Exception e) {
+				log.error("上传项目运行状态{}任务发生异常:",o.getName(), e);
+			}
+		}
+		log.info("上传项目运行状态的定时任务执行完毕");
+	}
+
+	public JobDetail getJobDetail() {
+		return JobBuilder.newJob(this.getClass())
+				.withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+				.build();
+
+	}
+
+	public Trigger getTrigger() {
+		return TriggerBuilder.newTrigger()
+				.withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+				.startNow()
+				.withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+				.build();
+	}
+
+
+}

+ 99 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadSampleDataJob.java

@@ -0,0 +1,99 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.service.SampleDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.SampleInfoService;
+import com.jiayue.ipfcst.d5000web.service.Upload2D5000Service;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机数据上传任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Component
+@Slf4j
+public class UploadSampleDataJob implements Job {
+
+    private static final String JOBNAME = "UploadSampleData";
+
+    @Value("${trigger.uploadSampleData}")
+    String triggerCron;
+
+    @Autowired
+    SampleDailyPowerService sampleDailyPowerService;
+
+    @Autowired
+    SampleInfoService sampleInfoService;
+
+    @Autowired
+    Upload2D5000Service upload2D5000Service;
+
+
+
+    @Override
+    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+        log.info("开始执行样板机数据上传任务");
+        try {
+            List<SampleInfo> samples = sampleInfoService.get(null);
+            SampleDailyPower sampleDailyPower;
+            List<SampleDailyPower> list;
+            for (SampleInfo s : samples) {
+                sampleDailyPower = new SampleDailyPower();
+                sampleDailyPower.setDate(new DateTime().minusDays(1).toString("yyyy-MM-dd"));
+                sampleDailyPower.setSampleId(s.getDid());
+                list = sampleDailyPowerService.get(sampleDailyPower);
+                try {
+                if (list.size() > 0) {
+                    log.info("开始上传{} - 编号为 {} 的样板机数据",list.get(0).getDate(),list.get(0).getSampleId());
+                    upload2D5000Service.uploadSamplePower(list.get(0));
+                }else{
+                    sampleDailyPower=sampleDailyPowerService.getLastRecode(s.getDid());
+                    if(sampleDailyPower!=null){
+                        log.info("没有 {}- 编号为{} 的样板机数据,使用最后一条数据代替",new DateTime().minusDays(1).toString("yyyy-MM-dd"),s.getDid());
+                        sampleDailyPower.setDate(new DateTime().minusDays(1).toString("yyyy-MM-dd"));
+                        sampleDailyPower.setId(null);
+                        sampleDailyPower.setIsAuto("Y");
+                        sampleDailyPower.setUploadDate("");
+                        sampleDailyPower.setSampleId(s.getDid());
+                        sampleDailyPower=sampleDailyPowerService.add(sampleDailyPower);
+                        upload2D5000Service.uploadSamplePower(sampleDailyPower);
+                    }
+                }
+                }catch (Exception e){
+                    log.error("上传样板机{}任务发生异常:",s.getName(),e);
+                }
+            }
+        }catch (Exception e){
+            log.error("上传样板机任务发生异常:",e);
+        }
+        log.info("样板机数据上传任务执行完毕");
+    }
+
+    public JobDetail getJobDetail() {
+        return JobBuilder.newJob(this.getClass())
+                .withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+                .build();
+
+    }
+
+    public Trigger getTrigger() {
+        return TriggerBuilder.newTrigger()
+                .withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+                .startNow()
+                .withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+                .build();
+    }
+
+
+}

+ 118 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/jobs/UploadShortForecastDataJob.java

@@ -0,0 +1,118 @@
+package com.jiayue.ipfcst.d5000web.jobs;
+
+
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.service.CollectedDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.Upload2D5000Service;
+import com.jiayue.ipfcst.d5000web.service.UploadedDailyPowerService;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.LocalDate;
+import org.joda.time.LocalTime;
+import org.quartz.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 短期预测数据上传任务
+ * @author: xiuwei
+ * @create: 2020-04-14 15:42
+ */
+@Slf4j
+@Component
+public class UploadShortForecastDataJob implements Job {
+
+	private static final String JOBNAME = "UploadShortForecastData";
+
+	@Value("${trigger.uploadShortForecastData}")
+	String triggerCron;
+
+	@Value("${uploadShortForecastDays}")
+	Integer uploadShortForecastDays = 7;
+
+
+
+	@Autowired
+	UploadedDailyPowerService uploadedDailyPowerService;
+
+	@Autowired
+	CollectedDailyPowerService collectedDailyPowerService;
+
+	@Autowired
+	Upload2D5000Service upload2D5000Service;
+
+
+	@Override
+	public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
+		log.info("开始执行上传短期数据定时任务");
+		try {
+			List<String> days = uploadedDailyPowerService.getFailedDays();
+			List<CollectedDailyPower> collectedDailyPowers;
+			if (LocalTime.now().isAfter(LocalTime.parse("06:15:00"))) {
+				log.info("6:15后上传所有的预测数据");
+				days = new ArrayList<>();
+				for (int i = 1; i <= this.uploadShortForecastDays; i++) {
+					days.add(LocalDate.now().plusDays(i).toString("yyyy-MM-dd"));
+				}
+			}
+			for (String s : days) {
+				CollectedDailyPower collectedDailyPower = new CollectedDailyPower();
+				collectedDailyPower.setIsManual(null);
+				collectedDailyPower.setDate(s);
+				collectedDailyPowers = collectedDailyPowerService.get(collectedDailyPower);
+				try {
+					if (collectedDailyPowers.size() > 0) {
+						log.info("开始上报:"+collectedDailyPower.getDate()+"的短期数据");
+						upload2D5000Service.uploadShortForecast(collectedDailyPowers.get(0));
+					} else {
+						collectedDailyPower=collectedDailyPowerService.getLastRecord();
+						if(collectedDailyPower!=null){
+							log.error("数据库内没有" + s + "短期数据,用数据库最后一条代替");
+							collectedDailyPower.setDate(s);
+							log.info("开始上报:"+collectedDailyPower.getDate()+"的短期数据");
+							upload2D5000Service.uploadShortForecast(collectedDailyPower);
+						}
+					}
+				} catch (Exception e) {
+					log.error("执行{}短期数据上传任务时发生异常:",s, e);
+				}
+			}
+			collectedDailyPowers=collectedDailyPowerService.getFutureRecord(LocalDate.now().plusDays(uploadShortForecastDays).toString("yyyy-MM-dd"));
+			if(collectedDailyPowers!=null && collectedDailyPowers.size()>0){
+				log.info("发现更多日期的预测数据,开始上报");
+				for(CollectedDailyPower collectedDailyPower  :collectedDailyPowers){
+					try {
+						log.info("开始上报:"+collectedDailyPower.getDate()+"的短期数据");
+						upload2D5000Service.uploadShortForecast(collectedDailyPower);
+					} catch (Exception e) {
+					log.error("执行{}短期数据上传任务时发生异常:", e);
+				}
+				}
+			}
+		} catch (Exception e) {
+			log.error("执行短期数据上传任务时发生异常:", e);
+		}
+		log.info("上传短期数据定时任务执行完毕");
+	}
+
+	public JobDetail getJobDetail() {
+		return JobBuilder.newJob(this.getClass())
+				.withIdentity(JOBNAME + "Job", "D5000TasksAndTriggers")
+				.build();
+
+	}
+
+	public Trigger getTrigger() {
+		return TriggerBuilder.newTrigger()
+				.withIdentity(JOBNAME + "Trigger", "D5000TasksAndTriggers")
+				.startNow()
+				.withSchedule(CronScheduleBuilder.cronSchedule(triggerCron))
+				.build();
+	}
+
+
+}

+ 39 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/CollectedDailyPowerMapper.java

@@ -0,0 +1,39 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 采集到的短期功率
+ * @author: xiuwei
+ * @create: 2020-04-09 19:03
+ */
+public interface CollectedDailyPowerMapper {
+
+    public List<CollectedDailyPower> get(CollectedDailyPower collectedDailyPower);
+
+    public int add(CollectedDailyPower collectedDailyPower);
+
+    /**
+     * 是否已经存在该日期的数据
+     * @param date
+     * @return
+     */
+    public int containThisDate(@Param("date") String  date);
+
+    /**
+     * 是否是手动存入的
+     * @param date
+     * @return
+     */
+    public Boolean isManual(@Param("date") String date);
+
+    public CollectedDailyPower getLastRecord();
+
+    public  List<CollectedDailyPower> getFutureRecord(@Param("date") String date);
+
+    public int update(CollectedDailyPower collectedDailyPower);
+}

+ 21 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/FailedDualRequestMapper.java

@@ -0,0 +1,21 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.FailedDualRequest;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 同步失败的请求
+ * @author: xiuwei
+ * @create: 2020-04-09 19:03
+ */
+public interface FailedDualRequestMapper {
+
+    public List<FailedDualRequest> getNotHandled();
+
+    public int add(FailedDualRequest failedDualRequest);
+
+    public int toBeRead(Integer id);
+
+}

+ 26 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/Gather104TcpChannelMapper.java

@@ -0,0 +1,26 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.Gather104TCPChannel;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 104采集通道信息数据库操作
+ * @author: tangle
+ * @create: 2023-02-06 14:36
+ */
+public interface Gather104TcpChannelMapper {
+
+
+    int add(Gather104TCPChannel gather104TCPChannel);
+
+    int update(Gather104TCPChannel gather104TCPChannel);
+
+    int delete(Integer id);
+
+    List<Gather104TCPChannel> get();
+
+    Gather104TCPChannel getById(Integer id);
+
+}

+ 14 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/OperatingCapacityMapper.java

@@ -0,0 +1,14 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+
+import com.jiayue.ipfcst.d5000web.bean.OperatingCapacity;
+
+import java.util.List;
+
+
+public interface OperatingCapacityMapper {
+
+    List<OperatingCapacity> get();
+
+    int update(OperatingCapacity operatingCapacity);
+}

+ 21 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/OperationStatusMapper.java

@@ -0,0 +1,21 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.OperationStatus;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 项目运行状态的数据操作
+ * @author: xiuwei
+ * @create: 2020-04-16 13:38
+ */
+public interface OperationStatusMapper {
+
+    List<OperationStatus> get(OperationStatus operationStatus);
+    int add(OperationStatus operationStatus);
+    int delete(OperationStatus operationStatus);
+    int update(OperationStatus operationStatus);
+
+
+}

+ 36 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/SampleDailyPowerMapper.java

@@ -0,0 +1,36 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.bean.UploadedDailyPower;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机数据操作接口
+ * @author: xiuwei
+ * @create: 2020-04-14 19:43
+ */
+public interface SampleDailyPowerMapper {
+
+
+    public List<String> getAllColumn();
+
+    public void addIsautoColumn();
+
+    public void addUpDateTimeColumn();
+
+    public int add(SampleDailyPower sampleDailyPower);
+
+    public List<SampleDailyPower> get(SampleDailyPower sampleDailyPower);
+
+
+    public SampleDailyPower getLastRecode( @Param("sampleId") String sampleId);
+
+    public Integer update(SampleDailyPower sampleDailyPower);
+
+
+    public SampleDailyPower getOne(String date, String sampleId);
+
+}

+ 23 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/SampleInfoMapper.java

@@ -0,0 +1,23 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机信息数据库操作
+ * @author: xiuwei
+ * @create: 2020-04-15 18:54
+ */
+public interface SampleInfoMapper {
+
+
+    List<SampleInfo> get(SampleInfo sampleInfo);
+    int add(SampleInfo sampleInfo);
+    int delete(SampleInfo sampleInfo);
+    int update(SampleInfo sampleInfo);
+
+    List<SampleInfo> getByChannelId(Integer channelId);
+
+}

+ 27 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedDailyPowerMapper.java

@@ -0,0 +1,27 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.UploadedDailyPower;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 上传的短期功率
+ * @author: xiuwei
+ * @create: 2020-04-09 19:05
+ */
+public interface UploadedDailyPowerMapper {
+
+    public int add(UploadedDailyPower uploadedDailyPower);
+
+    public int update(UploadedDailyPower uploadedDailyPower);
+
+
+    public List<UploadedDailyPower> get(UploadedDailyPower uploadedDailyPower);
+
+
+
+
+    public  int addAll(@Param("list") List<UploadedDailyPower> uploadedDailyPowers);
+}

+ 23 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedOperatingCapacityMapper.java

@@ -0,0 +1,23 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.UploadedOperatingCapacity;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 上传过的运行容量
+ * @author: xiuwei
+ * @create: 2020-04-16 16:47
+ */
+public interface UploadedOperatingCapacityMapper {
+
+
+
+    List<UploadedOperatingCapacity>  get(UploadedOperatingCapacity uploadedOperatingCapacity);
+
+    int add(UploadedOperatingCapacity uploadedOperatingCapacity);
+
+    int update(UploadedOperatingCapacity uploadedOperatingCapacity);
+
+}

+ 17 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UploadedOperationStatusMapper.java

@@ -0,0 +1,17 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.UploadedOperationStatus;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 已经上传过的运行状态
+ * @author: xiuwei
+ * @create: 2020-04-16 16:42
+ */
+public interface UploadedOperationStatusMapper {
+    int add (UploadedOperationStatus uploadedOperationStatus);
+    int update (UploadedOperationStatus uploadedOperationStatus);
+    List<UploadedOperationStatus> get(UploadedOperationStatus uploadedOperationStatus);
+}

+ 18 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/mapper/UsernameAndPasswordMapper.java

@@ -0,0 +1,18 @@
+package com.jiayue.ipfcst.d5000web.mapper;
+
+import com.jiayue.ipfcst.d5000web.bean.UsernameAndPassword;
+import org.apache.ibatis.annotations.Param;
+
+/**
+ * @program: d5000-web
+ * @description: 用户名密码操作类
+ * @author: xiuwei
+ * @create: 2020-04-13 10:49
+ */
+public interface UsernameAndPasswordMapper {
+
+    UsernameAndPassword get();
+
+    int update(@Param("password") String password);
+
+}

+ 105 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/CollectedDailyPowerService.java

@@ -0,0 +1,105 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower;
+import com.jiayue.ipfcst.d5000web.mapper.CollectedDailyPowerMapper;
+import org.joda.time.LocalDate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 采集到的短期数据的操作类
+ * @author: xiuwei
+ * @create: 2020-04-10 13:24
+ */
+@Service
+public class CollectedDailyPowerService {
+
+    @Autowired
+    CollectedDailyPowerMapper collectedDailyPowerMapper;
+
+    @Value("${uploadShortForecastDays}")
+    Integer uploadShortForecastDays;
+
+
+
+    public int add(CollectedDailyPower collectedDailyPower) {
+        if (collectedDailyPower.getDate() == null) {
+            return 0;
+        }
+        if (collectedDailyPowerMapper.containThisDate(collectedDailyPower.getDate()) > 0) {
+            if(collectedDailyPowerMapper.isManual(collectedDailyPower.getDate())&&!collectedDailyPower.getIsManual()){
+                return 0;
+            }
+            return  collectedDailyPowerMapper.update(collectedDailyPower);
+        } else {
+            return   collectedDailyPowerMapper.add(collectedDailyPower);
+        }
+    }
+
+
+    /**
+     * 查询出获取数据失败的日期
+     * @return
+     */
+    public List<String> getCollectedFailedDate(){
+        LocalDate date = LocalDate.now();
+        List<String> list=new ArrayList<>();
+        String nowDateString=date.toString("yyyy-MM-dd");
+        String dateString;
+        CollectedDailyPower collectedDailyPower;
+        for (int i = 1; i <=uploadShortForecastDays ; i++) {
+            dateString=date.plusDays(i).toString("yyyy-MM-dd");
+            collectedDailyPower=new CollectedDailyPower();
+            //未来日期下 更新日期为今天的数据是否存在
+            collectedDailyPower.setDate(dateString);
+            collectedDailyPower.setUpdateDate(nowDateString);
+            if(collectedDailyPowerMapper.get(collectedDailyPower).size()== 0){
+                //不存在 今天更新的  查询日期的数据
+                collectedDailyPower=new CollectedDailyPower();
+                collectedDailyPower.setDate(dateString);
+                collectedDailyPower.setIsManual(true);
+                if(collectedDailyPowerMapper.get(collectedDailyPower).size()== 0){
+                    //不存在 手动存储的 查询日期的数据
+                    //两者均不存在  存入失败队列
+                    list.add(dateString);
+                }
+            }
+        }
+        return  list;
+    }
+
+
+    public int addAll(List<CollectedDailyPower> collectedDailyPowers) {
+        int i = 0;
+        for (CollectedDailyPower c : collectedDailyPowers) {
+            i += add(c);
+        }
+        return i;
+    }
+
+
+    public List<CollectedDailyPower> get(CollectedDailyPower collectedDailyPower){
+        return  collectedDailyPowerMapper.get(collectedDailyPower);
+    };
+
+    public CollectedDailyPower getLastRecord(){
+        return  collectedDailyPowerMapper.getLastRecord();
+    };
+
+
+    /**
+     *获取未来几天的数据
+     *
+     * @return {@link CollectedDailyPower}
+     */
+    public  List<CollectedDailyPower> getFutureRecord(String date){
+        return  collectedDailyPowerMapper.getFutureRecord (date);
+    }
+
+
+}

+ 48 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/CollectedStatusService.java

@@ -0,0 +1,48 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import org.joda.time.DateTime;
+import org.joda.time.Days;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 数据获取情况服务
+ * @author: xiuwei
+ * @create: 2020-04-20 09:42
+ */
+@Service
+public class CollectedStatusService {
+
+
+    @Autowired
+    CollectedDailyPowerService collectedDailyPowerService;
+    @Autowired
+    SampleDailyPowerService sampleDailyPowerService;
+
+
+    public Map<String, List> getLocalStatus(){
+        Map<String, List> result=new HashMap<>();
+        List sample=sampleDailyPowerService.getFailedSample();
+        List<String> shortForecastString=collectedDailyPowerService.getCollectedFailedDate();
+        List<Integer> shortForecast=new ArrayList<>();
+        DateTime d=DateTime.now();
+        for(String s:shortForecastString){
+            shortForecast.add(Days.daysBetween(d,DateTime.parse(s)).getDays()+1) ;
+        }
+        result.put("sample",sample);
+        result.put("shortForecast",shortForecast);
+        return result;
+    }
+
+
+
+
+
+
+}

+ 34 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/FailedDualRequestService.java

@@ -0,0 +1,34 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.FailedDualRequest;
+import com.jiayue.ipfcst.d5000web.mapper.FailedDualRequestMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 同步失败请求的服务
+ * @author: xiuwei
+ * @create: 2020-04-22 18:34
+ */
+@Service
+public class FailedDualRequestService {
+
+    @Autowired
+    FailedDualRequestMapper failedDualRequestMapper;
+
+    public List<FailedDualRequest> getNotHandled(){
+       return failedDualRequestMapper.getNotHandled();
+    };
+
+    public int add(FailedDualRequest failedDualRequest){
+        return failedDualRequestMapper.add(failedDualRequest);
+    };
+
+    public int toBeRead(Integer id){
+        return failedDualRequestMapper.toBeRead(id);
+    };
+
+}

+ 67 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/Gather104TcpChannelService.java

@@ -0,0 +1,67 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+
+import com.jiayue.ipfcst.d5000web.bean.Gather104TCPChannel;
+import com.jiayue.ipfcst.d5000web.mapper.Gather104TcpChannelMapper;
+import com.jiayue.ipfcst.gather.Gather104tcpClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import wei.yigulu.iec104.nettyconfig.Iec104HSMasterBuilder;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 104采集通道信息服务类
+ * @author: tangle
+ * @create: 2023-02-006 14:41
+ */
+@Service
+public class Gather104TcpChannelService {
+
+    @Autowired
+    Gather104TcpChannelMapper gather104TCPChannelMapper;
+
+
+
+
+    public int add(Gather104TCPChannel gather104TCPChannel){
+        int r = gather104TCPChannelMapper.add(gather104TCPChannel);
+        if(r==1){
+            Gather104tcpClient.getInstance().start(gather104TCPChannel);
+        }
+
+        return r;
+    }
+
+    public int update(Gather104TCPChannel gather104TCPChannel){
+
+        Gather104TCPChannel gather104TCPChannelOld = gather104TCPChannelMapper.getById(gather104TCPChannel.getId());
+        int r = gather104TCPChannelMapper.update(gather104TCPChannel);
+        if(r==1){
+            Gather104tcpClient.getInstance().stop(gather104TCPChannelOld.getCid());
+
+            Gather104tcpClient.getInstance().start(gather104TCPChannel);
+        }
+        return r;
+    }
+
+    public int delete(Integer id){
+
+        Gather104TCPChannel gather104TCPChannel = gather104TCPChannelMapper.getById(id);
+        int r = gather104TCPChannelMapper.delete(id);
+        if(r==1){
+            Gather104tcpClient.getInstance().stop(gather104TCPChannel.getCid());
+        }
+        return r;
+    }
+
+    public List<Gather104TCPChannel> get(){return gather104TCPChannelMapper.get();}
+
+
+
+
+
+    }

+ 73 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/GzipUtil.java

@@ -0,0 +1,73 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+
+import org.apache.commons.codec.binary.Base64OutputStream;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * @author wll
+ * @date 2020-04-20 10:55:39
+ */
+public class GzipUtil {
+
+    private static int packSize = 800;
+
+    public static List<String> zipList(String result, int packSize) throws IOException {
+
+        String zipResult = zip(result);
+        zipResult = zipResult.replace("\r\n", "");
+
+        double length = zipResult.length();
+        int packageNumber = (int) Math.ceil(length / packSize);
+
+        List<String> list = new ArrayList<String>();
+
+        for (int i = 0; i < packageNumber; i++) {
+            if (i == packageNumber - 1) {
+                list.add(zipResult.substring(i * packSize, (int) length));
+            } else if (i == 0) {
+                list.add(zipResult.substring(0, packSize));
+            } else {
+                list.add(zipResult.substring(i * packSize, (i + 1) * packSize));
+            }
+        }
+
+
+        return list;
+    }
+
+    public static String zip(String result) throws IOException {
+
+        byte[] bytes = result.getBytes("utf-8");
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        Base64OutputStream b64os = new Base64OutputStream(bos);
+        GZIPOutputStream gout = new GZIPOutputStream(b64os);
+        gout.write(bytes);
+        gout.close();
+        b64os.close();
+
+        byte b1[] = bos.toByteArray();
+        bos.close();
+        return new String(b1, "utf-8");
+    }
+
+    public static String zip(byte[] bytes) throws IOException {
+
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        Base64OutputStream b64os = new Base64OutputStream(bos);
+        GZIPOutputStream gout = new GZIPOutputStream(b64os);
+        gout.write(bytes);
+        gout.close();
+        b64os.close();
+
+        byte b1[] = bos.toByteArray();
+        bos.close();
+        return new String(b1, "utf-8");
+    }
+
+}

+ 24 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/OperatingCapacityService.java

@@ -0,0 +1,24 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.OperatingCapacity;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: d5000-web
+ * @description:
+ * @author: xiuwei
+ * @create: 2020-04-16 17:01
+ */
+@Service
+public class OperatingCapacityService {
+
+    @Value("${d5000.operatingCapacity}")
+    Double capacity;
+
+   public OperatingCapacity get(){
+       OperatingCapacity operatingCapacity = new OperatingCapacity(capacity);
+       return operatingCapacity ;
+   };
+
+}

+ 37 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/OperationStatusService.java

@@ -0,0 +1,37 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.OperationStatus;
+import com.jiayue.ipfcst.d5000web.mapper.OperationStatusMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 项目运行状态的操作
+ * @author: xiuwei
+ * @create: 2020-04-16 13:52
+ */
+@Service
+public class OperationStatusService {
+
+
+    @Autowired
+    OperationStatusMapper operationStatusMapper;
+
+
+    public List<OperationStatus> get(OperationStatus operationStatus){
+       return operationStatusMapper.get(operationStatus);
+    };
+    public int add(OperationStatus operationStatus){
+        return operationStatusMapper.add(operationStatus);
+    };
+    public int delete(OperationStatus operationStatus){
+        return operationStatusMapper.delete(operationStatus);
+    };
+    public int update(OperationStatus operationStatus){
+        return operationStatusMapper.update(operationStatus);
+    };
+
+}

+ 201 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/QueryDataService.java

@@ -0,0 +1,201 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000.D5000Operation;
+import com.jiayue.ipfcst.d5000.D5000information.D5000DataInfo;
+import com.jiayue.ipfcst.d5000.D5000information.D5000FixedValue;
+import com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice.RequestDataType;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 查询数据的服务
+ * @author: xiuwei
+ * @create: 2020-04-10 16:41
+ */
+@Service
+public class QueryDataService {
+    @Autowired
+    UsernamePasswordService usernamePasswordService;
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日实际功率
+     * @Date 2020/4/10 19:54
+     * @Param date
+     **/
+    public List<Float> queryActualPower(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RSJGL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日申报功率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryShortForecastPower(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RSBGL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日样板机功率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> querySamplePower(DateTime date, String ids) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName() + ids, D5000FixedValue.RYBJSBGL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 返回一个日考核指定的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Integer> queryDEvaluation(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RKHZD);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日准确率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryDAccuracyRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RYCZQL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日合格率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryDPassRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RYCHGL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询日传送率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryDTransmissionRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.RYCCSL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询年考核结果
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryYEvaluation(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.NYCKHJG);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询年准确率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryYAccuracyRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.NYCZQL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询年合格率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryYPassRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.NYCHGL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * @return RequestDataType
+     * @Author 修唯
+     * @Description 查询年传送率的请求
+     * @Date 2020/4/10 19:54
+     * @Param date 查询日期
+     **/
+    public List<Float> queryYTransmissionRate(DateTime date) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(date, usernamePasswordService.getUserName(), D5000FixedValue.NYCCSL);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+    /**
+     * @Author 修唯
+     * @Description  查询项目运行状态
+     * @Date 2020/4/20 17:09
+     * @Param
+     * @return date 查询日期 ids项目编号
+     **/
+    public List<Float> queryOperationStatus(DateTime dateTime,String ids) throws Exception {
+        RequestDataType requestDataType = new RequestDataType(dateTime, usernamePasswordService.getUserName()+ids, D5000FixedValue.DCXMYXZT);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+
+    /**
+     * 查询一些杂项 不需要ids的
+     * @param dateTime
+     * @param d5000DataInfo
+     * @return
+     * @throws Exception
+     */
+    public List queryNoIds(DateTime dateTime, D5000DataInfo d5000DataInfo ) throws Exception{
+        RequestDataType requestDataType = new RequestDataType(dateTime,usernamePasswordService.getUserName(),d5000DataInfo);
+        usernamePasswordService.setUserNameAndPassword(requestDataType);
+        return D5000Operation.reqData(requestDataType);
+    }
+
+}

+ 130 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RequestOtherService.java

@@ -0,0 +1,130 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import cn.hutool.http.HttpRequest;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.jiayue.ipfcst.d5000web.bean.FailedDualRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 向另一台机器发送请求
+ * @author: xiuwei
+ * @create: 2020-04-21 14:12
+ */
+@Service
+@Slf4j
+public class RequestOtherService {
+
+
+    @Value("${dual.isDual}")
+    Boolean isDual;
+
+    @Value("${dual.otherIp}")
+    String otherIp;
+
+    @Value("${dual.otherPort}")
+    String otherPort;
+
+    @Autowired
+    FailedDualRequestService failedDualRequestService;
+
+    public JSONObject put(String url, Object object) {
+        String s = "";
+        try {
+            if (isDual) {
+                s = HttpRequest.put("http://" + otherIp + ":" + otherPort + url).form(JSON.parseObject(JSON.toJSONString(object), Map.class)).setConnectionTimeout(500).execute().body();
+            }
+            JSONObject jsonObject = JSON.parseObject(s);
+            log.info("另一台机器响应" + jsonObject);
+            if (jsonObject.containsKey("code") && jsonObject.get("code").equals(0)) {
+                return jsonObject.getJSONObject("data");
+            }
+        } catch (Exception e) {
+            FailedDualRequest failedDualRequest=new FailedDualRequest();
+            failedDualRequest.setRequestType(0);
+            failedDualRequest.setRequestUrl(url);
+            failedDualRequest.setInsertTime(DateTime.now().getMillis());
+            failedDualRequest.setRequestJson(JSON.toJSONString(object));
+            failedDualRequestService.add(failedDualRequest);
+            log.error("向另一台机器请求发生异常", e.getLocalizedMessage());
+        }
+        return null;
+    }
+
+
+    public JSONObject post(String url, Object object) {
+        String s = "";
+        try {
+            if (isDual) {
+                s = HttpRequest.post("http://" + otherIp + ":" + otherPort + url).form(JSON.parseObject(JSON.toJSONString(object), Map.class)).setConnectionTimeout(500).execute().body();
+            }
+            JSONObject jsonObject = JSON.parseObject(s);
+            log.info("另一台机器响应" + jsonObject);
+            if (jsonObject.containsKey("code") && jsonObject.get("code").equals(0)) {
+                return jsonObject.getJSONObject("data");
+            }
+        } catch (Exception e) {
+            log.error("向另一台机器请求发生异常",e.getLocalizedMessage());
+            FailedDualRequest failedDualRequest=new FailedDualRequest();
+            failedDualRequest.setRequestType(1);
+            failedDualRequest.setRequestUrl(url);
+            failedDualRequest.setInsertTime(DateTime.now().getMillis());
+            failedDualRequest.setRequestJson(JSON.toJSONString(object));
+            failedDualRequestService.add(failedDualRequest);
+        }
+        return null;
+    }
+
+
+    public JSONObject delete(String url, Object object) {
+        String s = "";
+        try {
+            if (isDual) {
+                s = HttpRequest.delete("http://" + otherIp + ":" + otherPort + url).form(JSON.parseObject(JSON.toJSONString(object), Map.class)).setConnectionTimeout(500).execute().body();
+            }
+            JSONObject jsonObject = JSON.parseObject(s);
+            log.info("另一台机器响应" + jsonObject);
+            if (jsonObject.containsKey("code") && jsonObject.get("code").equals(0)) {
+                return jsonObject.getJSONObject("data");
+            }
+        } catch (Exception e) {
+            log.error("向另一台机器请求发生异常",e.getLocalizedMessage());
+            FailedDualRequest failedDualRequest=new FailedDualRequest();
+            failedDualRequest.setRequestType(2);
+            failedDualRequest.setRequestUrl(url);
+            failedDualRequest.setRequestJson(JSON.toJSONString(object));
+            failedDualRequest.setInsertTime(DateTime.now().getMillis());
+            failedDualRequestService.add(failedDualRequest);
+
+            //处理未响应的请求
+        }
+        return null;
+    }
+
+    public String get(String url) {
+        String s = "";
+        try {
+            if (isDual) {
+                s = HttpRequest.get("http://" + otherIp + ":" + otherPort + url).setConnectionTimeout(500).execute().body();
+            }
+            JSONObject jsonObject = JSON.parseObject(s);
+            log.info("另一台机器响应" + jsonObject);
+            if (jsonObject!=null && jsonObject.containsKey("code") && jsonObject.get("code").equals(0)) {
+                return jsonObject.getString("data");
+            }
+        } catch (Exception e) {
+           log.error("向另一台机器请求发生异常", e.getLocalizedMessage());
+            //处理未响应的请求
+        }
+        return null;
+    }
+
+
+}

+ 36 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RunAfterStart.java

@@ -0,0 +1,36 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.mapper.SampleDailyPowerMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * 启动后运行的东西
+ *
+ * @author: xiuwei
+ * @version:
+ */
+@Component
+@Slf4j
+public class RunAfterStart  implements ApplicationRunner {
+
+	@Autowired
+    SampleDailyPowerMapper sampleDailyPowerMapper;
+
+
+	@Override
+	public void run(ApplicationArguments args) throws Exception {
+		List<String> columns=sampleDailyPowerMapper.getAllColumn();
+		if(!columns.contains("ISAUTO")){
+			sampleDailyPowerMapper.addIsautoColumn();
+		}
+		if(!columns.contains("UPDATETIME")){
+			sampleDailyPowerMapper.addUpDateTimeColumn();
+		}
+	}
+}

+ 60 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/RunAfterStarted.java

@@ -0,0 +1,60 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import cn.hutool.extra.ftp.SimpleFtpServer;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ftpserver.ftplet.Authority;
+import org.apache.ftpserver.usermanager.impl.BaseUser;
+import org.apache.ftpserver.usermanager.impl.WritePermission;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.ApplicationArguments;
+import org.springframework.boot.ApplicationRunner;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 启动成功后自动运行
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+@Component
+@Slf4j
+public class RunAfterStarted implements ApplicationRunner {
+
+    @Value("${ftp.isUse: false}")
+    Boolean isUse;
+
+    @Value("${ftp.port: 21}")
+    Integer port;
+
+    @Value("${ftp.username: syjy}")
+    String username;
+
+    @Value("${ftp.password: syjy}")
+    String password;
+
+
+    @Value("${ftp.dir: /home/syjy/D5000/}")
+    String dir;
+
+    @Override
+    public void run(ApplicationArguments args) throws Exception {
+        if (isUse) {
+            BaseUser user = new BaseUser();
+            user.setName(username);
+            user.setPassword(password);
+            user.setHomeDirectory(dir);
+            List<Authority> authorities = new ArrayList<>();
+            authorities.add(new WritePermission());
+            user.setAuthorities(authorities);
+            SimpleFtpServer
+                    .create()
+                    .addUser(user)
+                    .setPort(port)
+                    .start();
+            System.out.println("ftp服务端开启成功");
+        }
+    }
+}

+ 157 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/SampleDailyPowerService.java

@@ -0,0 +1,157 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.DailyPower;
+import com.jiayue.ipfcst.d5000web.bean.SampleDailyPower;
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.mapper.SampleDailyPowerMapper;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import wei.yigulu.netty.BaseProtocolBuilder;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机数据操作服务
+ * @author: xiuwei
+ * @create: 2020-04-15 16:51
+ */
+@Service
+public class SampleDailyPowerService {
+
+    @Autowired
+    SampleDailyPowerMapper sampleDailyPowerMapper;
+
+    @Autowired
+    SampleInfoService sampleInfoService;
+
+    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+
+    SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+
+    public SampleDailyPower add(SampleDailyPower sampleDailyPower){
+        SampleDailyPower sampleDailyPower1=new SampleDailyPower();
+        sampleDailyPower1.setSampleId(sampleDailyPower.getSampleId());
+        sampleDailyPower1.setDate(sampleDailyPower.getDate());
+        if(get(sampleDailyPower1).size()==0) {
+            sampleDailyPowerMapper.add(sampleDailyPower);
+        }else{
+            sampleDailyPowerMapper.update(sampleDailyPower);
+        }
+        return sampleDailyPower;
+    }
+
+    public List<SampleDailyPower> get(SampleDailyPower sampleDailyPower){
+        return sampleDailyPowerMapper.get(sampleDailyPower);
+    }
+
+    public SampleDailyPower getLastRecode(){
+        return getLastRecode(null);
+    }
+
+    public SampleDailyPower getLastRecode(String sampleId){
+        return sampleDailyPowerMapper.getLastRecode(sampleId);
+    }
+
+    public Integer update(SampleDailyPower sampleDailyPower){
+        return sampleDailyPowerMapper.update(sampleDailyPower);
+    }
+
+    public List<String> uploadFailedSample(){
+        List<String> all= new ArrayList<>();
+        List<String> uploaded= new ArrayList<>();
+        for(SampleInfo s : sampleInfoService.get(null)){
+            all.add(s.getDid());
+        }
+        SampleDailyPower sampleDailyPower=new SampleDailyPower();
+        sampleDailyPower.setUploadDate(DateTime.now().toString("yyyy-MM-dd"));
+        for(SampleDailyPower s : get(sampleDailyPower)){
+            uploaded.add(s.getSampleId());
+        }
+        all.removeAll(uploaded);
+        return all;
+    }
+
+    public List<String> getFailedSample(){
+        List<String> all= new ArrayList<>();
+        List<String> got= new ArrayList<>();
+        for(SampleInfo s : sampleInfoService.get(null)){
+            all.add(s.getDid());
+        }
+        SampleDailyPower sampleDailyPower=new SampleDailyPower();
+        sampleDailyPower.setDate(DateTime.now().minusDays(1).toString("yyyy-MM-dd"));
+        sampleDailyPower.setIsAuto("N");
+        for(SampleDailyPower s : get(sampleDailyPower)){
+            got.add(s.getSampleId());
+        }
+        all.removeAll(got);
+        return all;
+    }
+
+    public void saveGatherData(BaseProtocolBuilder builder, Date updateDate, Double value, String sampleId,Double multiplier) throws ReflectiveOperationException {
+
+
+        String key = sampleId + "PNUM";
+        if (TimeUtils.isMoment(updateDate.getTime())) {
+            int moment = TimeUtils.getMoment(updateDate.getTime(), 900000l);
+            if (builder.getConfigInfoMap().get(key) == null || (int) builder.getConfigInfoMap().get(key) != moment) {
+
+                String updateDateFormat = dateFormat.format(new Date(updateDate.getTime()-900000l));
+                String updateDateTimeFormat = dateTimeFormat.format(updateDate);
+
+
+                SampleDailyPower sampleDailyPower = new SampleDailyPower();
+                sampleDailyPower.setDate(updateDateFormat);
+                SampleDailyPower one = sampleDailyPowerMapper.getOne(updateDateFormat, sampleId);
+
+                DecimalFormat df = new DecimalFormat("0.00");
+
+                if (multiplier != null) value = value * multiplier;
+
+                String value2 = df.format(value);
+
+                if (one != null) {
+                    sampleDailyPower = one;
+                    getSampleDailyPowerMethod(moment).invoke(sampleDailyPower, Double.parseDouble(value2));
+                    sampleDailyPower.setUpdateTime(updateDateTimeFormat);
+                    sampleDailyPowerMapper.update(sampleDailyPower);
+                } else {
+
+                    sampleDailyPower = initSampleDailyPower(sampleDailyPower);
+                    getSampleDailyPowerMethod(moment).invoke(sampleDailyPower, Double.parseDouble(value2));
+                    sampleDailyPower.setDate(updateDateFormat);
+                    sampleDailyPower.setUpdateTime(updateDateTimeFormat);
+                    sampleDailyPower.setSampleId(sampleId);
+                    sampleDailyPower.setIsAuto("N");
+                    sampleDailyPowerMapper.add(sampleDailyPower);
+                }
+
+                builder.getConfigInfoMap().put(key, moment);
+            }
+        }
+
+
+    }
+
+
+    private Method getSampleDailyPowerMethod(int moment) throws NoSuchMethodException {
+        return DailyPower.class.getMethod("setP" + moment, Double.class);
+    }
+
+
+    private SampleDailyPower initSampleDailyPower(SampleDailyPower sampleDailyPower) throws ReflectiveOperationException {
+        for (int i = 1; i <97; i++) {
+            getSampleDailyPowerMethod(i).invoke(sampleDailyPower, Double.parseDouble("0"));
+        }
+        return sampleDailyPower;
+    }
+
+}

+ 45 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/SampleInfoService.java

@@ -0,0 +1,45 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.mapper.SampleInfoMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 样板机的服务类
+ * @author: xiuwei
+ * @create: 2020-04-15 19:09
+ */
+@Service
+public class SampleInfoService {
+
+    @Autowired
+    SampleInfoMapper sampleInfoMapper;
+
+
+    public List<SampleInfo> get(SampleInfo sampleInfo) {
+        return sampleInfoMapper.get(sampleInfo);
+    }
+
+
+    public List<SampleInfo> getByChannelId(Integer channelId) {
+        return sampleInfoMapper.getByChannelId(channelId);
+    }
+
+    public int add(SampleInfo sampleInfo) {
+        return sampleInfoMapper.add(sampleInfo);
+    }
+
+    public int delete(SampleInfo sampleInfo) {
+        return sampleInfoMapper.delete(sampleInfo);
+    }
+
+    public int update(SampleInfo sampleInfo) {
+        return sampleInfoMapper.update(sampleInfo);
+    }
+
+
+}

+ 129 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/TimeUtils.java

@@ -0,0 +1,129 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import java.util.Calendar;
+
+/**
+ * 时间工具类
+ *
+ * @author tl
+ * @datetime 2023/2/9 15:54
+ */
+public abstract class TimeUtils {
+
+
+    /**
+     * 获取指定时间在当天所处于的时刻
+     * 例如:dateTime:2018-10-22 16:44:00 momentLength: 15分钟,既 15*60*1000毫秒
+     * 从0点0分开始计算,0点0分-0点15为第一个时刻,依次类推该时间的时刻数为67
+     *
+     * @param dateTime     时间毫秒
+     * @param momentLength 时刻长度,单位毫秒
+     * @return 时刻
+     */
+    public static int getMoment(final Long dateTime, final Long momentLength) {
+
+
+        int n = (int) ((dateTime - TimeUtils.getDayStartTime(dateTime)) / momentLength);
+        return n == 0 ? 96 : n;
+    }
+
+
+    /**
+     * 获取指定时间所在天的最后一个时刻的标记时间 <br>
+     * 例如:dateTime:2018-10-22 16:44:00 momentLength: 15*60*1000 <br>
+     * 当前标记signType:1 那么最后一个时刻的标记时间为2018-10-22 23:45:00
+     * 当后标记singType:2 那么最后一个时刻的标记时间为2018-10-23 00:00:00
+     *
+     * @param dateTime     时间毫秒
+     * @param signType     标记方式:1前标记 2后标记, 当null时按照前标记1处理
+     * @param momentLength 时刻长度,单位:毫秒
+     * @return 一天第一个时刻的标记时间,单位:毫秒
+     */
+    public static long getDayLastMomentTime(final Long dateTime, final int signType, final Long momentLength) throws Exception {
+        if (24 * 3600 * 1000L % momentLength != 0)
+            throw new Exception("时刻长度非法,时刻长度需要能够被一天整除");
+        Calendar date = Calendar.getInstance();
+        date.setTimeInMillis(dateTime);
+        date.add(Calendar.DATE, 1);
+        date.set(Calendar.HOUR_OF_DAY, 0);
+        date.set(Calendar.MINUTE, 0);
+        date.set(Calendar.SECOND, 0);
+        date.set(Calendar.MILLISECOND, 0);
+        switch (signType) {
+            case 2:
+                return date.getTimeInMillis();
+            default:
+                return date.getTimeInMillis() - momentLength;
+        }
+    }
+
+    /**
+     * 获取指定时间所在天的0点0分
+     *
+     * @param dateTime 时间毫秒
+     * @return 0点0分的毫秒
+     */
+    public static long getDayStartTime(final Long dateTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTimeInMillis(dateTime);
+        date.set(Calendar.HOUR_OF_DAY, 0);
+        date.set(Calendar.MINUTE, 0);
+        date.set(Calendar.SECOND, 0);
+        date.set(Calendar.MILLISECOND, 0);
+        return date.getTimeInMillis();
+    }
+
+    /**
+     * 获取指定时间所在天的23点59分59秒
+     *
+     * @param dateTime 时间毫秒
+     * @return 23点59分59秒的毫秒
+     */
+    public static long getDayLastTime(final Long dateTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTimeInMillis(dateTime);
+        date.set(Calendar.HOUR_OF_DAY, 23);
+        date.set(Calendar.MINUTE, 59);
+        date.set(Calendar.SECOND, 59);
+        date.set(Calendar.MILLISECOND, 999);
+        return date.getTimeInMillis();
+    }
+
+    /**
+     * 获取两个时间间的间隔天数(自然天)
+     *
+     * @param dateFrom 开始时间
+     * @param dateTo   结束时间
+     * @return 自然天数
+     */
+    public static Integer getDaysBetweenTwoDate(Long dateFrom, Long dateTo) {
+        return (int) ((TimeUtils.getDayStartTime(dateTo) - TimeUtils.getDayStartTime(dateFrom)) / (1000 * 60 * 60 * 24L));
+    }
+
+
+    /**
+     * 获取指定时间段有多少时刻
+     * 例如:dateTime:2018-10-22 16:44:00 momentLength: 15分钟,既 15*60*1000毫秒
+     * 从0点0分开始计算,0点0分-0点15为第一个时刻,依次类推该时间的时刻数为67
+     *
+     * @param momentLength 时刻长度,单位毫秒
+     * @return 时刻
+     */
+    public static int getIntervalMoment(final Long startTime, final Long endTime, final Long momentLength) {
+        return (int) ((endTime - startTime) / momentLength) + 1;
+    }
+
+
+    /**
+     * 判断时间的分钟是不是整时刻
+     *
+     * @param time
+     * @return
+     */
+    public static boolean isMoment(Long time) {
+        Long startTime = getDayStartTime(time);
+        if (((time - startTime) % 900000l) < 60000) return true;
+        return false;
+    }
+
+}

+ 109 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/Upload2D5000Service.java

@@ -0,0 +1,109 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.alibaba.fastjson.JSON;
+import com.jiayue.ipfcst.d5000.D5000Operation;
+import com.jiayue.ipfcst.d5000.D5000information.D5000FixedValue;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.UploadDataType;
+import com.jiayue.ipfcst.d5000web.bean.*;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: d5000-web
+ * @description: 向D5000传送数据
+ * @author: xiuwei
+ * @create: 2020-04-17 14:48
+ */
+@Service
+@Slf4j
+public class Upload2D5000Service {
+
+
+    @Autowired
+    UsernamePasswordService usernamePasswordService;
+
+    @Autowired
+    UploadedDailyPowerService uploadedDailyPowerService;
+
+    @Autowired
+    SampleDailyPowerService sampleDailyPowerService;
+
+    @Autowired
+    UploadedOperationStatusService uploadedOperationStatusService;
+
+    @Autowired
+    UploadedOperatingCapacityService uploadedOperatingCapacityService;
+
+    /**
+     * @Author 修唯
+     * @Description  上传短期数据 并向已上传的表中插入一条数据
+     * @Date 2020/4/20 14:08
+     * @Param
+     * @return
+     **/
+    public void uploadShortForecast(CollectedDailyPower collectedDailyPower) throws Exception {
+        UploadDataType uploadDataType = new UploadDataType(DateTime.parse(collectedDailyPower.getDate()), usernamePasswordService.getUserName(), D5000FixedValue.DQFGLYCSB, collectedDailyPower.convert2List());
+        usernamePasswordService.setUserNameAndPassword(uploadDataType);
+        if( D5000Operation.uploadData(uploadDataType)){
+            log.info("短期数据上传成功"+ JSON.toJSONString(collectedDailyPower));
+            UploadedDailyPower uploadedDailyPower=new UploadedDailyPower();
+            uploadedDailyPower.setUploadDate(DateTime.now().toString("yyyy-MM-dd"));
+            uploadedDailyPower.setFormDailyPower(collectedDailyPower);
+            uploadedDailyPower.setDate(collectedDailyPower.getDate());
+            uploadedDailyPowerService.add(uploadedDailyPower);
+            log.info("向已上传数据库插入"+JSON.toJSONString(uploadedDailyPower));
+        }
+    }
+
+
+    public void uploadSamplePower(SampleDailyPower sampleDailyPower) throws Exception {
+        UploadDataType uploadDataType = new UploadDataType(DateTime.parse(sampleDailyPower.getDate()), usernamePasswordService.getUserName()+sampleDailyPower.getSampleId(), D5000FixedValue.YBJGLSB, sampleDailyPower.convert2List());
+        usernamePasswordService.setUserNameAndPassword(uploadDataType);
+        if( D5000Operation.uploadData(uploadDataType)){
+            log.info("向D5000上传样板机数据:"+JSON.toJSONString(sampleDailyPower));
+            SampleDailyPower sampleDailyPower1=new SampleDailyPower();
+            sampleDailyPower1.setDate(sampleDailyPower.getDate());
+            sampleDailyPower1.setUploadDate(DateTime.now().toString("yyyy-MM-dd"));
+            sampleDailyPowerService.update(sampleDailyPower1);
+            log.info("已上传,并保存样板机数据:"+JSON.toJSONString(sampleDailyPower));
+        }
+    }
+
+    public void uploadOperationStatus(OperationStatus operationStatus) throws Exception {
+        UploadDataType uploadDataType = new UploadDataType(DateTime.now(), usernamePasswordService.getUserName()+operationStatus.getDid(), D5000FixedValue.XMYXZTSB, operationStatus.covert2List());
+        usernamePasswordService.setUserNameAndPassword(uploadDataType);
+        if( D5000Operation.uploadData(uploadDataType)){
+            log.info("向D5000上传项目运行状态"+JSON.toJSONString(operationStatus));
+            UploadedOperationStatus uploadedOperationStatus=new UploadedOperationStatus();
+            uploadedOperationStatus.setDid(operationStatus.getDid());
+            uploadedOperationStatus.setUploadDate(DateTime.now().toString("yyyy-MM-dd"));
+            uploadedOperationStatus.setGridConnCapacity(operationStatus.getGridConnCapacity());
+            uploadedOperationStatus.setOperatingCapacity(operationStatus.getOperatingCapacity());
+            uploadedOperationStatus.setMaintenanceCapacity(operationStatus.getMaintenanceCapacity());
+            uploadedOperationStatus.setOperatingUnitsNum(operationStatus.getOperatingUnitsNum());
+            log.info("项目运行状态存入已上传表"+JSON.toJSONString(uploadedOperationStatus));
+            uploadedOperationStatusService.add(uploadedOperationStatus);
+        }
+    }
+
+
+    public void uploadOperatingCapacity(OperatingCapacity operatingCapacity) throws Exception {
+        UploadDataType uploadDataType = new UploadDataType((DateTime.now().plusDays(1)), usernamePasswordService.getUserName(), D5000FixedValue.RYCYXRLSB, operatingCapacity.convert2List());
+        usernamePasswordService.setUserNameAndPassword(uploadDataType);
+        if( D5000Operation.uploadData(uploadDataType)){
+            log.info("向D5000上传预测运行容量:"+JSON.toJSONString(operatingCapacity));
+            UploadedOperatingCapacity uploadedOperatingCapacity=new UploadedOperatingCapacity();
+            uploadedOperatingCapacity.setUploadDate((DateTime.now().toString("yyyy-MM-dd")));
+            uploadedOperatingCapacity.setFormDailyPower(operatingCapacity);
+            uploadedOperatingCapacityService.add(uploadedOperatingCapacity);
+            log.info("已上传预测运行容量,并存入数据库:"+JSON.toJSONString(uploadedOperatingCapacity));
+        }
+    }
+
+
+
+
+
+}

+ 57 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadStatusService.java

@@ -0,0 +1,57 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import org.joda.time.DateTime;
+import org.joda.time.Days;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @program: d5000-web
+ * @description: 文件获取和上传获取服务
+ * @author: xiuwei
+ * @create: 2020-04-17 12:52
+ */
+@Service
+public class UploadStatusService {
+
+    @Autowired
+    SampleDailyPowerService sampleDailyPowerService;
+
+    @Autowired
+    UploadedDailyPowerService uploadedDailyPowerService;
+
+    @Autowired
+    UploadedOperatingCapacityService uploadedOperatingCapacityService;
+
+    @Autowired
+    UploadedOperationStatusService uploadedOperationStatusService;
+
+
+
+
+    public Map<String, List> uploadLocalStatus(){
+        Map<String, List> result=new HashMap<>();
+        List sample=sampleDailyPowerService.uploadFailedSample();
+        List<String> shortForecastString=uploadedDailyPowerService.getFailedDays();
+        List<Integer> shortForecast=new ArrayList<>();
+        DateTime d=DateTime.now();
+        for(String s:shortForecastString){
+            shortForecast.add(Days.daysBetween(d,DateTime.parse(s)).getDays()+1) ;
+        }
+        List operatingCapacity=new ArrayList();
+        operatingCapacity.add(uploadedOperatingCapacityService.getFailedOperatingCapacity());
+        List operationStatus=uploadedOperationStatusService.uploadFailedOperationStatus();
+        result.put("sample",sample);
+        result.put("shortForecast",shortForecast);
+        result.put("operatingCapacity",operatingCapacity);
+        result.put("operationStatus",operationStatus);
+        return result;
+    }
+
+
+}

+ 67 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedDailyPowerService.java

@@ -0,0 +1,67 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.UploadedDailyPower;
+import com.jiayue.ipfcst.d5000web.mapper.UploadedDailyPowerMapper;
+import org.apache.ibatis.annotations.Param;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description: 已经上传的日短期预测服务
+ * @author: xiuwei
+ * @create: 2020-04-17 13:03
+ */
+@Service
+public class UploadedDailyPowerService {
+
+    @Value("${uploadShortForecastDays}")
+    Integer uploadShortForecastDays;
+
+    @Autowired
+    UploadedDailyPowerMapper uploadedDailyPowerMapper;
+
+
+    public int add(UploadedDailyPower uploadedDailyPower) {
+        if(get(uploadedDailyPower).size()>0){
+            uploadedDailyPowerMapper.update(uploadedDailyPower);
+        }
+        return uploadedDailyPowerMapper.add(uploadedDailyPower);
+    }
+
+
+
+    public List<UploadedDailyPower> get(UploadedDailyPower uploadedDailyPower) {
+        return uploadedDailyPowerMapper.get(uploadedDailyPower);
+    }
+
+
+
+    public int addAll(@Param("list") List<UploadedDailyPower> uploadedDailyPowers) {
+        return uploadedDailyPowerMapper.addAll(uploadedDailyPowers);
+    }
+
+
+    public List<String> getFailedDays() {
+        List<String> all=new ArrayList<>();
+        DateTime nowDate=DateTime.now();
+        String date = nowDate.toString("yyyy-MM-dd");
+        UploadedDailyPower uploadedDailyPower = new UploadedDailyPower();
+        uploadedDailyPower.setUploadDate(date);
+        List <String> uploadedDate=new ArrayList<>();
+        for (int i = 1; i <= uploadShortForecastDays; i++) {
+            all.add(nowDate.plusDays(i).toString("yyyy-MM-dd"));
+        }
+        for(UploadedDailyPower u:uploadedDailyPowerMapper.get(uploadedDailyPower)){
+            uploadedDate.add(u.getDate());
+        }
+        all.removeAll(uploadedDate);
+        return  all;
+    }
+
+}

+ 40 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedOperatingCapacityService.java

@@ -0,0 +1,40 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.UploadedOperatingCapacity;
+import com.jiayue.ipfcst.d5000web.mapper.UploadedOperatingCapacityMapper;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description:
+ * @author: xiuwei
+ * @create: 2020-04-16 16:53
+ */
+@Service
+public class UploadedOperatingCapacityService {
+
+    @Autowired
+    UploadedOperatingCapacityMapper uploadedOperatingCapacityMapper;
+
+
+    public List<UploadedOperatingCapacity> get(UploadedOperatingCapacity uploadedOperatingCapacity) {
+        return uploadedOperatingCapacityMapper.get(uploadedOperatingCapacity);
+    }
+
+    public int add(UploadedOperatingCapacity uploadedOperatingCapacity) {
+        if(get(uploadedOperatingCapacity).size()>0){
+            uploadedOperatingCapacityMapper.update(uploadedOperatingCapacity);
+        }
+        return uploadedOperatingCapacityMapper.add(uploadedOperatingCapacity);
+    }
+
+    public Boolean getFailedOperatingCapacity(){
+        UploadedOperatingCapacity uploadedOperatingCapacity=new UploadedOperatingCapacity();
+        uploadedOperatingCapacity.setUploadDate(new DateTime().toString("yyyy-MM-dd"));
+        return get(uploadedOperatingCapacity).size()!=0;
+    }
+}

+ 57 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UploadedOperationStatusService.java

@@ -0,0 +1,57 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000web.bean.OperationStatus;
+import com.jiayue.ipfcst.d5000web.bean.UploadedOperationStatus;
+import com.jiayue.ipfcst.d5000web.mapper.UploadedOperationStatusMapper;
+import org.joda.time.DateTime;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @program: d5000-web
+ * @description:
+ * @author: xiuwei
+ * @create: 2020-04-16 16:52
+ */
+@Service
+public class UploadedOperationStatusService {
+
+    @Autowired
+    UploadedOperationStatusMapper uploadedOperationStatusMapper;
+
+    @Autowired
+    OperationStatusService operationStatusService;
+
+    public int add(UploadedOperationStatus uploadedOperationStatus) {
+        if(get(uploadedOperationStatus).size()>0){
+            uploadedOperationStatusMapper.update(uploadedOperationStatus);
+        }
+        return uploadedOperationStatusMapper.add(uploadedOperationStatus);
+    }
+
+
+    public List<UploadedOperationStatus> get(UploadedOperationStatus uploadedOperationStatus) {
+        return uploadedOperationStatusMapper.get(uploadedOperationStatus);
+    }
+
+
+    public List<String> uploadFailedOperationStatus(){
+        List<String> all=new ArrayList<>();
+        List<String> uploaded=new ArrayList<>();
+        UploadedOperationStatus uploadedOperationStatus=new UploadedOperationStatus();
+        uploadedOperationStatus.setUploadDate(new DateTime().toString("yyyy-MM-dd"));
+        for(OperationStatus o:operationStatusService.get(null)){
+            all.add(o.getDid());
+        }
+        for(UploadedOperationStatus u: get(uploadedOperationStatus)){
+            uploaded.add(u.getDid());
+        }
+        all.removeAll(uploaded);
+        return all;
+    }
+
+
+}

+ 76 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/d5000web/service/UsernamePasswordService.java

@@ -0,0 +1,76 @@
+package com.jiayue.ipfcst.d5000web.service;
+
+import com.jiayue.ipfcst.d5000.D5000Exception;
+import com.jiayue.ipfcst.d5000.D5000Utils;
+import com.jiayue.ipfcst.d5000.d5000dataframe.sandandrevice.RequestDataType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.ChangePasswordType;
+import com.jiayue.ipfcst.d5000.d5000dataframe.send.UploadDataType;
+import com.jiayue.ipfcst.d5000web.bean.UsernameAndPassword;
+import com.jiayue.ipfcst.d5000web.mapper.UsernameAndPasswordMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * @program: d5000-web
+ * @description: 向数据帧内注入用户名密码
+ * @author: xiuwei
+ * @create: 2020-04-10 19:11
+ */
+@Service
+public class UsernamePasswordService {
+
+    @Autowired
+    UsernameAndPasswordMapper usernameAndPasswordMapper;
+
+   UsernameAndPassword usernameAndPassword;
+
+    public RequestDataType setUserNameAndPassword(RequestDataType requestDataType){
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getUsername(), requestDataType.getUserName());
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getPassword(), requestDataType.getPassword());
+        return requestDataType;
+    }
+
+
+    public UploadDataType setUserNameAndPassword(UploadDataType uploadDataType){
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getUsername(), uploadDataType.getUserName());
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getPassword(), uploadDataType.getPassword());
+        return uploadDataType;
+    }
+
+
+    public ChangePasswordType setUserNameAndPassword(ChangePasswordType changePasswordType){
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getUsername(), changePasswordType.getUserName());
+        D5000Utils.stringAdd2ByteArray(getUsernameAndPassword().getPassword(), changePasswordType.getOldPassword());
+        return changePasswordType;
+    }
+
+
+
+    public  String getUserName(){
+        return  this.getUsernameAndPassword().getUsername();
+    }
+
+    private UsernameAndPassword getUsernameAndPassword(){
+        if(this.usernameAndPassword==null){
+            usernameAndPassword=usernameAndPasswordMapper.get();
+        }
+        return  this.usernameAndPassword;
+    }
+
+    /**
+     * @Author 修唯
+     * @Description  修改场站密码
+     * @Date 2020/4/13 11:26
+     * @Param
+     * @return
+     **/
+    public  void updatePassword(String newPassword) throws D5000Exception {
+            if(usernameAndPasswordMapper.update(newPassword)>0){
+                this.getUsernameAndPassword().setPassword(newPassword);
+            }else{
+                throw  new D5000Exception(505,"修改密码失败");
+            }
+
+    }
+
+}

+ 8 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/BaseProtocolTunnel.java

@@ -0,0 +1,8 @@
+package com.jiayue.ipfcst.gather;
+
+import wei.yigulu.iec104.nettyconfig.Iec104HSMasterBuilder;
+
+public abstract class BaseProtocolTunnel {
+
+
+}

+ 124 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/Gather104tcpClient.java

@@ -0,0 +1,124 @@
+package com.jiayue.ipfcst.gather;
+
+import cn.hutool.core.thread.ThreadFactoryBuilder;
+import com.jiayue.ipfcst.d5000web.bean.Gather104TCPChannel;
+import com.jiayue.ipfcst.d5000web.config.SpringContextUtil;
+import com.jiayue.ipfcst.d5000web.service.Gather104TcpChannelService;
+import io.netty.channel.Channel;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.apdumodel.Asdu;
+import wei.yigulu.iec104.asdudataframe.TotalSummonType;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.nettyconfig.Iec104HSMasterBuilder;
+import wei.yigulu.iec104.util.SendAndReceiveNumUtil;
+
+import java.util.Map;
+import java.util.concurrent.*;
+
+
+
+@Slf4j
+public class Gather104tcpClient extends BaseProtocolTunnel {
+
+    private final ExecutorService calculatorThread = new ThreadPoolExecutor(15, 1000,
+            60L, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactoryBuilder().setNamePrefix("MyRecurringTaskThread-").build());
+
+
+    private Map<Integer,Iec104HSMasterBuilder> builderMap  =new ConcurrentHashMap<>();
+
+    public void pbSendTotalSummonFrame() {
+        for (Map.Entry<Integer, Iec104HSMasterBuilder> builderEntry : builderMap.entrySet()) {
+            calculatorThread.execute(new Runnable() {
+                @Override
+                public void run() {
+                    listen(builderEntry.getValue(),(Integer) builderEntry.getValue().getConfigInfoMap().get("publicAddress"),0);
+                }
+            });
+        }
+    }
+
+
+    public void listen(Iec104HSMasterBuilder masterBuilder,Integer publicAddress,Integer connect) {
+        if(masterBuilder.isConnected()){
+            try {
+                sendTotalSummonFrame(masterBuilder.getFuture().channel(),publicAddress,6,log);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    Iec104HSMasterBuilder getMasterBuilder(String ip, Integer port) {
+
+        return new Iec104HSMasterBuilder(ip,port);
+    }
+
+
+    public void stop(Integer cid) {
+        Iec104HSMasterBuilder iec104HSMasterBuilder = builderMap.get(cid);
+        if(iec104HSMasterBuilder!=null){
+            iec104HSMasterBuilder.stop();
+            builderMap.remove(cid);
+        }
+    }
+
+
+    public void run() {
+        Gather104TcpChannelService gather104TcpChannelService = SpringContextUtil.getBean(Gather104TcpChannelService.class);
+        for (Gather104TCPChannel gather104TCPChannel : gather104TcpChannelService.get()) {
+            start(gather104TCPChannel);
+        }
+    }
+
+    public Iec104HSMasterBuilder start(Gather104TCPChannel gather104TCPChannel) {
+        Iec104HSMasterBuilder masterBuilder = new Gather104tcpClient().getMasterBuilder(gather104TCPChannel.getRemoteIp(), gather104TCPChannel.getRemotePort());
+
+        calculatorThread.execute(new Runnable() {
+            @Override
+            public void run() {
+                masterBuilder.create();
+            }
+        });
+
+
+        masterBuilder.getConfigInfoMap().put("channelId",gather104TCPChannel.getCid());
+        masterBuilder.getConfigInfoMap().put("publicAddress",gather104TCPChannel.getPublicAddress());
+        builderMap.put(gather104TCPChannel.getCid(),masterBuilder);
+        return masterBuilder;
+    }
+
+
+    public static final Gather104tcpClient getInstance() {
+        return Gather104tcpClient.LazyHolder.INSTANCE;
+    }
+
+
+    /**
+     * 发送总召唤 帧
+     *
+     * @param channel 通道对象
+     * @param address 公共地址位
+     * @param cause   发送的原因
+     * @throws Exception 异常
+     */
+    public static void sendTotalSummonFrame(Channel channel, Integer address, Integer cause, Logger log) throws Exception {
+        Asdu asdu;
+        TotalSummonType dataFrameType = new TotalSummonType();
+        dataFrameType.setAddress(new InformationBodyAddress(0));
+        dataFrameType.setValue(20);
+        asdu = dataFrameType.generateBack();
+        asdu.setNot(cause);
+        asdu.setCommonAddress(address);
+        Apdu apdu = new Apdu().setAsdu(asdu);
+        SendAndReceiveNumUtil.sendIFrame(apdu, channel, log);
+    }
+
+    private static class LazyHolder {
+        private static final Gather104tcpClient INSTANCE = new Gather104tcpClient();
+    }
+
+
+}

+ 80 - 0
ipfcst/D5000-web/src/main/java/com/jiayue/ipfcst/gather/HandleShortFloat.java

@@ -0,0 +1,80 @@
+package com.jiayue.ipfcst.gather;
+
+
+import com.jiayue.ipfcst.d5000web.bean.SampleInfo;
+import com.jiayue.ipfcst.d5000web.config.SpringContextUtil;
+import com.jiayue.ipfcst.d5000web.service.SampleDailyPowerService;
+import com.jiayue.ipfcst.d5000web.service.SampleInfoService;
+import wei.yigulu.iec104.annotation.AsduType;
+import wei.yigulu.iec104.apdumodel.Apdu;
+import wei.yigulu.iec104.asdudataframe.ShortFloatType;
+import wei.yigulu.iec104.asdudataframe.qualitydescription.IeMeasuredQuality;
+import wei.yigulu.iec104.asdudataframe.typemodel.InformationBodyAddress;
+import wei.yigulu.iec104.nettyconfig.Iec104HSMasterBuilder;
+import wei.yigulu.netty.BaseProtocolBuilder;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 处理短浮点
+ *
+ * @author 修唯xiuwei
+ * @version 3.0
+ */
+@AsduType(typeId = 13)
+public class HandleShortFloat extends ShortFloatType {
+
+//  private ProtocolDataContainer protocolDataContainer = ProtocolDataContainer.getInstance();
+
+
+    /**
+     * 处理短浮点数据
+     */
+    @Override
+    public byte[][] handleAndAnswer(Apdu apdu) throws ReflectiveOperationException {
+        apdu.getLog().trace("----------处理短浮点数据---------");
+        BaseProtocolBuilder builder = apdu.getIec104Builder();
+        if (builder != null && builder instanceof Iec104HSMasterBuilder) {
+
+            HandleShortFloat handleShortFloat = (HandleShortFloat) apdu.getAsdu().getDataFrame();
+            List<InformationBodyAddress> address = handleShortFloat.getAddresses();
+            Map<IeMeasuredQuality, Float> dates = handleShortFloat.getDatas();
+            Integer channelId = (Integer) builder.getConfigInfoMap().get("channelId");
+            SampleInfoService sampleInfoService = SpringContextUtil.getBean(SampleInfoService.class);
+            SampleDailyPowerService sampleDailyPowerService = SpringContextUtil.getBean(SampleDailyPowerService.class);
+            Date date = new Date();
+            List<SampleInfo> sampleInfos = sampleInfoService.getByChannelId(channelId);
+
+            int i = 0;
+            //存入数据表
+            if (apdu.getAsdu().getVsq().getSq() == 0) {
+                apdu.getLog().info("------处理短浮点单一寻址-----");
+                for (Map.Entry<IeMeasuredQuality, Float> e : dates.entrySet()) {
+                    for (SampleInfo info : sampleInfos) {
+                        if (info.getPoint().equals(address.get(i).getAddress()) && e.getKey().isGoodValue()) {
+                            sampleDailyPowerService.saveGatherData(builder, date, e.getValue().doubleValue(), info.getDid() + "", info.getMultiplier());
+                        }
+                    }
+                    i++;
+                }
+            } else if (apdu.getAsdu().getVsq().getSq() == 1) {
+                apdu.getLog().info("------处理短浮点连续寻址-----");
+                i = address.get(0).getAddress();
+                for (Map.Entry<IeMeasuredQuality, Float> e : dates.entrySet()) {
+                    for (SampleInfo info : sampleInfos) {
+                        if (info.getPoint().equals(i) &&  e.getKey().isGoodValue()) {
+                            sampleDailyPowerService.saveGatherData(builder, date, e.getValue().doubleValue(), info.getDid() + "", info.getMultiplier());
+                        }
+                    }
+                    i++;
+                }
+            }
+        }
+
+
+        return null;
+    }
+
+}

+ 2 - 0
ipfcst/D5000-web/src/main/resources/IEC104.properties

@@ -0,0 +1,2 @@
+haveStartAsk=false
+

+ 26 - 0
ipfcst/D5000-web/src/main/resources/config/dev/application-D5000.yml

@@ -0,0 +1,26 @@
+d5000:
+  masterIp : 192.168.1.206  #省/地 调侧ip
+  masterSpareIp : 192.168.1.206   #省/地  调侧备用ip
+  masterPort : 2404          #省/地  调侧端口
+  selfIp : 192.168.1.180      #本机与省调通讯使用的ip  本侧ip
+  selfPortRange : 2400-2500   #本机对外请求时使用的端口   本侧
+  selfServerPort : 2404       #本机开放服务的端口       本侧
+  filePath : D:\1    # 短期文件放置的位置
+  operatingCapacity : 48         #场站运行容量 MW
+trigger:
+  getShortForecastData :  "0 * * * * ?"        # 获取短期数据定时任务 0-8点 0分开始每15分钟一次  0 0/15 0,1,2,3,4,5,6,7,8 * * ?
+  uploadShortForecastData :  "0 3/15 0,1,2,3,4,5,6,7,8 * * ?"     # 上传短期数据定时任务 0-8点 3分开始每15分钟一次  0 3/15 0,1,2,3,4,5,6,7,8 * * ? *
+  uploadOperationStatus :  "0 6/15 0,1,2,3,4 * * ? *"       # 上传项目运行转态定时任务 0-4点 6分开始每15分钟一次  0 6/15 0,1,2,3,4 * * ? *
+  uploadOperatingCapacity :  "0 9/15 0,1,2 * * ? *"     # 上传预测项目容量定时任务 0-2点 9分开始每15分钟一次  0 9/15 0,1,2 * * ? *
+  uploadSampleData :  "0 2/5 0,1,2 * * ? *"           # 上传样板机数据定时任务 0-2点 2分开始每5分钟一次  0 2/5 0,1,2 * * ? *
+  reportFileReceiveAndUploadStatus : "0 0/5 * * * ?"       # 每五分钟向功率预测上报短期文件接收和上传的状态
+  getSampleFileData : "0 0/1 * * * ? *"           #在功率预测提供样板机数据的情况下 每天的0-2点扫描  15分钟一次 0 10/15 0,1 * * ? *
+dual :
+  isDual : true                #是否存在备机   true:主备机模式  须填写下方的ip和端口    false :单机模式 可以不填下面ip和端口
+  otherIp : 192.168.9.156       #另一台服务器的ip
+  otherPort : 8999              #另一台服务器的端口
+
+uploadShortForecastDays : 10    #短期预测数据的天数 最多10天
+powerStationType : 1           #电场的类型  0:风电场    1:光伏电站
+forecastServerIpAndPort : 10.10.10.123:9001   # 功率预测服务器的 ip:端口   当功率预测是沈阳嘉越的V3时 可以配置ip  解开注释 其他厂家删除该配置
+ipOfThisServer : 10.10.10.10              # 本机与功率预测交互所使用的ip   当功率预测是沈阳嘉越的V3时 可以配置ip 其他厂家删除该配置

+ 17 - 0
ipfcst/D5000-web/src/main/resources/config/dev/application.properties

@@ -0,0 +1,17 @@
+server.port=8999
+server.ssl.key-store=classpath:ipfcst.keystore
+server.ssl.key-store-password=jiayue6677*
+server.ssl.key-store-type=JKS
+spring.datasource.url=jdbc:h2:file:./dbh2/dbc2m
+spring.datasource.username=sa
+spring.datasource.password=root
+spring.datasource.driver-class-name=org.h2.Driver
+spring.h2.console.enabled=true
+spring.h2.console.path=/h2-console
+spring.h2.console.settings.web-allow-others=false
+#spring.datasource.schema=classpath:create.sql
+spring.profiles.active=D5000
+mybatis.type-aliases-package=com.jiayue.ipfcst.d5000web.bean
+mybatis.mapper-locations=classpath:/mapper/*.xml
+logging.level.com.jiayue.ipfcst.d5000web.mapper=debug
+trigger.synchronizeDataTasks=0 0 1 * * ? *

+ 637 - 0
ipfcst/D5000-web/src/main/resources/create.sql

@@ -0,0 +1,637 @@
+create schema D5000;
+
+drop table if  exists COLLECTEDDAILYPOWER;
+create table D5000.COLLECTEDDAILYPOWER
+(
+    ID INTEGER  auto_increment,
+    DATE VARCHAR
+        constraint COLLECTEDDAILYPOWER_DATE_UINDEX
+            unique,
+    UPDATEDATE VARCHAR,
+    P1 DOUBLE,
+    P2 DOUBLE,
+    P3 DOUBLE,
+    P4 DOUBLE,
+    P5 DOUBLE,
+    P6 DOUBLE,
+    P7 DOUBLE,
+    P8 DOUBLE,
+    P9 DOUBLE,
+    P10 DOUBLE,
+    P11 DOUBLE,
+    P12 DOUBLE,
+    P13 DOUBLE,
+    P14 DOUBLE,
+    P15 DOUBLE,
+    P16 DOUBLE,
+    P17 DOUBLE,
+    P18 DOUBLE,
+    P19 DOUBLE,
+    P20 DOUBLE,
+    P21 DOUBLE,
+    P22 DOUBLE,
+    P23 DOUBLE,
+    P24 DOUBLE,
+    P25 DOUBLE,
+    P26 DOUBLE,
+    P27 DOUBLE,
+    P28 DOUBLE,
+    P29 DOUBLE,
+    P30 DOUBLE,
+    P31 DOUBLE,
+    P32 DOUBLE,
+    P33 DOUBLE,
+    P34 DOUBLE,
+    P35 DOUBLE,
+    P36 DOUBLE,
+    P37 DOUBLE,
+    P38 DOUBLE,
+    P39 DOUBLE,
+    P40 DOUBLE,
+    P41 DOUBLE,
+    P42 DOUBLE,
+    P43 DOUBLE,
+    P44 DOUBLE,
+    P45 DOUBLE,
+    P46 DOUBLE,
+    P47 DOUBLE,
+    P48 DOUBLE,
+    P49 DOUBLE,
+    P50 DOUBLE,
+    P51 DOUBLE,
+    P52 DOUBLE,
+    P53 DOUBLE,
+    P54 DOUBLE,
+    P55 DOUBLE,
+    P56 DOUBLE,
+    P57 DOUBLE,
+    P58 DOUBLE,
+    P59 DOUBLE,
+    P60 DOUBLE,
+    P61 DOUBLE,
+    P62 DOUBLE,
+    P63 DOUBLE,
+    P64 DOUBLE,
+    P65 DOUBLE,
+    P66 DOUBLE,
+    P67 DOUBLE,
+    P68 DOUBLE,
+    P69 DOUBLE,
+    P70 DOUBLE,
+    P71 DOUBLE,
+    P72 DOUBLE,
+    P73 DOUBLE,
+    P74 DOUBLE,
+    P75 DOUBLE,
+    P76 DOUBLE,
+    P77 DOUBLE,
+    P78 DOUBLE,
+    P79 DOUBLE,
+    P80 DOUBLE,
+    P81 DOUBLE,
+    P82 DOUBLE,
+    P83 DOUBLE,
+    P84 DOUBLE,
+    P85 DOUBLE,
+    P86 DOUBLE,
+    P87 DOUBLE,
+    P88 DOUBLE,
+    P89 DOUBLE,
+    P90 DOUBLE,
+    P91 DOUBLE,
+    P92 DOUBLE,
+    P93 DOUBLE,
+    P94 DOUBLE,
+    P95 DOUBLE,
+    P96 DOUBLE,
+    IS_MANUAL BOOLEAN default FALSE,
+    constraint COLLECTEDDAILYPOWER_PK
+        primary key (ID)
+);
+
+comment on column D5000.COLLECTEDDAILYPOWER.DATE is '该条短期数据描述的日期
+';
+
+drop table if  exists OPERATING_CAPACITY;
+create table D5000.OPERATING_CAPACITY
+(
+    ID INTEGER  auto_increment,
+    P1 DOUBLE,
+    P2 DOUBLE,
+    P3 DOUBLE,
+    P4 DOUBLE,
+    P5 DOUBLE,
+    P6 DOUBLE,
+    P7 DOUBLE,
+    P8 DOUBLE,
+    P9 DOUBLE,
+    P10 DOUBLE,
+    P11 DOUBLE,
+    P12 DOUBLE,
+    P13 DOUBLE,
+    P14 DOUBLE,
+    P15 DOUBLE,
+    P16 DOUBLE,
+    P17 DOUBLE,
+    P18 DOUBLE,
+    P19 DOUBLE,
+    P20 DOUBLE,
+    P21 DOUBLE,
+    P22 DOUBLE,
+    P23 DOUBLE,
+    P24 DOUBLE,
+    P25 DOUBLE,
+    P26 DOUBLE,
+    P27 DOUBLE,
+    P28 DOUBLE,
+    P29 DOUBLE,
+    P30 DOUBLE,
+    P31 DOUBLE,
+    P32 DOUBLE,
+    P33 DOUBLE,
+    P34 DOUBLE,
+    P35 DOUBLE,
+    P36 DOUBLE,
+    P37 DOUBLE,
+    P38 DOUBLE,
+    P39 DOUBLE,
+    P40 DOUBLE,
+    P41 DOUBLE,
+    P42 DOUBLE,
+    P43 DOUBLE,
+    P44 DOUBLE,
+    P45 DOUBLE,
+    P46 DOUBLE,
+    P47 DOUBLE,
+    P48 DOUBLE,
+    P49 DOUBLE,
+    P50 DOUBLE,
+    P51 DOUBLE,
+    P52 DOUBLE,
+    P53 DOUBLE,
+    P54 DOUBLE,
+    P55 DOUBLE,
+    P56 DOUBLE,
+    P57 DOUBLE,
+    P58 DOUBLE,
+    P59 DOUBLE,
+    P60 DOUBLE,
+    P61 DOUBLE,
+    P62 DOUBLE,
+    P63 DOUBLE,
+    P64 DOUBLE,
+    P65 DOUBLE,
+    P66 DOUBLE,
+    P67 DOUBLE,
+    P68 DOUBLE,
+    P69 DOUBLE,
+    P70 DOUBLE,
+    P71 DOUBLE,
+    P72 DOUBLE,
+    P73 DOUBLE,
+    P74 DOUBLE,
+    P75 DOUBLE,
+    P76 DOUBLE,
+    P77 DOUBLE,
+    P78 DOUBLE,
+    P79 DOUBLE,
+    P80 DOUBLE,
+    P81 DOUBLE,
+    P82 DOUBLE,
+    P83 DOUBLE,
+    P84 DOUBLE,
+    P85 DOUBLE,
+    P86 DOUBLE,
+    P87 DOUBLE,
+    P88 DOUBLE,
+    P89 DOUBLE,
+    P90 DOUBLE,
+    P91 DOUBLE,
+    P92 DOUBLE,
+    P93 DOUBLE,
+    P94 DOUBLE,
+    P95 DOUBLE,
+    P96 DOUBLE,
+    constraint OPERATING_CAPACITY_PK
+        primary key (ID)
+);
+
+drop table if  exists OPERATION_STATUS;
+create table D5000.OPERATION_STATUS
+(
+    ID INTEGER auto_increment,
+    DID VARCHAR
+        constraint OPERATION_STATUS_DID_UINDEX
+            unique,
+    GRIDCONNCAPACITY DOUBLE not null,
+    OPERATINGCAPACITY DOUBLE,
+    MAINTENANCECAPACITY DOUBLE,
+    OPERATINGUNITSNUM INTEGER,
+    NAME VARCHAR,
+    constraint OPERATION_STATUS_PK
+        primary key (ID)
+);
+
+comment on column D5000.OPERATION_STATUS.OPERATINGUNITSNUM is '运行机组台数';
+
+
+drop table if  exists SAMPLEDAILYPOWER;
+create table D5000.SAMPLEDAILYPOWER
+(
+    ID INTEGER  auto_increment,
+    DATE VARCHAR,
+    UPLOADDATE VARCHAR,
+    SAMPLEID VARCHAR,
+    P1 DOUBLE,
+    P2 DOUBLE,
+    P3 DOUBLE,
+    P4 DOUBLE,
+    P5 DOUBLE,
+    P6 DOUBLE,
+    P7 DOUBLE,
+    P8 DOUBLE,
+    P9 DOUBLE,
+    P10 DOUBLE,
+    P11 DOUBLE,
+    P12 DOUBLE,
+    P13 DOUBLE,
+    P14 DOUBLE,
+    P15 DOUBLE,
+    P16 DOUBLE,
+    P17 DOUBLE,
+    P18 DOUBLE,
+    P19 DOUBLE,
+    P20 DOUBLE,
+    P21 DOUBLE,
+    P22 DOUBLE,
+    P23 DOUBLE,
+    P24 DOUBLE,
+    P25 DOUBLE,
+    P26 DOUBLE,
+    P27 DOUBLE,
+    P28 DOUBLE,
+    P29 DOUBLE,
+    P30 DOUBLE,
+    P31 DOUBLE,
+    P32 DOUBLE,
+    P33 DOUBLE,
+    P34 DOUBLE,
+    P35 DOUBLE,
+    P36 DOUBLE,
+    P37 DOUBLE,
+    P38 DOUBLE,
+    P39 DOUBLE,
+    P40 DOUBLE,
+    P41 DOUBLE,
+    P42 DOUBLE,
+    P43 DOUBLE,
+    P44 DOUBLE,
+    P45 DOUBLE,
+    P46 DOUBLE,
+    P47 DOUBLE,
+    P48 DOUBLE,
+    P49 DOUBLE,
+    P50 DOUBLE,
+    P51 DOUBLE,
+    P52 DOUBLE,
+    P53 DOUBLE,
+    P54 DOUBLE,
+    P55 DOUBLE,
+    P56 DOUBLE,
+    P57 DOUBLE,
+    P58 DOUBLE,
+    P59 DOUBLE,
+    P60 DOUBLE,
+    P61 DOUBLE,
+    P62 DOUBLE,
+    P63 DOUBLE,
+    P64 DOUBLE,
+    P65 DOUBLE,
+    P66 DOUBLE,
+    P67 DOUBLE,
+    P68 DOUBLE,
+    P69 DOUBLE,
+    P70 DOUBLE,
+    P71 DOUBLE,
+    P72 DOUBLE,
+    P73 DOUBLE,
+    P74 DOUBLE,
+    P75 DOUBLE,
+    P76 DOUBLE,
+    P77 DOUBLE,
+    P78 DOUBLE,
+    P79 DOUBLE,
+    P80 DOUBLE,
+    P81 DOUBLE,
+    P82 DOUBLE,
+    P83 DOUBLE,
+    P84 DOUBLE,
+    P85 DOUBLE,
+    P86 DOUBLE,
+    P87 DOUBLE,
+    P88 DOUBLE,
+    P89 DOUBLE,
+    P90 DOUBLE,
+    P91 DOUBLE,
+    P92 DOUBLE,
+    P93 DOUBLE,
+    P94 DOUBLE,
+    P95 DOUBLE,
+    P96 DOUBLE,
+    constraint SAMPLEDAILYPOWER_PK
+        primary key (ID)
+);
+
+drop table if  exists SAMPLE_INFO;
+create table D5000.SAMPLE_INFO
+(
+    ID INTEGER  auto_increment,
+    NAME VARCHAR,
+    DID VARCHAR,
+    constraint SAMPLEINFO_PK
+        primary key (ID)
+);
+
+ALTER TABLE D5000.SAMPLE_INFO ADD POINT INTEGER ;
+ALTER TABLE D5000.SAMPLE_INFO ADD CHANNELID INTEGER ;
+
+comment on table D5000.SAMPLE_INFO is '样板机信息';
+
+comment on column D5000.SAMPLE_INFO.NAME is '样板机名称';
+
+comment on column D5000.SAMPLE_INFO.DID is '该样板机所属D5000内的id';
+
+drop table if  exists UPLOADDAILYPOWER;
+create table D5000.UPLOADDAILYPOWER
+(
+    ID INTEGER  auto_increment,
+    DATE VARCHAR,
+    UPLOADDATE VARCHAR,
+    P1 DOUBLE,
+    P2 DOUBLE,
+    P3 DOUBLE,
+    P4 DOUBLE,
+    P5 DOUBLE,
+    P6 DOUBLE,
+    P7 DOUBLE,
+    P8 DOUBLE,
+    P9 DOUBLE,
+    P10 DOUBLE,
+    P11 DOUBLE,
+    P12 DOUBLE,
+    P13 DOUBLE,
+    P14 DOUBLE,
+    P15 DOUBLE,
+    P16 DOUBLE,
+    P17 DOUBLE,
+    P18 DOUBLE,
+    P19 DOUBLE,
+    P20 DOUBLE,
+    P21 DOUBLE,
+    P22 DOUBLE,
+    P23 DOUBLE,
+    P24 DOUBLE,
+    P25 DOUBLE,
+    P26 DOUBLE,
+    P27 DOUBLE,
+    P28 DOUBLE,
+    P29 DOUBLE,
+    P30 DOUBLE,
+    P31 DOUBLE,
+    P32 DOUBLE,
+    P33 DOUBLE,
+    P34 DOUBLE,
+    P35 DOUBLE,
+    P36 DOUBLE,
+    P37 DOUBLE,
+    P38 DOUBLE,
+    P39 DOUBLE,
+    P40 DOUBLE,
+    P41 DOUBLE,
+    P42 DOUBLE,
+    P43 DOUBLE,
+    P44 DOUBLE,
+    P45 DOUBLE,
+    P46 DOUBLE,
+    P47 DOUBLE,
+    P48 DOUBLE,
+    P49 DOUBLE,
+    P50 DOUBLE,
+    P51 DOUBLE,
+    P52 DOUBLE,
+    P53 DOUBLE,
+    P54 DOUBLE,
+    P55 DOUBLE,
+    P56 DOUBLE,
+    P57 DOUBLE,
+    P58 DOUBLE,
+    P59 DOUBLE,
+    P60 DOUBLE,
+    P61 DOUBLE,
+    P62 DOUBLE,
+    P63 DOUBLE,
+    P64 DOUBLE,
+    P65 DOUBLE,
+    P66 DOUBLE,
+    P67 DOUBLE,
+    P68 DOUBLE,
+    P69 DOUBLE,
+    P70 DOUBLE,
+    P71 DOUBLE,
+    P72 DOUBLE,
+    P73 DOUBLE,
+    P74 DOUBLE,
+    P75 DOUBLE,
+    P76 DOUBLE,
+    P77 DOUBLE,
+    P78 DOUBLE,
+    P79 DOUBLE,
+    P80 DOUBLE,
+    P81 DOUBLE,
+    P82 DOUBLE,
+    P83 DOUBLE,
+    P84 DOUBLE,
+    P85 DOUBLE,
+    P86 DOUBLE,
+    P87 DOUBLE,
+    P88 DOUBLE,
+    P89 DOUBLE,
+    P90 DOUBLE,
+    P91 DOUBLE,
+    P92 DOUBLE,
+    P93 DOUBLE,
+    P94 DOUBLE,
+    P95 DOUBLE,
+    P96 DOUBLE,
+    constraint UPLOADDAILYPOWER_PK
+        primary key (ID)
+);
+
+drop table if  exists UPLOADED_OPERATING_CAPACITY;
+create table D5000.UPLOADED_OPERATING_CAPACITY
+(
+    ID INTEGER  auto_increment,
+    UPLOADDATE VARCHAR,
+    P1 DOUBLE,
+    P2 DOUBLE,
+    P3 DOUBLE,
+    P4 DOUBLE,
+    P5 DOUBLE,
+    P6 DOUBLE,
+    P7 DOUBLE,
+    P8 DOUBLE,
+    P9 DOUBLE,
+    P10 DOUBLE,
+    P11 DOUBLE,
+    P12 DOUBLE,
+    P13 DOUBLE,
+    P14 DOUBLE,
+    P15 DOUBLE,
+    P16 DOUBLE,
+    P17 DOUBLE,
+    P18 DOUBLE,
+    P19 DOUBLE,
+    P20 DOUBLE,
+    P21 DOUBLE,
+    P22 DOUBLE,
+    P23 DOUBLE,
+    P24 DOUBLE,
+    P25 DOUBLE,
+    P26 DOUBLE,
+    P27 DOUBLE,
+    P28 DOUBLE,
+    P29 DOUBLE,
+    P30 DOUBLE,
+    P31 DOUBLE,
+    P32 DOUBLE,
+    P33 DOUBLE,
+    P34 DOUBLE,
+    P35 DOUBLE,
+    P36 DOUBLE,
+    P37 DOUBLE,
+    P38 DOUBLE,
+    P39 DOUBLE,
+    P40 DOUBLE,
+    P41 DOUBLE,
+    P42 DOUBLE,
+    P43 DOUBLE,
+    P44 DOUBLE,
+    P45 DOUBLE,
+    P46 DOUBLE,
+    P47 DOUBLE,
+    P48 DOUBLE,
+    P49 DOUBLE,
+    P50 DOUBLE,
+    P51 DOUBLE,
+    P52 DOUBLE,
+    P53 DOUBLE,
+    P54 DOUBLE,
+    P55 DOUBLE,
+    P56 DOUBLE,
+    P57 DOUBLE,
+    P58 DOUBLE,
+    P59 DOUBLE,
+    P60 DOUBLE,
+    P61 DOUBLE,
+    P62 DOUBLE,
+    P63 DOUBLE,
+    P64 DOUBLE,
+    P65 DOUBLE,
+    P66 DOUBLE,
+    P67 DOUBLE,
+    P68 DOUBLE,
+    P69 DOUBLE,
+    P70 DOUBLE,
+    P71 DOUBLE,
+    P72 DOUBLE,
+    P73 DOUBLE,
+    P74 DOUBLE,
+    P75 DOUBLE,
+    P76 DOUBLE,
+    P77 DOUBLE,
+    P78 DOUBLE,
+    P79 DOUBLE,
+    P80 DOUBLE,
+    P81 DOUBLE,
+    P82 DOUBLE,
+    P83 DOUBLE,
+    P84 DOUBLE,
+    P85 DOUBLE,
+    P86 DOUBLE,
+    P87 DOUBLE,
+    P88 DOUBLE,
+    P89 DOUBLE,
+    P90 DOUBLE,
+    P91 DOUBLE,
+    P92 DOUBLE,
+    P93 DOUBLE,
+    P94 DOUBLE,
+    P95 DOUBLE,
+    P96 DOUBLE,
+    constraint UPLOADED_OPERATING_CAPACITY_PK
+        primary key (ID)
+);
+drop table if  exists UPLOADED_OPERATION_STATUS;
+create table D5000.UPLOADED_OPERATION_STATUS
+(
+    ID INTEGER  auto_increment,
+    UPLOADDATE VARCHAR,
+    DID VARCHAR
+        unique,
+    GRIDCONNCAPACITY DOUBLE not null,
+    OPERATINGCAPACITY DOUBLE,
+    MAINTENANCECAPACITY DOUBLE,
+    OPERATINGUNITSNUM INTEGER,
+    NAME VARCHAR,
+    constraint UPLOADED_OPERATION_STATUS_PK
+        primary key (ID)
+);
+drop table if  exists USERNAME_PASSWORD;
+create table D5000.USERNAME_PASSWORD
+(
+    ID INTEGER  auto_increment,
+    USERNAME VARCHAR,
+    PASSWORD VARCHAR,
+    constraint USERNAME_PASSWORD_PK
+        primary key (ID)
+);
+
+comment on table D5000.USERNAME_PASSWORD is '场站D5000的用户名密码';
+
+comment on column D5000.USERNAME_PASSWORD.USERNAME is '用户名';
+
+comment on column D5000.USERNAME_PASSWORD.PASSWORD is '密码';
+
+drop table if  exists FAILED_DUAL_REQUEST;
+create table D5000.FAILED_DUAL_REQUEST
+(
+    ID INTEGER  auto_increment,
+    REQUESTTYPE INTEGER,
+    REQUESTURL VARCHAR,
+    REQUESTJSON VARCHAR,
+    INSERTTIME INTEGER,
+    constraint FAILED_DUAL_REQUEST_PK
+        primary key (ID)
+);
+
+drop table if  exists GATHER_104_TCP_CHANNEL;
+create table D5000.GATHER_104_TCP_CHANNEL
+    (
+    ID INTEGER  auto_increment,
+    CID VARCHAR unique ,
+    CHANNELNAME VARCHAR,
+    REMOTEIP VARCHAR,
+    REMOTEPORT INTEGER,
+    REMOTESPAREPORT INTEGER,
+    LOCALIP VARCHAR,
+    LOCALPORT INTEGER,
+    PUBLICADDRESS VARCHAR,
+    constraint GATHER_104_TCP_CHANNELT_PK
+    primary key (ID)
+    );
+
+alter table D5000.SAMPLE_INFO add CHANNELID integer
+alter table D5000.SAMPLE_INFO add POINT integer
+alter table D5000.SAMPLE_INFO add MULTIPLIER double
+
+alter table D5000.SAMPLE_INFO drop index date

BIN
ipfcst/D5000-web/src/main/resources/ipfcst.keystore


+ 86 - 0
ipfcst/D5000-web/src/main/resources/logback.xml

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
+  scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
+  debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+
+    <!--子节点<property> :用来定义变量值,它有两个属性name和value,
+    通过<property>定义的值会被插入到logger上下文中,可以使“${}”来使用变量。-->
+    <property name="APP_Name" value="D5000"/>
+
+    <property name="Log_Dir" value="./"/>
+
+    <!-- 子节点<contextName>:用来设置上下文名称,每个logger都关联到logger上下文,默认上下文名称为default。
+    但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。-->
+    <contextName>${APP_Name}</contextName>
+
+
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder charset="UTF-8">
+            <pattern>${APP_Name}-%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="AllFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${Log_Dir}/logs/info.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <FileNamePattern>${Log_Dir}/logs/%d{yyyy-MM-dd}/info.%i.log</FileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <totalSizeCap>2GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+
+    <appender name="WebInfoFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${Log_Dir}/logs/webInfo.log</file>
+               
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+                       
+            <level>INFO</level>
+                       
+            <onMatch>ACCEPT</onMatch>
+                       
+            <onMismatch>DENY</onMismatch>
+                   
+        </filter>
+        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
+            <FileNamePattern>${Log_Dir}/logs/%d{yyyy-MM-dd}/webInfo.%i.log</FileNamePattern>
+            <MaxHistory>30</MaxHistory>
+            <maxFileSize>100MB</maxFileSize>
+            <totalSizeCap>2GB</totalSizeCap>
+        </rollingPolicy>
+        <encoder charset="UTF-8" class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</pattern>
+        </encoder>
+    </appender>
+
+
+    <!--子节点<root>:它也是<logger>元素,但是它是根logger,是所有<logger>的上级。
+    只有一个level属性,因为name已经被命名为"root",且已经是最上级了。
+  level: 用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,
+    不能设置为INHERITED或者同义词NULL。 默认是DEBUG。-->
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="WebInfoFile"/>
+    </root>
+    <logger name="com.jiayue.ipfcst.d5000web.mapper" level="WARN" additivity="false">
+        <appender-ref ref="WebInfoFile"/>
+    </logger>
+    <logger name="com.jiayue.ipfcst.d5000web.controllerutil.ControllerAOP" level="DEBUG" additivity="false">
+        <appender-ref ref="WebInfoFile"/>
+    </logger>
+
+    <logger name="com.syjy" level="info" additivity="false">
+        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="AllFile"/>
+    </logger>
+    <logger name="wei.yigulu" level="DEBUG" additivity="false">
+        <appender-ref ref="STDOUT"/>
+        <appender-ref ref="AllFile"/>
+    </logger>
+
+</configuration>

+ 246 - 0
ipfcst/D5000-web/src/main/resources/mapper/CollectedDailyPowerMapper.xml

@@ -0,0 +1,246 @@
+<?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.jiayue.ipfcst.d5000web.mapper.CollectedDailyPowerMapper">
+
+    <resultMap type="com.jiayue.ipfcst.d5000web.bean.DailyPower" id="dailyPower">
+        <result property="p1" column="P1"/>
+        <result property="p2" column="P2"/>
+        <result property="p3" column="P3"/>
+        <result property="p4" column="P4"/>
+        <result property="p5" column="P5"/>
+        <result property="p6" column="P6"/>
+        <result property="p7" column="P7"/>
+        <result property="p8" column="P8"/>
+        <result property="p9" column="P9"/>
+        <result property="p10" column="P10"/>
+        <result property="p11" column="P11"/>
+        <result property="p12" column="P12"/>
+        <result property="p13" column="P13"/>
+        <result property="p14" column="P14"/>
+        <result property="p15" column="P15"/>
+        <result property="p16" column="P16"/>
+        <result property="p17" column="P17"/>
+        <result property="p18" column="P18"/>
+        <result property="p19" column="P19"/>
+        <result property="p20" column="P20"/>
+        <result property="p21" column="P21"/>
+        <result property="p22" column="P22"/>
+        <result property="p23" column="P23"/>
+        <result property="p24" column="P24"/>
+        <result property="p25" column="P25"/>
+        <result property="p26" column="P26"/>
+        <result property="p27" column="P27"/>
+        <result property="p28" column="P28"/>
+        <result property="p29" column="P29"/>
+        <result property="p30" column="P30"/>
+        <result property="p31" column="P31"/>
+        <result property="p32" column="P32"/>
+        <result property="p33" column="P33"/>
+        <result property="p34" column="P34"/>
+        <result property="p35" column="P35"/>
+        <result property="p36" column="P36"/>
+        <result property="p37" column="P37"/>
+        <result property="p38" column="P38"/>
+        <result property="p39" column="P39"/>
+        <result property="p40" column="P40"/>
+        <result property="p41" column="P41"/>
+        <result property="p42" column="P42"/>
+        <result property="p43" column="P43"/>
+        <result property="p44" column="P44"/>
+        <result property="p45" column="P45"/>
+        <result property="p46" column="P46"/>
+        <result property="p47" column="P47"/>
+        <result property="p48" column="P48"/>
+        <result property="p49" column="P49"/>
+        <result property="p50" column="P50"/>
+        <result property="p51" column="P51"/>
+        <result property="p52" column="P52"/>
+        <result property="p53" column="P53"/>
+        <result property="p54" column="P54"/>
+        <result property="p55" column="P55"/>
+        <result property="p56" column="P56"/>
+        <result property="p57" column="P57"/>
+        <result property="p58" column="P58"/>
+        <result property="p59" column="P59"/>
+        <result property="p60" column="P60"/>
+        <result property="p61" column="P61"/>
+        <result property="p62" column="P62"/>
+        <result property="p63" column="P63"/>
+        <result property="p64" column="P64"/>
+        <result property="p65" column="P65"/>
+        <result property="p66" column="P66"/>
+        <result property="p67" column="P67"/>
+        <result property="p68" column="P68"/>
+        <result property="p69" column="P69"/>
+        <result property="p70" column="P70"/>
+        <result property="p71" column="P71"/>
+        <result property="p72" column="P72"/>
+        <result property="p73" column="P73"/>
+        <result property="p74" column="P74"/>
+        <result property="p75" column="P75"/>
+        <result property="p76" column="P76"/>
+        <result property="p77" column="P77"/>
+        <result property="p78" column="P78"/>
+        <result property="p79" column="P79"/>
+        <result property="p80" column="P80"/>
+        <result property="p81" column="P81"/>
+        <result property="p82" column="P82"/>
+        <result property="p83" column="P83"/>
+        <result property="p84" column="P84"/>
+        <result property="p85" column="P85"/>
+        <result property="p86" column="P86"/>
+        <result property="p87" column="P87"/>
+        <result property="p88" column="P88"/>
+        <result property="p89" column="P89"/>
+        <result property="p90" column="P90"/>
+        <result property="p91" column="P91"/>
+        <result property="p92" column="P92"/>
+        <result property="p93" column="P93"/>
+        <result property="p94" column="P94"/>
+        <result property="p95" column="P95"/>
+        <result property="p96" column="P96"/>
+    </resultMap>
+
+    <resultMap type="com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower" extends="dailyPower" id="collectedDailyPower">
+        <result property="id" column="ID"/>
+        <result property="date" column="DATE"/>
+        <result property="updateDate" column="UPDATEDATE"/>
+    </resultMap>
+
+    <insert id="add">
+        insert into D5000.COLLECTEDDAILYPOWER
+        (`date`,updatedate,`IS_MANUAL`,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20,p21,p22,p23,p24,p25,p26,p27,p28,p29,p30,p31,p32,p33,p34,p35,p36,p37,p38,p39,p40,p41,p42,p43,p44,p45,p46,p47,p48,p49,p50,p51,p52,p53,p54,p55,p56,p57,p58,p59,p60,p61,p62,p63,p64,p65,p66,p67,p68,p69,p70,p71,p72,p73,p74,p75,p76,p77,p78,p79,p80,p81,p82,p83,p84,p85,p86,p87,p88,p89,p90,p91,p92,p93,p94,p95,p96)
+        values
+        (
+        #{date},#{updateDate},#{isManual},#{p1},#{p2},#{p3},#{p4},#{p5},#{p6},#{p7},#{p8},#{p9},#{p10},#{p11},#{p12},#{p13},#{p14},#{p15},#{p16},#{p17},#{p18},#{p19},#{p20},#{p21},#{p22},#{p23},#{p24},#{p25},#{p26},#{p27},#{p28},#{p29},#{p30},#{p31},#{p32},#{p33},#{p34},#{p35},#{p36},#{p37},#{p38},#{p39},#{p40},#{p41},#{p42},#{p43},#{p44},#{p45},#{p46},#{p47},#{p48},#{p49},#{p50},#{p51},#{p52},#{p53},#{p54},#{p55},#{p56},#{p57},#{p58},#{p59},#{p60},#{p61},#{p62},#{p63},#{p64},#{p65},#{p66},#{p67},#{p68},#{p69},#{p70},#{p71},#{p72},#{p73},#{p74},#{p75},#{p76},#{p77},#{p78},#{p79},#{p80},#{p81},#{p82},#{p83},#{p84},#{p85},#{p86},#{p87},#{p88},#{p89},#{p90},#{p91},#{p92},#{p93},#{p94},#{p95},#{p96})
+    </insert>
+
+    <update id="update">
+        update D5000.COLLECTEDDAILYPOWER
+        <trim prefix="set" suffixOverrides=",">
+            <if test="updateDate!= null">updateDate = #{updateDate},</if>
+            <if test="isManual!= null">`IS_MANUAL` = #{isManual},</if>
+            <if test="p1!= null">p1 = #{p1},</if>
+            <if test="p2!= null">p2 = #{p2},</if>
+            <if test="p3!= null">p3 = #{p3},</if>
+            <if test="p4!= null">p4 = #{p4},</if>
+            <if test="p5!= null">p5 = #{p5},</if>
+            <if test="p6!= null">p6 = #{p6},</if>
+            <if test="p7!= null">p7 = #{p7},</if>
+            <if test="p8!= null">p8 = #{p8},</if>
+            <if test="p9!= null">p9 = #{p9},</if>
+            <if test="p10!= null">p10 = #{p10},</if>
+            <if test="p11!= null">p11 = #{p11},</if>
+            <if test="p12!= null">p12 = #{p12},</if>
+            <if test="p13!= null">p13 = #{p13},</if>
+            <if test="p14!= null">p14 = #{p14},</if>
+            <if test="p15!= null">p15 = #{p15},</if>
+            <if test="p16!= null">p16 = #{p16},</if>
+            <if test="p17!= null">p17 = #{p17},</if>
+            <if test="p18!= null">p18 = #{p18},</if>
+            <if test="p19!= null">p19 = #{p19},</if>
+            <if test="p20!= null">p20 = #{p20},</if>
+            <if test="p21!= null">p21 = #{p21},</if>
+            <if test="p22!= null">p22 = #{p22},</if>
+            <if test="p23!= null">p23 = #{p23},</if>
+            <if test="p24!= null">p24 = #{p24},</if>
+            <if test="p25!= null">p25 = #{p25},</if>
+            <if test="p26!= null">p26 = #{p26},</if>
+            <if test="p27!= null">p27 = #{p27},</if>
+            <if test="p28!= null">p28 = #{p28},</if>
+            <if test="p29!= null">p29 = #{p29},</if>
+            <if test="p30!= null">p30 = #{p30},</if>
+            <if test="p31!= null">p31 = #{p31},</if>
+            <if test="p32!= null">p32 = #{p32},</if>
+            <if test="p33!= null">p33 = #{p33},</if>
+            <if test="p34!= null">p34 = #{p34},</if>
+            <if test="p35!= null">p35 = #{p35},</if>
+            <if test="p36!= null">p36 = #{p36},</if>
+            <if test="p37!= null">p37 = #{p37},</if>
+            <if test="p38!= null">p38 = #{p38},</if>
+            <if test="p39!= null">p39 = #{p39},</if>
+            <if test="p40!= null">p40 = #{p40},</if>
+            <if test="p41!= null">p41 = #{p41},</if>
+            <if test="p42!= null">p42 = #{p42},</if>
+            <if test="p43!= null">p43 = #{p43},</if>
+            <if test="p44!= null">p44 = #{p44},</if>
+            <if test="p45!= null">p45 = #{p45},</if>
+            <if test="p46!= null">p46 = #{p46},</if>
+            <if test="p47!= null">p47 = #{p47},</if>
+            <if test="p48!= null">p48 = #{p48},</if>
+            <if test="p49!= null">p49 = #{p49},</if>
+            <if test="p50!= null">p50 = #{p50},</if>
+            <if test="p51!= null">p51 = #{p51},</if>
+            <if test="p52!= null">p52 = #{p52},</if>
+            <if test="p53!= null">p53 = #{p53},</if>
+            <if test="p54!= null">p54 = #{p54},</if>
+            <if test="p55!= null">p55 = #{p55},</if>
+            <if test="p56!= null">p56 = #{p56},</if>
+            <if test="p57!= null">p57 = #{p57},</if>
+            <if test="p58!= null">p58 = #{p58},</if>
+            <if test="p59!= null">p59 = #{p59},</if>
+            <if test="p60!= null">p60 = #{p60},</if>
+            <if test="p61!= null">p61 = #{p61},</if>
+            <if test="p62!= null">p62 = #{p62},</if>
+            <if test="p63!= null">p63 = #{p63},</if>
+            <if test="p64!= null">p64 = #{p64},</if>
+            <if test="p65!= null">p65 = #{p65},</if>
+            <if test="p66!= null">p66 = #{p66},</if>
+            <if test="p67!= null">p67 = #{p67},</if>
+            <if test="p68!= null">p68 = #{p68},</if>
+            <if test="p69!= null">p69 = #{p69},</if>
+            <if test="p70!= null">p70 = #{p70},</if>
+            <if test="p71!= null">p71 = #{p71},</if>
+            <if test="p72!= null">p72 = #{p72},</if>
+            <if test="p73!= null">p73 = #{p73},</if>
+            <if test="p74!= null">p74 = #{p74},</if>
+            <if test="p75!= null">p75 = #{p75},</if>
+            <if test="p76!= null">p76 = #{p76},</if>
+            <if test="p77!= null">p77 = #{p77},</if>
+            <if test="p78!= null">p78 = #{p78},</if>
+            <if test="p79!= null">p79 = #{p79},</if>
+            <if test="p80!= null">p80 = #{p80},</if>
+            <if test="p81!= null">p81 = #{p81},</if>
+            <if test="p82!= null">p82 = #{p82},</if>
+            <if test="p83!= null">p83 = #{p83},</if>
+            <if test="p84!= null">p84 = #{p84},</if>
+            <if test="p85!= null">p85 = #{p85},</if>
+            <if test="p86!= null">p86 = #{p86},</if>
+            <if test="p87!= null">p87 = #{p87},</if>
+            <if test="p88!= null">p88 = #{p88},</if>
+            <if test="p89!= null">p89 = #{p89},</if>
+            <if test="p90!= null">p90 = #{p90},</if>
+            <if test="p91!= null">p91 = #{p91},</if>
+            <if test="p92!= null">p92 = #{p92},</if>
+            <if test="p93!= null">p93 = #{p93},</if>
+            <if test="p94!= null">p94 = #{p94},</if>
+            <if test="p95!= null">p95 = #{p95},</if>
+            <if test="p96!= null">p96 = #{p96}</if>
+        </trim>
+        where `date`=#{date}
+    </update>
+
+    <select id="get" resultMap="collectedDailyPower">
+        SELECT
+        *
+        FROM
+        D5000.COLLECTEDDAILYPOWER
+        WHERE
+        1=1
+        <if test="updateDate!= null">and updateDate = #{updateDate}</if>
+        <if test="date!= null">and `date` = #{date}</if>
+        <if test="isManual!= null">and `IS_MANUAL` = #{isManual}</if>
+    </select>
+    <select id="containThisDate" resultType="java.lang.Integer">
+        select COUNT(id)  from D5000.COLLECTEDDAILYPOWER where `date`=#{date};
+    </select>
+    <select id="isManual" resultType="java.lang.Boolean">
+        select  IS_MANUAL   from D5000.COLLECTEDDAILYPOWER where  `date`=#{date};
+    </select>
+    <select id="getLastRecord" resultType="com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower">
+        SELECT * FROM D5000.COLLECTEDDAILYPOWER where id=select max(id) from D5000.COLLECTEDDAILYPOWER
+    </select>
+    <select id="getFutureRecord" resultType="com.jiayue.ipfcst.d5000web.bean.CollectedDailyPower">
+         SELECT * FROM D5000.COLLECTEDDAILYPOWER where  `date` > #{date}
+    </select>
+</mapper>

+ 19 - 0
ipfcst/D5000-web/src/main/resources/mapper/FailedDualRequestMapper.xml

@@ -0,0 +1,19 @@
+<?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.jiayue.ipfcst.d5000web.mapper.FailedDualRequestMapper">
+
+
+    <insert id="add">
+        insert into D5000.FAILED_DUAL_REQUEST (REQUESTTYPE,REQUESTURL,REQUESTJSON,INSERTTIME) values (#{requestType},#{requestUrl},#{requestJson},#{insertTime})
+    </insert>
+
+
+    <select id="getNotHandled" resultType="com.jiayue.ipfcst.d5000web.bean.FailedDualRequest">
+         select * from D5000.FAILED_DUAL_REQUEST where ISREAD = false;
+    </select>
+
+    <update id="toBeRead">
+        update D5000.FAILED_DUAL_REQUEST set ISREAD = true where id= #{id}
+    </update>
+
+</mapper>

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