Browse Source

提交接收服务代码

dylan 2 years ago
parent
commit
2cddb1f4de
100 changed files with 14920 additions and 0 deletions
  1. 2 0
      TSDDCS.iml
  2. 358 0
      pom.xml
  3. 57 0
      tsddcs-commonservice/pom.xml
  4. 27 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/command/CommandEntity.java
  5. 262 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/GBConstants.java
  6. 21 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/KafkaConstants.java
  7. 32 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/SwDatagramConstant.java
  8. 21 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/SzyDatagramConstant.java
  9. 33 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/BaseSettingFlag.java
  10. 33 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/RunSettingFlag.java
  11. 43 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/SzyRunSettingFlag.java
  12. 98 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/enums/AgreementEnum.java
  13. 118 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/enums/SwSiteKindEnum.java
  14. 82 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/DatagramMetadataEnum.java
  15. 106 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/ElementDataMetadataEnum.java
  16. 101 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/JsonPackMetadataEnum.java
  17. 93 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/TaishanV1JsonPackMetadataEnum.java
  18. 624 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Base64.java
  19. 1165 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/BytesHelp.java
  20. 813 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/BytesUtil.java
  21. 47 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC16.java
  22. 82 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC166.java
  23. 83 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC32.java
  24. 45 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CodecUtil.java
  25. 40 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Commands.java
  26. 347 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/DateUtil.java
  27. 31 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ElementJsonPackHelp.java
  28. 205 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/EncryptDecryptData.java
  29. 25 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ErrorCodes.java
  30. 295 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/FileUtil.java
  31. 548 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/StringUtil.java
  32. 306 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Sw2014DatagramTemplateHelp.java
  33. 58 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ToolUtil.java
  34. 30 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ValueLen.java
  35. 74 0
      tsddcs-datacollect-simple/pom.xml
  36. 21 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/DataCollectApplication.java
  37. 25 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/config/Config.java
  38. 21 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/config/ServerConfig.java
  39. 69 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/constant/BusinessConstant.java
  40. 6 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/constant/NetPortStatusConstant.java
  41. 166 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/controller/TestController.java
  42. 87 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataItemTemplateCache.java
  43. 54 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStream.java
  44. 197 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamAdapter.java
  45. 130 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamCache.java
  46. 243 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamLineManager.java
  47. 19 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamManageHolder.java
  48. 299 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamManager.java
  49. 105 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamProcessor.java
  50. 52 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DatagramHelp.java
  51. 79 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/SwDataStreamCache.java
  52. 74 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/TcpDataStreamAdapter.java
  53. 82 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/UdpDataStreamAdapter.java
  54. 80 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuDatagramProcessor.java
  55. 83 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuLinkDatagramProcessor.java
  56. 86 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwConfigDatagramProcessor.java
  57. 100 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwCrcCheckProcessor.java
  58. 162 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtMatchProcessor.java
  59. 304 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtraDatagramProcessor.java
  60. 87 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFileDatagramProcessor.java
  61. 296 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFixedTimeDatagramProcessor.java
  62. 230 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwHourDatagramProcessor.java
  63. 192 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwImageDatagramProcessor.java
  64. 89 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwLinkHeartProcessor.java
  65. 156 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwMatchProcessor.java
  66. 316 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadRunSettingDatagramProcessor.java
  67. 420 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadSettingDatagramProcessor.java
  68. 88 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRebootDatagramProcessor.java
  69. 195 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRgzsDatagramProcessor.java
  70. 174 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwStatusDatagramProcessor.java
  71. 227 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTestDatagramProcessor.java
  72. 238 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTimeIntervalDatagramProcessor.java
  73. 62 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwUnknownProcessor.java
  74. 91 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyCrcCheckProcessor.java
  75. 77 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtConfigFileDatagramProcessor.java
  76. 80 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtFileDatagramProcessor.java
  77. 77 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtLinkHeartDatagramProcessor.java
  78. 196 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtReadIpDatagramProcessor.java
  79. 77 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtRebootDatagramProcessor.java
  80. 195 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtSetIpDatagramProcessor.java
  81. 139 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtStatusDatagramProcessor.java
  82. 432 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyFixedTimeDatagramProcessor.java
  83. 84 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyLinkCheckDatagramProcessor.java
  84. 159 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyMatchDatagramProcessor.java
  85. 155 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadBaseSettingDatagramProcessor.java
  86. 93 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadRtuCodeDatagramProcessor.java
  87. 147 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadUpModelDatagramProcessor.java
  88. 81 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRebootDatagramProcessor.java
  89. 81 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRgzsDatagramProcessor.java
  90. 82 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetBaseSettingDatagramProcessor.java
  91. 120 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetClockDatagramProcessor.java
  92. 101 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetRtuCodeDatagramProcessor.java
  93. 81 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetUpModelDatagramProcessor.java
  94. 69 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyUnknownProcessor.java
  95. 206 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyWarnDatagramProcessor.java
  96. 55 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamKafkaSink.java
  97. 40 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSink.java
  98. 273 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwJpzKafkaSink.java
  99. 71 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwKafkaSink.java
  100. 39 0
      tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwMqttSink.java

+ 2 - 0
TSDDCS.iml

@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4" />

+ 358 - 0
pom.xml

@@ -0,0 +1,358 @@
+<?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 http://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.3.6.RELEASE</version>
+        <relativePath/> <!-- lookup parent from repository -->
+    </parent>
+
+
+    <groupId>org.ts.ddcs</groupId>
+    <artifactId>tsddcs</artifactId>
+    <name>${project.artifactId}</name>
+    <version>1.0.0.RELEASE</version>
+    <packaging>pom</packaging>
+    <description>数据平台</description>
+
+
+    <properties>
+        <ts.project.version>1.0.0.RELEASE</ts.project.version>
+
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <nacos.version>0.2.12</nacos.version>
+        <!--<kotlin.version>1.3.50</kotlin.version>-->
+        <spring.boot.version>2.3.12.RELEASE</spring.boot.version>
+        <!--<spring.cloud.version>Hoxton.SR12</spring.cloud.version>-->
+        <spring.platform.version>Cairo-SR8</spring.platform.version>
+
+        <maven.plugin.version>3.8.1</maven.plugin.version>
+    </properties>
+
+    <modules>
+        <module>tsddcs-commonservice</module>
+        <module>tsddcs-datacollect</module>
+        <module>tsddcs-datacollect-simple</module>
+        <module>tsddcs-datagramprocessor</module>
+        <module>tsddcs-warningservice</module>
+        <module>tsddcs-wuixinservice</module>
+        <module>tsddcs-datacacheservice</module>
+        <module>tsddcs-testservice</module>
+        <module>tsddcs-jobadmin</module>
+        <module>tsddcs-jobhandler</module>
+    </modules>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring.boot.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.cloud</groupId>-->
+            <!--<artifactId>spring-cloud-dependencies</artifactId>-->
+            <!--<version>${spring.cloud.version}</version>-->
+            <!--<type>pom</type>-->
+            <!--<scope>import</scope>-->
+            <!--</dependency>-->
+
+            <dependency>
+                <groupId>io.spring.platform</groupId>
+                <artifactId>platform-bom</artifactId>
+                <version>${spring.platform.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-websocket</artifactId>-->
+            <!--</dependency>-->
+            <!--<dependency>-->
+                <!--<groupId>org.springframework.boot</groupId>-->
+                <!--<artifactId>spring-boot-starter-json</artifactId>-->
+                <!--<version>${spring.boot.version}</version>-->
+            <!--</dependency>-->
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-web</artifactId>-->
+            <!--</dependency>-->
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-configuration-processor</artifactId>-->
+            <!--<optional>true</optional>-->
+            <!--</dependency>-->
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-actuator</artifactId>-->
+            <!--</dependency>-->
+
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-freemarker</artifactId>-->
+            <!--</dependency>-->
+
+            <!--&lt;!&ndash; mail-starter &ndash;&gt;-->
+            <!--<dependency>-->
+            <!--<groupId>org.springframework.boot</groupId>-->
+            <!--<artifactId>spring-boot-starter-mail</artifactId>-->
+            <!--</dependency>-->
+
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-jdbc</artifactId>
+                <version>${spring.boot.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-redis</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>org.ts.ddcs</groupId>
+                <artifactId>tsddcs-commonservice</artifactId>
+                <version>${ts.project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>1.2.76</version>
+            </dependency>
+            <!--文件系统-->
+            <dependency>
+                <groupId>com.github.tobato</groupId>
+                <artifactId>fastdfs-client</artifactId>
+                <version>1.27.2</version>
+            </dependency>
+            <!--线程池-->
+            <dependency>
+                <groupId>org.glassfish.jersey.core</groupId>
+                <artifactId>jersey-common</artifactId>
+                <version>2.28</version>
+            </dependency>
+            <dependency>
+                <groupId>org.eclipse.paho</groupId>
+                <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+                <version>1.2.2</version>
+            </dependency>
+            <dependency>
+                <groupId>com.sun.mail</groupId>
+                <artifactId>javax.mail</artifactId>
+                <version>1.6.0</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-net</groupId>
+                <artifactId>commons-net</artifactId>
+                <version>3.8.0</version>
+            </dependency>
+            <dependency>
+                <groupId>com.github.tobato</groupId>
+                <artifactId>fastdfs-client</artifactId>
+                <version>1.27.2</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>3.7</version>
+            </dependency>
+
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter</artifactId>
+                <version>3.5.3.1</version>
+            </dependency>
+            <dependency>
+                <groupId>com.baomidou</groupId>
+                <artifactId>mybatis-plus-boot-starter-test</artifactId>
+                <version>3.5.3.1</version>
+            </dependency>
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger2</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>io.springfox</groupId>
+                <artifactId>springfox-swagger-ui</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-annotations</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-databind</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+            <dependency>
+                <groupId>com.fasterxml.jackson.core</groupId>
+                <artifactId>jackson-core</artifactId>
+                <version>RELEASE</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>RELEASE</version>
+        </dependency>
+    </dependencies>
+    <build>
+        <finalName>${project.name}</finalName>
+        <resources>
+            <resource>
+                <directory>src/main/java</directory>
+                <includes>
+                    <!--<include>**/*.properties</include>-->
+                    <include>**/*.xml</include>
+                    <!--<include>**/*.yml</include>-->
+                </includes>
+                <!--<filtering>true</filtering>-->
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <!--打包时排除配置文件-->
+                <excludes>
+                    <exclude>**/config.properties</exclude>
+                </excludes>
+                <!--<filtering>false</filtering>-->
+            </resource>
+        </resources>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-maven-plugin</artifactId>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>${spring.boot.version}</version>
+                    <configuration>
+                        <!--<fork>true</fork>-->
+                        <!--<finalName>${project.build.finalName}</finalName>-->
+                        <source>${java.version}</source>
+                        <target>${java.version}</target>
+                    </configuration>
+                    <!--<executions>-->
+                    <!--<execution>-->
+                    <!--<goals>-->
+                    <!--<goal>repackage</goal>-->
+                    <!--</goals>-->
+                    <!--</execution>-->
+                    <!--</executions>-->
+                    <executions>
+                        <execution>
+                            <id>compile</id>
+                            <phase>compile</phase>
+                            <goals>
+                                <goal>compile</goal>
+                            </goals>
+                        </execution>
+                        <!--<execution>-->
+                        <!--<id>testCompile</id>-->
+                        <!--<phase>test-compile</phase>-->
+                        <!--<goals>-->
+                        <!--<goal>testCompile</goal>-->
+                        <!--</goals>-->
+                        <!--</execution>-->
+                    </executions>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>${maven.plugin.version}</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>UTF-8</encoding>
+                    <compilerArgs>
+                        <arg>-parameters</arg>
+                    </compilerArgs>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <repositories>
+        <repository>
+            <id>aliyun-repos</id>
+            <url>https://maven.aliyun.com/repository/public/</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>spring-milestones</id>
+            <name>Spring Milestones</name>
+            <url>https://repo.spring.io/milestone</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>repository.springframework.maven.release</id>
+            <name>Spring Framework Maven Release Repository</name>
+            <url>http://maven.springframework.org/milestone/</url>
+        </repository>
+        <repository>
+            <id>org.springframework</id>
+            <url>http://maven.springframework.org/snapshot</url>
+        </repository>
+        <repository>
+            <id>spring-milestone</id>
+            <name>Spring Maven MILESTONE Repository</name>
+            <url>http://repo.spring.io/libs-milestone</url>
+        </repository>
+        <repository>
+            <id>spring-release</id>
+            <name>Spring Maven RELEASE Repository</name>
+            <url>http://repo.spring.io/libs-release</url>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>aliyun-plugin</id>
+            <url>https://maven.aliyun.com/repository/public/</url>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+
+    <distributionManagement>
+        <repository>
+            <id>maven-releases</id>
+            <name>Maven Release Repository</name>
+            <url>http://nexus.zhkrc.com/repository/maven-releases/</url>
+        </repository>
+    </distributionManagement>
+
+</project>

+ 57 - 0
tsddcs-commonservice/pom.xml

@@ -0,0 +1,57 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>tsddcs</artifactId>
+        <groupId>org.ts.ddcs</groupId>
+        <version>1.0.0.RELEASE</version>
+    </parent>
+
+    <groupId>org.ts.ddcs</groupId>
+    <artifactId>tsddcs-commonservice</artifactId>
+    <name>${project.artifactId}</name>
+    <version>1.0.0.RELEASE</version>
+    <packaging>jar</packaging>
+    <description>泰山平台-服务通用模块</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+            <version>1.6.2</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+            <version>2.0.0.Final</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <skip>true</skip>
+                    <finalName>${project.name}</finalName>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 27 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/command/CommandEntity.java

@@ -0,0 +1,27 @@
+package org.ts.ddcs.common.command;
+
+import lombok.Data;
+
+import java.util.Date;
+
+
+/**
+ * @author dylan
+ */
+@Data
+public class CommandEntity {
+    private String command;
+    private String rtuCode;
+    private String datagram;
+    private int tryCount;
+    private boolean isNeedTry;
+    private Date createTime;
+    private int liveTime;
+    private String fileName;
+    private String funcCode;
+    private Date lastSendTime;
+    private boolean isTry;
+    private String key;
+    private String batchId;
+    private boolean waittingBack;
+}

+ 262 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/GBConstants.java

@@ -0,0 +1,262 @@
+package org.ts.ddcs.common.constant;
+
+public class GBConstants {
+
+	public final static String  VERSION_KEY_SZY_54 ="5.4";
+	public final static String  BASE_KEY_SERVER_MASTER ="server_master";
+	public final static String  BASE_KEY_COLLECT_SERVER ="collect_server_id";
+	public final static String  BASE_KEY_COLLECT_SERVER_GROUP ="collect_server_id_group";
+	public final static String  BASE_KEY_RTU ="rtuCode";
+	public final static String  BASE_KEY_AGREEMENT ="agreement";
+	public final static String  BASE_KEY_DATAGRAM ="datagram";
+	public final static String  BASE_KEY_VERSION ="version";
+	public final static String  BASE_KEY_SETTING ="setting_datagram";
+	public final static String  BASE_KEY_ORGID ="orgId";
+	public final static String  BASE_KEY_DATAGRAM_PICK_TM ="datagramPickTime";
+	public final static String  BASE_KEY_WARNING_INFO ="warningInfo";
+	public final static String  BASE_KEY_WARNING_KIND ="warningKind";
+	public final static String  BASE_KEY_WARNING_CHECK_TIME ="checkTime";
+	public final static String  BASE_KEY_WARNING_CONTENT ="warningContent";
+	public final static String  BASE_KEY_WARNING_STATUS ="warning_status";
+	public final static String  RELAY_KEY_URL ="key_url";
+	public final static String  RELAY_KEY_CHANNEL ="key_channel";
+	public final static String  RELAY_KEY_MQ ="MQ";
+	public final static String  RELAY_KEY_HTTP ="HTTP";
+	public final static String  RELAY_KEY_QUEUE ="key_queue";
+	public final static String  HTTP_REQUEST_KEY_CODE ="code";
+	public final static String  HTTP_REQUEST_KEY_OK ="0";
+	public final static String  HTTP_REQUEST_KEY_ERROR ="1";
+
+
+//	public final static String AGREEMENT_KIND_SW="SW";
+//	public final static String AGREEMENT_KIND_SZY="SZY";
+//	public final static String AGREEMENT_KIND_DTU="DTU";
+//	public final static String AGREEMENT_KIND_SW_NM_EXT="SWNMEXT";
+//	public final static String AGREEMENT_KIND_JT="JT808";
+//	public final static String AGREEMENT_KIND_SW_EXT="SWEXT";
+
+	public final static String REDIS_KEY ="redis_key";
+	public final static String REDIS_KEY_COMMAND ="command";
+	public final static String REDIS_KEY_COMMAND_QUERY ="command:query";
+	public final static String REDIS_KEY_COMMAND_SETTING = "command:setting";
+	public final static String REDIS_KEY_COMMAND_FILE = "command:file";
+	public final static String REDIS_KEY_SERVER_MASTER ="server_master";
+	public final static String REDIS_KEY_COLLECT_SERVER ="collect_server_id";
+	public final static String REDIS_KEY_RTU_SPACE_TIME ="spaceTime";
+	public final static String REDIS_KEY_RTU_STATUS_DATAGRAM ="statusDatagram";
+
+	/**
+	 * REDIS 键值 项目信息前缀
+	 */
+	public final static String REDIS_KEY_PROJECT_PREFIX ="project_";
+	public final static String REDIS_KEY_PROJECT_ID ="projectId";
+	public final static String REDIS_KEY_PROJECT_INFO_RTUCODEAGREEMENT="rtu_code_agreement";
+	public final static String REDIS_KEY_PROJECT_INFO_AGREEMENT = "agreement";
+	public final static String REDIS_KEY_PROJECT_INFO_AGREEMENT_CODE = "agreement_code";
+
+	public final static String DICT_CODE_AGREEMENT_SW ="DATAGRAM_AGREEMENT_SW2014";
+	public final static String DICT_CODE_AGREEMENT_SZY_2012 ="DATAGRAM_AGREEMENT_SZY2012";
+	public final static String DICT_CODE_AGREEMENT_SZY_2016="DATAGRAM_AGREEMENT_SZY2016";
+	public final static String DICT_CODE_AGREEMENT_SW_NM_EXT ="DATAGRAM_AGREEMENT_SW_NM_EXT";
+
+
+	public final static String RTU_CODE_AGREEMENT_0 ="0";
+	public final static String RTU_CODE_AGREEMENT_1 ="1";
+	public final static String RTU_CODE_AGREEMENT_2 ="2";
+
+    public final static String WARNING_KIND_DICT_ID ="ff8080817616e025017617e1852a0010";
+
+    public final static String WARNING_TYPE_UNDEFINE ="0";//未定义预警类型
+	public final static String WARNING_TYPE_OFFLINE ="1"; //RTU设备在线预警
+	public final static String WARNING_TYPE_DATAGRAM_DELAY ="2";//报文上报延时
+	public final static String WARNING_TYPE_RTU_FAULT_SE ="3";//水位计故障
+	public final static String WARNING_TYPE_RTU_FAULT_AC ="4";//交流电故障
+	public final static String WARNING_TYPE_RTU_FAULT_BV ="5";//电池电压故障
+	public final static String WARNING_TYPE_RTU_COLLECT_TIME_ERROR ="6";//采集时间错误
+	public final static String WARNING_TYPE_CRC_ERROR ="7";//CRC检验错误
+	public final static String WARNING_TYPE_OUTLIER_DATA ="8";//异常数据
+	public final static String WARNING_TYPE_SD_DAMAGE ="9";//SD卡损坏
+	public final static String WARNING_TYPE_RTU_SEND_DELAY ="10";//RTU发包延时
+
+
+	public final static String RTU_STATUS_INFO_NAME_WSE ="waterLevelDeviceStatus";//水位计
+	public final static String RTU_STATUS_INFO_NAME_ACC ="alternatingCurrentCharging";//交流电
+	public final static String RTU_STATUS_INFO_NAME_BV ="batteryVoltage";//电池电压
+	public final static String RTU_STATUS_INFO_NAME_PV ="powerVoltage";//电源电压
+
+	public final static long BASE_RTU_FRESH_CONNECT_TIME = 30000;
+
+
+	//0 未设定  1 交流电  2  交流电带电池  3 太阳能板
+	public final static String RTU_PROJECT_POWER_MODEL_UNDEFIND ="0";
+	public final static String RTU_PROJECT_POWER_MODEL_AC ="1";
+	public final static String RTU_PROJECT_POWER_MODEL_AC_BA ="2";
+	public final static String RTU_PROJECT_POWER_MODEL_SUN ="3";
+
+	public final static String WARNING_ACTIVE_ON ="1";//打开预警
+	public final static String WARNING_ACTIVE_OFF ="0"; //关闭预警
+
+	public final static String WARNING_STATUS_HAPPEN ="0";//预警中
+	public final static String WARNING_STATUS_RECOVERY ="1"; //预警结束
+
+
+	public final static String WARNING_PROJECT_SETTING_GB_ACTIVE_KEY ="warning_project_setting_gb_active";
+	public final static String WARNING_PROJECT_SETTING_MAIL_ACTIVE_KEY ="warning_project_setting_mail_active";
+	public final static String WARNING_PROJECT_SETTING_SMS_ACTIVE_KEY ="warning_project_setting_sms_active";
+	public final static String WARNING_PROJECT_SETTING_WX_ACTIVE_KEY ="warning_project_setting_wx_active";
+	public final static String WARNING_PROJECT_SETTING_WATER_LEVEL_ACTIVE_KEY ="warning_project_setting_water_level_active";
+
+	public final static String WARNING_PROJECT_SETTING_DATAGRAM_DELAY_TIME_KEY ="warning_project_setting_datagram_delay_time";
+	public final static String WARNING_PROJECT_SETTING_MAIL_KEY ="warning_project_setting_mail";
+	public final static String WARNING_PROJECT_SETTING_SMS_KEY ="warning_project_setting_sms";
+	public final static String WARNING_PROJECT_SETTING_WX_KEY ="warning_project_setting_wx";
+
+
+	public final static String RELAY_DATAGRAM_ACTIVE="1";
+	public final static String RELAY_DATAGRAM_ENABLE="0";
+	public final static String RELAY_DATAGRAM_REMOTE_IP_KEY="relayIp";
+	public final static String RELAY_DATAGRAM_KEY="relay";
+
+
+	public final static String SERVER_MESSAGE_KIND_RUNNING ="1";
+
+
+	public final static String TABLE_WATERGATE  = "st_watergate";
+	public final static String TABLE_RSVR  = "st_rsvr_r";
+	public final static String TABLE_RIVER  = "st_river_r";
+	public final static String TABLE_PPTN  = "ST_PPTN_R";
+	public final static String TABLE_PPTN_5_MIN  = "st_pptn_r_5_min";
+	public final static String TABLE_DRXNN  = "st_DRxnn";
+
+
+	//	/**
+//	 * GPRS帧类型
+//	 */
+	public final static int GPRS_TYPE_LOGIN = 0x01; //登录帧
+	public final static int GPRS_TYPE_LOGIN_REPLY = 0x02; //登录应答帧
+	public final static int GPRS_TYPE_LOGOUT = 0x03; //注销帧
+	public final static int GPRS_TYPE_LOGOUT_REPLY = 0x04; //注销应答帧
+	public final static int GPRS_TYPE_DATA = 0x05; //数据帧
+	public final static int GPRS_TYPE_DATA_REPLY = 0x06; //数据应答帧,暂时不用
+	public final static int GPRS_TYPE_HEART = 0x07; //心跳帧
+	public final static int GPRS_TYPE_HEART_REPLY = 0x08; //心跳应答帧
+	
+	/**
+	 * AFN
+	 */
+	// 链路检测
+	public final static int DATA_AFN_LOGIN = 0x02;
+	
+	// 参数设置及查询
+	public final static int DATA_AFN_RESET = 0x01; //复位命令
+	
+	
+	
+	public final static int DATA_AFN_SETWORKPATTERN = 0x07; //设置终端工作模式
+	public final static int DATA_AFN_QUERYWORKPATTERN = 0x08; //查询终端工作模式
+	public final static int DATA_AFN_SETTIMINGINTERVAL = 0x09; //设置终端自报时间间隔及时间起点
+	public final static int DATA_AFN_QUERYTIMINGINTERVAL = 0x0A; //查询终端自报时间间隔及时间起点
+	
+	public final static int DATA_AFN_SETALTITUDE = 0x14; //设置终端井口高程、水位下限及水位计量程
+	public final static int DATA_AFN_QUERYALTITUDE = 0x15; //查询终端井口高程、水位下限及水位计量程
+	
+	public final static int DATA_AFN_SETSIMID = 0x17; //设置终端SIM卡ID号
+	public final static int DATA_AFN_QUERYSIMID = 0x18; //查询终端SIM卡ID号
+	public final static int DATA_AFN_QUERYHISTIMEVALUE = 0x19; //查询终端某一天的历史记录
+	
+	public final static int DATA_AFN_CLEARHISDATA = 0x1B; //清空终端历史数据
+	
+//	public final static int DATA_AFN_QUERYREALTIMEVALUE = 0x16; //查询终端水位实时值
+//	public final static int DATA_AFN_QUERYREALTIMEWATERQUALITY = 0x26; //查询终端水质实时值
+	
+	//GZ设置终端地址
+	public final static int DATA_AFN_SETADDRESS = 0x10; 
+	//GZ查询终端地址
+	public final static int DATA_AFN_QUERYADDRESS = 0x50; 
+	
+	//GZ设置终端时钟
+	public final static int DATA_AFN_SETCLOCK = 0x11; //设置终端时钟
+	//GZ查询终端时钟
+	public final static int DATA_AFN_QUERYCLOCK = 0x51; 
+	//GZ定时自报数据
+	public final static int DATA_AFN_TIMINGDATA = 0xC0;
+	//GZ随机自报报警数据
+	public final static int DATA_AFN_WARNING = 0x81; 
+	//GZ查询终端实时值
+	public final static int DATA_AFN_QUERYREALTIMEVALUE = 0xB0; 
+	
+	//GZ查询终端报警状态和终端状态
+	public final static int DATA_AFN_QUERYWARNINGSTATUS = 0x5E; 
+	
+	
+	/*
+	 * zs20141025 用水计量 命令
+	 */
+	public final static int DATA_AFN_QUERY_WATER_INSTANTFLOW = 0x16; //查询用水瞬时流量
+	public final static int DATA_AFN_QUERY_WATER_TOTALFLOW = 0x26; //查询用水累计流量
+	public final static int DATA_AFN_WATERMEASURE_TIMINGDATA = 0x29;//zs20141025 定时自报数据
+	
+	public final static int DATA_AFN_SETRESPONSE = 0x00; //设置命令执行后返回的响应
+	
+	
+	
+	
+	
+	public final static int MAX_FCB = 3;
+	
+	// 控制域功能码
+	public final static int CONTROL_DIR0_FN_COMMAN_CONFIRM = 1;
+	public final static int CONTROL_DIR0_FN_QUERY_STATUS = 4;
+	
+	/*
+	 * GZ 功能码 水位参数
+	 */
+	public final static int CONTROL_DIR0_FN_QUERY_WATERLEVEL = 2;//5改为2 zs20151204 modify
+	
+	/*
+	 * GZ 功能码 水质参数
+	 */
+	public final static int CONTROL_DIR0_FN_QUERY_WATERQUALITY = 10;
+	
+	/*
+	 * GZ 报警和状态参数
+	 */
+	public final static int CONTROL_DIR0_FN_QUERY_RTUSTATUS = 13;
+	
+	/*
+	 * GZ 功能码 流量(水量)
+	 */
+	public final static int CONTROL_DIR0_FN_QUERY_WATERFLOW = 3;
+	
+	
+	
+	
+	public final static int CONTROL_DIR0_FN_QUERY_WARNPARAM = 6;
+	
+	
+	public final static int CONTROL_DIR1_FN_REPLY_CONFIRM = 1;
+	public final static int CONTROL_DIR1_FN_REPLY_NODATA = 2;
+	public final static int CONTROL_DIR1_FN_REPLY_STATUS = 4;
+	public final static int CONTROL_DIR0_FN_REPLY_WATERLEVEL = 5;
+	public final static int CONTROL_DIR0_FN_REPLY_WARNPARAM = 6;
+	
+	
+	/**
+	 * 报警种类
+	 */
+	public final static int WARN_AC_OFF = 0x0001; //工作用交流电停电
+	public final static int WARN_DC_OFF = 0x0002; //蓄电池电压低
+	public final static int WARN_EQUIP_ERR = 0x0020; //流量仪表故障
+	public final static int WARN_PUMP_ERR = 0x0040; //水泵故障
+	public final static int WARN_QUAN_LIMIT = 0x0080; //剩余水量下限报警
+	
+	public final static int WARN_TERM_IC = 0x0400; //终端IC卡功能报警
+	public final static int WARN_VAL_CON = 0x0800; //定值控制报警
+	public final static int WARN_TERM_STATE = 0x2000; //终端箱门状态报警
+
+
+	public final static String DEVICE_KIND_RTU ="rtu";
+	public final static String DEVICE_KIND_DTU ="dtu";
+
+}
+

+ 21 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/KafkaConstants.java

@@ -0,0 +1,21 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/11/14
+ */
+package org.ts.ddcs.common.constant;
+
+/*** 
+ * Date:2022/11/14
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class KafkaConstants {
+    public final static String DATA_STREAM_SOURCE_EVENT = "data_stream_source_event";
+    public final static String TOPIC_TSYWXT_DATAGRAM_MESSAGE = "topic-tsywxt-datagram-message";
+    public final static String TOPIC_TS_V1_DATAGRAM = "queue-waiting-process-datagram";
+}

+ 32 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/SwDatagramConstant.java

@@ -0,0 +1,32 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2024/2/20
+ */
+package org.ts.ddcs.common.constant;
+
+/*** 
+ * Date:2024/2/20
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class SwDatagramConstant {
+    public static final int FEATURE_WEIGHT = 13;
+
+    public static final byte[]  RTU_START_FLAG_2014 = { 0x7E}; //RTU2014年规约开始字段
+    public static final byte[]  PACKET_BODY_START_FLAG = { 0x02 }; //RTU2014年报文正文起始符
+
+    //报文帧控制字符定义
+    public static final byte[] PACKET_BODY_END_FLAG_ETX = {0x03}; //RTU2014年报文正文结束符,后续无报文
+    public static final byte[] PACKET_BODY_END_FLAG_ETB = {0x17}; //RTU2014年报文正文结束符,后续有报文
+    public static final byte[] PACKET_CONTROL_FLAG_ENQ = {0x05}; //询问
+    public static final byte[] PACKET_CONTROL_FLAG_EOT = {0x04}; //传输结束退出--作为传输结束确认帧报文结束符,表示可以退出通信
+    public static final byte[] PACKET_CONTROL_FLAG_ACK = {0x06}; //肯定确认,继续发送--作为有后续报文帧的“确认帧” 报文结束符
+    public static final byte[] PACKET_CONTROL_FLAG_NAK = {0x15}; //否定应答,反馈重发--用于要求对方重发某数据包的报文结束符
+    public static final byte[] PACKET_CONTROL_FLAG_ESC = {0x1B}; //传输结束,终端保持在线---在下行确认帧代替EOT作为报文结束符,要求终端在线。保持在线10min内若没有接收到中心站命令,终端退回原先设定的工作状态
+
+}

+ 21 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/constant/SzyDatagramConstant.java

@@ -0,0 +1,21 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2024/2/20
+ */
+package org.ts.ddcs.common.constant;
+
+/*** 
+ * Date:2024/2/20
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class SzyDatagramConstant {
+    public static final byte[]  RTU_START_FLAG_2012 = { 0x68 }; //RTU2012年规约开始字段
+    public static final byte[] RTU_END_FLAG_2012 =  { 0x16 }; //RTU2012年规约结束字段
+
+}

+ 33 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/BaseSettingFlag.java

@@ -0,0 +1,33 @@
+package org.ts.ddcs.common.dict;
+
+/**
+ * @author dylan
+ */
+
+public enum BaseSettingFlag {
+    /**
+     * 中心站地址
+     */
+    CENTER_ADD("01","中心站地址"),RTU_CODE("02","遥测站地址"),PASSWORD("03","密码"),IP1("04","中心站1主信道类型及地址"),IP1_SUB("05","中心站1备用信道类型及地址"),
+    IP2("06","中心站1主信道类型及地址"),IP2_SUB("07","中心站1备用信道类型及地址"),IP3("08","中心站1主信道类型及地址"),IP3_SUB("09","中心站1备用信道类型及地址"),
+    IP4("0A","中心站1主信道类型及地址"),IP4_SUB("0B","中心站1备用信道类型及地址"), WORK_TYPE("0C","工作方式"),COLLECT_SETTING("0D","遥测站采集要素设置"),
+    SERVER_ADD("0E","中继站(集合转发站)服务地址范围"),DEVICE_ID("0F","遥测站通信设备识别号"),WORK_MODEL("30","工作方式"),RTU_KIND("31","测站类型"),RAIN_PERCEN("32","雨量分辩率"),BLUETOOTH("33","蓝牙开关");
+
+
+
+    private final String id;
+    private final String name;
+
+    BaseSettingFlag(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 33 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/RunSettingFlag.java

@@ -0,0 +1,33 @@
+package org.ts.ddcs.common.dict;
+
+/**
+ * @author dylan
+ */
+
+public enum  RunSettingFlag {
+    /**
+     * 定时报时间间隔
+     */
+    intervalTime("20","定时报时间间隔"),addIntervalTime("21","加报时间间隔"),rainTime("22","降水量日起始时间"),collectInterval("23","采样间隔"),dataSaveInterval("24","水位数据存储间隔"),
+    rainAddValue("27","雨量加报阈值"),waterLevelBase("28","水位基值1"),waterLevelCorrectValue("30","水位修正基值1"),addWaterLevel("38","加报水位1"),
+    addWaterUpValue("40","加报水位以上加报阈值"),addWaterDownValue("41","加报水位以下加报阈值"), flowValue("42","流量加报阈值"),flowSpeetValue("43","流速加报阈值"),
+    waterGateValue("44","闸位加报阀值");
+
+
+
+    private final String id;
+    private final String name;
+
+    RunSettingFlag(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 43 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/dict/SzyRunSettingFlag.java

@@ -0,0 +1,43 @@
+package org.ts.ddcs.common.dict;
+
+
+/**
+ * @author dylan
+ */
+
+public enum SzyRunSettingFlag {
+    /**
+     * 雨量
+     */
+    RAIN_IT("szy_intervalTime_setting_0","雨量"),
+    WATER_HIGH_IT("szy_intervalTime_setting_1","水位"),
+    FLOW_RATE_IT("szy_intervalTime_setting_2","流量"),
+    FLOW_SPEED_IT("szy_intervalTime_setting_3","流速"),
+    WATER_GATE_IT("szy_intervalTime_setting_4","水闸"),
+    POWER_IT("szy_intervalTime_setting_5","功率"),
+    PRESSURE_IT("szy_intervalTime_setting_6","气压"),
+    WIN_SPEED_IT("szy_intervalTime_setting_7","风速"),
+    WATER_TEMPERATURE("szy_intervalTime_setting_8","水温"),
+    WATER_QUALITY("szy_intervalTime_setting_9","水质"),
+    SOIL_WATER_CONTENT("szy_intervalTime_setting_10","土壤含水率"),
+    EVAPORATION("szy_intervalTime_setting_11","蒸发量"),
+    WARNING("szy_intervalTime_setting_12","报警"),
+    WATER_PRESSURE("szy_intervalTime_setting_13","水压");
+
+
+    private final String id;
+    private final String name;
+
+    SzyRunSettingFlag(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 98 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/enums/AgreementEnum.java

@@ -0,0 +1,98 @@
+package org.ts.ddcs.common.enums;
+
+/***
+ * Date:2022/3/9
+ * Title:规约枚举类
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author swp
+ * @mender:(文件的修改者,文件创建者之外的人)
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum AgreementEnum {
+
+    /**
+     * 水文规约
+     */
+    AGREEMENT_SW(0, "SW2014"),
+
+    /**
+     * 水资源规约
+     */
+    AGREEMENT_SZY(1, "SZY2012"),
+
+    /**
+     * 水文扩展规约 测站编码为16位
+     */
+    AGREEMENT_SW_EXT(2, "SWEXT2014"),
+
+    /**
+     * 水文扩展规约 内蒙 特殊数据处理
+     */
+    AGREEMENT_SW_NM_EXT(3, "SWNMEXT2014"),
+
+    /**
+     * DTU透传规约
+     */
+    AGREEMENT_DTU(4, "DTU"),
+
+    /**
+     * 交通808规约
+     */
+    AGREEMENT_JT808(5, "JT808"),
+    ;
+
+    private int code;
+
+    private String name;
+
+    AgreementEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (AgreementEnum point : AgreementEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (AgreementEnum point : AgreementEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 118 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/enums/SwSiteKindEnum.java

@@ -0,0 +1,118 @@
+package org.ts.ddcs.common.enums;
+
+/***
+ * Date:2022/3/9
+ * Title:测站类别枚举类
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author swp
+ * @mender:(文件的修改者,文件创建者之外的人)
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum SwSiteKindEnum {
+
+    /**
+     * 降水,①降水;②蒸发③气象
+     */
+    RTU_KIND_P(0x50, "P"),
+
+    /**
+     * 河道,①降水;②蒸发;③河道水情④气象⑤水质
+     */
+    RTU_KIND_H(0x48, "H"),
+
+    /**
+     * 水库(湖泊),①降水;②蒸发;③水库水情④气象⑤水质
+     */
+    RTU_KIND_K(0x4b, "K"),
+
+    /**
+     * 闸坝,①降水;②蒸发;③闸坝水情④气象⑤水质
+     */
+    RTU_KIND_Z(0x5a, "Z"),
+
+    /**
+     * 泵站,①降水;②蒸发;③泵站水情④气象⑤水质
+     */
+    RTU_KIND_D(0x44, "D"),
+
+    /**
+     * 潮汐,①降水;②蒸发;③潮汐水情④气象
+     */
+    RTU_KIND_T(0x54, "T"),
+    /**
+     * 墒情,①降水;②蒸发;③墒情
+     */
+    RTU_KIND_M(0x4d, "M"),
+    /**
+     * 地下水,①埋深;②水质;③开采量
+     */
+    RTU_KIND_G(0x47, "G"),
+    /**
+     * 水质,①水质;②流量;③降水
+     */
+    RTU_KIND_Q(0x51, "Q"),
+    /**
+     * 取水口,①水位; ②水质;③水量④水压等
+     */
+    RTU_KIND_I(0x49, "I"),
+    /**
+     * 排水口,①水位; ②水质;③水量④水压等
+     */
+    RTU_KIND_O(0x4f, "O")
+    ;
+
+    private int code;
+
+    private String name;
+
+    SwSiteKindEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (SwSiteKindEnum point : SwSiteKindEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (SwSiteKindEnum point : SwSiteKindEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 82 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/DatagramMetadataEnum.java

@@ -0,0 +1,82 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.common.metadata;
+
+/*** 
+ * Date:2023/10/31
+ * Title:数据报文解析数据缓存元数据定义
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum DatagramMetadataEnum {
+    /**
+     * 元素编码
+     */
+    CACHE_METADATA_ELEMENT_CODE(0, "element_code"),
+
+    /**
+     * 数据项
+     */
+    CACHE_METADATA_DATA(1, "data");
+
+    private int code;
+
+    private String name;
+
+    DatagramMetadataEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (DatagramMetadataEnum point : DatagramMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (DatagramMetadataEnum point : DatagramMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 106 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/ElementDataMetadataEnum.java

@@ -0,0 +1,106 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.common.metadata;
+
+/*** 
+ * Date:2023/10/31
+ * Title:数据元素项定义
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum ElementDataMetadataEnum {
+    /**
+     * 元素编码
+     */
+    ELEMENT_METADATA_CODE(0, "key"),
+
+    /**
+     * 参数名称
+     */
+    ELEMENT_METADATA_NAME(1, "name"),
+
+    /**
+     * 参数编码
+     */
+    ELEMENT_METADATA_SUB_CODE(2, "code"),
+
+    /**
+     * 参数值
+     */
+    ELEMENT_METADATA_VALUE(3, "value"),
+    /**
+     * 参数单位
+     */
+    ELEMENT_METADATA_UNIT(4, "unit"),
+
+    /**
+     * 参数说明
+     */
+    ELEMENT_METADATA_DESC(5, "desc"),
+
+    /**
+     * 数据状态
+     */
+    ELEMENT_METADATA_ERROR(6, "error")
+    ;
+
+    private int code;
+
+    private String name;
+
+    ElementDataMetadataEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (ElementDataMetadataEnum point : ElementDataMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (ElementDataMetadataEnum point : ElementDataMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 101 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/JsonPackMetadataEnum.java

@@ -0,0 +1,101 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.common.metadata;
+
+/*** 
+ * Date:2023/10/31
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum JsonPackMetadataEnum {
+    /**
+     * 接收时间
+     */
+    PACK_METADATA_FROM_TIME(0, "from_time"),
+    /**
+     * 上报时间
+     */
+    PACK_METADATA_UP_TIME(1, "up_time"),
+    /**
+     * 原始报文
+     */
+    PACK_METADATA_DATAGRAM(2, "datagram_text"),
+    /**
+     * 测站编码
+     */
+    PACK_METADATA_RTU_CODE(3, "rtu_code"),
+    /**
+     * 报文类型
+     */
+    PACK_METADATA_DATAGRAM_TYPE(4, "datagram_type"),
+    /**
+     * 规约
+     */
+    PACK_METADATA_AGREEMENT_TYPE(5, "agreement_type"),
+    /**
+     * 数据项
+     */
+    PACK_METADATA_DATA(6, "data");
+
+    private int code;
+
+    private String name;
+
+    JsonPackMetadataEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (JsonPackMetadataEnum point : JsonPackMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (JsonPackMetadataEnum point : JsonPackMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 93 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/TaishanV1JsonPackMetadataEnum.java

@@ -0,0 +1,93 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.common.metadata;
+
+/***
+ * Date:2023/10/31
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum TaishanV1JsonPackMetadataEnum {
+    /**
+     * 接收时间
+     */
+    PACK_METADATA_FROM_TIME(0, "datagramPickTime"),
+    /**
+     * 原始报文
+     */
+    PACK_METADATA_DATAGRAM(1, "datagram"),
+    /**
+     * 测站编码
+     */
+    PACK_METADATA_RTU_CODE(2, "rtuCode"),
+    /**
+     * 报文类型
+     */
+    PACK_METADATA_DATAGRAM_TYPE(3, "afc"),
+    /**
+     * 规约
+     */
+    PACK_METADATA_AGREEMENT_TYPE(4, "agreement");
+
+    private int code;
+
+    private String name;
+
+    TaishanV1JsonPackMetadataEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * 根据CODE查名称
+     *
+     * @param code
+     * @return
+     */
+    public static String getName(int code) {
+        for (TaishanV1JsonPackMetadataEnum point : TaishanV1JsonPackMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (TaishanV1JsonPackMetadataEnum point : TaishanV1JsonPackMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 624 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Base64.java

@@ -0,0 +1,624 @@
+package org.ts.ddcs.common.util;
+
+import java.util.Arrays;
+
+public class Base64 {
+
+	private static final boolean devLineSep = true;
+
+	private static final char[] CA = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+			.toCharArray();
+
+	private static final int[] IA = new int[256];
+
+	static {
+
+		Arrays.fill(IA, -1);
+
+		for (int i = 0, iS = CA.length; i < iS; i++)
+
+			IA[CA[i]] = i;
+
+		IA['='] = 0;
+
+	}
+
+	public final static char[] encodeToChar(byte[] sArr) {
+
+		return encodeToChar(sArr, devLineSep);
+
+	}
+
+	public final static char[] encodeToChar(byte[] sArr, boolean lineSep) {
+
+		int sLen = sArr != null ? sArr.length : 0;
+
+		if (sLen == 0)
+
+			return new char[0];
+
+		int eLen = (sLen / 3) * 3;
+
+		int cCnt = ((sLen - 1) / 3 + 1) << 2;
+
+		int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0); // Length
+
+		char[] dArr = new char[dLen];
+
+		for (int s = 0, d = 0, cc = 0; s < eLen;) {
+
+			int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8
+
+			| (sArr[s++] & 0xff);
+
+			dArr[d++] = CA[(i >>> 18) & 0x3f];
+
+			dArr[d++] = CA[(i >>> 12) & 0x3f];
+
+			dArr[d++] = CA[(i >>> 6) & 0x3f];
+
+			dArr[d++] = CA[i & 0x3f];
+
+			if (lineSep && ++cc == 19 && d < dLen - 2) {
+
+				dArr[d++] = '\r';
+
+				dArr[d++] = '\n';
+
+				cc = 0;
+
+			}
+
+		}
+
+		int left = sLen - eLen; // 0 - 2.
+
+		if (left > 0) {
+
+			int i = ((sArr[eLen] & 0xff) << 10)
+
+			| (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+			dArr[dLen - 4] = CA[i >> 12];
+
+			dArr[dLen - 3] = CA[(i >>> 6) & 0x3f];
+
+			dArr[dLen - 2] = left == 2 ? CA[i & 0x3f] : '=';
+
+			dArr[dLen - 1] = '=';
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] decode(char[] sArr) {
+
+		int sLen = sArr != null ? sArr.length : 0;
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int sepCnt = 0;
+
+		for (int i = 0; i < sLen; i++)
+
+			if (IA[sArr[i]] < 0)
+
+				sepCnt++;
+
+		if ((sLen - sepCnt) % 4 != 0)
+
+			return null;
+
+		int pad = 0;
+
+		for (int i = sLen; i > 1 && IA[sArr[--i]] <= 0;)
+
+			if (sArr[i] == '=')
+
+				pad++;
+
+		int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+		byte[] dArr = new byte[len];
+
+		for (int s = 0, d = 0; d < len;) {
+
+			int i = 0;
+
+			for (int j = 0; j < 4; j++) { // j
+
+				int c = IA[sArr[s++]];
+
+				if (c >= 0)
+
+					i |= c << (18 - j * 6);
+
+				else
+
+					j--;
+
+			}
+
+			dArr[d++] = (byte) (i >> 16);
+
+			if (d < len) {
+
+				dArr[d++] = (byte) (i >> 8);
+
+				if (d < len)
+
+					dArr[d++] = (byte) i;
+
+			}
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] decodeFast(char[] sArr) {
+
+		int sLen = sArr.length;
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int sIx = 0, eIx = sLen - 1;
+
+		while (sIx < eIx && IA[sArr[sIx]] < 0)
+
+			sIx++;
+
+		while (eIx > 0 && IA[sArr[eIx]] < 0)
+
+			eIx--;
+
+		int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0;
+
+		int cCnt = eIx - sIx + 1;
+
+		int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+		int len = ((cCnt - sepCnt) * 6 >> 3) - pad;
+
+		byte[] dArr = new byte[len];
+
+		int d = 0;
+
+		for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+
+			int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12
+
+			| IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+			dArr[d++] = (byte) (i >> 16);
+
+			dArr[d++] = (byte) (i >> 8);
+
+			dArr[d++] = (byte) i;
+
+			if (sepCnt > 0 && ++cc == 19) {
+
+				sIx += 2;
+
+				cc = 0;
+
+			}
+
+		}
+
+		if (d < len) {
+
+			int i = 0;
+
+			for (int j = 0; sIx <= eIx - pad; j++)
+
+				i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+			for (int r = 16; d < len; r -= 8)
+
+				dArr[d++] = (byte) (i >> r);
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] encodeToByte(byte[] sArr) {
+
+		return encodeToByte(sArr, devLineSep);
+
+	}
+
+	public final static byte[] encodeToByte(byte[] sArr, boolean lineSep) {
+
+		int sLen = sArr != null ? sArr.length : 0;
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int eLen = (sLen / 3) * 3;
+		int cCnt = ((sLen - 1) / 3 + 1) << 2;
+
+		int dLen = cCnt + (lineSep ? (cCnt - 1) / 76 << 1 : 0);
+
+		byte[] dArr = new byte[dLen];
+
+		for (int s = 0, d = 0, cc = 0; s < eLen;) {
+
+			int i = (sArr[s++] & 0xff) << 16 | (sArr[s++] & 0xff) << 8
+
+			| (sArr[s++] & 0xff);
+
+			dArr[d++] = (byte) CA[(i >>> 18) & 0x3f];
+
+			dArr[d++] = (byte) CA[(i >>> 12) & 0x3f];
+
+			dArr[d++] = (byte) CA[(i >>> 6) & 0x3f];
+
+			dArr[d++] = (byte) CA[i & 0x3f];
+
+			if (lineSep && ++cc == 19 && d < dLen - 2) {
+
+				dArr[d++] = '\r';
+
+				dArr[d++] = '\n';
+
+				cc = 0;
+
+			}
+
+		}
+
+		int left = sLen - eLen;
+		if (left > 0) {
+
+			int i = ((sArr[eLen] & 0xff) << 10)
+
+			| (left == 2 ? ((sArr[sLen - 1] & 0xff) << 2) : 0);
+
+			dArr[dLen - 4] = (byte) CA[i >> 12];
+
+			dArr[dLen - 3] = (byte) CA[(i >>> 6) & 0x3f];
+
+			dArr[dLen - 2] = left == 2 ? (byte) CA[i & 0x3f] : (byte) '=';
+
+			dArr[dLen - 1] = '=';
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] decode(byte[] sArr) {
+
+		int sLen = sArr.length;
+
+		int sepCnt = 0;
+		for (int i = 0; i < sLen; i++)
+
+			if (IA[sArr[i] & 0xff] < 0)
+
+				sepCnt++;
+
+		if ((sLen - sepCnt) % 4 != 0)
+
+			return null;
+
+		int pad = 0;
+
+		for (int i = sLen; i > 1 && IA[sArr[--i] & 0xff] <= 0;)
+
+			if (sArr[i] == '=')
+
+				pad++;
+
+		int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+		byte[] dArr = new byte[len];
+
+		for (int s = 0, d = 0; d < len;) {
+
+			int i = 0;
+
+			for (int j = 0; j < 4; j++) {
+
+				int c = IA[sArr[s++] & 0xff];
+
+				if (c >= 0)
+
+					i |= c << (18 - j * 6);
+
+				else
+
+					j--;
+
+			}
+
+			dArr[d++] = (byte) (i >> 16);
+
+			if (d < len) {
+
+				dArr[d++] = (byte) (i >> 8);
+
+				if (d < len)
+
+					dArr[d++] = (byte) i;
+
+			}
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] encode(byte[] sArr) {
+
+		return encodeToString(sArr).getBytes();
+	}
+
+	public final static byte[] decodeFast(byte[] sArr) {
+
+		int sLen = sArr.length;
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int sIx = 0, eIx = sLen - 1;
+
+		while (sIx < eIx && IA[sArr[sIx] & 0xff] < 0)
+
+			sIx++;
+
+		while (eIx > 0 && IA[sArr[eIx] & 0xff] < 0)
+
+			eIx--;
+
+		int pad = sArr[eIx] == '=' ? (sArr[eIx - 1] == '=' ? 2 : 1) : 0;
+
+		int cCnt = eIx - sIx + 1;
+
+		int sepCnt = sLen > 76 ? (sArr[76] == '\r' ? cCnt / 78 : 0) << 1 : 0;
+
+		int len = ((cCnt - sepCnt) * 6 >> 3) - pad;
+
+		byte[] dArr = new byte[len];
+		int d = 0;
+
+		for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+
+			int i = IA[sArr[sIx++]] << 18 | IA[sArr[sIx++]] << 12
+
+			| IA[sArr[sIx++]] << 6 | IA[sArr[sIx++]];
+
+			dArr[d++] = (byte) (i >> 16);
+
+			dArr[d++] = (byte) (i >> 8);
+
+			dArr[d++] = (byte) i;
+
+			if (sepCnt > 0 && ++cc == 19) {
+
+				sIx += 2;
+
+				cc = 0;
+
+			}
+
+		}
+
+		if (d < len) {
+
+			int i = 0;
+
+			for (int j = 0; sIx <= eIx - pad; j++)
+
+				i |= IA[sArr[sIx++]] << (18 - j * 6);
+
+			for (int r = 16; d < len; r -= 8)
+
+				dArr[d++] = (byte) (i >> r);
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static String encodeToString(byte[] sArr, boolean lineSep) {
+
+		return new String(encodeToChar(sArr, lineSep));
+
+	}
+
+	public final static String encodeToString(byte[] sArr) {
+
+		return new String(encodeToChar(sArr, devLineSep));
+
+	}
+
+	public final static byte[] decodeByte(String str) {
+
+		int sLen = str != null ? str.length() : 0;
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int sepCnt = 0;
+		for (int i = 0; i < sLen; i++)
+
+			if (IA[str.charAt(i)] < 0)
+
+				sepCnt++;
+
+		if ((sLen - sepCnt) % 4 != 0)
+
+			return null;
+
+		int pad = 0;
+
+		for (int i = sLen; i > 1 && IA[str.charAt(--i)] <= 0;)
+
+			if (str.charAt(i) == '=')
+
+				pad++;
+
+		int len = ((sLen - sepCnt) * 6 >> 3) - pad;
+
+		byte[] dArr = new byte[len];
+
+		for (int s = 0, d = 0; d < len;) {
+
+			int i = 0;
+
+			for (int j = 0; j < 4; j++) {
+
+				int c = IA[str.charAt(s++)];
+
+				if (c >= 0)
+
+					i |= c << (18 - j * 6);
+
+				else
+
+					j--;
+
+			}
+
+			dArr[d++] = (byte) (i >> 16);
+
+			if (d < len) {
+
+				dArr[d++] = (byte) (i >> 8);
+
+				if (d < len)
+
+					dArr[d++] = (byte) i;
+
+			}
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static byte[] decodeFast(String s) {
+
+		int sLen = s.length();
+
+		if (sLen == 0)
+
+			return new byte[0];
+
+		int sIx = 0, eIx = sLen - 1;
+
+		while (sIx < eIx && IA[s.charAt(sIx) & 0xff] < 0)
+
+			sIx++;
+
+		while (eIx > 0 && IA[s.charAt(eIx) & 0xff] < 0)
+
+			eIx--;
+
+		int pad = s.charAt(eIx) == '=' ? (s.charAt(eIx - 1) == '=' ? 2 : 1) : 0;
+		int cCnt = eIx - sIx + 1;
+		int sepCnt = sLen > 76 ? (s.charAt(76) == '\r' ? cCnt / 78 : 0) << 1
+
+		: 0;
+
+		int len = ((cCnt - sepCnt) * 6 >> 3) - pad;
+		byte[] dArr = new byte[len];
+		int d = 0;
+
+		for (int cc = 0, eLen = (len / 3) * 3; d < eLen;) {
+
+			int i = IA[s.charAt(sIx++)] << 18 | IA[s.charAt(sIx++)] << 12
+
+			| IA[s.charAt(sIx++)] << 6 | IA[s.charAt(sIx++)];
+
+			dArr[d++] = (byte) (i >> 16);
+
+			dArr[d++] = (byte) (i >> 8);
+
+			dArr[d++] = (byte) i;
+
+			if (sepCnt > 0 && ++cc == 19) {
+
+				sIx += 2;
+
+				cc = 0;
+
+			}
+
+		}
+
+		if (d < len) {
+
+			int i = 0;
+
+			for (int j = 0; sIx <= eIx - pad; j++)
+
+				i |= IA[s.charAt(sIx++)] << (18 - j * 6);
+
+			for (int r = 16; d < len; r -= 8)
+
+				dArr[d++] = (byte) (i >> r);
+
+		}
+
+		return dArr;
+
+	}
+
+	public final static String byte2hex(byte[] b) {
+
+		String hs = "";
+		String stmp = "";
+		for (int n = 0; n < b.length; n++) {
+			stmp = (Integer.toHexString(b[n] & 0XFF));
+			if (stmp.length() == 1) {
+				hs = hs + "0" + stmp;
+			} else {
+				hs = hs + stmp;
+			}
+		}
+		return hs;
+
+	}
+
+	public static byte[] hex2byte(String str) {
+
+		if (str == null) {
+			return null;
+		}
+		str = str.trim();
+		int len = str.length();
+		if (len == 0 || len % 2 == 1) {
+			return null;
+		}
+		byte[] b = new byte[len / 2];
+		try {
+			for (int i = 0; i < str.length(); i += 2) {
+				b[i / 2] = (byte) Integer
+						.decode("0x" + str.substring(i, i + 2)).intValue();
+			}
+			return b;
+		} catch (Exception e) {
+			return null;
+		}
+	}
+
+}

+ 1165 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/BytesHelp.java

@@ -0,0 +1,1165 @@
+package org.ts.ddcs.common.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.util.Calendar;
+
+public class BytesHelp {
+
+    /**
+     * 字节数组转成二进制字符串
+     */
+//    public static String BytesToBinStr(byte[] bytes) {
+//        String binStr = "";
+//        if (null != bytes && bytes.length > 0) {
+//            for (int i = 0; i < bytes.length; i++) {
+//                byte b = bytes[i];
+//                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+//                binStr += tmpStr;
+//            }
+//        }
+//        return binStr;
+//    }
+//
+//    /**
+//     * 字节数组转成二进制字符串,反转字节
+//     */
+//    public static String BytesToBinStr2(byte[] bytes) {
+//        String binStr = "";
+//        if (null != bytes && bytes.length > 0) {
+//            for (int i = bytes.length; i > 0; i--) {
+//                byte b = bytes[i - 1];
+//                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+//                binStr += tmpStr;
+//            }
+//        }
+//        return binStr;
+//    }
+
+    /**
+     * 产生引导符
+     *
+     * @param guide
+     * @param len
+     * @param decimalLen
+     * @return
+     */
+    public static byte[] createGuideBytes(byte guide, int len, int decimalLen) {
+        byte[] guideBuff = new byte[2];
+        int tmpTotalLen = 0x000000FF & len << 3;
+        int tmpDecimalLen = decimalLen & 0x00000007;
+        int valueByte = tmpTotalLen | tmpDecimalLen;
+        guideBuff[0] = guide;
+        guideBuff[1] = (byte) valueByte;
+        return guideBuff;
+    }
+
+    public static String toIp(byte[] buff) {
+        String ipStr = BytesHelp.byte2HexStr(buff);
+        String ip = String.format("%d", Integer.parseInt(ipStr.substring(0, 3)));
+        ip += "." + String.format("%d", Integer.parseInt(ipStr.substring(3, 6)));
+        ip += "." + String.format("%d", Integer.parseInt(ipStr.substring(6, 9)));
+        ip += "." + String.format("%d", Integer.parseInt(ipStr.substring(9, 12)));
+        return ip;
+    }
+
+    public static byte[] createSzyIpBytes(byte guide, String ip) {
+        String[] ips = ip.split(":");
+        String[] texts = ips[0].split("[.]");
+        String newIp = String.format("%03d", Integer.parseInt(texts[0]));
+        newIp += String.format("%03d", Integer.parseInt(texts[1]));
+        newIp += String.format("%03d", Integer.parseInt(texts[2]));
+        newIp += String.format("%03d", Integer.parseInt(texts[3]));
+        String newPort = String.format("%06d", Integer.parseInt(ips[1]));
+        byte[] ipBuff = BytesHelp.hexStr2Bytes(newIp + newPort);
+        int count = 0;
+        byte[] guideBytes = new byte[3];
+        guideBytes[0] = guide;
+        guideBytes[1] = 0x02;
+        guideBytes[2] = (byte) ipBuff.length;
+        byte[] byteBuff = new byte[3 + ipBuff.length];
+        byteBuff[count++] = guideBytes[0];
+        byteBuff[count++] = guideBytes[1];
+        byteBuff[count++] = guideBytes[2];
+        System.arraycopy(ipBuff, 0, byteBuff, count, ipBuff.length);
+        return byteBuff;
+    }
+
+    public static byte[] createIpBytes(byte guide, String ip) {
+        String[] ips = ip.split(":");
+        String[] texts = ips[0].split("[.]");
+        String newIp = String.format("%03d", Integer.parseInt(texts[0]));
+        newIp += String.format("%03d", Integer.parseInt(texts[1]));
+        newIp += String.format("%03d", Integer.parseInt(texts[2]));
+        newIp += String.format("%03d", Integer.parseInt(texts[3]));
+        String newPort = String.format("%06d", Integer.parseInt(ips[1]));
+        byte[] ipBuff = BytesHelp.hexStr2Bytes("02" + newIp + newPort);
+        int count = 0;
+        byte[] guideBytes = BytesHelp.createGuideBytes(guide, ipBuff.length, 0);
+        byte[] byteBuff = new byte[2 + ipBuff.length];
+        byteBuff[count++] = guideBytes[0];
+        byteBuff[count++] = guideBytes[1];
+        System.arraycopy(ipBuff, 0, byteBuff, count, ipBuff.length);
+        return byteBuff;
+    }
+
+    public static byte[] createIpv6Bytes(byte guide, String ip, String port) {
+        byte[] ipBuff = BytesHelp.string2bytes(ip, 39);
+        int portValue = Integer.parseInt(port);
+        byte[] portBuff = BytesHelp.short2bytes((short) portValue);
+        byte[] buff = BytesHelp.arrayApend(ipBuff, portBuff);
+        int count = 0;
+        byte[] guideBytes = BytesHelp.createGuideBytes(guide, buff.length, 0);
+        byte[] byteBuff = new byte[2 + buff.length];
+        byteBuff[count++] = guideBytes[0];
+        byteBuff[count++] = guideBytes[1];
+        System.arraycopy(buff, 0, byteBuff, count, buff.length);
+        return byteBuff;
+    }
+
+    /**
+     * 产生带引导符的BCD字符串字节数组
+     *
+     * @param guide
+     * @param bcdStr
+     * @return
+     */
+    public static byte[] createBcdBytes(byte guide, String bcdStr) {
+        byte[] bcdBuff = BytesHelp.hexStr2Bytes(bcdStr);
+        int buffLen = 2 + bcdBuff.length;
+        byte[] byteBuff = new byte[buffLen];
+        int count = 0;
+        byte[] guideBytes = BytesHelp.createGuideBytes(guide, bcdBuff.length, 0);
+        byteBuff[count++] = guideBytes[0];
+        byteBuff[count++] = guideBytes[1];
+        System.arraycopy(bcdBuff, 0, byteBuff, count, bcdBuff.length);
+        return byteBuff;
+    }
+
+    /**
+     * 产生带引导符的数值字节数组
+     *
+     * @param guide
+     * @param value
+     * @param decimalLen
+     * @return
+     */
+    public static byte[] createValueBytes(byte guide, String value, int decimalLen, int byteLen) {
+        String valueStr = "";
+        if (decimalLen == 0) {
+            if (value.contains(".")) {
+                String[] arr = value.split("[.]");
+                valueStr = arr[0];
+            } else {
+                valueStr = value;
+            }
+        } else {
+            if (value.contains(".")) {
+                String[] arr = value.split("[.]");
+                valueStr = arr[0];
+                if (arr[1].length() >= decimalLen) {
+                    for (int i = 0; i < decimalLen; i++) {
+                        valueStr += arr[1].substring(i, i + 1);
+                    }
+                } else {
+                    for (int i = 0; i < arr[1].length(); i++) {
+                        valueStr += arr[1].substring(i, i + 1);
+                    }
+                    for (int i = arr[1].length(); i < decimalLen; i++) {
+                        valueStr += "0";
+                    }
+                }
+            } else {
+                valueStr = value;
+                for (int i = 0; i < decimalLen; i++) {
+                    valueStr += "0";
+                }
+            }
+        }
+
+//        BigDecimal newValue = value.setScale(decimalLen, BigDecimal.ROUND_DOWN);
+//        String valueStr ="";// newValue.toPlainString();
+//        if (value.contains(".")){
+//            if (decimalLen==0){
+//                valueStr = valueStr.substring(0,valueStr.indexOf("."));
+//            }else{
+//                valueStr = valueStr.replace(".", "");
+//            }
+//        }else{
+//
+//        }
+
+        String contentStr = valueStr;
+        if (valueStr.startsWith("-")) {
+            contentStr = valueStr.substring(1);
+        }
+        byte[] contentBuff = new byte[byteLen];
+        byte[] tmpBuf = BytesHelp.hexStr2Bytes(contentStr);
+        if (tmpBuf.length == contentBuff.length) {
+            contentBuff = tmpBuf;
+        } else {
+            System.arraycopy(tmpBuf, 0, contentBuff, contentBuff.length - tmpBuf.length, tmpBuf.length);
+        }
+        if (valueStr.startsWith("-")) {
+            byte[] tmpContentBuff = new byte[byteLen + 1];
+            tmpContentBuff[0] = (byte) 0xFF;
+            System.arraycopy(contentBuff, 0, tmpContentBuff, 1, contentBuff.length);
+            contentBuff = tmpContentBuff;
+        }
+
+        byte[] guideBytes = BytesHelp.createGuideBytes(guide, contentBuff.length, decimalLen);
+
+        int buffLen = contentBuff.length + 2;
+
+        byte[] byteBuff = new byte[buffLen];
+        int count = 0;
+        byteBuff[count++] = guideBytes[0];
+        byteBuff[count++] = guideBytes[1];
+        System.arraycopy(contentBuff, 0, byteBuff, count, contentBuff.length);
+        return byteBuff;
+    }
+
+    public static boolean errorValue(byte[] buff) {
+        if ((byte) 0xFF == buff[0]) {
+            for (int i = 1; i < buff.length; i++) {
+                if ((byte) 0xFF != buff[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public static BigDecimal toDecimal(byte[] buff, int decimalLen) {
+        String hexStr = BytesHelp.byte2HexStr(buff);
+        StringBuffer valueStr = new StringBuffer();
+        if ("FF".equals(hexStr.substring(0, 2).toUpperCase())) {
+            valueStr.append("-");
+            valueStr.append(hexStr.substring(2));
+        } else {
+            valueStr.append(hexStr);
+        }
+        if (decimalLen != 0) {
+            valueStr.insert(valueStr.length() - decimalLen, ".");
+        }
+        String decimalValue = valueStr.toString();
+        return new BigDecimal(decimalValue);
+    }
+
+    public static BigDecimal toDecimal(byte[] buff, int index, int dataLen, int decimalLen) {
+        byte[] valueBuff = BytesHelp.subBytes(buff, index, dataLen);
+        if (null == valueBuff || valueBuff.length <= 0) {
+            return null;
+        }
+        String hexStr = BytesHelp.byte2HexStr(valueBuff);
+        StringBuffer dataStr = new StringBuffer(hexStr);
+        String pre = "";
+        if (hexStr.substring(0, 2).equals("FF")) {
+            dataStr = new StringBuffer(hexStr.substring(2));
+            pre = "-";
+        }
+        if (decimalLen != 0) {
+            dataStr.insert(dataStr.length() - decimalLen, ".");
+        }
+        String decimalValue = StringUtil.getPrettyNumber(dataStr.toString());
+        decimalValue = pre + decimalValue;
+        return new BigDecimal(decimalValue);
+    }
+
+    /**
+     * 数值转换
+     *
+     * @param value
+     * @param decimalLen
+     * @return
+     */
+    public static BigDecimal toDecimal(String value, int decimalLen) {
+        String hexStr = value;
+        StringBuffer dataStr = new StringBuffer(hexStr);
+        if (hexStr.substring(0, 2).equals("FF")) {
+            dataStr = new StringBuffer(hexStr.substring(2));
+        }
+        if (decimalLen != 0) {
+            dataStr.insert(dataStr.length() - decimalLen, ".");
+        }
+        String decimalValue = StringUtil.getPrettyNumber(dataStr.toString());
+        if (hexStr.substring(0, 2).equals("FF")) {
+            decimalValue = "-" + decimalValue;
+        }
+        return new BigDecimal(decimalValue);
+    }
+
+    /**
+     * 转整形
+     *
+     * @param value
+     * @return
+     */
+    public static Integer toInt(String value) {
+        StringBuffer dataStr = new StringBuffer(value);
+        if ("FF".equals(value.substring(0, 2))) {
+            dataStr = new StringBuffer(value.substring(2));
+        }
+        String intValue = Integer.valueOf(dataStr.toString()).toString();
+        if ("FF".equals(value.substring(0, 2))) {
+            intValue = "-" + intValue;
+        }
+        return Integer.valueOf(intValue);
+    }
+
+    /**
+     * 转长整形
+     *
+     * @param value
+     * @return
+     */
+    public static Long toLong(String value) {
+        StringBuffer dataStr = new StringBuffer(value);
+        if ("FF".equals(value.substring(0, 2))) {
+            dataStr = new StringBuffer(value.substring(2));
+        }
+        String intValue = Long.valueOf(dataStr.toString()).toString();
+        if ("FF".equals(value.substring(0, 2))) {
+            intValue = "-" + intValue;
+        }
+        return Long.valueOf(intValue);
+    }
+
+
+    /**
+     * 字节数组转成二进制字符串
+     */
+    public static String BytesToBinStr(byte[] bytes) {
+        String binStr = "";
+        if (null != bytes && bytes.length > 0) {
+            for (int i = 0; i < bytes.length; i++) {
+                byte b = bytes[i];
+                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+                binStr += tmpStr;
+            }
+        }
+        return binStr;
+    }
+
+    /**
+     * 字节数组转成二进制字符串,反转字节
+     */
+    public static String BytesToBinStr2(byte[] bytes) {
+        String binStr = "";
+        if (null != bytes && bytes.length > 0) {
+            for (int i = bytes.length; i > 0; i--) {
+                byte b = bytes[i - 1];
+                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+                binStr += tmpStr;
+            }
+        }
+        return binStr;
+    }
+
+//    public static String BytesToBinStr2(byte[] bytes) {
+//        String binStr = "";
+//        if (null != bytes && bytes.length > 0) {
+//            for (int i = 0; i < bytes.length; i++) {
+//                byte b = bytes[i];
+//                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+//                binStr += tmpStr;
+//            }
+//        }
+//        return binStr;
+//    }
+
+    /**
+     * 二进制字符串转成字节数组
+     */
+    public static byte[] BinStrToBytes(String binStr) {
+        byte[] b = new byte[1];
+        for (int i = 0; i < b.length; i++) {
+            b[i] = Integer.valueOf(binStr, 2).byteValue();
+        }
+        return b;
+    }
+
+
+    /**
+     * bcd码转int
+     *
+     * @param bs  cbcd16进制数组
+     * @param off 起始位置
+     * @param len 长度
+     * @return int
+     */
+    public static int cbcd2int(byte[] bs, int off, int len) {
+        int v = 0;
+        for (int i = off; i < (off + len); i++) {
+            v = (v * 100) + (((bs[i] & 0xFF) >> 4) * 10) + (bs[i] & 0x0F);
+        }
+        return v;
+    }
+
+    /**
+     * int转bcd码
+     *
+     * @param i   int数值
+     * @param len (bcd长度)
+     * @return byte[] cbcd16进制数组
+     */
+    public static byte[] int2cbcd(int i, int len) {
+        byte[] bs = new byte[len];
+        int temp;
+        for (int j = len - 1; j >= 0; j--) {
+            temp = i % 100;
+            bs[j] = (byte) (((temp / 10) << 4) + ((temp % 10) & 0x0F));
+            i /= 100;
+        }
+        return bs;
+    }
+
+    /**
+     * 数值类型转byte数组(long(8),int(4),short(2))
+     *
+     * @param num (long,int,short)
+     * @param len (8, 4, 2)
+     * @return
+     */
+    public static byte[] number2bytes(long num, int len) {
+        byte[] bs = new byte[len];
+        for (int j = 0; j < len; j++) {
+            bs[len - j - 1] = (byte) (num >> (j * 8));
+        }
+        return bs;
+    }
+
+    /**
+     * byte数组转short
+     *
+     * @param bs
+     * @return
+     */
+    public static short bytes2short(byte[] bs) {
+        short s = (short) (bs[1] & 0xFF);
+        s |= (bs[0] << 8) & 0xFF00;
+        return s;
+    }
+
+    /**
+     * short转byte数组
+     *
+     * @param s
+     * @return
+     */
+    public static byte[] short2bytes(short s) {
+        byte[] bs = new byte[2];
+        for (int i = 1; i >= 0; i--) {
+            bs[i] = (byte) (s % 256);
+            s >>= 8;
+        }
+        return bs;
+    }
+
+    /**
+     * String转bcd byte数组
+     *
+     * @param s
+     * @return
+     */
+    public static byte[] string2cbcd(String s) {
+        if (s.length() % 2 != 0) {
+            s = "0" + s;
+        }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        char[] cs = s.toCharArray();
+        for (int i = 0; i < cs.length; i += 2) {
+            int high = cs[i] - 48;
+            int low = cs[i + 1] - 48;
+            baos.write(high << 4 | low);
+        }
+        return baos.toByteArray();
+    }
+
+    /**
+     * 转数据为字符串
+     *
+     * @param bs
+     * @param off
+     * @param len
+     * @return
+     */
+    public static String getHexString(byte[] bs, int off, int len) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = off; i < (off + len); i++) {
+            String hex = Integer.toHexString(bs[i] & 0xFF);
+            if (hex.length() == 1) {
+                sb.append('0').append(hex);
+            } else {
+                sb.append(hex);
+            }
+            // sb.append(' ');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * byte数组转String
+     *
+     * @param bs
+     * @param off
+     * @param len
+     * @return
+     */
+    public static String bytes2String(byte[] bs, int off, int len) {
+        return new String(bs, off, len, Charset.forName("UTF-8")).trim();
+    }
+
+    /**
+     * String 转 byte[]
+     *
+     * @param str
+     * @param len
+     * @return
+     */
+    public static byte[] string2bytes(String str, int len) {
+        byte[] bs;
+        if (str != null) {
+            bs = str.getBytes();
+        } else {
+            bs = new byte[len];
+        }
+        return bs;
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @return
+     */
+    public static byte[] int2Bytes(int i) {
+        return int2Bytes(i, 4);
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @return
+     */
+    public static byte[] intToBytes(int i, int length) {
+        return int2Bytes(i, length);
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @param len
+     * @return
+     */
+    public static byte[] int2Bytes(int i, int len) {
+        byte[] bs = new byte[len];
+        for (int j = 0; j < len; j++) {
+            bs[len - j - 1] = (byte) (i >> (j * 8));
+        }
+        return bs;
+    }
+
+
+    public static int byteslowbitToInt(byte[] bytes, int off) {
+
+        byte[] tmpbuf = new byte[4];
+        tmpbuf[2] = (byte) (bytes[off] & 0x0f);
+        tmpbuf[3] = bytes[off + 1];
+        int v = 0;
+        for (int ii = 0; ii < 4; ii++) {
+            int shi = (4 - 1 - ii) * 8;
+            v += (tmpbuf[ii] & 0x000000FF) << shi;
+        }
+        return v;
+    }
+
+    /**
+     * byte数组转int(命令字专用)
+     *
+     * @param bytes
+     * @return
+     */
+    public static int bytes2Int(byte[] bytes, int off, int len) {
+        int v = 0;
+        int pos = off + len - 1;
+        if (pos >= 0) {
+            v |= (bytes[pos] & 0xFF);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 8) & 0xFF00);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 16) & 0xFF0000);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 24) & 0xFF000000);
+        }
+        return v;
+    }
+
+    // bytes补位用
+    public static byte[] string2Bytes(String src, int len, int max) {
+        byte[] dest = new byte[max];
+
+        if (src == null) {
+            return dest;
+        }
+        while (src.length() < len) {
+            src += " ";
+        }
+        byte[] temp = src.getBytes();
+
+        System.arraycopy(temp, 0, dest, 0, temp.length >= len ? len
+                : temp.length);
+
+        return dest;
+    }
+
+    public static byte[] getBytesFromFile(File file) {
+        byte[] ret = null;
+        try {
+            if (file == null) {
+                return null;
+            }
+            FileInputStream in = new FileInputStream(file);
+            ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+            byte[] b = new byte[4096];
+            int n;
+            while ((n = in.read(b)) != -1) {
+                out.write(b, 0, n);
+            }
+            in.close();
+            out.close();
+            ret = out.toByteArray();
+        } catch (Exception e) {
+            return null;
+        }
+        return ret;
+    }
+
+    public static String getMD5Digest(String str) {
+        return getMD5Digest(str.getBytes());
+    }
+
+    public static String getMD5Digest(byte[] bytes) {
+        MessageDigest messageDigest = null;
+        try {
+            messageDigest = MessageDigest.getInstance("MD5");
+            messageDigest.reset();
+            messageDigest.update(bytes);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        byte[] byteArray = messageDigest.digest();
+        StringBuffer md5StrBuff = new StringBuffer();
+
+        for (int i = 0; i < byteArray.length; i++) {
+            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
+                md5StrBuff.append("0").append(
+                        Integer.toHexString(0xFF & byteArray[i]));
+            else
+                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
+        }
+
+        return md5StrBuff.toString();
+    }
+
+    public static String leftFill(String src, int len, char fillChar) {
+
+        int length = src.length();
+        if (src == null || len < length)
+            return src;
+
+        String result = src;
+        for (int i = length; i < len; i++) {
+            result = String.valueOf(fillChar) + result;
+        }
+
+        return result;
+    }
+
+    /**
+     * 将字符串拼接成指定长度的字符串,不足的补空格
+     *
+     * @param str    字符串
+     * @param length
+     * @return
+     */
+    public static String spliceSpaces(String str, int length) {
+        int strLen = str.length();
+        if (strLen > length) {
+            str = "";
+            for (int i = 0; i < length; i++) {
+                str += " ";
+            }
+        } else {
+            for (int i = 0; i < (length - strLen); i++) {
+                str += " ";
+            }
+        }
+        return str;
+    }
+
+    /**
+     * 将字符串拼接成指定长度的字符串,不足的补0
+     *
+     * @param str    字符串
+     * @param length
+     * @return
+     */
+    public static String spliceZero(String str, int length) {
+        int strLen = str.length();
+        if (strLen > length) {
+            str = "";
+            for (int i = 0; i < length; i++) {
+                str += "0";
+            }
+        } else {
+            for (int i = 0; i < (length - strLen); i++) {
+                str = "0" + str;
+            }
+        }
+        return str;
+    }
+
+    public static byte[] arrayApend(byte[] a, byte[] b) {
+        int a_len = (a == null ? 0 : a.length);
+        int b_len = (b == null ? 0 : b.length);
+        byte[] c = new byte[a_len + b_len];
+        if (a_len == 0 && b_len == 0) {
+            return null;
+        } else if (a_len == 0) {
+            System.arraycopy(b, 0, c, 0, b.length);
+        } else if (b_len == 0) {
+            System.arraycopy(a, 0, c, 0, a.length);
+        } else {
+            System.arraycopy(a, 0, c, 0, a.length);
+            System.arraycopy(b, 0, c, a.length, b.length);
+        }
+        return c;
+    }
+
+
+    public static byte[] arrayApendbyte(byte[] a, byte b) {
+        int a_len = (a == null ? 0 : a.length);
+
+        byte[] c = new byte[a_len + 1];
+        if (a_len == 0) {
+            return null;
+        } else {
+            System.arraycopy(a, 0, c, 0, a.length);
+            System.arraycopy(b, 0, c, a.length, 1);
+        }
+        return c;
+    }
+
+
+    /**
+     * 获取字符Ascii值
+     *
+     * @param str
+     * @return
+     */
+    public static int getAsciiValue(String str) {
+        if (str.length() != 1) {
+            return 0;
+        }
+        char[] ch = str.toCharArray();
+
+        return ch[0];
+    }
+
+    /**
+     * 获取字符Ascii值 16
+     *
+     * @param str
+     * @return
+     */
+    public static String getAsciiHexValueS(String str) {
+        char[] ch = str.toCharArray();
+        StringBuffer retStr = new StringBuffer();
+        for (int i = 0; i < ch.length; i++) {
+            retStr.append(Integer.toHexString(ch[i]));
+        }
+        return retStr.toString();
+    }
+
+    /**
+     * 获取字符Ascii值
+     *
+     * @param str
+     * @return
+     */
+    public static String getAsciiValueS(String str) {
+        char[] ch = str.toCharArray();
+        StringBuffer retStr = new StringBuffer();
+        for (int i = 0; i < ch.length; i++) {
+            retStr.append((int) ch[i]);
+        }
+        return retStr.toString();
+    }
+
+    public static String getAsciiStr(int d) {
+        char e = (char) d;
+        return e + "";
+    }
+
+
+    public static String byte2HexStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+    public static String byte2HexStr(byte[] b, int pos, int length) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < length; n++) {
+            stmp = Integer.toHexString(b[n + pos] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+    public static byte[] hexStr2Bytes(String hexString) {
+        hexString = hexString.toLowerCase();
+        int remainder = hexString.length() % 2;
+        if (remainder > 0) {
+            hexString = "0" + hexString;
+        }
+        final byte[] byteArray = new byte[hexString.length() / 2];
+        int k = 0;
+        for (int i = 0; i < byteArray.length; i++) {
+            //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
+            //将hex 转换成byte   "&" 操作为了防止负数的自动扩展
+            // hex转换成byte 其实只占用了4位,然后把高位进行右移四位
+            // 然后“|”操作  低四位 就能得到 两个 16进制数转换成一个byte.
+            //
+            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
+            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
+            byteArray[i] = (byte) (high << 4 | low);
+            k += 2;
+        }
+        return byteArray;
+    }
+
+    public static byte[] subBytes(byte[] src, int begin, int count) {
+        byte[] bs = new byte[count];
+        for (int i = begin; i < begin + count; i++) bs[i - begin] = src[i];
+        return bs;
+    }
+
+    //CRC校验运算
+    public static byte GetCRCByte(byte[] data) {
+        int crc = 0x0; // 初始值为0
+        for (byte bt : data) {
+            crc = crc ^ bt;
+            for (int j = 1; j <= 8; j++) {
+                if ((crc & 0x80) == 0x80) {
+                    // 多项式值为E5,被校验值左移
+                    crc = (crc << 1) ^ 0xE5;
+                } else {
+                    crc = crc << 1;
+                }
+            }
+        }
+        return (byte) crc;
+    }
+
+    //将16进制字符串转换为16进制byte数组
+    public static byte[] HexString2Bytes(String src) {
+        byte[] ret = new byte[8];
+        byte[] tmp = src.getBytes();
+        for (int i = 0; i < 8; i++) {
+            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
+        }
+        return ret;
+    }
+
+    public static byte uniteBytes(byte src0, byte src1) {
+        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
+        _b0 = (byte) (_b0 << 4);
+        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
+        byte ret = (byte) (_b0 ^ _b1);
+        return ret;
+    }
+
+
+    //16进制字符串转换为2进制字符串
+    public static String hexString2binaryString(String hexString) {
+        if (hexString == null || hexString.length() % 2 != 0)
+            return null;
+        String bString = "", tmp;
+        for (int i = 0; i < hexString.length(); i++) {
+            tmp = "0000"
+                    + Integer.toBinaryString(Integer.parseInt(
+                    hexString.substring(i, i + 1), 16));
+            bString += tmp.substring(tmp.length() - 4);
+        }
+        return bString;
+    }
+
+    /**
+     * 获取时间戳位
+     *
+     * @return
+     */
+    public static byte[] getTPByte() {
+
+
+        Calendar now = Calendar.getInstance();
+        //String year = now.get(Calendar.YEAR)+"";
+        String second = now.get(Calendar.SECOND) + "";
+        String minute = now.get(Calendar.MINUTE) + "";
+        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
+        String day = now.get(Calendar.DATE) + "";
+        byte[] tpArea;
+
+        if (second.length() == 1) {
+            tpArea = BytesHelp.hexStr2Bytes("0" + second);
+        } else {
+            tpArea = BytesHelp.hexStr2Bytes(second);
+        }
+
+        if (minute.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + minute));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(minute));
+        }
+        if (hour.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + hour));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(hour));
+        }
+        if (day.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + day));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(day));
+        }
+
+        tpArea = BytesHelp.arrayApend(tpArea,
+                BytesHelp.hexStr2Bytes("00"));
+
+        return tpArea;
+
+    }
+
+
+    /**
+     * 单一字节中选择指定位bcd码转换为整数
+     *
+     * @param b
+     * @param highBit 高位,最大7
+     * @param lowBit  低位,从0开始
+     * @return
+     */
+    public static int bcdToInt(byte b, int highBit, int lowBit) {
+        int g = highBit - lowBit + 1;
+        int a = ((int) Math.pow(2, g) - 1) << lowBit;
+        int b2 = (b & a) >> lowBit;
+        return b2;
+    }
+
+    public static byte[] crcFun2014(byte[] packet, int pos, int length) {
+        int n = length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = byteToInteger(packet[pos + b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesHelp.int2Bytes(crc, 2);
+    }
+
+    public static byte[] crcFun2014(byte[] packet) {
+        int n = packet.length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = byteToInteger(packet[b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesHelp.int2Bytes(crc, 2);
+    }
+
+    public static int byteToInteger(byte b) {
+        int value;
+        value = b & 0xff;
+        return value;
+    }
+
+
+    /**
+     * 获取发报时间
+     *
+     * @return
+     */
+    public static byte[] getFBTm() {
+
+
+        Calendar now = Calendar.getInstance();
+        String year = now.get(Calendar.YEAR) + "";
+        String month = now.get(Calendar.MONTH) + 1 + "";
+        String day = now.get(Calendar.DATE) + "";
+        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
+        String minute = now.get(Calendar.MINUTE) + "";
+        String second = now.get(Calendar.SECOND) + "";
+
+        byte[] tpArea;
+
+        tpArea = BytesHelp.hexStr2Bytes(year.substring(2, year.length()));
+
+        if (month.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + month));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(month));
+        }
+
+        if (day.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + day));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(day));
+        }
+        if (hour.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + hour));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(hour));
+        }
+        if (minute.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + minute));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(minute));
+        }
+
+        if (second.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + second));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(second));
+        }
+
+        return tpArea;
+
+    }
+
+
+    //将16进制RTU编码改成10进制
+    public static String byte2HexMpCdStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < 3; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+
+        int mpcd = 0;
+        if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式
+            String str4 = Integer.toHexString(b[4] & 0xFF);
+            String mpcdStr = Integer.toHexString(b[3] & 0xFF);
+            if (str4.length() == 1) {
+                mpcdStr += "0" + str4;
+            } else {
+                mpcdStr += str4;
+            }
+            //String mpcdStr = Integer.toHexString(b[3] & 0xFF)+Integer.toHexString(b[4] & 0xFF);
+            mpcd = Integer.parseInt(mpcdStr);
+        } else {
+            mpcd = bytes2Int(BytesHelp.subBytes(b, 3, 2), 0, 2) % 10000;
+        }
+        sb.append(StringUtil.leftFill(mpcd + "", 4, '0'));
+        return sb.toString().toUpperCase().trim();
+    }
+
+
+    //将16进制RTU编码改成10进制(东深厂商专用),编号最后俩个字节颠倒
+    public static String byte2HexMpCdStrDS(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < 3; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+
+        int mpcd = 0;
+        if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式
+            String mpcdStr = Integer.toHexString(b[3] & 0xFF) + Integer.toHexString(b[4] & 0xFF);
+            mpcd = Integer.parseInt(mpcdStr);
+        } else {
+            byte[] mpCdTail = new byte[2];
+            mpCdTail[0] = b[4];
+            mpCdTail[1] = b[3];
+            //mpcd =  bytes2Int( BytesHelp.subBytes(b, 3, 2),0,2) %10000;
+            mpcd = bytes2Int(mpCdTail, 0, 2) % 10000;
+        }
+        sb.append(StringUtil.leftFill(mpcd + "", 4, '0'));
+        return sb.toString().toUpperCase().trim();
+    }
+
+    //bdcd十六进字符串转成字节数组
+    public static byte[] hstrToBytes(String str) {
+        char[] ca = str.toCharArray();
+        byte[] databuff = new byte[ca.length / 2];
+        for (int j = 0; j < ca.length; j += 2) {
+
+            byte bb = (byte) (charToByte(ca[j]) << 4 | charToByte(ca[j + 1]));
+            databuff[j == 0 ? 0 : (j / 2)] = bb;
+        }
+        return databuff;
+    }
+
+    public static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+    public static boolean isNumeric(String str) {
+        for (int i = str.length(); --i >= 0; ) {
+            if (!Character.isDigit(str.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

+ 813 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/BytesUtil.java

@@ -0,0 +1,813 @@
+package org.ts.ddcs.common.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.MessageDigest;
+import java.util.Calendar;
+
+public class BytesUtil {
+
+    /**
+     * bcd码转int
+     *
+     * @param bs  cbcd16进制数组
+     * @param off 起始位置
+     * @param len 长度
+     * @return int
+     */
+    public static int cbcd2int(byte[] bs, int off, int len) {
+        int v = 0;
+        for (int i = off; i < (off + len); i++) {
+            v = (v * 100) + (((bs[i] & 0xFF) >> 4) * 10) + (bs[i] & 0x0F);
+        }
+        return v;
+    }
+
+    /**
+     * 字节数组转成二进制字符串
+     */
+    public static String bytesToBinStr(byte[] bytes) {
+        String binStr = "";
+        if (null != bytes && bytes.length > 0) {
+            for (int i = 0; i < bytes.length; i++) {
+                byte b = bytes[i];
+                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+                binStr += tmpStr;
+            }
+        }
+        return binStr;
+    }
+
+
+    /**
+     * 字节数组转成二进制字符串,反转字节
+     */
+    public static String bytesToBinStr2(byte[] bytes) {
+        String binStr = "";
+        if (null != bytes && bytes.length > 0) {
+            for (int i = bytes.length; i > 0; i--) {
+                byte b = bytes[i - 1];
+                String tmpStr = Integer.toBinaryString((b & 0xFF) + 0x100).substring(1);
+                binStr += tmpStr;
+            }
+        }
+        return binStr;
+    }
+
+    /**
+     * 二进制字符串转成字节数组
+     */
+    public static byte[] binStrToBytes(String binStr) {
+        byte[] b = new byte[binStr.length() / 8];
+        for (int i = 0; i < b.length; i++) {
+            String bin = binStr.substring(i * 8, i * 8 + 8);
+            b[i] = Integer.valueOf(bin, 2).byteValue();
+        }
+        return b;
+    }
+
+    /**
+     * int转bcd码
+     *
+     * @param i   int数值
+     * @param len (bcd长度)
+     * @return byte[] cbcd16进制数组
+     */
+    public static byte[] int2cbcd(int i, int len) {
+        byte[] bs = new byte[len];
+        int temp;
+        for (int j = len - 1; j >= 0; j--) {
+            temp = i % 100;
+            bs[j] = (byte) (((temp / 10) << 4) + ((temp % 10) & 0x0F));
+            i /= 100;
+        }
+        return bs;
+    }
+
+    /**
+     * 数值类型转byte数组(long(8),int(4),short(2))
+     *
+     * @param num (long,int,short)
+     * @param len (8, 4, 2)
+     * @return
+     */
+    public static byte[] number2bytes(long num, int len) {
+        byte[] bs = new byte[len];
+        for (int j = 0; j < len; j++) {
+            bs[len - j - 1] = (byte) (num >> (j * 8));
+        }
+        return bs;
+    }
+
+    /**
+     * byte数组转short
+     *
+     * @param bs
+     * @return
+     */
+    public static short bytes2short(byte[] bs) {
+        short s = (short) (bs[1] & 0xFF);
+        s |= (bs[0] << 8) & 0xFF00;
+        return s;
+    }
+
+    /**
+     * short转byte数组
+     *
+     * @param s
+     * @return
+     */
+    public static byte[] short2bytes(short s) {
+        byte[] bs = new byte[2];
+        for (int i = 1; i >= 0; i--) {
+            bs[i] = (byte) (s % 256);
+            s >>= 8;
+        }
+        return bs;
+    }
+
+    /**
+     * String转bcd byte数组
+     *
+     * @param s
+     * @return
+     */
+    public static byte[] string2cbcd(String s) {
+        if (s.length() % 2 != 0) {
+            s = "0" + s;
+        }
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        char[] cs = s.toCharArray();
+        for (int i = 0; i < cs.length; i += 2) {
+            int high = cs[i] - 48;
+            int low = cs[i + 1] - 48;
+            baos.write(high << 4 | low);
+        }
+        return baos.toByteArray();
+    }
+
+    /**
+     * 转数据为字符串
+     *
+     * @param bs
+     * @param off
+     * @param len
+     * @return
+     */
+    public static String getHexString(byte[] bs, int off, int len) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = off; i < (off + len); i++) {
+            String hex = Integer.toHexString(bs[i] & 0xFF);
+            if (hex.length() == 1) {
+                sb.append('0').append(hex);
+            } else {
+                sb.append(hex);
+            }
+            // sb.append(' ');
+        }
+        return sb.toString();
+    }
+
+    /**
+     * byte数组转String
+     *
+     * @param bs
+     * @param off
+     * @param len
+     * @return
+     */
+    public static String bytes2String(byte[] bs, int off, int len) {
+        return new String(bs, off, len).trim();
+    }
+
+    /**
+     * String 转 byte[]
+     *
+     * @param str
+     * @param len
+     * @return
+     */
+    public static byte[] string2bytes(String str, int len) {
+        byte[] bs;
+        if (str != null) {
+            bs = str.getBytes();
+        } else {
+            bs = new byte[len];
+        }
+        return bs;
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @return
+     */
+    public static byte[] int2Bytes(int i) {
+        return int2Bytes(i, 4);
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @return
+     */
+    public static byte[] intToBytes(int i, int length) {
+        return int2Bytes(i, length);
+    }
+
+    /**
+     * int 转 byte数组
+     *
+     * @param i
+     * @param len
+     * @return
+     */
+    public static byte[] int2Bytes(int i, int len) {
+        byte[] bs = new byte[len];
+        for (int j = 0; j < len; j++) {
+            bs[len - j - 1] = (byte) (i >> (j * 8));
+        }
+        return bs;
+    }
+
+
+    public static int byteslowbitToInt(byte[] bytes, int off) {
+
+        byte[] tmpbuf = new byte[4];
+        tmpbuf[2] = (byte) (bytes[off] & 0x0f);
+        tmpbuf[3] = bytes[off + 1];
+        int v = 0;
+        for (int ii = 0; ii < 4; ii++) {
+            int shi = (4 - 1 - ii) * 8;
+            v += (tmpbuf[ii] & 0x000000FF) << shi;
+        }
+        return v;
+    }
+
+    /**
+     * byte数组转int(命令字专用)
+     *
+     * @param bytes
+     * @return
+     */
+    public static int bytes2Int(byte[] bytes, int off, int len) {
+        int v = 0;
+        int pos = off + len - 1;
+        if (pos >= 0) {
+            v |= (bytes[pos] & 0xFF);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 8) & 0xFF00);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 16) & 0xFF0000);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 24) & 0xFF000000);
+        }
+        return v;
+    }
+
+    // bytes补位用
+    public static byte[] string2Bytes(String src, int len, int max) {
+        byte[] dest = new byte[max];
+
+        if (src == null) {
+            return dest;
+        }
+        while (src.length() < len) {
+            src += " ";
+        }
+        byte[] temp = src.getBytes();
+
+        System.arraycopy(temp, 0, dest, 0, temp.length >= len ? len
+                : temp.length);
+
+        return dest;
+    }
+
+    public static byte[] getBytesFromFile(File file) {
+        byte[] ret = null;
+        try {
+            if (file == null) {
+                return null;
+            }
+            FileInputStream in = new FileInputStream(file);
+            ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+            byte[] b = new byte[4096];
+            int n;
+            while ((n = in.read(b)) != -1) {
+                out.write(b, 0, n);
+            }
+            in.close();
+            out.close();
+            ret = out.toByteArray();
+        } catch (Exception e) {
+            return null;
+        }
+        return ret;
+    }
+
+    public static String getMD5Digest(String str) {
+        return getMD5Digest(str.getBytes());
+    }
+
+    public static String getMD5Digest(byte[] bytes) {
+        MessageDigest messageDigest = null;
+        try {
+            messageDigest = MessageDigest.getInstance("MD5");
+            messageDigest.reset();
+            messageDigest.update(bytes);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        byte[] byteArray = messageDigest.digest();
+        StringBuffer md5StrBuff = new StringBuffer();
+
+        for (int i = 0; i < byteArray.length; i++) {
+            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
+                md5StrBuff.append("0").append(
+                        Integer.toHexString(0xFF & byteArray[i]));
+            else
+                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
+        }
+
+        return md5StrBuff.toString();
+    }
+
+    public static String leftFill(String src, int len, char fillChar) {
+
+        int length = src.length();
+        if (src == null || len < length)
+            return src;
+
+        String result = src;
+        for (int i = length; i < len; i++) {
+            result = String.valueOf(fillChar) + result;
+        }
+
+        return result;
+    }
+
+    /**
+     * 将字符串拼接成指定长度的字符串,不足的补空格
+     *
+     * @param str    字符串
+     * @param length
+     * @return
+     */
+    public static String spliceSpaces(String str, int length) {
+        int strLen = str.length();
+        if (strLen > length) {
+            str = "";
+            for (int i = 0; i < length; i++) {
+                str += " ";
+            }
+        } else {
+            for (int i = 0; i < (length - strLen); i++) {
+                str += " ";
+            }
+        }
+        return str;
+    }
+
+    /**
+     * 将字符串拼接成指定长度的字符串,不足的补0
+     *
+     * @param str    字符串
+     * @param length
+     * @return
+     */
+    public static String spliceZero(String str, int length) {
+        int strLen = str.length();
+        if (strLen > length) {
+            str = "";
+            for (int i = 0; i < length; i++) {
+                str += "0";
+            }
+        } else {
+            for (int i = 0; i < (length - strLen); i++) {
+                str = "0" + str;
+            }
+        }
+        return str;
+    }
+
+    public static byte[] arrayApend(byte[] a, byte[] b) {
+        int a_len = (a == null ? 0 : a.length);
+        int b_len = (b == null ? 0 : b.length);
+        byte[] c = new byte[a_len + b_len];
+        if (a_len == 0 && b_len == 0) {
+            return null;
+        } else if (a_len == 0) {
+            System.arraycopy(b, 0, c, 0, b.length);
+        } else if (b_len == 0) {
+            System.arraycopy(a, 0, c, 0, a.length);
+        } else {
+            System.arraycopy(a, 0, c, 0, a.length);
+            System.arraycopy(b, 0, c, a.length, b.length);
+        }
+        return c;
+    }
+
+
+    public static byte[] arrayApendbyte(byte[] a, byte b) {
+        int a_len = (a == null ? 0 : a.length);
+
+        byte[] c = new byte[a_len + 1];
+        if (a_len == 0) {
+            return null;
+        } else {
+            System.arraycopy(a, 0, c, 0, a.length);
+            System.arraycopy(b, 0, c, a.length, 1);
+        }
+        return c;
+    }
+
+
+    /**
+     * 获取字符Ascii值
+     *
+     * @param str
+     * @return
+     */
+    public static int getAsciiValue(String str) {
+        if (str.length() != 1) {
+            return 0;
+        }
+        char[] ch = str.toCharArray();
+
+        return ch[0];
+    }
+
+    /**
+     * 获取字符Ascii值 16
+     *
+     * @param str
+     * @return
+     */
+    public static String getAsciiHexValueS(String str) {
+        char[] ch = str.toCharArray();
+        StringBuffer retStr = new StringBuffer();
+        for (int i = 0; i < ch.length; i++) {
+            retStr.append(Integer.toHexString(ch[i]));
+        }
+        return retStr.toString();
+    }
+
+    /**
+     * 获取字符Ascii值
+     *
+     * @param str
+     * @return
+     */
+    public static String getAsciiValueS(String str) {
+        char[] ch = str.toCharArray();
+        StringBuffer retStr = new StringBuffer();
+        for (int i = 0; i < ch.length; i++) {
+            retStr.append((int) ch[i]);
+        }
+        return retStr.toString();
+    }
+
+    public static String getAsciiStr(int d) {
+        char e = (char) d;
+        return e + "";
+    }
+
+
+    public static String byte2HexStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < b.length; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+            //sb.append(" ");
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+    public static String byte2HexStr(byte[] b, int pos, int length) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < length; n++) {
+            stmp = Integer.toHexString(b[n + pos] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+        return sb.toString().toUpperCase().trim();
+    }
+
+    public static byte[] hexStr2Bytes(String hexString) {
+        hexString = hexString.toLowerCase();
+        int remainder = hexString.length() % 2;
+        if (remainder > 0) {
+            hexString = "0" + hexString;
+        }
+        final byte[] byteArray = new byte[hexString.length() / 2];
+        int k = 0;
+        for (int i = 0; i < byteArray.length; i++) {
+            //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
+            //将hex 转换成byte   "&" 操作为了防止负数的自动扩展
+            // hex转换成byte 其实只占用了4位,然后把高位进行右移四位
+            // 然后“|”操作  低四位 就能得到 两个 16进制数转换成一个byte.
+            //
+            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
+            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
+            byteArray[i] = (byte) (high << 4 | low);
+            k += 2;
+        }
+        return byteArray;
+    }
+
+    public static byte[] subBytes(byte[] src, int begin, int count) {
+        byte[] bs = new byte[count];
+        for (int i = begin; i < begin + count; i++) bs[i - begin] = src[i];
+        return bs;
+    }
+
+    //CRC校验运算
+    public static byte GetCRCByte(byte[] data) {
+        int crc = 0x0; // 初始值为0
+        for (byte bt : data) {
+            crc = crc ^ bt;
+            for (int j = 1; j <= 8; j++) {
+                if ((crc & 0x80) == 0x80)
+                    crc = (crc << 1) ^ 0xE5;// 多项式值为E5,被校验值左移
+                else
+                    crc = crc << 1;
+            }
+        }
+        return (byte) crc;
+    }
+
+    //将16进制字符串转换为16进制byte数组
+    public static byte[] HexString2Bytes(String src) {
+        byte[] ret = new byte[8];
+        byte[] tmp = src.getBytes();
+        for (int i = 0; i < 8; i++) {
+            ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]);
+        }
+        return ret;
+    }
+
+    public static byte uniteBytes(byte src0, byte src1) {
+        byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})).byteValue();
+        _b0 = (byte) (_b0 << 4);
+        byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})).byteValue();
+        byte ret = (byte) (_b0 ^ _b1);
+        return ret;
+    }
+
+
+    //16进制字符串转换为2进制字符串
+    public static String hexString2binaryString(String hexString) {
+        if (hexString == null || hexString.length() % 2 != 0)
+            return null;
+        String bString = "", tmp;
+        for (int i = 0; i < hexString.length(); i++) {
+            tmp = "0000"
+                    + Integer.toBinaryString(Integer.parseInt(
+                    hexString.substring(i, i + 1), 16));
+            bString += tmp.substring(tmp.length() - 4);
+        }
+        return bString;
+    }
+
+    /**
+     * 获取时间戳位
+     *
+     * @return
+     */
+    public static byte[] getTPByte() {
+
+
+        Calendar now = Calendar.getInstance();
+        //String year = now.get(Calendar.YEAR)+"";
+        String second = now.get(Calendar.SECOND) + "";
+        String minute = now.get(Calendar.MINUTE) + "";
+        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
+        String day = now.get(Calendar.DATE) + "";
+        byte[] tpArea;
+
+        if (second.length() == 1) {
+            tpArea = BytesUtil.hexStr2Bytes("0" + second);
+        } else {
+            tpArea = BytesUtil.hexStr2Bytes(second);
+        }
+
+        if (minute.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + minute));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(minute));
+        }
+        if (hour.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + hour));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(hour));
+        }
+        if (day.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + day));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(day));
+        }
+
+        tpArea = BytesUtil.arrayApend(tpArea,
+                BytesUtil.hexStr2Bytes("00"));
+
+        return tpArea;
+
+    }
+
+
+    /**
+     * 单一字节中选择指定位bcd码转换为整数
+     *
+     * @param b
+     * @param highBit 高位,最大7
+     * @param lowBit  低位,从0开始
+     * @return
+     */
+    public static int bcdToInt(byte b, int highBit, int lowBit) {
+        int g = highBit - lowBit + 1;
+        int a = ((int) Math.pow(2, g) - 1) << lowBit;
+        int b2 = (b & a) >> lowBit;
+        return b2;
+    }
+
+    public static byte[] crcFun2014(byte[] packet, int pos, int length) {
+        int n = length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = byteToInteger(packet[pos + b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesUtil.int2Bytes(crc, 2);
+    }
+
+    public static byte[] crcFun2014(byte[] packet) {
+        int n = packet.length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = byteToInteger(packet[b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesUtil.int2Bytes(crc, 2);
+    }
+
+    public static int byteToInteger(byte b) {
+        int value;
+        value = b & 0xff;
+        return value;
+    }
+
+
+    /**
+     * 获取发报时间
+     *
+     * @return
+     */
+    public static byte[] getFBTm() {
+        Calendar now = Calendar.getInstance();
+        String year = now.get(Calendar.YEAR) + "";
+        String month = now.get(Calendar.MONTH) + 1 + "";
+        String day = now.get(Calendar.DATE) + "";
+        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
+        String minute = now.get(Calendar.MINUTE) + "";
+        String second = now.get(Calendar.SECOND) + "";
+        byte[] tpArea;
+        tpArea = BytesUtil.hexStr2Bytes(year.substring(2, year.length()));
+        if (month.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + month));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(month));
+        }
+        if (day.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + day));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(day));
+        }
+        if (hour.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + hour));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(hour));
+        }
+        if (minute.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes("0" + minute));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea,
+                    BytesUtil.hexStr2Bytes(minute));
+        }
+        if (second.length() == 1) {
+            tpArea = BytesUtil.arrayApend(tpArea, BytesUtil.hexStr2Bytes("0" + second));
+        } else {
+            tpArea = BytesUtil.arrayApend(tpArea, BytesUtil.hexStr2Bytes(second));
+        }
+        return tpArea;
+    }
+
+
+    //将16进制RTU编码改成10进制
+    public static String byte2HexMpCdStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < 3; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+
+        int mpcd = 0;
+        if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式
+            String str4 = Integer.toHexString(b[4] & 0xFF);
+            String mpcdStr = Integer.toHexString(b[3] & 0xFF);
+            if (str4.length() == 1) {
+                mpcdStr += "0" + str4;
+            } else {
+                mpcdStr += str4;
+            }
+            //String mpcdStr = Integer.toHexString(b[3] & 0xFF)+Integer.toHexString(b[4] & 0xFF);
+            mpcd = Integer.parseInt(mpcdStr);
+        } else {
+            mpcd = bytes2Int(BytesUtil.subBytes(b, 3, 2), 0, 2) % 10000;
+        }
+        sb.append(StringUtil.leftFill(mpcd + "", 4, '0'));
+        return sb.toString().toUpperCase().trim();
+    }
+
+
+    //将16进制RTU编码改成10进制(东深厂商专用),编号最后俩个字节颠倒
+    public static String byte2HexMpCdStrDS(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < 3; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+
+        int mpcd = 0;
+        if (sb.toString().startsWith("00")) {//00开头的站点编号按照10进制处理,99的按照16进制处理,为了满足威控的编码格式
+            String mpcdStr = Integer.toHexString(b[3] & 0xFF) + Integer.toHexString(b[4] & 0xFF);
+            mpcd = Integer.parseInt(mpcdStr);
+        } else {
+            byte[] mpCdTail = new byte[2];
+            mpCdTail[0] = b[4];
+            mpCdTail[1] = b[3];
+            //mpcd =  bytes2Int( BytesUtil.subBytes(b, 3, 2),0,2) %10000;
+            mpcd = bytes2Int(mpCdTail, 0, 2) % 10000;
+        }
+        sb.append(StringUtil.leftFill(mpcd + "", 4, '0'));
+        return sb.toString().toUpperCase().trim();
+    }
+
+    //bdcd十六进字符串转成字节数组
+    public static byte[] hstrToBytes(String str) {
+        char[] ca = str.toCharArray();
+        byte[] databuff = new byte[ca.length / 2];
+        for (int j = 0; j < ca.length; j += 2) {
+
+            byte bb = (byte) (charToByte(ca[j]) << 4 | charToByte(ca[j + 1]));
+            databuff[j == 0 ? 0 : (j / 2)] = bb;
+        }
+        return databuff;
+    }
+
+    public static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+}

+ 47 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC16.java

@@ -0,0 +1,47 @@
+package org.ts.ddcs.common.util;
+
+public class CRC16 {
+	
+	private short[] crcTable = new short[256];
+    private int gPloy = 0x1021; // 生成多项式
+
+    public CRC16() {
+        computeCrcTable();
+    }
+
+    private short getCrcOfByte(int aByte) {
+        int value = aByte << 8;
+
+        for (int count = 7; count >= 0; count--) {
+            if ((value & 0x8000) != 0) { // 高第16位为1,可以按位异或
+                value = (value << 1) ^ gPloy;
+            } else {
+                value = value << 1; // 首位为0,左移
+            }
+
+        }
+        value = value & 0xFFFF; // 取低16位的值
+        return (short)value;
+    }
+
+    /*
+     * 生成0 - 255对应的CRC16校验码
+     */
+    private void computeCrcTable() {
+        for (int i = 0; i < 256; i++) {
+            crcTable[i] = getCrcOfByte(i);
+        }
+    }
+
+    public short getCrc(byte[] data) {
+        int crc = 0;
+        int length = data.length;
+        for (int i = 0; i < length; i++) {
+            crc = ((crc & 0xFF) << 8) ^ crcTable[(((crc & 0xFF00) >> 8) ^ data[i]) & 0xFF];
+        }
+        crc = crc & 0xFFFF;
+        return (short)crc;
+    }
+
+	
+}

+ 82 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC166.java

@@ -0,0 +1,82 @@
+package org.ts.ddcs.common.util;
+
+public class CRC166 {
+
+	private final static short[] CRC16_TABLE = { 0x0000, 0x1021, 0x2042,
+			0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, (short) 0x8108,
+			(short) 0x9129, (short) 0xa14a, (short) 0xb16b, (short) 0xc18c,
+			(short) 0xd1ad, (short) 0xe1ce, (short) 0xf1ef, 0x1231, 0x0210,
+			0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, (short) 0x9339,
+			(short) 0x8318, (short) 0xb37b, (short) 0xa35a, (short) 0xd3bd,
+			(short) 0xc39c, (short) 0xf3ff, (short) 0xe3de, 0x2462, 0x3443,
+			0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, (short) 0xa56a,
+			(short) 0xb54b, (short) 0x8528, (short) 0x9509, (short) 0xe5ee,
+			(short) 0xf5cf, (short) 0xc5ac, (short) 0xd58d, 0x3653, 0x2672,
+			0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, (short) 0xb75b,
+			(short) 0xa77a, (short) 0x9719, (short) 0x8738, (short) 0xf7df,
+			(short) 0xe7fe, (short) 0xd79d, (short) 0xc7bc, 0x48c4, 0x58e5,
+			0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, (short) 0xc9cc,
+			(short) 0xd9ed, (short) 0xe98e, (short) 0xf9af, (short) 0x8948,
+			(short) 0x9969, (short) 0xa90a, (short) 0xb92b, 0x5af5, 0x4ad4,
+			0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, (short) 0xdbfd,
+			(short) 0xcbdc, (short) 0xfbbf, (short) 0xeb9e, (short) 0x9b79,
+			(short) 0x8b58, (short) 0xbb3b, (short) 0xab1a, 0x6ca6, 0x7c87,
+			0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, (short) 0xedae,
+			(short) 0xfd8f, (short) 0xcdec, (short) 0xddcd, (short) 0xad2a,
+			(short) 0xbd0b, (short) 0x8d68, (short) 0x9d49, 0x7e97, 0x6eb6,
+			0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, (short) 0xff9f,
+			(short) 0xefbe, (short) 0xdfdd, (short) 0xcffc, (short) 0xbf1b,
+			(short) 0xaf3a, (short) 0x9f59, (short) 0x8f78, (short) 0x9188,
+			(short) 0x81a9, (short) 0xb1ca, (short) 0xa1eb, (short) 0xd10c,
+			(short) 0xc12d, (short) 0xf14e, (short) 0xe16f, 0x1080, 0x00a1,
+			0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, (short) 0x83b9,
+			(short) 0x9398, (short) 0xa3fb, (short) 0xb3da, (short) 0xc33d,
+			(short) 0xd31c, (short) 0xe37f, (short) 0xf35e, 0x02b1, 0x1290,
+			0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, (short) 0xb5ea,
+			(short) 0xa5cb, (short) 0x95a8, (short) 0x8589, (short) 0xf56e,
+			(short) 0xe54f, (short) 0xd52c, (short) 0xc50d, 0x34e2, 0x24c3,
+			0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, (short) 0xa7db,
+			(short) 0xb7fa, (short) 0x8799, (short) 0x97b8, (short) 0xe75f,
+			(short) 0xf77e, (short) 0xc71d, (short) 0xd73c, 0x26d3, 0x36f2,
+			0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, (short) 0xd94c,
+			(short) 0xc96d, (short) 0xf90e, (short) 0xe92f, (short) 0x99c8,
+			(short) 0x89e9, (short) 0xb98a, (short) 0xa9ab, 0x5844, 0x4865,
+			0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, (short) 0xcb7d,
+			(short) 0xdb5c, (short) 0xeb3f, (short) 0xfb1e, (short) 0x8bf9,
+			(short) 0x9bd8, (short) 0xabbb, (short) 0xbb9a, 0x4a75, 0x5a54,
+			0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, (short) 0xfd2e,
+			(short) 0xed0f, (short) 0xdd6c, (short) 0xcd4d, (short) 0xbdaa,
+			(short) 0xad8b, (short) 0x9de8, (short) 0x8dc9, 0x7c26, 0x6c07,
+			0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, (short) 0xef1f,
+			(short) 0xff3e, (short) 0xcf5d, (short) 0xdf7c, (short) 0xaf9b,
+			(short) 0xbfba, (short) 0x8fd9, (short) 0x9ff8, 0x6e17, 0x7e36,
+			0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0 };
+
+	/**
+	 * 获取crc校验的short形式
+	 * 
+	 * @param data
+	 * @return
+	 */
+	private static short getCrc16(byte[] data) {
+		int crc = 0;
+		int length = data.length;
+		for (int i = 0; i < length; i++) {
+			crc = ((crc & 0xFF) << 8)
+					^ CRC16_TABLE[(((crc & 0xFF00) >> 8) ^ data[i]) & 0xFF];
+		}
+		crc = crc & 0xFFFF;
+		return (short) crc;
+	}
+
+	/**
+	 * 获取crc校验的byte形式
+	 * 
+	 * @param data
+	 * @return
+	 */
+	public static byte[] crc16Bytes(byte[] data) {
+		return BytesUtil.short2bytes(getCrc16(data));
+	}
+
+}

+ 83 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CRC32.java

@@ -0,0 +1,83 @@
+package org.ts.ddcs.common.util;
+
+public class CRC32 {
+	private int crc = 0xffffffff;
+	
+	private final static int[] CRC32_TABLE = { 0x00000000, 0x77073096,
+			0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535,
+			0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+			0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064,
+			0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb,
+			0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a,
+			0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+			0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1,
+			0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+			0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf,
+			0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+			0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e,
+			0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11,
+			0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc,
+			0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+			0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb,
+			0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162,
+			0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1,
+			0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+			0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158,
+			0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+			0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846,
+			0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+			0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525,
+			0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998,
+			0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b,
+			0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+			0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12,
+			0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d,
+			0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268,
+			0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+			0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f,
+			0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+			0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd,
+			0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+			0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c,
+			0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703,
+			0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92,
+			0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+			0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9,
+			0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14,
+			0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7,
+			0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+			0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6,
+			0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+			0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354,
+			0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+			0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53,
+			0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a,
+			0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729,
+			0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+			0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
+
+	public CRC32() {
+	}
+	
+  public CRC32(byte[] data) {
+    appendBytes(data, 0, data.length);
+  }
+  
+	public CRC32(byte[] bytes, int offset, int len) {
+	  appendBytes(bytes, offset, len);
+	}
+	
+	public void appendBytes(byte[] bytes, int offset, int len) {
+		for (int i=offset; (i<offset + len && i<bytes.length); i++) {
+			crc = crc >>> 8 ^ CRC32_TABLE[(crc ^ bytes[i]) & 0xff];
+		}
+	}
+
+	/**
+	 * Returns CRC-32 value.
+	 */
+	public int getValue() {
+	  return crc ^ 0xffffffff;
+	}
+
+}

+ 45 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/CodecUtil.java

@@ -0,0 +1,45 @@
+package org.ts.ddcs.common.util;
+
+public class CodecUtil {
+	static CRC16 crc16 = new CRC16();
+
+	private CodecUtil() {
+	}
+
+	public static byte[] short2bytes(short s) {
+		byte[] bytes = new byte[2];
+		for (int i = 1; i >= 0; i--) {
+			bytes[i] = (byte) (s % 256);
+			s >>= 8;
+		}
+		return bytes;
+	}
+
+	public static short bytes2short(byte[] bytes) {
+		short s = (short) (bytes[1] & 0xFF);
+		s |= (bytes[0] << 8) & 0xFF00;
+		return s;
+	}
+
+	/*
+	 * 获取crc校验的byte形式
+	 */
+	public static byte[] crc16Bytes(byte[] data) {
+		return short2bytes(crc16Short(data));
+	}
+
+	/*
+	 * 获取crc校验的short形式
+	 */
+	public static short crc16Short(byte[] data) {
+		return crc16.getCrc(data);
+	}
+
+	public static void main(String[] args) {
+
+		//System.out.println(BytesUtil.byte2HexStr(crc16Bytes(BytesUtil.hexStr2Bytes("0001160112153400F1F1000000000348F0F01601121530392309999999"))));
+		System.out.println(BytesUtil.byte2HexStr(crc16Bytes(BytesUtil.hexStr2Bytes("0A0312120708085004"))));
+		
+	}
+
+}

+ 40 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Commands.java

@@ -0,0 +1,40 @@
+package org.ts.ddcs.common.util;
+
+/**
+ * 命令字段
+ * @author TYQ
+ *
+ */
+public class Commands {
+
+  public static boolean running = false; //监控程序启动标识
+  public static final String UNICODE = "GB2312"; 
+	
+  public static final byte HEART_BEAT_RMT = 0x01; // 心跳(终端--前置)
+  public static final byte UPDATE_FIEL = 0x02; // 程序更新和配置文件
+  public static final byte UPLOAD_INFO = 0x03; // 信息上传
+  public static final byte CLOCK_SYN = 0x04; // 时钟同步
+  public static final byte LOG_UPLOAD = 0x05; // 日志文件上传
+  public static final byte MONITOR_TRANS_MUTUAL = 0x06; //监控网关与加油卡中心系统信息交互
+  
+  public static final byte[]  RTU_START_FLAG_2012 = { 0x68 }; //RTU2012年规约开始字段
+  public static final byte[] RTU_END_FLAG_2012 =  { 0x16 }; //RTU2012年规约结束字段
+
+  
+  
+  //2014年规约
+  public static final byte[]  RTU_START_FLAG_2014 = { 0x7E}; //RTU2014年规约开始字段
+  public static final byte[]  PACKET_BODY_START_FLAG = { 0x02 }; //RTU2014年报文正文起始符
+  
+  //报文帧控制字符定义
+  public static final byte[]  PACKET_BODY_END_FLAG_ETX = { 0x03 }; //RTU2014年报文正文结束符,后续无报文
+  public static final byte[]  PACKET_BODY_END_FLAG_ETB = { 0x17 }; //RTU2014年报文正文结束符,后续有报文
+  
+  public static final byte[]  PACKET_CONTROL_FLAG_ENQ = { 0x05 }; //询问
+  public static final byte[]  PACKET_CONTROL_FLAG_EOT = { 0x04 }; //传输结束退出--作为传输结束确认帧报文结束符,表示可以退出通信
+  public static final byte[]  PACKET_CONTROL_FLAG_ACK = { 0x06 }; //肯定确认,继续发送--作为有后续报文帧的“确认帧” 报文结束符
+  public static final byte[]  PACKET_CONTROL_FLAG_NAK = { 0x15 }; //否定应答,反馈重发--用于要求对方重发某数据包的报文结束符
+  public static final byte[]  PACKET_CONTROL_FLAG_ESC= { 0x1B }; //传输结束,终端保持在线---在下行确认帧代替EOT作为报文结束符,要求终端在线。保持在线10min内若没有接收到中心站命令,终端退回原先设定的工作状态
+
+
+}

+ 347 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/DateUtil.java

@@ -0,0 +1,347 @@
+package org.ts.ddcs.common.util;
+
+
+import java.sql.Timestamp;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+
+public class DateUtil {
+	
+	//static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 将时间格式转换成符合Timestamp要求的格式.
+	//static SimpleDateFormat sdfHour = new SimpleDateFormat("yyyyMMddHH0000");// 将时间格式转换成符合Timestamp要求的格式.
+	//static SimpleDateFormat sdfDay = new SimpleDateFormat("yyyyMMdd000000");// 将时间格式转换成符合Timestamp要求的格式.
+	//static SimpleDateFormat sdfHour1 = new SimpleDateFormat("yyyy-MM-dd HH:00:00");// 将时间格式转换成符合Timestamp要求的格式.
+	//static SimpleDateFormat strToDateSdf = new SimpleDateFormat("yyyyMMddHHmmss");// 将时间格式转换成符合Timestamp要求的格式.
+
+	
+    private DateUtil() {
+
+    }
+
+    public static String getSystemDate(String format) {
+
+        Calendar calendar = Calendar.getInstance();
+        Date date = calendar.getTime();
+        String str = getDateString(date, format);
+        return str;
+    }
+
+    public static String getCurrYear() {
+
+        return String.valueOf(Calendar.getInstance().get(Calendar.YEAR));
+    }
+
+    public static String getCurrMonth() {
+
+        int currMonth = Calendar.getInstance().get(Calendar.MONTH) + 1;
+        return currMonth < 10 ? "0" + currMonth : String.valueOf(currMonth);
+    }
+
+    public static String getCurrDay() {
+
+        int currDay = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
+        return currDay < 10 ? "0" + currDay : String.valueOf(currDay);
+    }
+
+    public static String formatDate(String dateString, String oldFormat,
+            String newFormat) {
+
+        if ("".equals(dateString.trim())) {
+            return "";
+        }
+        String result = "";
+        SimpleDateFormat sdf = new SimpleDateFormat(oldFormat);
+        Date date = null;
+        try {
+            date = sdf.parse(dateString);
+            sdf = new SimpleDateFormat(newFormat);
+            result = sdf.format(date);
+        }
+        catch (Exception e) {
+            result = dateString;
+        }
+        return result;
+    }
+
+    public static Date getDate(String dateString, String format)
+            throws ParseException {
+
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        return sdf.parse(dateString);
+    }
+
+    public static String getDateString(Date date, String format) {
+
+        SimpleDateFormat sdf = new SimpleDateFormat(format);
+        return sdf.format(date);
+    }
+
+    public static String roll(String origin, String pattern, int field,
+            int amount) throws Exception {
+
+        SimpleDateFormat sdf = new SimpleDateFormat();
+        sdf.applyPattern(pattern);
+        Date date = sdf.parse(origin);
+
+        GregorianCalendar gc = new GregorianCalendar();
+        gc.setTime(date);
+        gc.add(field, amount);
+
+        return sdf.format(gc.getTime());
+    }
+
+    public static String dateBefAft(int days, String format) {
+
+        if (format == null || "".equals(format)) {
+            format = "yyyy/MM/dd hh:mm:ss";
+        }
+        Calendar now = Calendar.getInstance();
+        SimpleDateFormat formatter = new SimpleDateFormat(format);
+        now.add(Calendar.DAY_OF_YEAR, days);
+        return formatter.format(now.getTime());
+    }
+
+    public static String secondTimeBefAft(int second, String format) {
+
+        if (format == null || "".equals(format)) {
+            format = "yyyy/MM/dd hh:mm:ss";
+        }
+        Calendar now = Calendar.getInstance();
+        SimpleDateFormat formatter = new SimpleDateFormat(format);
+        now.add(Calendar.SECOND, second);
+        return formatter.format(now.getTime());
+    }
+
+    public static String miniteTimeBefAft(int minute, String format) {
+
+        if (format == null || "".equals(format)) {
+            format = "yyyy/MM/dd hh:mm:ss";
+        }
+        Calendar now = Calendar.getInstance();
+        SimpleDateFormat formatter = new SimpleDateFormat(format);
+        now.add(Calendar.MINUTE, minute);
+        return formatter.format(now.getTime());
+    }
+
+    public static boolean compareWithNowTime(String dateTime)
+            throws ParseException {
+
+        Calendar now = Calendar.getInstance();
+        Calendar c1 = Calendar.getInstance();
+
+        SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
+        c1.setTime(formatter.parse(dateTime));
+        return now.compareTo(c1) > 0;
+    }
+    
+    public static String getLastDayOfMonth(String year, String month) throws Exception {
+        
+        String day = "";
+        switch (Integer.parseInt(month)) {
+            case 1:
+            case 3:
+            case 5:
+            case 7:
+            case 8:
+            case 10:
+            case 12:
+                day = "31";
+                break;
+            case 4:
+            case 6:
+            case 9:
+            case 11:
+                day = "30";
+                break;
+            case 2:
+                int nYear = Integer.parseInt(year);
+                if ((nYear % 4 == 0 && nYear % 100 != 0) || nYear % 400 == 0) {
+                    day = "29";
+                } else {
+                    day = "28";
+                }
+                break;
+            default:
+                break;
+        }
+        return day;
+    }
+    
+    //获取时间戳
+    public static Timestamp getTs_time(){
+    	Date date = new Date();// 获得系统时间.
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    	String nowTime = sdf.format(date);// 将时间格式转换成符合Timestamp要求的格式.
+    	Timestamp ts_time = Timestamp.valueOf(nowTime);// 把时间转换
+    	return ts_time;
+    }
+    
+   
+    /**
+     *获取当前整点的时间
+     * @return
+     */
+    public static String getCurrentHour(){
+
+        SimpleDateFormat sdfHour = new SimpleDateFormat("yyyyMMddHH0000");
+        return  sdfHour.format(new Date());
+    }
+    
+    /**
+     *获取当前整点的时间
+     * @return
+     */
+    public static String getCurrentHour1(){
+        SimpleDateFormat sdfHour1 = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
+		return  sdfHour1.format(new Date());
+    }
+    
+    /**
+     *获取当前时间 preHour个小时前整点的时间
+     * @return
+     */
+    public static String getPreHour(int preHour){
+    	Calendar calendar = Calendar.getInstance();  /* HOUR_OF_DAY 指示一天中的小时 */
+		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - preHour);
+        SimpleDateFormat sdfHour = new SimpleDateFormat("yyyyMMddHH0000");
+		return  sdfHour.format(calendar.getTime());
+    }
+    
+    /**
+     *获取指定日期的的钱preHour个小时前的时间
+     * @return
+     */
+    public static String getPreHourTime(String dateStr , int preHour){
+		
+		try {
+			SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
+	    	Date d = df.parse(dateStr);
+	    	Calendar calendar = Calendar.getInstance();// HOUR_OF_DAY 指示一天中的小时 
+			calendar.setTime(d);
+			calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - preHour);		
+			return  df.format(calendar.getTime());
+		} catch (ParseException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return  dateStr;
+    }
+    
+    /**
+     *获取当前时间 preHour个小时前整点的时间
+     * @return
+     */
+    public static String getPreHour1(int preHour){
+    	Calendar calendar = Calendar.getInstance();  /* HOUR_OF_DAY 指示一天中的小时 */
+		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - preHour);
+        SimpleDateFormat sdfHour1 = new SimpleDateFormat("yyyy-MM-dd HH:00:00");
+		return  sdfHour1.format(calendar.getTime());
+    }
+    
+    /**
+     * 获取当前时间 30天前的整点的时间
+     * @return
+     */
+    public static String getPreMouth(int preHour){
+    	Calendar calendar = Calendar.getInstance();  /* HOUR_OF_DAY 指示一天中的小时 */
+		calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 30);
+		calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - preHour);
+        SimpleDateFormat sdfHour = new SimpleDateFormat("yyyyMMddHH0000");
+		return  sdfHour.format(calendar.getTime());
+    }
+ 
+    /**
+     * 获取当前时间 preNum天前的整天的时间
+     * @return
+     */
+    public static String getPreDays(int preNum){
+    	Calendar calendar = Calendar.getInstance();  /* HOUR_OF_DAY 指示一天中的小时 */
+		calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - preNum);
+        SimpleDateFormat sdfDay = new SimpleDateFormat("yyyyMMdd000000");
+		return  sdfDay.format(calendar.getTime());
+    }
+    
+    /**
+     * 计算俩个时间之间相差多少秒
+     * @param preTime
+     * @param afterTime
+     * @return
+     */
+    public static long getTimeMinusSecond(String preTime,String afterTime) throws ParseException {
+    	try {
+            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+			Date preDate = sdf.parse(preTime);
+			Date afterDate = sdf.parse(afterTime);
+			long diff =  afterDate.getTime() - preDate.getTime();
+			long second = diff/1000;
+			return second;
+		} catch (ParseException e) {
+			throw e;
+		}
+    }
+    
+    
+    /**
+     *将20170808121212转化为2017-08-08 12:12:12
+     * @return
+     */
+    public static String getFormatDateStr(String dateStr){
+    	StringBuffer formatDateStr = new StringBuffer();
+    	formatDateStr.append(dateStr.substring(0, 4));
+    	formatDateStr.append("-");
+    	formatDateStr.append(dateStr.substring(4, 6));
+    	formatDateStr.append("-");
+    	formatDateStr.append(dateStr.substring(6, 8));
+    	formatDateStr.append(" ");
+    	formatDateStr.append(dateStr.substring(8, 10));
+    	formatDateStr.append(":");
+    	formatDateStr.append(dateStr.substring(10,12));
+    	formatDateStr.append(":");
+    	formatDateStr.append(dateStr.substring(12, 14));
+    	
+		return  formatDateStr.toString();
+    }
+    
+    /**
+     * 获取当前时间类型为Timestamp的时间
+     * @return
+     */
+    public static String getCurrTimestamp() {
+
+    	Date date = new Date();// 获得系统时间.
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+		String nowTime = sdf.format(date);// 将时间格式转换成符合Timestamp要求的格式.
+		//Timestamp currTime = Timestamp.valueOf(nowTime);// 把时间转换
+        return nowTime;
+    }
+    
+    /**
+     * 获取当前时间类型为Timestamp的时间
+     * @return
+     */
+    public static String getCurrTimestampStr() {
+
+    	Date date = new Date();// 获得系统时间.
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+		String nowTime = sdf.format(date);// 将时间格式转换成符合Timestamp要求的格式.
+		//Timestamp currTime = Timestamp.valueOf(nowTime);// 把时间转换
+        return nowTime;
+    }
+    public static void main(String[] args) {
+    	//System.out.println(getTimeMinusSecond("2016-01-11 160000","20160111160006"));
+    	System.out.println(getFormatDateStr("20160111160006"));
+    	
+    	/*try {
+			Date date = strToDateSdf.parse("20080710192034");
+			String str = sdf.format(date);
+			System.out.println(str);
+		} catch (ParseException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}*/
+	}
+}

+ 31 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ElementJsonPackHelp.java

@@ -0,0 +1,31 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/30
+ */
+package org.ts.ddcs.common.util;
+
+import com.alibaba.fastjson.JSONObject;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+
+/***
+ * Date:2023/10/30
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class ElementJsonPackHelp {
+    public static JSONObject toJson(String type, String name, String subCode, String value, String unit, String desc) {
+        JSONObject item = new JSONObject();
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), type);
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), name);
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_SUB_CODE.getName(), subCode);
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), value);
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), unit);
+        item.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), desc);
+        return item;
+    }
+}

+ 205 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/EncryptDecryptData.java

@@ -0,0 +1,205 @@
+package org.ts.ddcs.common.util;
+
+import javax.crypto.*;
+import javax.crypto.spec.DESKeySpec;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.spec.InvalidKeySpecException;
+
+/**
+ * 
+ * 通过DES加密解密实现一个String字符串的加密和解密.
+ * 
+ * 
+ * 
+ * @author badpeas
+ * 
+ * 
+ */
+
+public class EncryptDecryptData {
+
+	public static void main(String[] args) throws NoSuchAlgorithmException,
+
+	InvalidKeyException, NoSuchPaddingException,
+
+	InvalidKeySpecException, IllegalBlockSizeException,
+
+	BadPaddingException {
+
+		// 1.1 >>> 首先要创建一个密匙
+
+		// DES算法要求有一个可信任的随机数源
+
+		SecureRandom sr = new SecureRandom();
+
+		// 为我们选择的DES算法生成一个KeyGenerator对象
+
+		KeyGenerator kg = KeyGenerator.getInstance("DES");
+
+		kg.init(sr);
+
+		// 生成密匙
+
+		SecretKey key = kg.generateKey();
+
+		// 获取密匙数据
+
+		//byte rawKeyData[] = key.getEncoded();
+		
+	    String sign = "I8twH63Is8I=";
+
+	    byte rawKeyData[] = Base64.decodeByte(sign);
+		System.out.println("密匙===>" + new String(Base64.encode(rawKeyData)));
+		
+		String str = "tacsp_brfe"; // 待加密数据
+		String pw = "tacsp_brfe"; // 待加密数据
+
+		// 2.1 >>> 调用加密方法
+
+		byte[] encryptedData = encrypt(rawKeyData, str);
+		byte[] encryptedPw = encrypt(rawKeyData, pw);
+		
+		System.out.println("用户===>" + new String(Base64.encode(encryptedData)));
+		System.out.println("密码===>" + new String(Base64.encode(encryptedPw)));
+
+		// 3.1 >>> 调用解密方法
+
+		decrypt(rawKeyData, encryptedData);
+
+	}
+
+	/**
+	 * 
+	 * 加密方法
+	 * 
+	 * 
+	 * 
+	 * @param rawKeyData
+	 * 
+	 * @param str
+	 * 
+	 * @return
+	 * 
+	 * @throws InvalidKeyException
+	 * 
+	 * @throws NoSuchAlgorithmException
+	 * 
+	 * @throws IllegalBlockSizeException
+	 * 
+	 * @throws BadPaddingException
+	 * 
+	 * @throws NoSuchPaddingException
+	 * 
+	 * @throws InvalidKeySpecException
+	 */
+
+	public static byte[] encrypt(byte rawKeyData[], String str)
+
+	throws InvalidKeyException, NoSuchAlgorithmException,
+
+	IllegalBlockSizeException, BadPaddingException,
+
+	NoSuchPaddingException, InvalidKeySpecException {
+
+		// DES算法要求有一个可信任的随机数源
+
+		SecureRandom sr = new SecureRandom();
+
+		// 从原始密匙数据创建一个DESKeySpec对象
+
+		DESKeySpec dks = new DESKeySpec(rawKeyData);
+
+		// 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象
+
+		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+
+		SecretKey key = keyFactory.generateSecret(dks);
+
+		// Cipher对象实际完成加密操作
+
+		Cipher cipher = Cipher.getInstance("DES");
+
+		// 用密匙初始化Cipher对象
+
+		cipher.init(Cipher.ENCRYPT_MODE, key, sr);
+
+		// 现在,获取数据并加密
+
+		byte data[] = str.getBytes();
+
+		// 正式执行加密操作
+
+		byte[] encryptedData = cipher.doFinal(data);
+
+		//System.out.println("加密后===>" + encryptedData);
+
+		return encryptedData;
+
+	}
+
+	/**
+	 * 
+	 * 解密方法
+	 * 
+	 * 
+	 * 
+	 * @param rawKeyData
+	 * 
+	 * @param encryptedData
+	 * 
+	 * @throws IllegalBlockSizeException
+	 * 
+	 * @throws BadPaddingException
+	 * 
+	 * @throws InvalidKeyException
+	 * 
+	 * @throws NoSuchAlgorithmException
+	 * 
+	 * @throws NoSuchPaddingException
+	 * 
+	 * @throws InvalidKeySpecException
+	 */
+
+	public static String decrypt(byte rawKeyData[], byte[] encryptedData)
+
+	throws IllegalBlockSizeException, BadPaddingException,
+
+	InvalidKeyException, NoSuchAlgorithmException,
+
+	NoSuchPaddingException, InvalidKeySpecException {
+
+		// DES算法要求有一个可信任的随机数源
+
+		SecureRandom sr = new SecureRandom();
+
+		// 从原始密匙数据创建一个DESKeySpec对象
+
+		DESKeySpec dks = new DESKeySpec(rawKeyData);
+
+		// 创建一个密匙工厂,然后用它把DESKeySpec对象转换成一个SecretKey对象
+
+		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+
+		SecretKey key = keyFactory.generateSecret(dks);
+
+		// Cipher对象实际完成解密操作
+
+		Cipher cipher = Cipher.getInstance("DES");
+
+		// 用密匙初始化Cipher对象
+
+		cipher.init(Cipher.DECRYPT_MODE, key, sr);
+
+		// 正式执行解密操作
+
+		byte decryptedData[] = cipher.doFinal(encryptedData);
+
+		//System.out.println("解密后===>" + new String(decryptedData));
+
+		return new String(decryptedData);
+
+	}
+
+}

+ 25 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ErrorCodes.java

@@ -0,0 +1,25 @@
+package org.ts.ddcs.common.util;
+
+public class ErrorCodes {
+  // 报文类错
+  public final static byte SUCCESSFUL = 0x00; // 成功或报文正确
+  public final static byte PACKET_CRC_ERR = 0x01; // CRC16校验错
+  public final static byte WRONG_COMMAND = 0x02; // 命令不存在
+  public final static byte NODE_NOT_EXISTS = 0x03; // 网点不存在
+  public final static byte FAIL = 0x04; // 失败或报文错误
+  public final static byte RMF_NOT_EXISTS = 0x05; // 前置不存在
+  public final static byte UNKNOWN_ERR = 0x0f; // 未知错误
+
+  public final static byte FILE_SEND_ERR = 0x11; // 文件传输错
+  public final static byte FILE_SRC_ERR = 0x12; // 源文件错
+  public final static byte WRONG_FILE_CLASS = 0x13; // 文件类别错
+  public final static byte FILE_NOT_EXISTS = 0x14; // 文件不存在
+  public final static byte FILE_SAVE_ERR = 0x15; // 文件保存错
+  public final static byte VER_NOT_EXISTS = 0x16; // 版本不存在
+  public final static byte IP_LIST_EMPTY = 0x17; // ip列表不存在
+  public final static byte COMBINE_SEND_IS_BIG = 0x18; // 终端并发量太大
+  public final static byte RMT_RMF_NOT_MATCHING = 0x19; // 终端与前置不匹配
+  
+  public final static byte LOG_NOT_SAVED = 0x1A; // 日志尚未保存入库
+
+}

+ 295 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/FileUtil.java

@@ -0,0 +1,295 @@
+package org.ts.ddcs.common.util;
+
+import java.io.*;
+import java.util.*;
+
+public class FileUtil {
+
+	private FileUtil() {
+
+	}
+
+	public static Map loadProperties(String fileName, String encoding) {
+
+		Map result = null;
+		FileInputStream inStream = null;
+		try {
+			result = new HashMap(1000);
+			inStream = new FileInputStream(fileName);
+			Properties prop = new Properties();
+			prop.load(inStream);
+			inStream.close();
+
+			/*
+			 * If the method had specialed encoding, so should convert encoding
+			 * here.
+			 */
+			if (encoding != null) {
+				Collection col = prop.keySet();
+				Iterator iter = col.iterator();
+				while (iter.hasNext()) {
+					Object strKey = iter.next();
+					String tmp = (String) prop.get(strKey);
+					tmp = StringUtil.convertStringEnc(tmp, encoding);
+					result.put(strKey, tmp);
+					// System.out.println(strKey.toString()
+					// + " = " + tmp);
+				}
+			} else {
+				result = prop;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			try {
+				if (inStream != null) {
+					inStream.close();
+				}
+			} catch (Exception ex) {
+				ex.printStackTrace();
+			}
+		}
+		return result;
+	}
+
+	public static void createFilePath(String filePath) throws IOException {
+
+		if (filePath == null || filePath.trim().equals(""))
+			throw new IOException("File path name is null.");
+
+		File f = new File(filePath);
+
+		if (!f.exists()) {
+			f.mkdirs();
+		}
+	}
+
+	public static String readFile(String fileName, String encoding)
+			throws IOException {
+
+		InputStream is = new FileInputStream(fileName);
+		int length = is.available();
+		byte buffer[] = new byte[length];
+		is.read(buffer, 0, length);
+		return new String(buffer, encoding);
+	}
+
+	public static void writeFile(String fileName, String data, String encoding)
+			throws IOException {
+
+		OutputStream os = new FileOutputStream(fileName);
+		byte buffer[] = data.getBytes(encoding);
+		os.write(buffer, 0, buffer.length);
+	}
+
+	public static void writeFile(String fileName, String data)
+			throws IOException {
+
+		OutputStream os = new FileOutputStream(fileName);
+		byte buffer[] = data.getBytes();
+		os.write(buffer, 0, buffer.length);
+	}
+
+	public static void deleteOverdueFiles(String path, int intervalDay)
+			throws IOException {
+
+		long currenTime = System.currentTimeMillis();
+		long interval = (long) 24 * 60 * 60 * 1000 * intervalDay;
+		File reportFiles = new File(path);
+		String[] tmpFiles = reportFiles.list();
+		if (tmpFiles == null)
+			return;
+		int size = tmpFiles.length;
+		for (int i = 0; i < size; i++) {
+			File tmp = new File(path + "/" + tmpFiles[i]);
+			long lastTime = tmp.lastModified();
+			if ((currenTime - lastTime) > interval)
+				tmp.delete();
+		}
+	}
+
+	public static void deleteOverdueFiles2(String path, int intervalDay)
+			throws IOException {
+
+		long currenTime = System.currentTimeMillis();
+		long interval = (long) 24 * 60 * 60 * 1000 * intervalDay;
+		File reportFiles = new File(path);
+		String[] tmpFiles = reportFiles.list();
+
+		if (tmpFiles == null)
+			return;
+		int size = tmpFiles.length;
+		for (int i = 0; i < size; i++) {
+			File tmp = new File(path + "/" + tmpFiles[i]);
+			if (tmp.isDirectory())
+				continue;
+			long lastTime = tmp.lastModified();
+			if ((currenTime - lastTime) > interval)
+				tmp.delete();
+		}
+	}
+
+	public static void copyFile(File src, File dest) throws Exception {
+
+		FileInputStream in = new FileInputStream(src);
+		FileOutputStream out = new FileOutputStream(dest);
+
+		byte[] buffer = new byte[1024];
+		int n = 0;
+		while (-1 != (n = in.read(buffer))) {
+			out.write(buffer, 0, n);
+		}
+
+		in.close();
+		out.close();
+	}
+
+	public static void copyFile(InputStream in, File dest) throws Exception {
+
+		FileOutputStream out = new FileOutputStream(dest);
+
+		byte[] buffer = new byte[1024];
+		int n = 0;
+		while (-1 != (n = in.read(buffer))) {
+			out.write(buffer, 0, n);
+		}
+
+		in.close();
+		out.close();
+	}
+
+	public static void writeStreamToFile(InputStream is, String filePath)
+			throws IOException {
+
+		File flowFile = new File(filePath);
+		File flowDir = new File(flowFile.getParent());
+		if (!flowDir.exists()) {
+			flowDir.mkdirs();
+		}
+
+		FileOutputStream os = new FileOutputStream(flowFile);
+
+		byte[] buffer = new byte[1024];
+		while (is.read(buffer) > 0) {
+			os.write(buffer);
+		}
+
+		// is.close();
+		os.close();
+	}
+
+	public static void writeStreamToFile(String is, String filePath)
+			throws IOException {
+
+		File flowFile = new File(filePath);
+		File flowDir = new File(flowFile.getParent());
+		if (!flowDir.exists()) {
+			flowDir.mkdirs();
+		}
+
+		FileOutputStream os = new FileOutputStream(flowFile);
+
+		os.write(is.getBytes("UTF-8"));
+		os.close();
+	}
+
+	public static boolean deleteAll(File path) {
+
+		if (path.isFile()) {
+			return path.delete();
+		}
+
+		if (!path.exists()) {
+			return true;
+		}
+
+		File[] files = path.listFiles();
+
+		if (files == null)
+			return true;
+
+		for (int i = files.length - 1; i >= 0; i--) {
+			if (files[i].isDirectory()) {
+				deleteAll(files[i]);
+			}
+			files[i].delete();
+		}
+
+		files = path.listFiles();
+		return files.length == 0 ? true : false;
+	}
+
+	public static boolean deleteAllAndShelf(File path) {
+
+		if (!path.exists())
+			return true;
+
+		deleteAll(path);
+		return path.delete();
+	}
+
+	public static boolean deleteAllAndShelfAndParent(File path) {
+
+		if (!path.exists())
+			return true;
+
+		deleteAll(path);
+		boolean flag = path.delete();
+
+		if (flag) {
+			String file = path.getParent();
+			File parentFile = new File(file);
+			if (parentFile.isDirectory()) {
+				if (parentFile.list().length == 0) {
+
+					deleteAllAndShelf(parentFile);
+				}
+			}
+		}
+		return flag;
+	}
+
+	public static void delFolder(String folderPath) {
+
+		try {
+			delAllFile(folderPath);
+			String filePath = folderPath;
+			filePath = filePath.toString();
+			File myFilePath = new File(filePath);
+			myFilePath.delete();
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static boolean delAllFile(String path) {
+
+		boolean flag = false;
+		File file = new File(path);
+		if (!file.exists()) {
+			return flag;
+		}
+		if (!file.isDirectory()) {
+			return flag;
+		}
+		String[] tempList = file.list();
+		File temp = null;
+		for (int i = 0; i < tempList.length; i++) {
+			if (path.endsWith(File.separator)) {
+				temp = new File(path + tempList[i]);
+			} else {
+				temp = new File(path + File.separator + tempList[i]);
+			}
+			if (temp.isFile()) {
+				temp.delete();
+			}
+			if (temp.isDirectory()) {
+				delAllFile(path + "/" + tempList[i]);
+				delFolder(path + "/" + tempList[i]);
+				flag = true;
+			}
+		}
+		return flag;
+	}
+
+}

+ 548 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/StringUtil.java

@@ -0,0 +1,548 @@
+package org.ts.ddcs.common.util;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class StringUtil {
+
+	private StringUtil() {
+
+	}
+
+	/**
+	 * @param str
+	 *            xxx,xxx,xxx
+	 * @return Collection - String
+	 */
+	public static Collection SimpleStringToCollection(String str) {
+
+		Collection list = new ArrayList();
+		StringTokenizer st = new StringTokenizer(str, ",");
+		while (st.hasMoreTokens()) {
+			list.add(st.nextToken());
+		}
+		return list;
+	}
+
+	public static Collection SimpleStringToCollection(String str,
+			String delimChar) {
+
+		Collection list = new ArrayList();
+		StringTokenizer sToken = new StringTokenizer(str, delimChar);
+		while (sToken.hasMoreTokens()) {
+			list.add(sToken.nextToken());
+		}
+		return list;
+	}
+
+	/**
+	 * @param str
+	 *            "xx|xx,xx|xx" or "x,x" or ...
+	 * @return Collection - Collection - String
+	 */
+	public static Collection StringToCollection(String str) {
+
+		Collection result = new ArrayList();
+		Collection colRecord = null;
+		StringTokenizer stFirst = new StringTokenizer(str, ",");
+		StringTokenizer stSecond = null;
+		String record = null;
+		String column = null;
+		while (stFirst.hasMoreTokens()) {
+			colRecord = new ArrayList();
+			record = stFirst.nextToken();
+			stSecond = new StringTokenizer(record, "|");
+			while (stSecond.hasMoreTokens()) {
+				column = stSecond.nextToken();
+				colRecord.add(column);
+			}
+			result.add(colRecord);
+		}
+
+		Iterator it = result.iterator();
+		while (it.hasNext()) {
+			colRecord = (Collection) it.next();
+			Iterator iter = colRecord.iterator();
+			while (iter.hasNext())
+				System.out.print(iter.next().toString() + " ");
+			System.out.println();
+		}
+		return result;
+	}
+
+	/**
+	 * @param str
+	 *            xxx,xxx,xxx
+	 * @return String[]
+	 */
+	public static String[] StringToArray(String str) {
+
+		if (str == null || str.equals(""))
+			return null;
+
+		Collection list = new ArrayList();
+		StringTokenizer st = new StringTokenizer(str, ",");
+		while (st.hasMoreTokens()) {
+			list.add(st.nextToken());
+		}
+
+		return (String[]) list.toArray(new String[list.size()]);
+	}
+
+	/**
+	 * @param str
+	 *            xxx,xxx,xxx
+	 * @return String[]
+	 */
+	public static String[] StringToArray(String str, String token) {
+
+		if (str == null || str.equals(""))
+			return null;
+
+		Collection list = new ArrayList();
+		StringTokenizer st = new StringTokenizer(str, token);
+		while (st.hasMoreTokens()) {
+			list.add(st.nextToken());
+		}
+
+		return (String[]) list.toArray(new String[list.size()]);
+	}
+
+	public static String leftFill(String src, int len, char fillChar) {
+
+		if (src == null || len < src.length())
+			return src;
+
+		String result = src;
+		for (int i = src.length(); i < len; i++) {
+			result = String.valueOf(fillChar) + result;
+		}
+
+		return result;
+	}
+
+	public static String rightFill(String src, String encoding, int len,
+			char fillChar) throws UnsupportedEncodingException {
+
+		int length = src.getBytes(encoding).length;
+		if (src == null || len < length)
+			return src;
+
+		String result = src;
+		for (int i = length; i < len; i++) {
+			result += String.valueOf(fillChar);
+		}
+
+		return result;
+	}
+
+	public static String rightFill(String src, int len, char fillChar) {
+
+		if (src == null || len < src.length())
+			return src;
+
+		String result = src;
+		for (int i = src.getBytes().length; i < len; i++) {
+			result += String.valueOf(fillChar);
+		}
+
+		return result;
+	}
+
+	public static String replace(String source, String oldString,
+			String newString) {
+
+		return replaceAll(source, oldString, newString);
+	}
+
+	public static String subString(String src, int index, int len,
+			String charset) {
+
+		if (src == null) {
+			return src;
+		}
+
+		String result = "";
+		try {
+			int subTotal = 0;
+
+			for (int i = 0; i < src.length(); i++) {
+				String subStr = src.substring(index, index + 1);
+				subTotal += subStr.getBytes(charset).length;
+				result += subStr;
+
+				if (subTotal >= len) {
+					if (index < src.length()) {
+						result += "...";
+					}
+					break;
+				}
+
+				index++;
+			}
+		} catch (Exception ex) {
+			ex.printStackTrace();
+		}
+		return result;
+	}
+
+	public static String replaceAll(String source, String from, String to) {
+
+		if (source == null || source.equals(""))
+			return source;
+		String remain = source;
+		String result = "";
+		while (remain.indexOf(from) != -1) {
+
+			result += remain.substring(0, remain.indexOf(from)) + to;
+			remain = remain.substring(remain.indexOf(from) + from.length(),
+					remain.length());
+		}
+		if (remain != null && !remain.equals(""))
+			result += remain;
+		return result;
+	}
+
+	public static int firstIndexOf(String src, char ch) {
+
+		int result = -1;
+		if (src == null) {
+			return result;
+		}
+
+		return src.indexOf(ch);
+	}
+
+	public static int lastIndexOf(String src, char ch) {
+
+		int result = -1;
+		if (src == null) {
+			return result;
+		}
+
+		for (int i = src.length() - 1; i >= 0; i--) {
+			if (src.charAt(i) == ch) {
+				return i;
+			}
+		}
+		return result;
+	}
+
+	public static String arrayToString(String[] arr) {
+
+		String result = "";
+		if (arr == null) {
+			return result;
+		}
+
+		for (int i = 0; i < arr.length; i++) {
+			if (i == 0) {
+				result = arr[i];
+			} else {
+				result += "," + arr[i];
+			}
+		}
+
+		return result;
+	}
+
+	public static String[] getDistinctArray(String[] oldArray) {
+
+		int cnt = 0;
+		for (int i = 0; i < oldArray.length; i++) {
+			if (oldArray[i] == null) {
+				continue;
+			}
+			if (oldArray[i].equals("")) {
+				oldArray[i] = null;
+				continue;
+			}
+			cnt++;
+			for (int j = i + 1; j < oldArray.length; j++) {
+				if (oldArray[j] == null) {
+					continue;
+				}
+				if (oldArray[j].equals("")) {
+					oldArray[j] = null;
+					continue;
+				}
+				if (oldArray[i].equals(oldArray[j])) {
+					oldArray[j] = null;
+				}
+			}
+		}
+
+		String[] newArray = new String[cnt];
+		if (cnt > 0) {
+			int index = 0;
+			for (int i = 0; i < oldArray.length; i++) {
+				if (oldArray[i] != null) {
+					newArray[index++] = oldArray[i];
+					// System.out.println("i=" +
+					// oldArray[i]);
+				}
+			}
+		}
+		return newArray;
+	}
+
+	public static String[] replaceArray(String[] oldArray, Map map) {
+
+		String[] result = new String[oldArray.length];
+		for (int i = 0; i < result.length; i++) {
+			String key = oldArray[i];
+			String value = (String) map.get(key);
+			result[i] = value == null ? key : value;
+		}
+
+		return result;
+	}
+
+	public static boolean isBlank(String str) {
+
+		if (str == null || str.trim().equals("")) {
+			return true;
+		}
+		return false;
+	}
+	
+	public static boolean isNotBlank(String str) {
+
+		if (null != str  && !str.trim().equals("")) {
+			return true;
+		}
+		return false;
+	}
+
+	public static String replace(String sourceStr, int start, int end,
+			String str) {
+
+		if (sourceStr == null || sourceStr.trim().equals("")) {
+			return sourceStr;
+		}
+
+		if (sourceStr.length() < end)
+			return sourceStr;
+
+		String s = sourceStr.substring(0, start) + str
+				+ sourceStr.substring(end);
+		return s;
+	}
+
+	public static int getSubstringCount(String src, String substr) {
+
+		if (src == null)
+			return 0;
+
+		int num = 0;
+		int index = 0;
+		while ((index = src.indexOf(substr, index)) != -1) {
+			num++;
+			index += substr.length();
+		}
+		return num;
+	}
+
+	/**
+	 * remove rest of string content if the string includes 2 bytes(0x81 0x40)
+	 * or 00
+	 * 
+	 * @param src
+	 * @return pure string
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String trimRightZero(String src, String encoding)
+			throws UnsupportedEncodingException {
+
+		byte pattern[] = { (byte) 0x81, 0x40 };
+		String match = new String(pattern, encoding);
+		int i = src.indexOf((char) 0);
+		int j = src.indexOf(match);
+		// int k = src.indexOf("@");
+		if (i > 0) {
+			return src.substring(0, i);
+		} else if (j > 0) {
+			return src.substring(0, j);
+		} else {
+			return src;
+		}
+	}
+
+	public static String getLastlenStr(String source, int len) {
+
+		String str = "";
+		if (source != null && source.length() > 0) {
+			int strlen = source.length();
+			if (strlen > len) {
+				str = source.substring(strlen - len);
+			} else
+				str = source;
+		}
+		return str;
+	}
+
+	public static String trim(String src) {
+
+		if (src == null)
+			return null;
+
+		char halfSpace = ' ';
+		int headIndex = 0;
+		int tailIndex = 0;
+		int len = src.length();
+		for (int i = 0; i < len; i++) {
+			char tmp = src.charAt(i);
+			if (tmp == halfSpace) {
+				headIndex++;
+			} else {
+				break;
+			}
+		}
+
+		for (int i = (len - 1); i >= 0; i--) {
+			char tmp = src.charAt(i);
+			if (tmp == halfSpace) {
+				tailIndex++;
+			} else {
+				break;
+			}
+		}
+
+		if (headIndex == len)
+			return "";
+
+		String result = src.substring(headIndex, len - tailIndex);
+
+		return result;
+	}
+
+	public static String convertStringEnc(String strSource, String strEncoding)
+			throws UnsupportedEncodingException {
+
+		String strResult = new String(strSource.getBytes("ISO-8859-1"),
+				strEncoding);
+		return strResult;
+	}
+
+	public static String map2String(Map map) {
+
+		if (map == null) {
+			return "";
+		}
+
+		if (map.isEmpty()) {
+			return "";
+		}
+		String dataStr = "";
+		Object[] expKeys = map.keySet().toArray();
+		for (int i = 0; i < expKeys.length; i++) {
+			String code = expKeys[i].toString();
+			String value = (String) map.get(code);
+			dataStr += "".equals(dataStr) ? code + ":" + value : ", " + code
+					+ ":" + value;
+		}
+		return dataStr;
+	}
+
+
+
+	private static String getMD5Digest(String src)
+			throws NoSuchAlgorithmException {
+
+		char[] ha = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a',
+				'b', 'c', 'd', 'e', 'f' };
+		try {
+
+			MessageDigest md = MessageDigest.getInstance("MD5");
+
+			md.update(src.getBytes("UTF-8"));
+
+			byte[] ba = md.digest();
+
+			int j = ba.length;
+			char[] ca = new char[j * 2];
+			int k = 0;
+
+			for (int i = 0; i < j; i++) {
+				byte b = ba[i];
+				ca[k++] = ha[b >>> 4 & 0xf];
+				ca[k++] = ha[b & 0xf];
+			}
+
+			return new String(ca);
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+
+	}
+
+	
+	public static String getNotNullStr(String str){
+		return str!= null ? str.trim():"";
+	}
+	
+	//去掉多余的0, 000908.8900  变为908.89
+	public static String getPrettyNumber(String number) {
+		if(number.contains("F")){
+			return "0";
+		}
+	    return BigDecimal.valueOf(Double.parseDouble(number))  
+	            .stripTrailingZeros().toPlainString();  
+	}
+	
+	/**
+	 * 判断当前日期是星期几<br>
+	 * <br>
+	 * 
+	 * @param pTime
+	 *            修要判断的时间<br>
+	 * @return dayForWeek 判断结果<br>
+	 * @Exception 发生异常<br>
+	 */
+	public static int dayForWeek(String pTime) throws Exception {
+		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
+		Calendar c = Calendar.getInstance();
+		c.setTime(format.parse(pTime));
+		int dayForWeek = 0;
+		if (c.get(Calendar.DAY_OF_WEEK) == 1) {
+			dayForWeek = 7;
+		} else {
+			dayForWeek = c.get(Calendar.DAY_OF_WEEK) - 1;
+		}
+		return dayForWeek;
+	}
+	
+	
+	 /**
+     * 
+     * 提供精确的小数位四舍五入处理。
+     * @param v 需要四舍五入的数字
+     * @param scale  小数点后保留几位
+     * @return 四舍五入后的结果
+    * 
+     */
+	 public static String roundForNumber(String v,int scale){
+         if(scale<0){
+             throw new IllegalArgumentException("The scale must be a positive integer or zero");
+         }
+         BigDecimal b = new BigDecimal(v);
+         BigDecimal one = new BigDecimal("1");
+         double retV =  b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
+         return retV+"";
+     }
+	 
+	 public static String convertSecondToHourQ(String qStr){
+			if(null==qStr || "".equals(qStr)){
+				return null;
+			}
+			Double qSecond = Double.parseDouble(qStr);
+			Double qHour = qSecond*3600;
+			return qHour.toString();
+		}
+	
+}

+ 306 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/Sw2014DatagramTemplateHelp.java

@@ -0,0 +1,306 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/2/23
+ */
+package org.ts.ddcs.common.util;
+
+
+import java.math.BigDecimal;
+import java.util.Calendar;
+
+/***
+ * Date:2022/2/23
+ * Title: 数据项模板
+ * Description:解析数据帮助,公共方法
+ * @author dylan
+ *
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class Sw2014DatagramTemplateHelp {
+    private static final String SYMBOL_FLAG = "FF";
+
+    /**
+     * 解析数值字节长度及小数位长度
+     *
+     * @param byteValue
+     * @return
+     */
+    public static ValueLen getValueLen(byte byteValue) {
+        int dataTotalLen = byteValue >> 3;
+        int decimalLen = byteValue & 7;
+        ValueLen valueLen = new ValueLen();
+        valueLen.setByteLen(dataTotalLen);
+        valueLen.setDecimalLen(decimalLen);
+        return valueLen;
+    }
+
+    /**
+     * 解析数值字节长度及小数位长度
+     *
+     * @param dataBuff
+     * @param pos
+     * @return
+     */
+    public static ValueLen getValueLen(byte[] dataBuff, int pos) {
+        byte byteValue = dataBuff[pos];
+        int dataTotalLen = byteValue >> 3;
+        int decimalLen = byteValue & 7;
+        ValueLen valueLen = new ValueLen();
+        valueLen.setByteLen(dataTotalLen);
+        valueLen.setDecimalLen(decimalLen);
+        return valueLen;
+    }
+
+    /**
+     * 报文体长度
+     *
+     * @param buff
+     * @return
+     */
+    public static int getContentLen(byte[] buff) {
+        byte[] tmpbuf = new byte[2];
+        tmpbuf[0] = (byte) (buff[0] & 0x0f);
+        tmpbuf[1] = buff[1];
+        int v = 0;
+        for (int ii = 0; ii < 2; ii++) {
+            int shi = (2 - 1 - ii) * 8;
+            v += (tmpbuf[ii] & 0x00FF) << shi;
+        }
+        return v;
+    }
+
+    public static BigDecimal getDecimalValue(byte[] buff, int pos) {
+        return null;
+    }
+
+    /**
+     * 解析数字类型数值
+     *
+     * @param buff
+     * @param index
+     * @param byteLen
+     * @param decimalLen
+     * @return
+     */
+    public static BigDecimal toDecimal(byte[] buff, int index, int byteLen, int decimalLen) {
+        String decimalValue = Sw2014DatagramTemplateHelp.toDecimalString(buff, index, byteLen, decimalLen);
+        if (null != decimalValue) {
+            return new BigDecimal(decimalValue);
+        }
+        return null;
+    }
+
+    /**
+     * 解析数字类型数值并转成字符串
+     *
+     * @param buff
+     * @param index
+     * @param byteLen
+     * @param decimalLen
+     * @return
+     */
+    public static String toDecimalString(byte[] buff, int index, int byteLen, int decimalLen) {
+        if (buff.length == 0 || (buff.length - index) < byteLen) {
+            return null;
+        }
+        byte[] valueBuff = BytesUtil.subBytes(buff, index, byteLen);
+        if (null == valueBuff || valueBuff.length <= 0) {
+            return null;
+        }
+        String hexStr = BytesUtil.byte2HexStr(valueBuff);
+        StringBuffer tmpString = new StringBuffer(hexStr);
+        String symbol = "";
+        if (SYMBOL_FLAG.equals(hexStr.substring(0, 2))) {
+            tmpString = new StringBuffer(hexStr.substring(2));
+            symbol = "-";
+        }
+        if (decimalLen != 0) {
+            tmpString.insert(tmpString.length() - decimalLen, ".");
+        }
+        String decimalValue = StringUtil.getPrettyNumber(tmpString.toString());
+        decimalValue = symbol + decimalValue;
+        return decimalValue;
+    }
+
+    /**
+     * 水文规约2014CRC检验
+     *
+     * @param packet
+     * @param pos
+     * @param length
+     * @return
+     */
+    public static byte[] crcFun2014(byte[] packet, int pos, int length) {
+        int n = length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = BytesHelp.byteToInteger(packet[pos + b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesHelp.int2Bytes(crc, 2);
+    }
+
+    /**
+     * 水文规约2014CRC检验
+     *
+     * @param packet
+     * @return
+     */
+    public static byte[] crcFun2014(byte[] packet) {
+        int n = packet.length;
+        int crc = 0xFFFF;
+        for (int b = 0; b < n; b++) {
+            crc = BytesHelp.byteToInteger(packet[b]) ^ crc;
+            for (int c = 0; c < 8; c++) {
+                int dd = crc & 0x0001;
+                if (dd == 1) {
+                    crc = crc >> 1;
+                    crc ^= 0xA001;
+                } else {
+                    crc = crc >> 1;
+                }
+            }
+        }
+        return BytesHelp.int2Bytes(crc, 2);
+    }
+
+    /**
+     * 流水号
+     *
+     * @param dataBuff
+     * @param pos
+     * @return
+     */
+    public static String toSerialNo(byte[] dataBuff, int pos) {
+        int sn = BytesHelp.bytes2Int(dataBuff, pos, 2);
+        return Integer.toString(sn);
+    }
+
+    /**
+     * 发报时间
+     * 格式 yyyyMMddHHmmss
+     *
+     * @param buff
+     * @return
+     */
+    public static String toSendPacketTime(byte[] buff) {
+        return "20" + BytesHelp.byte2HexStr(buff);
+    }
+
+    /**
+     * 发报时间
+     * 格式 yyyyMMddHHmmss
+     *
+     * @param buff
+     * @param pos
+     * @return
+     */
+    public static String toSendPacketTime(byte[] buff, int pos) {
+        byte[] timeBuff = BytesHelp.subBytes(buff, pos, 6);
+        return "20" + BytesHelp.byte2HexStr(timeBuff);
+    }
+
+    /**
+     * 获取发报时间
+     *
+     * @return
+     */
+    public static byte[] getFBTm() {
+
+
+        Calendar now = Calendar.getInstance();
+        String year = now.get(Calendar.YEAR) + "";
+        String month = now.get(Calendar.MONTH) + 1 + "";
+        String day = now.get(Calendar.DATE) + "";
+        String hour = now.get(Calendar.HOUR_OF_DAY) + "";
+        String minute = now.get(Calendar.MINUTE) + "";
+        String second = now.get(Calendar.SECOND) + "";
+
+        byte[] tpArea;
+
+        tpArea = BytesHelp.hexStr2Bytes(year.substring(2, year.length()));
+
+        if (month.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + month));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(month));
+        }
+
+        if (day.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + day));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(day));
+        }
+        if (hour.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + hour));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(hour));
+        }
+        if (minute.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes("0" + minute));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea,
+                    BytesHelp.hexStr2Bytes(minute));
+        }
+
+        if (second.length() == 1) {
+            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes("0" + second));
+        } else {
+            tpArea = BytesHelp.arrayApend(tpArea, BytesHelp.hexStr2Bytes(second));
+        }
+
+        return tpArea;
+
+    }
+
+    public BigDecimal readBigDecimal(byte[] dataBuff, int pos) {
+        byte len = dataBuff[pos];
+        int dataTotalLen = len >> 3;
+        int decimalLen = len & 7;
+        byte[] buff = BytesHelp.subBytes(dataBuff, pos + 1, dataTotalLen);
+        if (BytesHelp.errorValue(buff)) {
+            return null;
+        }
+        BigDecimal v = BytesHelp.toDecimal(buff, decimalLen);
+        return v;
+    }
+
+    public BigDecimal readBigDecimal(byte[] dataBuff, int pos, int byteLenCheck) {
+        byte len = dataBuff[pos];
+        int dataTotalLen = len >> 3;
+        int decimalLen = len & 7;
+        byte[] buff = BytesHelp.subBytes(dataBuff, pos + 1, dataTotalLen);
+        if (BytesHelp.errorValue(buff)) {
+            return null;
+        }
+        if ((byte) buff[0] == 0xFF) {
+            if (dataTotalLen - 1 != byteLenCheck) {
+                return null;
+            }
+        } else {
+            if (dataTotalLen != byteLenCheck) {
+                return null;
+            }
+        }
+        BigDecimal v = BytesHelp.toDecimal(buff, decimalLen);
+        return v;
+    }
+}

+ 58 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ToolUtil.java

@@ -0,0 +1,58 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2024/2/20
+ */
+package org.ts.ddcs.common.util;
+
+import java.util.Random;
+import java.util.UUID;
+
+/***
+ * Date:2024/2/20
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class ToolUtil {
+    public static int hexStrToInt(String hex) {
+        return Integer.valueOf(hex, 16);
+    }
+
+    public static String getRootPath(Object mainClass) {
+        String path = mainClass.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
+        if (System.getProperty("os.name").contains("dows")) {
+            path = path.substring(1, path.length());
+        }
+        if (path.contains("jar")) {
+            path = path.substring(0, path.lastIndexOf("."));
+            return path.substring(0, path.lastIndexOf("/"));
+        }
+        return path.replace("target/classes/", "");
+    }
+
+
+    /**
+     * 返回长度为【strLength】的随机数,在前面补0
+     *
+     * @param strLength 长度
+     * @return 随机数
+     */
+    public static String getFixLengthString(int strLength) {
+        Random rm = new Random();
+        // 获得随机数
+        double pross = (1 + rm.nextDouble()) * Math.pow(10, strLength);
+        // 将获得的获得随机数转化为字符串
+        String fixLengthString = String.valueOf(pross);
+        // 返回固定的长度的随机数
+        return fixLengthString.substring(1, strLength + 1);
+    }
+
+
+    public static String randomUUID() {
+        return UUID.randomUUID().toString().replace("-", "").toLowerCase();
+    }
+}

+ 30 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/util/ValueLen.java

@@ -0,0 +1,30 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/2/23
+ */
+package org.ts.ddcs.common.util;
+
+import lombok.Data;
+
+/***
+ * Date:2022/2/23
+ * Title:数据项模板
+ * Description:数值的字节长度及小数点长度
+ * @author dylan
+ *
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Data
+public class ValueLen {
+    /**
+     * 值总共占多少位字节
+     */
+    private int byteLen;
+    /**
+     * 小数位长度
+     */
+    private int decimalLen;
+}

+ 74 - 0
tsddcs-datacollect-simple/pom.xml

@@ -0,0 +1,74 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>tsddcs</artifactId>
+        <groupId>org.ts.ddcs</groupId>
+        <version>1.0.0.RELEASE</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.ts.ddcs</groupId>
+    <artifactId>datacollect-simple</artifactId>
+    <name>${project.artifactId}</name>
+    <version>1.0.0.RELEASE</version>
+    <packaging>jar</packaging>
+    <description>数据平台-设备数据采集服务单服务版</description>
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.ts.ddcs</groupId>
+            <artifactId>tsddcs-commonservice</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-all</artifactId>
+            <version>4.1.66.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.dom4j</groupId>
+            <artifactId>dom4j</artifactId>
+            <version>2.1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-common</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <!--KAFKA-->
+        <dependency>
+            <groupId>org.springframework.kafka</groupId>
+            <artifactId>spring-kafka</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-streams</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-streams-scala_2.13</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.kafka</groupId>
+            <artifactId>kafka-clients</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.rocksdb</groupId>
+            <artifactId>rocksdbjni</artifactId>
+            <version>5.5.1</version>
+        </dependency>
+        <!--REDIS-->
+        <!--<dependency>-->
+        <!--<groupId>org.springframework.boot</groupId>-->
+        <!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
+        <!--</dependency>-->
+    </dependencies>
+
+</project>

+ 21 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/DataCollectApplication.java

@@ -0,0 +1,21 @@
+package org.ts.ddcs;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+
+
+/**
+ * 主应用入口
+ *
+ * @author dylan
+ */
+@SpringBootApplication
+@EnableScheduling
+public class DataCollectApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(DataCollectApplication.class, args);
+    }
+}

+ 25 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/config/Config.java

@@ -0,0 +1,25 @@
+package  org.ts.ddcs.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+@Component
+public class Config {
+    @Autowired
+    public ServerConfig serverConfig;
+
+    private static class ServerConfigInstanceHolder {
+        private static Config instance = new Config();
+    }
+
+    public static Config newInstance() {
+        return Config.ServerConfigInstanceHolder.instance;
+    }
+
+    @PostConstruct
+    void init() {
+        Config.newInstance().serverConfig = serverConfig;
+    }
+}

+ 21 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/config/ServerConfig.java

@@ -0,0 +1,21 @@
+package  org.ts.ddcs.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * @author dylan
+ */
+@Component
+@Configuration
+@ConfigurationProperties(prefix = "run-config.server", ignoreUnknownFields = false)
+@Data
+public class ServerConfig {
+    private String tcpPort;
+    private String udpPort;
+    private String templatesDir;
+    private String templates;
+    private String tmpDir;
+}

+ 69 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/constant/BusinessConstant.java

@@ -0,0 +1,69 @@
+/**
+ * Copyright
+ * All right reserved.
+ * 项目名称:
+ * 创建日期:2022/3/7
+ */
+package org.ts.ddcs.constant;
+
+/***
+ * Date:2022/3/7
+ * Title:业务常量类
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author admin
+ * @mender:(文件的修改者,文件创建者之外的人)
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class BusinessConstant {
+	public static final  int DATAGRAM_BODY_MAX_LEN =4095;
+
+    public static final String SW_DATA_STREAM_CACHE_SERIAL_NO="serialNo";
+	public static final String SW_DATA_STREAM_CACHE_SEND_TIME="sendPacketTime";
+	public static final String SW_DATA_STREAM_CACHE_RTU_CODE="rtuCode";
+	public static final String SW_DATA_STREAM_CACHE_SITE_KIND="siteKind";
+	public static final String SW_DATA_STREAM_CACHE_COLLECT_TIME="collectTime";
+	public static final String SW_DATA_STREAM_CACHE_REV_TIME="receiveTime";
+	public static final String SW_DATA_STREAM_CACHE_VALUE="values";
+
+	public final static String BASE_KEY_DATAGRAM ="datagram";
+	public final static String REDIS_KEY ="redis_key";
+	public final static String REDIS_KEY_COMMAND_QUEUE = "command:queue";
+	public final static String REDIS_KEY_COMMAND_QUERY ="command:query";
+	public final static String REDIS_KEY_COMMAND_SETTING = "command:setting";
+	public final static String REDIS_KEY_COMMAND_FILE = "command:file";
+	public final static String REDIS_KEY_SERVER_MASTER ="server_master";
+	public final static String REDIS_KEY_COLLECT_SERVER ="collect_server_id";
+	public final static String REDIS_KEY_RTU_SPACE_TIME ="spaceTime";
+	public final static String REDIS_KEY_RTU_STATUS_DATAGRAM ="statusDatagram";
+
+	public final static String REDIS_KEY_COMMAND_BACK_FLAG = "command_back_flag";
+	public final static String REDIS_KEY_COMMAND_DATAGRAM_CODE = "command_datagram_code";
+	public final static String REDIS_KEY_COMMAND_TRY_COUNT = "command_try_count";
+	public final static String REDIS_KEY_COMMAND_SEND_TIME = "command_send_time";
+	public final static String REDIS_KEY_COMMAND_DATAGRAM = "command_datagram";
+
+//    public static final int featureWeight = 13;
+
+
+//
+//    //报文帧控制字符定义
+//    public static final byte[] PACKET_BODY_END_FLAG_ETX = {0x03}; //RTU2014年报文正文结束符,后续无报文
+//    public static final byte[] PACKET_BODY_END_FLAG_ETB = {0x17}; //RTU2014年报文正文结束符,后续有报文
+//
+//    public static final byte[] PACKET_CONTROL_FLAG_ENQ = {0x05}; //询问
+//    public static final byte[] PACKET_CONTROL_FLAG_EOT = {0x04}; //传输结束退出--作为传输结束确认帧报文结束符,表示可以退出通信
+//    public static final byte[] PACKET_CONTROL_FLAG_ACK = {0x06}; //肯定确认,继续发送--作为有后续报文帧的“确认帧” 报文结束符
+//    public static final byte[] PACKET_CONTROL_FLAG_NAK = {0x15}; //否定应答,反馈重发--用于要求对方重发某数据包的报文结束符
+//    public static final byte[] PACKET_CONTROL_FLAG_ESC = {0x1B}; //传输结束,终端保持在线---在下行确认帧代替EOT作为报文结束符,要求终端在线。保持在线10min内若没有接收到中心站命令,终端退回原先设定的工作状态
+
+
+    public final static String TEMPLATE_TYPE_PROCESSOR = "processor";
+    public final static String TEMPLATE_TYPE_SINK = "sink";
+//
+    public final static long DATAGRAM_DELAY_TIME = 5000L;
+
+
+
+//    public static final String SYMBOL_FLAG = "FF";
+}

+ 6 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/constant/NetPortStatusConstant.java

@@ -0,0 +1,6 @@
+package org.ts.ddcs.constant;
+
+public class NetPortStatusConstant {
+  public final static String ON = "ON";
+  public final static String OFF = "OFF";
+}

+ 166 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/controller/TestController.java

@@ -0,0 +1,166 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/10/27
+ */
+package org.ts.ddcs.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.ts.ddcs.common.util.BytesUtil;
+
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+
+/***
+ * Date:2022/10/27
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@RestController
+public class TestController {
+
+
+    public static byte[] hexStr2Bytes(String hexString) {
+        hexString = hexString.toLowerCase();
+        int remainder = hexString.length() % 2;
+        if (remainder > 0) {
+            hexString = "0" + hexString;
+        }
+        final byte[] byteArray = new byte[hexString.length() / 2];
+        int k = 0;
+        for (int i = 0; i < byteArray.length; i++) {
+            //因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
+            //将hex 转换成byte   "&" 操作为了防止负数的自动扩展
+            // hex转换成byte 其实只占用了4位,然后把高位进行右移四位
+            // 然后“|”操作  低四位 就能得到 两个 16进制数转换成一个byte.
+            //
+            byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
+            byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
+            byteArray[i] = (byte) (high << 4 | low);
+            k += 2;
+        }
+        return byteArray;
+    }
+
+    public static byte[] subBytes(byte[] src, int begin, int count) {
+        byte[] bs = new byte[count];
+        for (int i = begin; i < begin + count; i++) {
+            bs[i - begin] = src[i];
+        }
+        return bs;
+    }
+
+    public static int bytes2Int(byte[] bytes, int off, int len) {
+        int v = 0;
+        int pos = off + len - 1;
+        if (pos >= 0) {
+            v |= (bytes[pos] & 0xFF);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 8) & 0xFF00);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 16) & 0xFF0000);
+        }
+        pos--;
+        if (pos >= 0) {
+            v |= ((bytes[pos] << 24) & 0xFF000000);
+        }
+        return v;
+    }
+
+    public static String leftFill(String src, int len, char fillChar) {
+
+
+        String result = src;
+        for (int i = src.length(); i < len; i++) {
+            result = String.valueOf(fillChar) + result;
+        }
+
+        return result;
+    }
+
+    public static String byte2HexMpCdStr(byte[] b) {
+        String stmp = "";
+        StringBuilder sb = new StringBuilder("");
+        for (int n = 0; n < 3; n++) {
+            stmp = Integer.toHexString(b[n] & 0xFF);
+            sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
+        }
+        int mpcd = bytes2Int(subBytes(b, 3, 2), 0, 2) % 10000;
+
+        sb.append(leftFill(mpcd + "", 4, '0'));
+        return sb.toString().toUpperCase().trim();
+    }
+
+
+    @GetMapping("collect/test/fun")
+    public String getFun() {
+        byte[] buff = hexStr2Bytes("1522005A02");
+        String str = byte2HexMpCdStr(buff);
+        return str;
+    }
+
+    @GetMapping("collect/test/fun1")
+    public String getFun1() {
+        String rtuCode = "1522005A02";
+        String rtutail = rtuCode.substring(rtuCode.length() - 4, rtuCode.length());
+        byte[] rtubuff = BytesUtil.hexStr2Bytes(rtutail);
+        int rtuvalue = BytesUtil.bytes2short(rtubuff);
+        if (rtuvalue >= 0 && rtuvalue <= 9999) {
+            rtutail = String.format("%04d", rtuvalue);
+            rtuCode = rtuCode.substring(0, 6) + rtutail;
+
+        }
+
+        return rtuCode;
+    }
+
+    @GetMapping(value = "collect/test")
+    public String toTest() {
+        try {
+            // 1.定义服务器的地址、端口号、数据
+            InetAddress address = InetAddress.getByName("localhost");
+            // 2.定义服务器端口
+            int port = 8002;
+
+            // 3.创建发送端对象:发送端自带默认端口号
+            DatagramSocket socket = new DatagramSocket(2222);
+
+            // 4.客户端启动成功,输出提示信息
+            System.out.println("****客户端启动成功****");
+            String msg ="7E7E01005128290300002F20080230522230271439160396987E7E01005128290300002F0008023052221027144016034F497E7E01005128290300002F0008023052221027144116038F187E7E01005128290300002F0008023052221027144216038FE87E7E01005128290300002F0008023052221027144316034FB97E7E01005128290300002F0008023052221027144416038E087E7E01005128290300002F0008023052221027144516034E597E7E01005128290300002F0008023052221027144616034EA97E7E01005128290300002F0008023052221027144716038EF8";
+            byte[] buffer= BytesUtil.hexStr2Bytes(msg);
+
+            DatagramPacket packets = new DatagramPacket(buffer, buffer.length, address, port);
+            // 5.4 发送数据出去
+            socket.send(packets);
+
+            while (true) {
+                byte[] buf = new byte[1024 * 64];
+                DatagramPacket packet = new DatagramPacket(buf, buf.length);
+                // 6.2 接收服务器响应的数据
+                socket.receive(packet);
+                // 6.3 取出数据
+                int len = packet.getLength();
+                if (len >0) {
+                    String rs = new String(buf, 0, len);
+                    System.out.println("收到了ip为:" + packet.getAddress() + " 端口号为:" + packet.getPort() + "的消息:" + rs);
+                    break;
+                }
+            }
+            socket.close();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return "ok";
+    }
+}

+ 87 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataItemTemplateCache.java

@@ -0,0 +1,87 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/12/27
+ */
+package org.ts.ddcs.dataStream;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/***
+ * Date:2022/12/27
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+
+public class DataItemTemplateCache {
+    private byte[] dataBuff;
+    private int readSize;
+    private Map<String, Object> keyStore = new HashMap<>();
+
+    public void setDataBuff(byte[] data) {
+        this.dataBuff = data;
+    }
+
+    public int remainDataSize() {
+        if (null != this.dataBuff) {
+            if (this.readSize == this.dataBuff.length) {
+                return 0;
+            }
+            return this.dataBuff.length - this.readSize;
+        }
+        return 0;
+    }
+
+    public void readIndex(int readSize) {
+        this.readSize = readSize;
+    }
+
+    public void readSize(int readSize) {
+        this.readSize = this.readSize + readSize;
+    }
+
+    public void resetStore(){
+        this.keyStore.clear();
+    }
+
+    public byte getByte() throws NullPointerException, IndexOutOfBoundsException {
+        return this.dataBuff[this.readSize];
+    }
+
+    public byte[] getBytes(int length) throws NullPointerException, IndexOutOfBoundsException {
+        byte[] buf = new byte[length];
+        System.arraycopy(this.dataBuff, this.readSize, buf, 0, length);
+        return buf;
+    }
+
+    public byte getByte(int pos) throws NullPointerException, IndexOutOfBoundsException {
+        return this.dataBuff[pos];
+    }
+
+    public byte[] getBytes(int pos, int length) throws NullPointerException, IndexOutOfBoundsException {
+        byte[] buf = new byte[length];
+        System.arraycopy(this.dataBuff, pos, buf, 0, length);
+        return buf;
+    }
+
+    public void addValue(String key, Object value) {
+        this.keyStore.put(key, value);
+    }
+
+    public Set<String> keys() {
+        return this.keyStore.keySet();
+    }
+
+    public Object getValue(String key) {
+        return this.keyStore.get(key);
+    }
+    public boolean hasValue(String key){
+        return  this.keyStore.containsKey(key);
+    }
+}

+ 54 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStream.java

@@ -0,0 +1,54 @@
+package org.ts.ddcs.dataStream;
+import lombok.Data;
+import org.ts.ddcs.datatemplate.TestState;
+
+
+/**
+ * 数据流
+ * @author dylan
+ */
+@Data
+public class DataStream {
+    private byte[] dataBuff;
+    private TestState state;
+    private Integer readSize;
+    private String agreement;
+    private DataStreamProcessor matchDataStreamProcessor;
+    private Boolean crcOk;
+    private byte[] respPacket;
+    private String datagramCode;
+    private Integer datagramSize;
+
+    public int dataSize() {
+        if (null != dataBuff) {
+            return dataBuff.length;
+        }
+        return 0;
+    }
+
+    public byte getByte(int pos) {
+        if (dataBuff != null && pos < dataBuff.length) {
+            return dataBuff[pos];
+        }
+        return 0x00;
+    }
+
+    public byte[] getBytes(int length) {
+        if (dataBuff != null && dataBuff.length >= length) {
+            byte[] buf = new byte[length];
+            System.arraycopy(dataBuff, 0, buf, 0, length);
+            return buf;
+        }
+        return new byte[0];
+    }
+
+    public byte[] getBytes(int pos, int length) {
+        if (dataBuff != null && dataBuff.length >= (pos + length)) {
+            byte[] buf = new byte[length];
+            System.arraycopy(dataBuff, pos, buf, 0, length);
+            return buf;
+        }
+        return new byte[0];
+    }
+
+}

+ 197 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamAdapter.java

@@ -0,0 +1,197 @@
+package org.ts.ddcs.dataStream;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.socket.DatagramPacket;
+import org.ts.ddcs.common.enums.AgreementEnum;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+
+/**
+ * 适配器,用于连接网络接口与数据处理器
+ *
+ * @author dylan
+ */
+@Data
+@Slf4j
+public abstract class DataStreamAdapter {
+    protected LinkedBlockingQueue<byte[]> blockQueue = new LinkedBlockingQueue<>();
+    protected ChannelHandlerContext ctx;
+    private byte[] remainBuff = new byte[0];
+    public Map<String, Object> keyStore = new ConcurrentHashMap<>();
+    protected String remoteIp;
+    protected String rtuCode;
+    protected String adapterKey;
+    private boolean isClose = false;
+    private boolean lock = false;
+    private String agreement;
+    private String channelKey;
+    private Long lookTime;
+
+    public DataStreamAdapter() {
+        this.adapterKey = UUID.randomUUID().toString().replace("-", "").toLowerCase();
+    }
+
+    public void init(String channelKey, String agreement, String remoteIp) {
+        log.info("{} 初始化连接 IP:{}", this.adapterKey, remoteIp);
+        this.channelKey = channelKey;
+        this.agreement = agreement;
+        this.remoteIp = remoteIp;
+        DataStreamManageHolder.newInstance().dataStreamManager.regConnect(this);
+    }
+
+    public void putValue(String key, Integer value) {
+        this.keyStore.put(key, value);
+    }
+
+    public Integer getIntValue(String key) {
+        return (Integer) this.keyStore.get(key);
+    }
+
+    public void putValue(String key, String value) {
+        this.keyStore.put(key, value);
+    }
+
+    public String getStringValue(String key) {
+        return (String) this.keyStore.get(key);
+    }
+
+    public void putValue(String key, byte[] value) {
+        this.keyStore.put(key, value);
+    }
+
+    public byte[] getByteValue(String key) {
+        return (byte[]) this.keyStore.get(key);
+    }
+
+    public String getAdapterKey() {
+        return this.adapterKey;
+    }
+
+    public void error() {
+        log.info("{} 数据处理发生错误,测站编码:{}", this.adapterKey, this.rtuCode);
+        this.remainBuff = new byte[0];
+    }
+
+    public boolean remaining() {
+        if (remainBuff.length > 0) {
+            return true;
+        }
+        if (blockQueue.isEmpty()) {
+            return false;
+        }
+        return true;
+    }
+
+    public byte[] getBlock() {
+        try {
+            if (null == blockQueue) {
+                return new byte[0];
+            }
+            if (!blockQueue.isEmpty()) {
+                byte[] block = blockQueue.poll();
+                int len = block.length;
+                if (remainBuff.length > 0) {
+                    len += remainBuff.length;
+                }
+                byte[] tmpBuff = new byte[len];
+                if (remainBuff.length > 0) {
+                    System.arraycopy(remainBuff, 0, tmpBuff, 0, remainBuff.length);
+                }
+                System.arraycopy(block, 0, tmpBuff, remainBuff.length, block.length);
+                remainBuff = tmpBuff;
+                return remainBuff;
+            } else {
+                if (remainBuff.length > 0) {
+                    return remainBuff;
+                } else {
+                    return new byte[0];
+                }
+            }
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return new byte[0];
+        }
+    }
+
+    void readIndex(int index) {
+        if (index <= 0 || index > remainBuff.length) {
+            log.info("{} DataStreamAdapter read out index", this.adapterKey);
+        } else {
+            if (index == remainBuff.length) {
+                remainBuff = new byte[0];
+            } else {
+                byte[] tmpBuff = new byte[remainBuff.length - index];
+                System.arraycopy(remainBuff, index, tmpBuff, 0, remainBuff.length - index);
+                remainBuff = tmpBuff;
+            }
+        }
+    }
+
+    public void close() {
+        log.info("{} 连接关闭 ", this.adapterKey);
+        this.ctx = null;
+        this.isClose = true;
+        if (null == this.remainBuff || this.remainBuff.length == 0) {
+            DataStreamManageHolder.newInstance().dataStreamManager.closeConnect(this);
+        }
+    }
+
+    public int moveToNext() {
+        if (null != agreement && agreement.equals(AgreementEnum.AGREEMENT_SW.getName())) {
+            for (int i = 3; i < this.remainBuff.length; i++) {
+                if (this.remainBuff[i - 1] == 0x7E && this.remainBuff[i] == 0x7E) {
+                    return i - 1;
+                }
+            }
+        } else if (null != agreement && agreement.equals(AgreementEnum.AGREEMENT_SW_EXT.getName())) {
+            for (int i = 3; i < this.remainBuff.length; i++) {
+                if (this.remainBuff[i - 1] == 0x7E && this.remainBuff[i] == 0x7E) {
+                    return i - 1;
+                }
+            }
+        } else if (null != agreement && agreement.equals(AgreementEnum.AGREEMENT_SW_NM_EXT.getName())) {
+            for (int i = 3; i < this.remainBuff.length; i++) {
+                if (this.remainBuff[i - 1] == 0x7E && this.remainBuff[i] == 0x7E) {
+                    return i - 1;
+                }
+            }
+        } else if (null != agreement && agreement.equals(AgreementEnum.AGREEMENT_SZY.getName())) {
+            for (int i = 5; i < this.remainBuff.length; i++) {
+                if (this.remainBuff[i - 2] == 0x68 && this.remainBuff[i] == 0x68) {
+                    return i - 2;
+                }
+            }
+        }
+        return this.remainBuff.length;
+    }
+
+    /**
+     * 输出到数据连接通道
+     *
+     * @param respBody
+     */
+    public abstract void output(byte[] respBody);
+
+    /**
+     * UDP数据包
+     *
+     * @param buf
+     * @param cx
+     * @param datagramPacket
+     */
+    public abstract void pushData(ByteBuf buf, ChannelHandlerContext cx, DatagramPacket datagramPacket);
+
+    /**
+     * TCP数据包
+     *
+     * @param buf
+     * @param cx
+     */
+    public abstract void pushData(ByteBuf buf, ChannelHandlerContext cx);
+
+}

+ 130 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamCache.java

@@ -0,0 +1,130 @@
+
+package org.ts.ddcs.dataStream;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.ts.ddcs.constant.BusinessConstant;
+import org.ts.ddcs.datatemplate.TestState;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 数据缓存
+ *
+ * @author swp
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class DataStreamCache {
+    private TestState state = TestState.LOOK;
+    private byte[] dataBuff;
+    private int readSize;
+    private String datagramCode;
+    private String rtuCode;
+    private LocalDateTime pickPacketTime;
+    private Integer datagramSize;
+    private byte[] datagramBuff;
+    private DataStreamProcessor matchProcessor;
+
+    private Map<String, Object> keyStore = new HashMap<>();
+
+    public void resetStore() {
+        this.keyStore.clear();
+    }
+
+    public int remainDataSize() {
+        if (null != this.dataBuff) {
+            if (this.readSize == this.dataBuff.length) {
+                return 0;
+            }
+            return this.dataBuff.length - this.readSize;
+        }
+        return 0;
+    }
+
+    public void readIndex(int readSize) {
+        this.readSize = readSize;
+    }
+
+    public void readSize(int readSize) {
+        this.readSize = this.readSize + readSize;
+    }
+
+
+    public int dataSize() {
+        if (null != dataBuff) {
+            return dataBuff.length;
+        }
+        return 0;
+    }
+
+    public byte getByte() throws NullPointerException, IndexOutOfBoundsException {
+        return this.dataBuff[this.readSize];
+    }
+
+    public byte[] getBytes(int length) throws NullPointerException, IndexOutOfBoundsException {
+        byte[] buf = new byte[length];
+        System.arraycopy(this.dataBuff, this.readSize, buf, 0, length);
+        return buf;
+    }
+
+    public byte getByte(int pos) throws NullPointerException, IndexOutOfBoundsException {
+        return this.dataBuff[pos];
+    }
+
+    public byte[] getBytes(int pos, int length) throws NullPointerException, IndexOutOfBoundsException {
+        byte[] buf = new byte[length];
+        System.arraycopy(this.dataBuff, pos, buf, 0, length);
+        return buf;
+    }
+
+    public void putValue(String key, Object value) {
+        this.keyStore.put(key, value);
+    }
+
+    public Set<String> keys() {
+        return this.keyStore.keySet();
+    }
+
+    public Object getValue(String key) {
+        return this.keyStore.get(key);
+    }
+
+    public Integer getIntValue(String key) {
+        Object value = this.keyStore.get(key);
+        if (value instanceof Integer) {
+            return (Integer) value;
+        }
+        return null;
+    }
+
+    public byte[] getBytesValue(String key) {
+        Object value = this.keyStore.get(key);
+        if (value instanceof byte[]) {
+            return (byte[]) value;
+        }
+        return null;
+    }
+
+    public String getStringValue(String key) {
+        Object value = this.keyStore.get(key);
+        if (value instanceof String) {
+            return (String) value;
+        }
+        return null;
+    }
+
+    public Object getItemValue(String key) {
+        Object itemTemplateCacheObj = this.keyStore.get(BusinessConstant.SW_DATA_STREAM_CACHE_VALUE);
+        if (null != itemTemplateCacheObj) {
+            if (itemTemplateCacheObj instanceof DataItemTemplateCache) {
+                DataItemTemplateCache itemTemplateCache = (DataItemTemplateCache) itemTemplateCacheObj;
+                return itemTemplateCache.getValue(key);
+            }
+        }
+        return null;
+    }
+}

+ 243 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamLineManager.java

@@ -0,0 +1,243 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/3/25
+ */
+package org.ts.ddcs.dataStream;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.enums.AgreementEnum;
+import org.ts.ddcs.common.util.BytesUtil;
+import org.ts.ddcs.constant.BusinessConstant;
+import org.ts.ddcs.dataStream.sink.DataStreamSink;
+import org.ts.ddcs.datatemplate.Template;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.itemdatatemplate.ItemTemplate;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+
+/***
+ * Date:2022/3/25
+ * Title:数据流处理链
+ * Description:数据链处理管理器
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamLineManager {
+
+    private boolean isLock = false;
+    /**
+     * 数据处理器
+     */
+    private Map<String, List<DataStreamProcessor>> processors = new HashMap<>();
+    /**
+     * 数据元素解析器
+     */
+    private Map<String, Map<String, DataItemTemplate>> itemTemplates = new HashMap<>();
+    /**
+     * 输出处理器
+     */
+    private Map<String, List<DataStreamSink>> sinks = new HashMap<>();
+    /**
+     * 缓存器
+     */
+    private DataStreamCache dataStreamCache = new DataStreamCache();
+
+    public void lock(boolean lock) {
+        this.isLock = lock;
+    }
+
+    public boolean lock() {
+        return this.isLock;
+    }
+
+    public void addProcessor(String agreement, Template template) throws NullPointerException, ClassNotFoundException, IllegalAccessException, InstantiationException {
+        if (null == agreement || null == template) {
+            throw new NullPointerException("参数不能为空");
+        }
+        if (null == template.getStreamProcessorClass()) {
+            throw new NullPointerException("处理器类不能为空");
+        }
+        Class className = Class.forName(template.getStreamProcessorClass());
+        Object instance = className.newInstance();
+        if (instance instanceof DataStreamProcessor) {
+            DataStreamProcessor dataStreamProcessor = (DataStreamProcessor) instance;
+            dataStreamProcessor.setProcessorName(template.getProcessorName());
+            dataStreamProcessor.setTemplateName(template.getTemplateName());
+            if (this.processors.containsKey(agreement)) {
+                List<DataStreamProcessor> processorList = this.processors.get(agreement);
+                if (processorList.size() > 0) {
+                    dataStreamProcessor.setPreProcessor(processorList.get(processorList.size() - 1));
+                    processorList.get(processorList.size() - 1).setNextProcessor(dataStreamProcessor);
+                }
+                processorList.add(dataStreamProcessor);
+                dataStreamProcessor.init(this);
+            } else {
+                List<DataStreamProcessor> processorList = new LinkedList<>();
+                processorList.add(dataStreamProcessor);
+                dataStreamProcessor.init(this);
+                this.processors.put(agreement, processorList);
+            }
+        } else {
+            throw new ClassNotFoundException();
+        }
+    }
+
+    public void addItemTemplates(String agreement, ItemTemplate itemTemplate) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
+        if (null == agreement || null == itemTemplate) {
+            throw new NullPointerException("参数不能为空");
+        }
+        if (null == itemTemplate.getItemTemplateClass()) {
+            throw new NullPointerException("处理器类不能为空");
+        }
+        Class className = Class.forName(itemTemplate.getItemTemplateClass());
+        Object instance = className.newInstance();
+        if (instance instanceof DataItemTemplate) {
+            DataItemTemplate dataItemTemplate = (DataItemTemplate) instance;
+            dataItemTemplate.setFeture(itemTemplate.getFunc());
+            dataItemTemplate.setName(itemTemplate.getFuncName());
+            dataItemTemplate.setUnit(itemTemplate.getUnit());
+            dataItemTemplate.setDesc(itemTemplate.getDesc());
+            if (this.itemTemplates.containsKey(agreement)) {
+                Map<String, DataItemTemplate> map = this.itemTemplates.get(agreement);
+                map.put(itemTemplate.getFunc(), dataItemTemplate);
+            } else {
+                Map<String, DataItemTemplate> map = new HashMap<>();
+                map.put(itemTemplate.getFunc(), dataItemTemplate);
+                this.itemTemplates.put(agreement, map);
+            }
+        } else {
+            throw new ClassNotFoundException();
+        }
+    }
+
+    public void addSink(String agreement, Template template) throws NullPointerException, ClassNotFoundException, IllegalAccessException, InstantiationException {
+        if (null == agreement || null == template) {
+            throw new NullPointerException("参数不能为空");
+        }
+        if (null == template.getStreamProcessorClass()) {
+            throw new NullPointerException("处理器类不能为空");
+        }
+        Class className = Class.forName(template.getStreamProcessorClass());
+        Object instance = className.newInstance();
+        if (instance instanceof DataStreamSink) {
+            DataStreamSink dataStreamSink = (DataStreamSink) instance;
+            dataStreamSink.setSinkName(template.getProcessorName());
+            dataStreamSink.setTemplateName(template.getTemplateName());
+            if (this.sinks.containsKey(agreement)) {
+                List<DataStreamSink> sinkList = this.sinks.get(agreement);
+                sinkList.add(dataStreamSink);
+                dataStreamSink.init(this);
+            } else {
+                List<DataStreamSink> sinkList = new LinkedList<>();
+                sinkList.add(dataStreamSink);
+                dataStreamSink.init(this);
+                this.sinks.put(agreement, sinkList);
+            }
+        } else {
+            throw new ClassNotFoundException();
+        }
+    }
+
+    public DataStreamCache getCache() {
+        return this.dataStreamCache;
+    }
+
+    public Map<String, DataItemTemplate> getItemTemplate(String agreement) {
+        if (this.itemTemplates.containsKey(agreement)) {
+            return this.itemTemplates.get(agreement);
+        }
+        return null;
+    }
+
+    public void stream(DataStreamAdapter dataStreamAdapter) {
+        try {
+            log.info("{} 开始处理数据", dataStreamAdapter.getAdapterKey());
+            int readIndex = 0;
+            byte[] block = dataStreamAdapter.getBlock();
+            if (block.length == 0) {
+                return;
+            }
+            log.info("{} 待处理数据包 {}", dataStreamAdapter.getAdapterKey(), BytesUtil.byte2HexStr(block));
+            String agreement = dataStreamAdapter.getAgreement();
+            if (null == agreement) {
+                if (block.length >= 3) {
+                    if (block[0] == 0x7e && block[1] == 0x7e) {
+                        dataStreamAdapter.setAgreement(AgreementEnum.AGREEMENT_SW.getName());
+                        agreement = AgreementEnum.AGREEMENT_SW.getName();
+                    } else if (block[0] == 0x68 && block[2] == 0x68) {
+                        dataStreamAdapter.setAgreement(AgreementEnum.AGREEMENT_SZY.getName());
+                        agreement = AgreementEnum.AGREEMENT_SZY.getName();
+                    }
+                } else if (block.length >= 2) {
+                    if (block[0] == 0x7e && block[1] == 0x7e) {
+                        dataStreamAdapter.setAgreement(AgreementEnum.AGREEMENT_SW.getName());
+                        agreement = AgreementEnum.AGREEMENT_SW.getName();
+                    }
+                }
+            }
+            if (null != agreement && processors.containsKey(agreement)) {
+                List<DataStreamProcessor> processorList = processors.get(agreement);
+                this.dataStreamCache.resetStore();
+                this.dataStreamCache.setDataBuff(block);
+                this.dataStreamCache.setState(TestState.LOOK);
+                this.dataStreamCache.setReadSize(0);
+                processorList.get(0).stream(dataStreamAdapter);
+                if (dataStreamCache.getState() == TestState.ERROR) {
+                    DataStreamProcessor matchProcessor = this.dataStreamCache.getMatchProcessor();
+                    matchProcessor.batchComplete(dataStreamAdapter);
+                    readIndex = dataStreamCache.getReadSize();
+                    dataStreamAdapter.setLookTime(0L);
+                } else if (dataStreamCache.getState() == TestState.LOOK) {
+                    Long lookTime = dataStreamAdapter.getLookTime();
+                    if (0 == lookTime) {
+                        dataStreamAdapter.setLookTime(System.currentTimeMillis());
+                    } else {
+                        if ((System.currentTimeMillis() - lookTime) >= BusinessConstant.DATAGRAM_DELAY_TIME) {
+                            readIndex = dataStreamAdapter.moveToNext();
+                        }
+                    }
+                } else if (this.dataStreamCache.getState() == TestState.MATHCE) {
+                    DataStreamProcessor matchProcessor = this.dataStreamCache.getMatchProcessor();
+                    //回包
+                    matchProcessor.batchComplete(dataStreamAdapter);
+                    //输出
+                    List<Map<String, Object>> elementDatas = matchProcessor.sink(dataStreamAdapter);
+                    if (null != elementDatas) {
+                        List<DataStreamSink> sinkList = this.sinks.get(agreement);
+                        if (null != sinkList && sinkList.size() > 0) {
+                            for (DataStreamSink streamSink : sinkList) {
+                                streamSink.sink(dataStreamAdapter, elementDatas);
+                            }
+                        }
+                    }
+                    readIndex = this.dataStreamCache.getReadSize();
+                    dataStreamAdapter.setLookTime(0L);
+                } else {
+                    //未定义报文,不做任何处理
+                    DataStreamProcessor matchProcessor = this.dataStreamCache.getMatchProcessor();
+                    matchProcessor.batchComplete(dataStreamAdapter);
+                    readIndex = dataStreamCache.getReadSize();
+                    dataStreamAdapter.setLookTime(0L);
+                }
+                dataStreamAdapter.readIndex(readIndex);
+            } else {
+                log.info("{} 没找到适配处理器", dataStreamAdapter.getAdapterKey());
+                dataStreamAdapter.readIndex(1);
+            }
+        } catch (Exception e) {
+            log.error(dataStreamAdapter.getAdapterKey(), e);
+            dataStreamAdapter.error();
+        } finally {
+            log.info("{} 数据处理任务结束", dataStreamAdapter.getAdapterKey());
+        }
+    }
+}

+ 19 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamManageHolder.java

@@ -0,0 +1,19 @@
+package  org.ts.ddcs.dataStream;
+
+
+/**
+ * 数据流主模块实例
+ *
+ * @author dylan
+ */
+public class DataStreamManageHolder {
+    private static class InstanceHolder {
+        static DataStreamManageHolder instance = new DataStreamManageHolder();
+    }
+
+    public static DataStreamManageHolder newInstance() {
+        return DataStreamManageHolder.InstanceHolder.instance;
+    }
+
+    public DataStreamManager dataStreamManager;
+}

+ 299 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamManager.java

@@ -0,0 +1,299 @@
+package org.ts.ddcs.dataStream;
+
+import lombok.extern.slf4j.Slf4j;
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+
+import org.rocksdb.RocksDB;
+import org.ts.ddcs.common.enums.AgreementEnum;
+import org.ts.ddcs.constant.BusinessConstant;
+import org.ts.ddcs.datatemplate.DataTemplateManageHolder;
+import org.ts.ddcs.datatemplate.Template;
+import org.ts.ddcs.itemdatatemplate.ItemTemplate;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.*;
+
+
+/**
+ * 数据流主模块
+ *
+ * @author dylan
+ */
+@Slf4j
+public class DataStreamManager {
+
+    private  RocksDB rocksDB;
+    /**
+     * 数据流工作线程数量
+     */
+    private static final int STREAM_THREAD_NUM = 4;
+
+    private int taskIdelCount = 0;
+
+    /**
+     * 连接适配器
+     */
+    private Map<String, DataStreamAdapter> dataStreamAdapterCache = new ConcurrentHashMap<>(2048);
+
+    /**
+     * 数据有变化适配器队列
+     */
+    private LinkedBlockingQueue<String> readQueue = new LinkedBlockingQueue<>();
+
+    /**
+     * 模板处理器链
+     */
+    private Map<Integer, DataStreamLineManager> streamLineCache = new ConcurrentHashMap<>(DataStreamManager.STREAM_THREAD_NUM);
+
+    /**
+     * 线程池
+     **/
+    private static ThreadFactory batchThreadFactory = new ThreadFactoryBuilder().setNameFormat("batch-thread-pool-%d").build();
+    private static ExecutorService batchThreadPool = new ThreadPoolExecutor(4, 4,
+            0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), batchThreadFactory, new ThreadPoolExecutor.AbortPolicy());
+
+    /**
+     * 任务定时器
+     */
+    private ScheduledExecutorService scheduleExecutor = Executors.newSingleThreadScheduledExecutor(r -> new Thread(r, "batch-stream-task-" + r.hashCode()));
+
+    /**
+     * 创建数据流处理链
+     *
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     * @throws ClassNotFoundException
+     */
+    private void createDataStreamLine(String templates) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
+        for (int i = 1; i <= STREAM_THREAD_NUM; i++) {
+            DataStreamLineManager lineManager = new DataStreamLineManager();
+            String[] list = templates.split(",");
+            if (list.length > 0) {
+                for (String templateName : list) {
+                    if (AgreementEnum.AGREEMENT_SW.getName().equals(templateName)) {
+                        List<Template> templateList = DataTemplateManageHolder.newInstance().dataTemplateManager.cloneTemplateLine(AgreementEnum.AGREEMENT_SW.getName());
+                        if (null != templateList && templateList.size() > 0) {
+                            for (Template template : templateList) {
+                                if (BusinessConstant.TEMPLATE_TYPE_PROCESSOR.equals(template.getType())) {
+                                    lineManager.addProcessor(AgreementEnum.AGREEMENT_SW.getName(), template);
+                                } else if (BusinessConstant.TEMPLATE_TYPE_SINK.equals(template.getType())) {
+                                    lineManager.addSink(AgreementEnum.AGREEMENT_SW.getName(), template);
+                                }
+                            }
+                        }
+                        List<ItemTemplate> itemTemplateList = DataTemplateManageHolder.newInstance().dataTemplateManager.cloneItemTemplateLine(AgreementEnum.AGREEMENT_SW.getName());
+                        if (null != itemTemplateList && itemTemplateList.size() > 0) {
+                            for (ItemTemplate itemTemplate : itemTemplateList) {
+                                lineManager.addItemTemplates(AgreementEnum.AGREEMENT_SW.getName(), itemTemplate);
+                            }
+                        }
+                    } else if (AgreementEnum.AGREEMENT_SZY.getName().equals(templateName)) {
+                        List<Template> templateList = DataTemplateManageHolder.newInstance().dataTemplateManager.cloneTemplateLine(AgreementEnum.AGREEMENT_SZY.getName());
+                        if (null != templateList && templateList.size() > 0) {
+                            for (Template template : templateList) {
+                                if (BusinessConstant.TEMPLATE_TYPE_PROCESSOR.equals(template.getType())) {
+                                    lineManager.addProcessor(AgreementEnum.AGREEMENT_SZY.getName(), template);
+                                } else if (BusinessConstant.TEMPLATE_TYPE_SINK.equals(template.getType())) {
+                                    lineManager.addSink(AgreementEnum.AGREEMENT_SZY.getName(), template);
+                                }
+                            }
+                        }
+                        List<ItemTemplate> itemTemplateList = DataTemplateManageHolder.newInstance().dataTemplateManager.cloneItemTemplateLine(AgreementEnum.AGREEMENT_SZY.getName());
+                        if (null != itemTemplateList && itemTemplateList.size() > 0) {
+                            for (ItemTemplate itemTemplate : itemTemplateList) {
+                                lineManager.addItemTemplates(AgreementEnum.AGREEMENT_SZY.getName(), itemTemplate);
+                            }
+                        }
+                    }
+                }
+            }
+            streamLineCache.put(i, lineManager);
+        }
+    }
+
+    /**
+     * 数据流管理器初始化
+     */
+    public void init(String templates,RocksDB rocksDB) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
+        try {
+            this.rocksDB = rocksDB;
+            //初始化数据流处理器
+            this.createDataStreamLine(templates);
+            //任务定时器
+            this.scheduleExecutor.scheduleWithFixedDelay(() -> {
+                try {
+                    boolean idel = false;
+                    boolean hasTask = false;
+                    for (int i = 1; i <= STREAM_THREAD_NUM; i++) {
+                        DataStreamLineManager lineManager = streamLineCache.get(i);
+                        if (!lineManager.lock()) {
+                            //有空闲处理器
+                            String key = readQueue.poll();
+                            if (null != key) {
+                                DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.get(key);
+                                if (null != dataStreamAdapter) {
+                                    if (!dataStreamAdapter.isLock()) {
+                                        //数据流适配器空闲
+                                        if (dataStreamAdapter.remaining()) {
+                                            lineManager.lock(true);
+                                            dataStreamAdapter.setLock(true);
+                                            //创建数据处理任务
+                                            long tm = System.currentTimeMillis();
+                                            BatchDataStreamTask task = new BatchDataStreamTask(tm, lineManager, dataStreamAdapter);
+                                            FutureTask<Integer> futureTask = new FutureTask<>(task);
+                                            batchThreadPool.execute(futureTask);
+                                            hasTask = true;
+                                        }
+                                    }
+                                } else {
+                                    log.info("找不到适配器 {}", key);
+                                }
+                            }
+                            idel = true;
+                        } else {
+                            log.info("数据流处理器已被锁住 {}", i);
+                        }
+                    }
+                    if (!idel) {
+                        log.info("任务处理器性能故障");
+                    }
+                    if (!hasTask) {
+                        taskIdelCount += 1;
+                    } else {
+                        taskIdelCount = 0;
+                    }
+                    //log.info("task idel count {}",taskIdelCount);
+                    if (taskIdelCount >= 10) {
+                        //没有任务
+                        Set<String> keySet = dataStreamAdapterCache.keySet();
+                        for (String key : keySet) {
+                            DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.get(key);
+                            if (!dataStreamAdapter.isLock()) {
+                                //数据流适配器空闲
+                                if (dataStreamAdapter.remaining()) {
+                                    idel = false;
+                                    //有待处理数据
+                                    for (int i = 1; i <= STREAM_THREAD_NUM; i++) {
+                                        DataStreamLineManager lineManager = streamLineCache.get(i);
+                                        if (!lineManager.lock()) {
+                                            //有空闲处理器
+                                            dataStreamAdapter.setLock(true);
+                                            lineManager.lock(true);
+                                            //创建数据处理任务
+                                            long tm = System.currentTimeMillis();
+                                            BatchDataStreamTask task = new BatchDataStreamTask(tm, lineManager, dataStreamAdapter);
+                                            FutureTask<Integer> futureTask = new FutureTask<>(task);
+                                            batchThreadPool.execute(futureTask);
+                                            idel = true;
+                                            break;
+                                        } else {
+                                            log.info("数据流处理器已被锁住 {}", i);
+                                        }
+                                    }
+                                    if (!idel) {
+                                        log.info("任务处理器性能故障");
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        taskIdelCount = 0;
+                    }
+
+                } catch (Exception e) {
+                    log.error(this.getClass().getName(), e);
+                }
+            }, 0, 10, TimeUnit.MILLISECONDS);
+        } catch (Exception e) {
+            log.error(this.getClass().getName(), e);
+            throw e;
+        }
+    }
+
+    private class BatchDataStreamTask implements Callable<Integer> {
+
+        private long batchTime;
+
+        private DataStreamAdapter dataStreamAdapter;
+
+        private DataStreamLineManager dataStreamLineManager;
+
+        BatchDataStreamTask(long batchTime, DataStreamLineManager dataStreamLineManager, DataStreamAdapter dataStreamAdapter) {
+            this.batchTime = batchTime;
+            this.dataStreamLineManager = dataStreamLineManager;
+            this.dataStreamAdapter = dataStreamAdapter;
+        }
+
+        @Override
+        public Integer call() {
+            try {
+                dataStreamLineManager.stream(dataStreamAdapter);
+                dataStreamAdapter.setLock(false);
+                dataStreamLineManager.lock(false);
+//                long ut = System.currentTimeMillis() - batchTm;
+//                LogHelper.info("time " + ut);
+//                if (ut > 10) {
+//                    LogHelper.info("task time too long !!!!!!!!!!!!!!!");
+//                }
+            } catch (Exception e) {
+                log.error(this.getClass().getName(), e);
+            }
+            return 0;
+        }
+    }
+
+
+    /**
+     * 注册连接
+     *
+     * @param adapter
+     */
+    public void regConnect(DataStreamAdapter adapter) {
+        dataStreamAdapterCache.put(adapter.getAdapterKey(), adapter);
+    }
+
+    /**
+     * 关闭连接
+     *
+     * @param adapter
+     */
+    public void closeConnect(DataStreamAdapter adapter) {
+        if (dataStreamAdapterCache.containsKey(adapter.getAdapterKey())) {
+            if (!adapter.isLock()) {
+                byte[] block = adapter.getBlock();
+                if (null == block || block.length == 0) {
+                    dataStreamAdapterCache.remove(adapter.getAdapterKey());
+                }
+            }
+        }
+    }
+
+    public void readEvent(DataStreamAdapter adapter) {
+        readQueue.offer(adapter.getAdapterKey());
+    }
+
+    public void responseEvent(String key, byte[] respBlock) {
+        if (this.dataStreamAdapterCache.containsKey(key)) {
+            DataStreamAdapter dataStreamAdapter = this.dataStreamAdapterCache.get(key);
+            if (!dataStreamAdapter.isClose()) {
+                dataStreamAdapter.output(respBlock);
+            } else {
+                log.info("运行错误,链接已经提前关闭: {}", key);
+            }
+        }
+    }
+
+    public DataStreamAdapter getAdapter(String rtuCode){
+        Set<String> keySet = dataStreamAdapterCache.keySet();
+        for (String key : keySet) {
+            DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.get(key);
+            String stcd =dataStreamAdapter.getRtuCode();
+            if (null != stcd && stcd.equals(rtuCode)){
+                return dataStreamAdapter;
+            }
+        }
+        return null;
+    }
+}

+ 105 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DataStreamProcessor.java

@@ -0,0 +1,105 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.UnsupportedEncodingException;
+import java.text.ParseException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+/***
+ * Date:2021/12/16
+ * Title:数据匹配器模块
+ * Description:每个适配器处理器
+ * @author dylan
+ * @mender:(文件的修改者,文件创建者之外的人)
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public abstract class DataStreamProcessor {
+    private String processorName;
+    private String templateName;
+    private DataStreamProcessor preProcessor;
+    private DataStreamProcessor nextProcessor;
+    protected DataStreamLineManager context;
+    private boolean isNext = false;
+
+    public abstract void init(DataStreamLineManager context);
+
+    public abstract void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException, ParseException;
+
+    public abstract void close(DataStreamAdapter dataStreamAdapter);
+
+    public abstract void batchComplete(DataStreamAdapter dataStreamAdapter) throws ParseException;
+
+    public abstract List<Map<String,Object>> sink(DataStreamAdapter dataStreamAdapter);
+
+    public void setPreProcessor(DataStreamProcessor processor) {
+        this.preProcessor = processor;
+    }
+
+    public void setNextProcessor(DataStreamProcessor processor) {
+        this.nextProcessor = processor;
+    }
+
+    public DataStreamProcessor getPreProcessor() {
+        return this.preProcessor;
+    }
+
+    public DataStreamProcessor getNextProcessor() {
+        return this.nextProcessor;
+    }
+
+    public void setProcessorName(String processorName) {
+        this.processorName = processorName;
+    }
+
+    public void setTemplateName(String templateName) {
+        this.templateName = templateName;
+    }
+
+    public void next(boolean isNext) {
+        this.isNext = isNext;
+    }
+
+    public void stream(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException, ParseException {
+        try {
+            this.isNext = false;
+            log.info("processor {}",this.getClass().getName());
+            this.process(dataStreamAdapter);
+            if (this.isNext) {
+                if (null != nextProcessor) {
+                    nextProcessor.stream(dataStreamAdapter);
+                }
+            } else {
+                this.backStream(dataStreamAdapter);
+            }
+        }catch (Exception e){
+            throw  e;
+        }
+    }
+
+    private void backStream(DataStreamAdapter dataStreamAdapter) {
+        try {
+            this.close(dataStreamAdapter);
+            if (null != preProcessor) {
+                preProcessor.backStream(dataStreamAdapter);
+            }
+        }catch (Exception e){
+            throw  e;
+        }
+    }
+
+}

+ 52 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/DatagramHelp.java

@@ -0,0 +1,52 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/13
+ */
+package org.ts.ddcs.dataStream;
+
+import com.alibaba.fastjson.JSONObject;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/10/13
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public class DatagramHelp {
+    public static Date getCollectTime(Map<String, List<JSONObject>> keyStore) throws ParseException {
+        List<JSONObject> objs = keyStore.get(SwElementCodeEnum.CODE_TT.getCode());
+        String tm = objs.get(0).getString(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName());
+        SimpleDateFormat strToDateSdf = new SimpleDateFormat("yyyyMMddHHmmss");
+        return strToDateSdf.parse(tm);
+    }
+
+    public static Double getDoubleValue(Map<String, List<JSONObject>> keyStore, String key) {
+        List<JSONObject> objs = keyStore.get(key);
+        if (null != objs&&objs.size()>0) {
+            String value = objs.get(0).getString(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName());
+            return Double.valueOf(value);
+        }
+        return null;
+    }
+
+    public static Long getLongValue(Map<String, List<JSONObject>> keyStore, String key) {
+        List<JSONObject> objs = keyStore.get(key);
+        if (null != objs&&objs.size()>0){
+            String value = objs.get(0).getString(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName());
+            return Long.valueOf(value);
+        }
+        return null;
+    }
+}

+ 79 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/SwDataStreamCache.java

@@ -0,0 +1,79 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/11/11
+ */
+package org.ts.ddcs.dataStream;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+
+/***
+ * Date:2022/11/11
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SwDataStreamCache extends DataStreamCache {
+
+    /**
+     * 包数据
+     */
+    private byte[] packet;
+    /**
+     * 包长度
+     */
+    private int len;
+
+    /**
+     * 命令(HEX_2)
+     */
+    private byte command;
+    /**
+     * 报文头7E7E
+     */
+    private byte[] packetHeader;
+    /**
+     * 中心站地址
+     */
+    private byte[] centerStation;
+    /**
+     * RTU地址
+     */
+    private byte[] rtuCodeByte;
+    /**
+     * RTU密码
+     */
+    private byte[] rtuPw;
+    /**
+     * 功能码
+     */
+    private byte[] funcCode;
+    /**
+     * 报文上下行标识及长度
+     */
+    private byte[] dataAreaLen;
+    /**
+     * 报文起始符
+     */
+    private byte[] dataAreaStartFlag;
+    /**
+     * 报文正文
+     */
+    private byte[] dataArea;
+    /**
+     * 报文起始符
+     */
+    private byte[] dataAreaEndFlag;
+    /**
+     * 校验码
+     */
+    private byte[] packetCrc16;
+
+}

+ 74 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/TcpDataStreamAdapter.java

@@ -0,0 +1,74 @@
+package org.ts.ddcs.dataStream;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.socket.DatagramPacket;
+import lombok.extern.slf4j.Slf4j;
+
+
+/**
+ * created by swp on 2017/8/21
+ * 适配器,用于连接网络通道与数据处理器
+ *
+ * @author dylan
+ */
+@Slf4j
+public class TcpDataStreamAdapter extends DataStreamAdapter {
+
+    public TcpDataStreamAdapter() {
+        super();
+    }
+
+    @Override
+    public void output(byte[] respBody) {
+        if (null != this.ctx) {
+            try {
+                ByteBuf buf = Unpooled.buffer(respBody.length);
+                buf.writeBytes(respBody);
+                ChannelFuture cf = this.ctx.writeAndFlush(buf);
+                cf.addListener(new ChannelFutureListener() {
+                    @Override
+                    public void operationComplete(ChannelFuture channelFuture) throws Exception {
+                        //写操作完成,并没有错误发生
+                        if (channelFuture.isSuccess()) {
+                            log.info("{} tcp writeAndFlush is successful", adapterKey);
+                        } else {
+                            //记录错误
+                            log.error("{} tcp writeAndFlush is error {}",adapterKey, channelFuture.cause().getMessage());
+                        }
+                    }
+                });
+            } catch (Exception e) {
+                log.error(this.getClass().getName(), e);
+            } finally {
+                log.info("{} tcp writeAndFlush to rtuCode {}",adapterKey ,rtuCode);
+            }
+        } else {
+            log.info("{} tcp net channel close",adapterKey );
+        }
+    }
+
+    @Override
+    public void pushData(ByteBuf buf, ChannelHandlerContext cx, DatagramPacket datagramPacket) {
+
+    }
+
+    @Override
+    public void pushData(ByteBuf buf, ChannelHandlerContext cx) {
+        try {
+            this.ctx = cx;
+            int byteSize = buf.readableBytes();
+            if (byteSize > 0) {
+                byte[] block = new byte[byteSize];
+                buf.readBytes(block);
+                this.blockQueue.offer(block);
+                DataStreamManageHolder.newInstance().dataStreamManager.readEvent(this);
+            }
+        } catch (IndexOutOfBoundsException e) {
+            log.error(this.adapterKey, e);
+        }
+    }
+}

+ 82 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/UdpDataStreamAdapter.java

@@ -0,0 +1,82 @@
+package org.ts.ddcs.dataStream;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.socket.DatagramPacket;
+import lombok.extern.slf4j.Slf4j;
+
+import java.net.InetSocketAddress;
+
+
+/**
+ * created by swp on 2017/8/21
+ * 适配器,用于匹配数据模板与数据处理器
+ *
+ * @author dylan
+ */
+@Slf4j
+public class UdpDataStreamAdapter extends DataStreamAdapter {
+
+    private InetSocketAddress socketAddress = null;
+
+    public UdpDataStreamAdapter() {
+        super();
+    }
+
+    @Override
+    public void output(byte[] respBody) {
+        if (null != ctx) {
+            try {
+                ByteBuf buf = Unpooled.buffer(respBody.length);
+                buf.writeBytes(respBody);
+                if (null != socketAddress) {
+                    DatagramPacket datagram = new DatagramPacket(buf, socketAddress);
+                    ChannelFuture cf = this.ctx.writeAndFlush(datagram);
+                    cf.addListener(new ChannelFutureListener() {
+                        @Override
+                        public void operationComplete(ChannelFuture channelFuture) throws Exception {
+                            //写操作完成,并没有错误发生
+                            if (channelFuture.isSuccess()) {
+                                log.info("{} udp writeAndFlush is successful!!", adapterKey);
+                            } else {
+                                //记录错误
+                                log.info("{} udp writeAndFlush is error {}", adapterKey, channelFuture.cause().getMessage());
+                            }
+                        }
+                    });
+                }
+            } catch (Exception e) {
+                log.error(adapterKey, e);
+            } finally {
+                log.info("{} udp output to rtuCode:{} ip:{} port:{}", adapterKey, rtuCode, socketAddress.getHostName(), socketAddress.getPort());
+            }
+        } else {
+            log.info("{} udp ctx is null", adapterKey);
+        }
+    }
+
+    @Override
+    public void pushData(ByteBuf buf, ChannelHandlerContext cx, DatagramPacket datagramPacket) {
+        try {
+            this.ctx = cx;
+            this.socketAddress = new InetSocketAddress(datagramPacket.sender().getAddress(), datagramPacket.sender().getPort());
+            int byteSize = buf.readableBytes();
+            if (byteSize > 0) {
+                byte[] block = new byte[byteSize];
+                buf.readBytes(block);
+                this.blockQueue.offer(block);
+                DataStreamManageHolder.newInstance().dataStreamManager.readEvent(this);
+            }
+        } catch (IndexOutOfBoundsException e) {
+            log.error(this.adapterKey, e);
+        }
+    }
+
+    @Override
+    public void pushData(ByteBuf buf, ChannelHandlerContext cx) {
+
+    }
+}

+ 80 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuDatagramProcessor.java

@@ -0,0 +1,80 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/9/4
+ */
+package org.ts.ddcs.dataStream.processor.dtu;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+
+import java.io.UnsupportedEncodingException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/9/4
+ * Title:数据处理器模块
+ * Description:DTU报文
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamDtuDatagramProcessor extends DataStreamProcessor {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        int count = 0;
+        byte[] addressHeader = new byte[1];
+        addressHeader[0] = this.dataStreamCache.getByte(count);
+        count += 1;
+        String add = BytesHelp.byte2HexStr(addressHeader);
+        if (!add.equals("FA")) {
+            byte[] command = new byte[1];
+            command[0] = this.dataStreamCache.getByte(count);
+            count += 1;
+            int len = (int) this.dataStreamCache.getByte(count);
+            count += 1;
+            byte[] body = this.dataStreamCache.getBytes(count, len);
+            count += len;
+            byte[] crc = this.dataStreamCache.getBytes(count, 2);
+            count += 2;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+}

+ 83 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuLinkDatagramProcessor.java

@@ -0,0 +1,83 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/9/4
+ */
+package org.ts.ddcs.dataStream.processor.dtu;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/9/4
+ * Title:数据处理器模块
+ * Description:DTU报文
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamDtuLinkDatagramProcessor extends DataStreamProcessor {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        int count = 0;
+        byte[] addressHeader = new byte[1];
+        addressHeader[0] = this.dataStreamCache.getByte(count);
+        count += 1;
+        String add = BytesHelp.byte2HexStr(addressHeader);
+        if (add.equals("FA")) {
+            byte[] command = new byte[1];
+            command[0] = this.dataStreamCache.getByte(count);
+            count += 1;
+            int len = (int) this.dataStreamCache.getByte(count);
+            count += 1;
+            byte[] body = this.dataStreamCache.getBytes(count, len);
+            byte[] content = this.dataStreamCache.getBytes(count, 20);
+            byte[] uuid = content;
+            count += 20;
+
+            byte[] crc = this.dataStreamCache.getBytes(count, 2);
+            count += 2;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+}

+ 86 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwConfigDatagramProcessor.java

@@ -0,0 +1,86 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:配置文件更新 0xF4
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwConfigDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_EX_F4.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            count += 2;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            // 发报时间
+            String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            count += 6;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), sendPacketTime);
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        String sendPacketTime = this.dataStreamCache.getStringValue("sendPacketTime");
+        log.info("配置文件更新完成 {} {}", this.dataStreamCache.getRtuCode(), sendPacketTime);
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> list = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        list.add(data);
+        return list;
+    }
+}

+ 100 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwCrcCheckProcessor.java

@@ -0,0 +1,100 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:报文CRC校验处理器
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwCrcCheckProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private boolean crcCehck = false;
+    private byte[] packetCrc16;
+    private byte[] crc16;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        LocalDateTime now = LocalDateTime.now().withNano(0);
+        DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        this.dataStreamCache.setPickPacketTime(now);
+        this.dataStreamCache.setMatchProcessor(this);
+        byte[] datagramBuff = this.dataStreamCache.getDatagramBuff();
+        //校验码,取报文最后两个字节
+        this.packetCrc16 = new byte[2];
+        this.packetCrc16[0] = datagramBuff[datagramBuff.length - 2];
+        this.packetCrc16[1] = datagramBuff[datagramBuff.length - 1];
+        //生成校验码,包体去掉报文最后两个字节
+        this.crc16 = Sw2014DatagramTemplateHelp.crcFun2014(datagramBuff, 0, datagramBuff.length - 2);
+        if (BytesHelp.byte2HexStr(this.packetCrc16).equals(BytesHelp.byte2HexStr(this.crc16))) {
+            this.crcCehck = true;
+            byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+            dataStreamCache.setDatagramCode(BytesHelp.byte2HexStr(funcCodeByte));
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName(), now.format(timeFormat));
+            byte[] rtuCodeByte = dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+            dataStreamCache.setRtuCode(BytesHelp.byte2HexStr(rtuCodeByte));
+            if (null == dataStreamAdapter.getRtuCode()) {
+                dataStreamAdapter.setRtuCode(BytesHelp.byte2HexStr(rtuCodeByte));
+            }
+            this.next(true);
+        } else {
+            this.dataStreamCache.setState(TestState.ERROR);
+            this.dataStreamCache.setMatchProcessor(this);
+            this.crcCehck = false;
+            this.next(false);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        if (!this.crcCehck) {
+            byte[] datagram = this.dataStreamCache.getDatagramBuff();
+            log.info("原始报文 {}", BytesHelp.byte2HexStr(datagram));
+            log.info("报文CRC校验错误 {} {}", BytesHelp.byte2HexStr(this.packetCrc16), BytesHelp.byte2HexStr(this.crc16));
+            dataStreamCache.setReadSize(this.dataStreamCache.getDatagramSize());
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+}

+ 162 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtMatchProcessor.java

@@ -0,0 +1,162 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.List;
+import java.util.Map;
+
+;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description: 报文检测处理器,主要负责检测出一个完整正确的报文
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwExtMatchProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.LOOK);
+        this.dataStreamCache.setMatchProcessor(this);
+        byte[] block = dataStreamAdapter.getBlock();
+        if (block.length == 0) {
+            this.next(false);
+        }
+        this.dataStreamCache.setDataBuff(block);
+        if (dataStreamCache.dataSize() < 2) {
+            this.next(false);
+        }
+        if (dataStreamCache.getByte(0) != 0x7E || dataStreamCache.getByte(1) != 0x7E) {
+            dataStreamCache.setState(TestState.ERROR);
+            this.next(false);
+        }
+        if (dataStreamCache.dataSize() < SwDatagramConstant.FEATURE_WEIGHT) {
+            this.next(false);
+        }
+        // 报文正文长度
+        byte[] dataAreaLen = new byte[2];
+        dataAreaLen[0] = dataStreamCache.getByte(11);
+        dataAreaLen[1] = dataStreamCache.getByte(12);
+        int contentLen = Sw2014DatagramTemplateHelp.getContentLen(dataAreaLen);
+        int datagramSize = 11 + contentLen + 6;
+        if (dataStreamCache.dataSize() < datagramSize) {
+            this.next(false);
+        }
+        dataStreamCache.setDatagramSize(datagramSize);
+        byte[] datagramBuff = dataStreamCache.getBytes(datagramSize);
+        dataStreamCache.setDatagramBuff(datagramBuff);
+        int count = 0;
+        byte[] packetHeader = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PACKET_HEADER.getName(), packetHeader);
+        //中心站地址
+        byte[] centerStation = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName(), centerStation);
+        //RTU地址
+        byte[] rtuCodeByte = BytesHelp.subBytes(datagramBuff, count, 8);
+        count += 8;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName(), rtuCodeByte);
+        //RTU密码
+        byte[] rtuPw = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_PW.getName(), rtuPw);
+        //功能码
+        byte[] funcCode = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName(), funcCode);
+        //byte[] datagramCode = dataStreamCache.getBytes(DatagramConstant.featureWeight - 1, 1);
+        // dataStreamCache.setDatagramCode(BytesHelp.byte2HexStr(funcCode));
+
+        //byte command = funcCode[0];
+        //dataStreamCache.putValue("command", (int) command);
+        //报文上下行标识及长度  高四位用作上下行标识(0000 表示上行,1000,表示下行);
+        //其余12位表示报文正文长度,表示报文起始符之后,报文结束符之前的报文字节数,允许长度为0001-4095
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_LEN.getName(), dataAreaLen);
+        count += 2;
+        //报文起始符
+        byte[] dataAreaStartFlag = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName(), dataAreaStartFlag);
+        //报文正文
+        byte[] dataArea = BytesHelp.subBytes(datagramBuff, count, contentLen);
+        count += contentLen;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName(), dataArea);
+        //报文结束符
+        byte[] dataAreaEndFlag = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_END_FLAG.getName(), dataAreaEndFlag);
+        //校验码
+        byte[] packetCrc16 = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CRC.getName(), packetCrc16);
+        dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
+        dataStreamCache.setState(TestState.MATHCE);
+        this.next(true);
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+//        if (this.dataStreamCache.getState() == TestState.ERROR) {
+//            this.dataStreamCache.setMatchProcessor(this);
+//        }
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        if (dataStreamCache.getState() == TestState.ERROR) {
+            int size = this.dataStreamCache.dataSize();
+            int count = 0;
+            for (int i = 1; i < size; i++) {
+                byte v = dataStreamCache.getByte(i);
+                if (v == 0x7E) {
+                    count = i;
+                    break;
+                }
+            }
+            if (count > 0) {
+                dataStreamCache.setReadSize(count);
+            } else {
+                dataStreamCache.setReadSize(size);
+            }
+        }
+//        else if (dataStreamCache.getState() == TestState.MATHCE) {
+//            dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
+//        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+
+}

+ 304 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtraDatagramProcessor.java

@@ -0,0 +1,304 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据匹配器模块
+ * Description:加加报
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwExtraDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        this.keyStore.clear();
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_33.getName().equals(datagramCode)) {
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //遥测站分类码
+            byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+            //采集时间
+            DataItemTemplate itemTemplateTt = itemTemplateMap.get(SwElementCodeEnum.CODE_TT.getCode());
+            readSize = itemTemplateTt.stream(dataArea, count);
+            if (itemTemplateTt.isMacth()) {
+                itemTemplateTt.saveValue(this.keyStore);
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), itemTemplateTt.getStringValue());
+            }
+            count += readSize;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (true) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                    if (index >= orgLen) {
+                        break;
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到33加加报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String, Object>> elements = this.keyStore.get(key);
+                for (Map<String, Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                if (null != elements) {
+                    data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                }
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        List<JSONObject> datagramList = new LinkedList<>();
+//        JSONObject datagram = new JSONObject();
+//        datagram.put("fromTime", this.dataStreamCache.getPickPacketTime());
+//        try {
+//            datagram.put("tm", DatagramHelp.getCollectTime(this.keyStore));
+//        } catch (ParseException e) {
+//            e.printStackTrace();
+//        }
+//        datagram.put("stcd", this.dataStreamCache.getRtuCode());
+//        String siteKind = this.dataStreamCache.getStringValue("siteKind");
+//        if (DatagramConstant.RTU_KIND_CODE_I.equals(siteKind)) {
+//            //流量站
+//            datagram.put("st", "I");
+//            //累计流量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_ACCF.getName())) {
+//                datagram.put("accf", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_ACCF.getName()));
+//            }
+//            //当前瞬时流速
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_VJ.getName())) {
+//                datagram.put("vj", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_VJ.getName()));
+//            }
+//            //瞬时流量、抽水流量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_Q.getName())) {
+//                datagram.put("q", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_Q.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_H.equals(siteKind)) {
+//            //水位站
+//            datagram.put("st", "H");
+//            //瞬时水位
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_Z.getName())) {
+//                datagram.put("z", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_Z.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_P.equals(siteKind)) {
+//            //气象站
+//            datagram.put("st", "P");
+//            //5 分钟时段降水量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PN05.getName())) {
+//                datagram.put("pn05", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PN05.getName()));
+//            }
+//            //降水量累计值
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PT.getName())) {
+//                datagram.put("pt", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PT.getName()));
+//            }
+//            //瞬时气温
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_AI.getName())) {
+//                datagram.put("ai", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_AI.getName()));
+//            }
+//            //湿度
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_MST.getName())) {
+//                datagram.put("mst", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_MST.getName()));
+//            }
+//            //PM2.5
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PM.getName())) {
+//                datagram.put("pm", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PM.getName()));
+//            }
+//            //气压
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_FL.getName())) {
+//                datagram.put("fl", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_FL.getName()));
+//            }
+//            //风速
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_US.getName())) {
+//                datagram.put("us", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_US.getName()));
+//            }
+//            //风向
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_UC.getName())) {
+//                datagram.put("uc", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_UC.getName()));
+//            }
+//            //紫外线
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_UV.getName())) {
+//                datagram.put("uv", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_UV.getName()));
+//            }
+//            //太阳总辐射
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_RAD.getName())) {
+//                datagram.put("rad", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_RAD.getName()));
+//            }
+//            //二氧化氮
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_ND.getName())) {
+//                datagram.put("nd", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_ND.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_Q.equals(siteKind)) {
+//            //水质站
+//            datagram.put("st", "Q");
+//            //电导率
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_COND.getName())) {
+//                datagram.put("cond", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_COND.getName()));
+//            }
+//            //瞬时水温
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_C.getName())) {
+//                datagram.put("c", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_C.getName()));
+//            }
+//            //PH值
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PH.getName())) {
+//                datagram.put("ph", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PH.getName()));
+//            }
+//        }
+//        datagramList.add(datagram);
+//        return datagramList;
+//    }
+
+}

+ 87 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFileDatagramProcessor.java

@@ -0,0 +1,87 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:多包回报
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwFileDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_EX_F1.getName().equals(datagramCode)) {
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            byte[] packageIndexBuff = BytesHelp.subBytes(dataArea, count, 2);
+            int packageIndex = BytesHelp.bytes2Int(packageIndexBuff, 0, 2);
+            count += 2;
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到F1多包转输");
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+}

+ 296 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFixedTimeDatagramProcessor.java

@@ -0,0 +1,296 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:定时报
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwFixedTimeDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_32.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), "20" + BytesHelp.byte2HexStr(sendPacketTime));
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //遥测站分类码
+            byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+            //采集时间
+            DataItemTemplate itemTemplateTt = itemTemplateMap.get(SwElementCodeEnum.CODE_TT.getCode());
+            readSize = itemTemplateTt.stream(dataArea, count);
+            if (itemTemplateTt.isMacth()) {
+                itemTemplateTt.saveValue(this.keyStore);
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), itemTemplateTt.getStringValue());
+            }
+            count += readSize;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (index < orgLen) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到32定时报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        //   List<Map<String, Object>> elementDataList = new LinkedList<>();
+//        Map<String, Object> datagram = new HashMap<>();
+//        datagram.put("fromTime", this.dataStreamCache.getPickPacketTime());
+//        try {
+//            datagram.put("tm", DatagramHelp.getCollectTime(this.keyStore));
+//        } catch (ParseException e) {
+//            e.printStackTrace();
+//        }
+//        datagram.put("stcd", this.dataStreamCache.getRtuCode());
+//        String siteKind = this.dataStreamCache.getStringValue("siteKind");
+//        if (DatagramConstant.RTU_KIND_CODE_I.equals(siteKind)) {
+//            //流量站
+//            datagram.put("st", "I");
+//            //累计流量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_ACCF.getName())) {
+//                datagram.put("accf", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_ACCF.getName()));
+//            }
+//            //当前瞬时流速
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_VJ.getName())) {
+//                datagram.put("vj", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_VJ.getName()));
+//            }
+//            //瞬时流量、抽水流量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_Q.getName())) {
+//                datagram.put("q", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_Q.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_H.equals(siteKind)) {
+//            //水位站
+//            datagram.put("st", "H");
+//            //瞬时水位
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_Z.getName())) {
+//                datagram.put("z", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_Z.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_P.equals(siteKind)) {
+//            //气象站
+//            datagram.put("st", "P");
+//            //5 分钟时段降水量
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PN05.getName())) {
+//                datagram.put("pn05", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PN05.getName()));
+//            }
+//            //降水量累计值
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PT.getName())) {
+//                datagram.put("pt", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PT.getName()));
+//            }
+//            //瞬时气温
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_AI.getName())) {
+//                datagram.put("ai", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_AI.getName()));
+//            }
+//            //湿度
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_MST.getName())) {
+//                datagram.put("mst", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_MST.getName()));
+//            }
+//            //PM2.5
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PM.getName())) {
+//                datagram.put("pm", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PM.getName()));
+//            }
+//            //气压
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_FL.getName())) {
+//                datagram.put("fl", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_FL.getName()));
+//            }
+//            //风速
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_US.getName())) {
+//                datagram.put("us", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_US.getName()));
+//            }
+//            //风向
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_UC.getName())) {
+//                datagram.put("uc", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_UC.getName()));
+//            }
+//            //紫外线
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_UV.getName())) {
+//                datagram.put("uv", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_UV.getName()));
+//            }
+//            //太阳总辐射
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_RAD.getName())) {
+//                datagram.put("rad", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_RAD.getName()));
+//            }
+//            //二氧化氮
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_ND.getName())) {
+//                datagram.put("nd", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_ND.getName()));
+//            }
+//        } else if (DatagramConstant.RTU_KIND_CODE_Q.equals(siteKind)) {
+//            //水质站
+//            datagram.put("st", "Q");
+//            //电导率
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_COND.getName())) {
+//                datagram.put("cond", DatagramHelp.getLongValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_COND.getName()));
+//            }
+//            //瞬时水温
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_C.getName())) {
+//                datagram.put("c", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_C.getName()));
+//            }
+//            //PH值
+//            if (this.keyStore.containsKey(Sw2014DatagramElementEnum.ELEMENT_PH.getName())) {
+//                datagram.put("ph", DatagramHelp.getDoubleValue(this.keyStore, Sw2014DatagramElementEnum.ELEMENT_PH.getName()));
+//            }
+//        }
+//        elementDataList.add(datagram);
+
+         try {
+             List<Map<String, Object>> elementDataList = new LinkedList<>();
+             Set<String> keys = this.keyStore.keySet();
+             for (String key : keys) {
+                 Map<String, Object> data = new HashMap<>();
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+               //  data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                 // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+               //  data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//                 String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                 if (null != collectTime) {
+//                     data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                 } else {
+//                     data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                 }
+                 //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+               //  data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                 data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                 List<Map<String,Object>> elements = this.keyStore.get(key);
+                 for (Map<String,Object> jsonObject : elements) {
+                     log.info("element {}", JSONObject.toJSONString(jsonObject));
+                 }
+                 if (null != elements) {
+                     data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                 }
+                 elementDataList.add(data);
+             }
+             return elementDataList;
+         }catch (Exception e){
+             return null;
+         }
+    }
+
+}

+ 230 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwHourDatagramProcessor.java

@@ -0,0 +1,230 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:小时报
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwHourDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_34.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getName());
+         //   itemTemplateSt.clear();
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //遥测站分类码
+            byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+            //采集时间
+            DataItemTemplate itemTemplateTt = itemTemplateMap.get(SwElementCodeEnum.CODE_TT.getName());
+          // itemTemplateSt.clear();
+            readSize = itemTemplateTt.stream(dataArea, count);
+            if (itemTemplateTt.isMacth()) {
+                itemTemplateTt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (true) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                       // itemTemplateSt.clear();
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                    if (index >= orgLen) {
+                        break;
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String,Object>> list = this.keyStore.get(key);
+            if (null != list){
+                for (Map<String,Object> jsonObject:list){
+                    log.info("item {} {}",key,JSONObject.toJSONString(jsonObject));
+                }
+            }
+        }
+
+        log.info("接收到34小时报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+              //  data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+               // data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+              //  data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String, Object>> elements = this.keyStore.get(key);
+                for (Map<String, Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                if (null != elements) {
+                    data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                }
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        List<JSONObject> datas = new LinkedList<>();
+//        JSONObject body = new JSONObject();
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM, BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        body.put(DatagramPostEntityConstant.BASE_KEY_RTU, dataStreamAdapter.getRtuCode());
+//        body.put(DatagramPostEntityConstant.BASE_KEY_AGREEMENT, DatagramPostEntityConstant.AGREEMENT_KIND_SW);
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM_PICK_TM, this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//        datas.add(body);
+//        return datas;
+//    }
+
+}

+ 192 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwImageDatagramProcessor.java

@@ -0,0 +1,192 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+
+import java.io.UnsupportedEncodingException;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:图片报 0x36
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwImageDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+    private int packpagSize;
+    private int packpageCount;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_36.getName().equals(datagramCode)) {
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            byte[] packIndex = BytesHelp.subBytes(dataArea, count, 3);
+            int indexValue = BytesHelp.bytes2Int(packIndex, 0, 3);
+            this.packpagSize = (indexValue >> 12) & 0x0FFF;
+            this.packpageCount = indexValue & 0x0FFF;
+            count += 3;
+            if (packpageCount == 1) {
+                //流水号
+                byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+                count += 2;
+                //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+                // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+                // 发报时间
+                byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+                count += 6;
+                //遥测站地址
+                DataItemTemplate itemTemplateSt = itemTemplateMap.get("F1");
+               // itemTemplateSt.clear();
+                int readSize = itemTemplateSt.stream(dataArea, count);
+                if (itemTemplateSt.isMacth()) {
+                    itemTemplateSt.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //遥测站分类码
+                byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+                count += 1;
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+                //采集时间
+                DataItemTemplate itemTemplateTt = itemTemplateMap.get("F0");
+               // itemTemplateSt.clear();
+                readSize = itemTemplateTt.stream(dataArea, count);
+                if (itemTemplateSt.isMacth()) {
+                    itemTemplateSt.saveValue(this.keyStore);
+                }
+                count += readSize;
+                dataStreamAdapter.putValue("packpagSize", packpagSize);
+                if (dataArea.length - count > 0) {
+                    count += 2;
+                    if (dataArea.length - count > 0) {
+                        byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                        if (null != imageData && imageData.length > 0) {
+                            dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
+                        }
+                    }
+                }
+            } else if (packpagSize == packpageCount) {
+                if (dataArea.length - count > 0) {
+                    byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                    if (null != imageData && imageData.length > 0) {
+                        dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
+                    }
+                }
+            } else {
+                if (dataArea.length - count > 0) {
+                    byte[] imageData = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                    if (null != imageData && imageData.length > 0) {
+                        dataStreamAdapter.putValue(String.format("imageData%d", packpageCount), imageData);
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到36图片报,回复报文");
+        byte[] respPacket = new byte[2];
+        //帧起始符
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] ps = new byte[1];
+        ps[0] = 0x02;
+        respPacket = BytesHelp.arrayApend(respPacket, ps);
+
+       // byte[] packIndex = BytesHelp.subBytes(packetContext, 14, 3);
+        //int indexValue = BytesHelp.bytes2Int(packIndex, 0, 3);
+       // int total = (indexValue >> 12) & 0x0FFF;
+      //  int count = indexValue & 0x0FFF;
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        if (this.packpageCount == 1) {
+            ps[0] = 0x05;
+            respPacket = BytesHelp.arrayApend(respPacket, ps);
+        } else if (this.packpagSize == this.packpageCount) {
+            ps[0] = 0x05;
+            respPacket = BytesHelp.arrayApend(respPacket, ps);
+        } else {
+            ps[0] = 0x05;
+            respPacket = BytesHelp.arrayApend(respPacket, ps);
+        }
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+
+
+}

+ 89 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwLinkHeartProcessor.java

@@ -0,0 +1,89 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.text.ParseException;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:链路报 0x2F
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwLinkHeartProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws ParseException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_2F.getName().equals(datagramCode)) {
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            // 发报时间
+            byte[] sendPacketTimeBuff = BytesHelp.subBytes(dataArea, count, 6);
+            String sendPacketTime = "20" + BytesHelp.byte2HexStr(sendPacketTimeBuff);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), sendPacketTime);
+            count += 6;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+      //  SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+       // String sendPacketTime = (String) this.dataStreamCache.getValue(DatagramConstant.sendPacketTime);
+       // String pickPacketTime = (String) this.dataStreamCache.getValue(DatagramConstant.pickPacketTime);
+      //  Date st = timeFormat.parse(sendPacketTime);
+       // Date pt = timeFormat.parse(pickPacketTime);
+       // SimpleDateFormat timeFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+       // log.info("接收到2F报文 发报时间:{} 接收时间:{}", timeFormat2.format(st), timeFormat2.format(pt));
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> elementDataList = new ArrayList<>(0);
+        return elementDataList;
+    }
+
+
+}

+ 156 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwMatchProcessor.java

@@ -0,0 +1,156 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.List;
+import java.util.Map;;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description: 报文检测处理器,主要负责检测出一个完整正确的报文
+ * @author dylan
+ * @mender:(文件的修改者,文件创建者之外的人)
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwMatchProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.LOOK);
+        this.dataStreamCache.setMatchProcessor(this);
+        byte[] block = dataStreamAdapter.getBlock();
+        if (block.length == 0) {
+            this.next(false);
+        }
+        this.dataStreamCache.setDataBuff(block);
+        if (dataStreamCache.dataSize() < 2) {
+            this.next(false);
+        }
+        if (dataStreamCache.getByte(0) != 0x7E || dataStreamCache.getByte(1) != 0x7E) {
+            dataStreamCache.setState(TestState.ERROR);
+            this.next(false);
+        }
+        if (dataStreamCache.dataSize() < SwDatagramConstant.FEATURE_WEIGHT) {
+            this.next(false);
+        }
+//        if (dataStreamCache.dataSize() < 13) {
+//            this.next(false);
+//        }
+        // 报文正文长度
+        byte[] dataAreaLen = new byte[2];
+        dataAreaLen[0] = dataStreamCache.getByte(11);
+        dataAreaLen[1] = dataStreamCache.getByte(12);
+        int contentLen = Sw2014DatagramTemplateHelp.getContentLen(dataAreaLen);
+        int datagramSize = 11 + contentLen + 6;
+        if (dataStreamCache.dataSize() < datagramSize) {
+            this.next(false);
+        }
+        dataStreamCache.setDatagramSize(datagramSize);
+        byte[] datagramBuff = dataStreamCache.getBytes(datagramSize);
+        dataStreamCache.setDatagramBuff(datagramBuff);
+        int count = 0;
+        byte[] packetHeader = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PACKET_HEADER.getName(), packetHeader);
+        //中心站地址
+        byte[] centerStation = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName(), centerStation);
+        //RTU地址
+        byte[] rtuCodeByte = BytesHelp.subBytes(datagramBuff, count, 5);
+        count += 5;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName(), rtuCodeByte);
+        //RTU密码
+        byte[] rtuPw = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_PW.getName(), rtuPw);
+        //功能码
+        byte[] funcCode = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName(), funcCode);
+        //byte[] datagramCode = dataStreamCache.getBytes(DatagramConstant.featureWeight - 1, 1);
+        // dataStreamCache.setDatagramCode(BytesHelp.byte2HexStr(funcCode));
+
+        //byte command = funcCode[0];
+        //dataStreamCache.putValue("command", (int) command);
+        //报文上下行标识及长度  高四位用作上下行标识(0000 表示上行,1000,表示下行);
+        //其余12位表示报文正文长度,表示报文起始符之后,报文结束符之前的报文字节数,允许长度为0001-4095
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_LEN.getName(), dataAreaLen);
+        count += 2;
+        //报文起始符
+        byte[] dataAreaStartFlag = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName(), dataAreaStartFlag);
+        //报文正文
+        byte[] dataArea = BytesHelp.subBytes(datagramBuff, count, contentLen);
+        count += contentLen;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName(), dataArea);
+        //报文结束符
+        byte[] dataAreaEndFlag = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA_END_FLAG.getName(), dataAreaEndFlag);
+        //校验码
+        byte[] packetCrc16 = BytesHelp.subBytes(datagramBuff, count, 2);
+        count += 2;
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CRC.getName(), packetCrc16);
+        dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
+        dataStreamCache.setState(TestState.MATHCE);
+        this.next(true);
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        if (dataStreamCache.getState() == TestState.ERROR) {
+            int size = this.dataStreamCache.dataSize();
+            int count = 0;
+            for (int i = 1; i < size; i++) {
+                byte v = dataStreamCache.getByte(i);
+                if (v == 0x7E) {
+                    count = i;
+                    break;
+                }
+            }
+            if (count > 0) {
+                dataStreamCache.setReadSize(count);
+            } else {
+                dataStreamCache.setReadSize(size);
+            }
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+
+}

+ 316 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadRunSettingDatagramProcessor.java

@@ -0,0 +1,316 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.common.dict.RunSettingFlag;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.StringUtil;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:读取运行参数回报 0x43
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwReadRunSettingDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_43.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+            //itemTemplateSt.clear();
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            while (count < dataArea.length) {
+
+                byte[] f = BytesHelp.subBytes(dataArea, count, 1);
+                count += 1;
+                String flagCode = BytesHelp.byte2HexStr(f);
+                ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(dataArea, count);
+                int dataTotalLen = valueLen.getByteLen();
+                int decimalLen = valueLen.getDecimalLen();
+                count += 1;
+                byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                count += dataTotalLen;
+                if (flagCode.equals(RunSettingFlag.intervalTime.getId())) {
+                    //定时报时间间隔
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "intervalTime");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), BytesHelp.byte2HexStr(value));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.intervalTime.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("intervalTime", list);
+                } else if (flagCode.equals(RunSettingFlag.addIntervalTime.getId())) {
+                    //加报时间间隔
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "addIntervalTime");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), StringUtil.getPrettyNumber(BytesHelp.byte2HexStr(value)));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.addIntervalTime.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("addIntervalTime", list);
+                } else if (flagCode.equals(RunSettingFlag.rainTime.getId())) {
+                    //降水量日起始时间
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "rainTime");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), StringUtil.getPrettyNumber(BytesHelp.byte2HexStr(value)));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.rainTime.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("rainTime", list);
+                } else if (flagCode.equals(RunSettingFlag.collectInterval.getId())) {
+                    //采样间隔
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "collectInterval");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), StringUtil.getPrettyNumber(BytesHelp.byte2HexStr(value)));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.collectInterval.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("collectInterval", list);
+                } else if (flagCode.equals(RunSettingFlag.dataSaveInterval.getId())) {
+                    //水位数据存储间隔
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "dataSaveInterval");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), StringUtil.getPrettyNumber(BytesHelp.byte2HexStr(value)));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.dataSaveInterval.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("dataSaveInterval", list);
+                } else if (flagCode.equals(RunSettingFlag.rainAddValue.getId())) {
+                    //雨量加报阈值
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "rainAddValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), StringUtil.getPrettyNumber(BytesHelp.byte2HexStr(value)));
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.rainAddValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("rainAddValue", list);
+                } else if (flagCode.equals(RunSettingFlag.waterLevelBase.getId())) {
+                    //水位基值1
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "waterLevelBase");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.waterLevelBase.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("waterLevelBase", list);
+                } else if (flagCode.equals(RunSettingFlag.waterLevelCorrectValue.getId())) {
+                    //水位修正基值1
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "waterLevelCorrectValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.waterLevelCorrectValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("waterLevelCorrectValue", list);
+                } else if (flagCode.equals(RunSettingFlag.addWaterLevel.getId())) {
+                    //加报水位1
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "addWaterLevel");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.addWaterLevel.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("addWaterLevel", list);
+                } else if (flagCode.equals(RunSettingFlag.addWaterUpValue.getId())) {
+                    //加报水位以上加报阈值
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "addWaterUpValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.addWaterUpValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("addWaterUpValue", list);
+                } else if (flagCode.equals(RunSettingFlag.addWaterDownValue.getId())) {
+                    //加报水位以下加报阈值
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "addWaterDownValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.addWaterDownValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("addWaterDownValue", list);
+                } else if (flagCode.equals(RunSettingFlag.flowValue.getId())) {
+                    //流量加报阈值
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "flowValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.flowValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("flowValue", list);
+                } else if (flagCode.equals(RunSettingFlag.flowSpeetValue.getId())) {
+                    //流速加报阈值
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "flowSpeetValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.flowSpeetValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("flowSpeetValue", list);
+                } else if (flagCode.equals(RunSettingFlag.waterGateValue.getId())) {
+                    //闸位加报阀值
+                    Map<String, Object> data = new HashMap<>();
+                    BigDecimal dec = BytesHelp.toDecimal(BytesHelp.byte2HexStr(value), decimalLen);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), "waterGateValue");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), dec.toPlainString());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), RunSettingFlag.waterGateValue.getId());
+                    List<Map<String, Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put("waterGateValue", list);
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+
+        log.info("接收到43读取运行参数,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                if (null != elements) {
+                    data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                }
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

+ 420 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadSettingDatagramProcessor.java

@@ -0,0 +1,420 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.common.dict.BaseSettingFlag;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:读取基本参数回报 0x41
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwReadSettingDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_41.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+           // itemTemplateSt.clear();
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+
+            while (true) {
+                if (count >= dataArea.length) {
+                    break;
+                }
+                byte[] f = BytesHelp.subBytes(dataArea, count, 1);
+                count += 1;
+                String flagCode = BytesHelp.byte2HexStr(f);
+                ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(dataArea, count);
+                int dataTotalLen = valueLen.getByteLen();
+                int decimalLen = valueLen.getDecimalLen();
+                count += 1;
+
+                if (flagCode.equals(BaseSettingFlag.CENTER_ADD.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.RTU_CODE.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    data.put("rtucode", BytesHelp.byte2HexStr(value));
+                    data.put("code", BaseSettingFlag.RTU_CODE.getId());
+                    List<Map<String,Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put(BaseSettingFlag.RTU_CODE.getId(), list);
+                } else if (flagCode.equals(BaseSettingFlag.PASSWORD.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.IP1.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (value[0] != 0x00) {
+                        data.put("ip1", BytesHelp.toIp(BytesHelp.subBytes(value, 1, 6)));
+                        data.put("ip1port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 7, 3)))));
+                        data.put("code", BaseSettingFlag.IP1.getId());
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP1.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP1_SUB.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.IP2.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (value[0] != 0x00) {
+                        data.put("ip2", BytesHelp.toIp(BytesHelp.subBytes(value, 1, 6)));
+                        data.put("ip2port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 7, 3)))));
+                        data.put("code", BaseSettingFlag.IP2.getId());
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP2.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP2_SUB.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.IP3.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (value[0] != 0x00) {
+                        data.put("ip3", BytesHelp.toIp(BytesHelp.subBytes(value, 1, 6)));
+                        data.put("ip3port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 7, 3)))));
+                        data.put("code", BaseSettingFlag.IP3.getId());
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP3.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP3_SUB.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.IP4.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (value[0] != 0x00) {
+                        data.put("ip4", BytesHelp.toIp(BytesHelp.subBytes(value, 1, 6)));
+                        data.put("ip4port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 7, 3)))));
+                        data.put("code", BaseSettingFlag.IP4.getId());
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP4.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP4_SUB.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals("34")) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, 39);
+                    String ipText = BytesHelp.bytes2String(value, 0, value.length);
+                    count += 39;
+                    byte[] port = BytesHelp.subBytes(dataArea, count, 2);
+                    String portText = "" + BytesHelp.bytes2short(port);
+                    count += 2;
+                    if (null != portText && !portText.equals("0")) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip1", ipText);
+                        data.put("ip1port", portText);
+                        data.put("code", "34");
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put("34", list);
+                    }
+                } else if (flagCode.equals("35")) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, 39);
+                    String ipText = BytesHelp.bytes2String(value, 0, value.length);
+                    count += 39;
+                    byte[] port = BytesHelp.subBytes(dataArea, count, 2);
+                    String portText = "" + BytesHelp.bytes2short(port);
+                    count += 2;
+                    if (null != portText && !portText.equals("0")) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip2", ipText);
+                        data.put("ip2port", portText);
+                        data.put("code", "35");
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put("35", list);
+                    }
+                } else if (flagCode.equals("36")) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, 39);
+                    String ipText = BytesHelp.bytes2String(value, 0, value.length);
+                    count += 39;
+                    byte[] port = BytesHelp.subBytes(dataArea, count, 2);
+                    String portText = "" + BytesHelp.bytes2short(port);
+                    count += 2;
+                    if (null != portText && !portText.equals("0")) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip3", ipText);
+                        data.put("ip3port", portText);
+                        data.put("code", "36");
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put("36", list);
+                    }
+                } else if (flagCode.equals("37")) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, 39);
+                    String ipText = BytesHelp.bytes2String(value, 0, value.length);
+                    count += 39;
+                    byte[] port = BytesHelp.subBytes(dataArea, count, 2);
+                    String portText = "" + BytesHelp.bytes2short(port);
+                    count += 2;
+                    if (null != portText && !portText.equals("0")) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip4", ipText);
+                        data.put("ip4port", portText);
+                        data.put("code", "37");
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put("37", list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.WORK_TYPE.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.COLLECT_SETTING.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    if (value.length == 8) {
+                        Map<String,Object> data = new HashMap<>();
+                        for (int i = 0; i < 8; i++) {
+                            String binStr = BytesHelp.BytesToBinStr(BytesHelp.subBytes(value, i, 1));
+                            binStr = new StringBuilder(binStr).reverse().toString();
+                            for (int j = 0; j < 8; j++) {
+                                String key = "G_" + String.format("%02d", i) + "_V_" + String.format("%02d", j);
+                                data.put(key, binStr.substring(j, j + 1));
+                            }
+                        }
+                        data.put("code", BaseSettingFlag.COLLECT_SETTING.getId());
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.COLLECT_SETTING.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.SERVER_ADD.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.DEVICE_ID.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+
+                } else if (flagCode.equals(BaseSettingFlag.WORK_MODEL.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (value[0] == 0x00) {
+                        data.put("workModel", "0");
+                    } else {
+                        data.put("workModel", "1");
+                    }
+                    data.put("code", BaseSettingFlag.WORK_MODEL.getId());
+                    List<Map<String,Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put(BaseSettingFlag.WORK_MODEL.getId(), list);
+                } else if (flagCode.equals(BaseSettingFlag.RTU_KIND.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    data.put("code", BaseSettingFlag.RTU_KIND.getId());
+                    if (value[0] == 0x50) {
+                        data.put("rtuKind", "P");
+                    } else if (value[0] == 0x48) {
+                        data.put("rtuKind", "H");
+                    } else if (value[0] == 0x4B) {
+                        data.put("rtuKind", "K");
+                    } else if (value[0] == 0x5A) {
+                        data.put("rtuKind", "Z");
+                    } else if (value[0] == 0x44) {
+                        data.put("rtuKind", "D");
+                    } else if (value[0] == 0x54) {
+                        data.put("rtuKind", "T");
+                    } else if (value[0] == 0x4D) {
+                        data.put("rtuKind", "M");
+                    } else if (value[0] == 0x47) {
+                        data.put("rtuKind", "G");
+                    } else if (value[0] == 0x51) {
+                        data.put("rtuKind", "Q");
+                    } else if (value[0] == 0x49) {
+                        data.put("rtuKind", "I");
+                    } else if (value[0] == 0x4F) {
+                        data.put("rtuKind", "O");
+                    }
+                    List<Map<String,Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put(BaseSettingFlag.RTU_KIND.getId(), list);
+                } else if (flagCode.equals(BaseSettingFlag.RAIN_PERCEN.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    data.put("code", BaseSettingFlag.RAIN_PERCEN.getId());
+                    data.put("rainPercenValue", BytesHelp.byte2HexStr(value).substring(1, 2));
+                    List<Map<String,Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put(BaseSettingFlag.RAIN_PERCEN.getId(), list);
+                } else if (flagCode.equals(BaseSettingFlag.BLUETOOTH.getId())) {
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    data.put("code", BaseSettingFlag.BLUETOOTH.getId());
+                    data.put("bluetoothValue", BytesHelp.byte2HexStr(value).substring(1, 2));
+                    List<Map<String,Object>> list = new ArrayList<>();
+                    list.add(data);
+                    this.keyStore.put(BaseSettingFlag.BLUETOOTH.getId(), list);
+                } else {
+                    count += dataTotalLen;
+                }
+            }
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到41读取基本参数,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+               // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                if (null != elements) {
+                    data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                }
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+}

+ 88 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRebootDatagramProcessor.java

@@ -0,0 +1,88 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.ArrayList;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:测站重启回报 0xF3
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwRebootDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_EX_F3.getName().equals(datagramCode)) {
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到f3重启");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> elementDataList = new ArrayList<>(0);
+        return elementDataList;
+    }
+
+}

+ 195 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRgzsDatagramProcessor.java

@@ -0,0 +1,195 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:测试报 0x30
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwRgzsDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context =context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_35.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (true) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        int readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                    if (index >= orgLen) {
+                        break;
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String,Object>> list = this.keyStore.get(key);
+            if (null != list){
+                for (Map<String,Object> jsonObject:list){
+                    log.info("item {} {}",key,JSONObject.toJSONString(jsonObject));
+                }
+            }
+        }
+
+        log.info("接收到35 人工置数报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+                //data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+               // data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+              //  data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+
+                    data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+
+                elementDataList.add(data);
+            }
+           return elementDataList;
+        } catch (Exception e) {
+           return null;
+        }
+    }
+
+}

+ 174 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwStatusDatagramProcessor.java

@@ -0,0 +1,174 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:测站状态扩展报 0xF5
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwStatusDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_EX_F5.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            int readSize = 0;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (true) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        //  itemTemplate.clear();
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                    if (index >= orgLen) {
+                        break;
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String,Object>> list = this.keyStore.get(key);
+            if (null != list) {
+                for (Map<String,Object> jsonObject : list) {
+                    log.info("item {} {}", key, JSONObject.toJSONString(jsonObject));
+                }
+            }
+        }
+
+        log.info("接收到f5状态报");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+                //  data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+
+                //  data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+                //  data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        List<JSONObject> datas = new LinkedList<>();
+//        JSONObject body = new JSONObject();
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM, BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        body.put(DatagramPostEntityConstant.BASE_KEY_RTU, dataStreamAdapter.getRtuCode());
+//        body.put(DatagramPostEntityConstant.BASE_KEY_AGREEMENT, DatagramPostEntityConstant.AGREEMENT_KIND_SW);
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM_PICK_TM, this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//        datas.add(body);
+//        return datas;
+//    }
+
+}

+ 227 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTestDatagramProcessor.java

@@ -0,0 +1,227 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:测试报 0x30
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwTestDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_30.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //遥测站分类码
+            byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+            //采集时间
+            DataItemTemplate itemTemplateTt = itemTemplateMap.get(SwElementCodeEnum.CODE_TT.getCode());
+            readSize = itemTemplateTt.stream(dataArea, count);
+            if (itemTemplateTt.isMacth()) {
+                itemTemplateTt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (true) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                    if (index >= orgLen) {
+                        break;
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String,Object>> list = this.keyStore.get(key);
+            if (null != list) {
+                for (Map<String,Object> jsonObject : list) {
+                    log.info("item {} {}", key, JSONObject.toJSONString(jsonObject));
+                }
+            }
+        }
+
+        log.info("接收到30测试报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        List<JSONObject> datas = new LinkedList<>();
+//        JSONObject body = new JSONObject();
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM, BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        body.put(DatagramPostEntityConstant.BASE_KEY_RTU, dataStreamAdapter.getRtuCode());
+//        body.put(DatagramPostEntityConstant.BASE_KEY_AGREEMENT, DatagramPostEntityConstant.AGREEMENT_KIND_SW);
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM_PICK_TM, this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//        datas.add(body);
+//        return datas;
+//    }
+
+}

+ 238 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTimeIntervalDatagramProcessor.java

@@ -0,0 +1,238 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.SwDatagramConstant;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SwDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description:均匀时段降水信息报 0x31
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwTimeIntervalDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SwDatagramTypeCodeEnum.DATAGRAM_CODE_31.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //流水号
+            byte[] serialNo = BytesHelp.subBytes(dataArea, count, 2);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName(), serialNo);
+            count += 2;
+            //String serialNo = Sw2014DatagramTemplateHelp.toSerialNo(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.serialNo, serialNo);
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            //String sendPacketTime = Sw2014DatagramTemplateHelp.toSendPacketTime(dataArea, count);
+            // dataStreamCache.putValue(DatagramConstant.sendPacketTime, sendPacketTime);
+            //遥测站地址
+            DataItemTemplate itemTemplateSt = itemTemplateMap.get(SwElementCodeEnum.CODE_ST.getCode());
+            int readSize = itemTemplateSt.stream(dataArea, count);
+            if (itemTemplateSt.isMacth()) {
+                itemTemplateSt.saveValue(this.keyStore);
+            }
+            count += readSize;
+            //遥测站分类码
+            byte[] siteKind = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName(), BytesHelp.byte2HexStr(siteKind));
+            //采集时间
+            DataItemTemplate itemTemplateTt = itemTemplateMap.get(SwElementCodeEnum.CODE_TT.getCode());
+            readSize = itemTemplateTt.stream(dataArea, count);
+            if (itemTemplateTt.isMacth()) {
+                itemTemplateTt.saveValue(this.keyStore);
+            }
+            count += readSize;
+
+            int mValue = 0;
+            DataItemTemplate dataItemTemplateDRxnn = itemTemplateMap.get(SwElementCodeEnum.CODE_DRxnn.getCode());
+            readSize = dataItemTemplateDRxnn.stream(dataArea, count);
+            if (dataItemTemplateDRxnn.isMacth()) {
+                byte[] valueBuff = dataItemTemplateDRxnn.getValueBuff();
+                mValue = valueBuff[2];
+            }
+            count += readSize;
+            if (mValue == 5) {
+                //只处理5分钟时段数据
+                //解析观测要素
+                if (dataArea.length - count > 0) {
+                    byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                    int index = 0;
+                    int orgLen = content.length;
+                    while (true) {
+                        String func = BytesHelp.byte2HexStr(content, index, 1);
+                        int funcLen = 0;
+                        if ("FF".equals(func.toUpperCase())) {
+                            func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                            funcLen = 2;
+                        } else {
+                            funcLen = 1;
+                        }
+                        if (itemTemplateMap.containsKey(func)) {
+                            DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                            readSize = itemTemplate.stream(content, index);
+                            index += readSize;
+                            if (itemTemplate.isMacth()) {
+                                itemTemplate.saveValue(this.keyStore);
+                            }
+                        } else {
+                            index += funcLen;
+                            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                            index += 1;
+                            index += valueLen.getByteLen() * 12;
+                        }
+                        if (index >= orgLen) {
+                            break;
+                        }
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String,Object>> list = this.keyStore.get(key);
+            if (null != list) {
+                for (Map<String,Object> jsonObject : list) {
+                    log.info("item {} {}", key, JSONObject.toJSONString(jsonObject));
+                }
+            }
+        }
+        log.info("接收到31均匀时段水文信息报,回复报文");
+        //帧起始符
+        byte[] respPacket = new byte[2];
+        respPacket[0] = 0x7e;
+        respPacket[1] = 0x7e;
+        //遥测站地址
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuCodeByte);
+        //中心站地址
+        byte[] centerStationByte =  this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CENTER_STATION_CODE.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, centerStationByte);
+        //密码
+        byte[] rtuPwByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_PW.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, rtuPwByte);
+        //功能码
+        byte[] funcCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SW_AFN.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, funcCodeByte);
+        //报文下行标识及长度
+        respPacket = BytesHelp.arrayApend(respPacket, BytesHelp.hexStr2Bytes("8008"));
+        //报文起始符
+        byte[] dataAreaStartFlagByte =this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA_START_FLAG.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, dataAreaStartFlagByte);
+        //流水号
+        byte[] serialNoByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_SERIAL_NO.getName());
+        respPacket = BytesHelp.arrayApend(respPacket, serialNoByte);
+        //发报时间
+        respPacket = BytesHelp.arrayApend(respPacket, Sw2014DatagramTemplateHelp.getFBTm());
+        //RTU2014年报文正文结束符
+        respPacket = BytesHelp.arrayApend(respPacket, SwDatagramConstant.PACKET_CONTROL_FLAG_ESC);
+        //CRC16
+        byte[] crc16 = Sw2014DatagramTemplateHelp.crcFun2014(respPacket);
+        respPacket = BytesHelp.arrayApend(respPacket, crc16);
+        dataStreamAdapter.output(respPacket);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        try {
+            List<Map<String, Object>> elementDataList = new LinkedList<>();
+            Set<String> keys = this.keyStore.keySet();
+            for (String key : keys) {
+                Map<String, Object> data = new HashMap<>();
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+                // data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+                // data.put(SinkJsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//                data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//
+//                String collectTime = this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//                if (null != collectTime) {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), collectTime);
+//                } else {
+//                    data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), DatagramHelp.getCollectTime(this.keyStore));
+//                }
+                //  data.put(SinkJsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+                //   data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+                data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+                List<Map<String,Object>> elements = this.keyStore.get(key);
+                for (Map<String,Object> jsonObject : elements) {
+                    log.info("element {}", JSONObject.toJSONString(jsonObject));
+                }
+                data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+                elementDataList.add(data);
+            }
+            return elementDataList;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        List<JSONObject> datas = new LinkedList<>();
+//        JSONObject body = new JSONObject();
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM, BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        body.put(DatagramPostEntityConstant.BASE_KEY_RTU, dataStreamAdapter.getRtuCode());
+//        body.put(DatagramPostEntityConstant.BASE_KEY_AGREEMENT, DatagramPostEntityConstant.AGREEMENT_KIND_SW);
+//        body.put(DatagramPostEntityConstant.BASE_KEY_DATAGRAM_PICK_TM, this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//        datas.add(body);
+//        return datas;
+//    }
+
+}

+ 62 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwUnknownProcessor.java

@@ -0,0 +1,62 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:数据处理器模块
+ * Description: 未定义报文处理器
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwUnknownProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setMatchProcessor(this);
+        this.dataStreamCache.setState(TestState.UNKNOWN);
+
+        this.next(false);
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        byte[] datagram = this.dataStreamCache.getDatagramBuff();
+        log.info("未知报文 {}", BytesHelp.byte2HexStr(datagram));
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+}

+ 91 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyCrcCheckProcessor.java

@@ -0,0 +1,91 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源报文CRC校验处理器
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyCrcCheckProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private boolean crcCehck = false;
+    private byte[] packetCrc;
+    private byte[] crc;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        LocalDateTime now =LocalDateTime.now().withNano(0);
+        DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        this.dataStreamCache.setPickPacketTime(now);
+        this.dataStreamCache.setMatchProcessor(this);
+        byte[] datagramBuff = this.dataStreamCache.getDatagramBuff();
+        this.packetCrc = new byte[1];
+        this.packetCrc[0] = BytesHelp.GetCRCByte(BytesHelp.subBytes(datagramBuff, 3, datagramBuff.length - 5));
+        this.crc = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_CRC.getName());
+        if (this.packetCrc[0] == this.crc[0]) {
+            this.crcCehck = true;
+            byte[] funcCodeByte = (byte[]) dataStreamCache.getValue(DataStreamCacheMetadata.METADATA_SZY_AFN.getName());
+            dataStreamCache.setDatagramCode(BytesHelp.byte2HexStr(funcCodeByte));
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName(), now.format(timeFormat));
+            byte[] rtuCodeByte = (byte[]) dataStreamCache.getValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+            dataStreamCache.setRtuCode(BytesHelp.byte2HexStr(rtuCodeByte));
+            if (null == dataStreamAdapter.getRtuCode()) {
+                dataStreamAdapter.setRtuCode(dataStreamCache.getRtuCode());
+            }
+            this.next(true);
+        } else {
+            this.dataStreamCache.setState(TestState.ERROR);
+            this.dataStreamCache.setMatchProcessor(this);
+            this.crcCehck = false;
+            this.next(false);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        if (!this.crcCehck) {
+            byte[] datagram = this.dataStreamCache.getDatagramBuff();
+            log.info("原始报文 {}", BytesHelp.byte2HexStr(datagram));
+            log.info("报文CRC校验错误 {} {}", BytesHelp.byte2HexStr(this.packetCrc), BytesHelp.byte2HexStr(this.crc));
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+
+        return null;
+    }
+
+}

+ 77 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtConfigFileDatagramProcessor.java

@@ -0,0 +1,77 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 发送升级配置文件 0xF4
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtConfigFileDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_F4.getName().equals(datagramCode)) {
+            byte[] dataArea = dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //byte[] packageIndexBuff= BytesHelp.subBytes(this.dataArea, count, 2);
+            //this.packageIndex = BytesHelp.bytes2Int(packageIndexBuff,0,2);
+            count += 2;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 F4 发送升级配置文件");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 80 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtFileDatagramProcessor.java

@@ -0,0 +1,80 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 文件下发 0xF1
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtFileDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_F1.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            byte[] packageIndexBuff = BytesHelp.subBytes(dataArea, count, 2);
+            int packageIndex = BytesHelp.bytes2Int(packageIndexBuff, 0, 2);
+            count += 2;
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 F1 文件下发");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 77 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtLinkHeartDatagramProcessor.java

@@ -0,0 +1,77 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:扩展链接报 0xE1
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtLinkHeartDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_E1.getName().equals(datagramCode)) {
+            byte[] dataArea = dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 E1 扩展链接报");
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 196 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtReadIpDatagramProcessor.java

@@ -0,0 +1,196 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.dict.BaseSettingFlag;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 读取遥测站IP和端口 0xE8
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtReadIpDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_E8.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            while (count < dataArea.length) {
+                byte[] flagCodeBuff = BytesHelp.subBytes(dataArea, count, 1);
+                count += 1;
+                String flagCode = BytesHelp.byte2HexStr(flagCodeBuff);
+                if (flagCode.equals(BaseSettingFlag.CENTER_ADD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.RTU_CODE.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.PASSWORD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.IP1.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    if (kind[0] != 0x00) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP1.getId(),list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP1_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP2.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP2.getId(),list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP2_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP3.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP3.getId(),list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP3_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP4.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP4.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP4_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.WORK_TYPE.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.COLLECT_SETTING.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.SERVER_ADD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.DEVICE_ID.getId())) {
+
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 E8 读取遥测站IP和端口");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 77 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtRebootDatagramProcessor.java

@@ -0,0 +1,77 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 重启 0xF3
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtRebootDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_90.getName().equals(datagramCode)) {
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 F3 重启");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 195 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtSetIpDatagramProcessor.java

@@ -0,0 +1,195 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.dict.BaseSettingFlag;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 中心站设置遥测站IP和端口 0xE7
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtSetIpDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String,Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_82.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            while (count < dataArea.length) {
+                byte[] flagCodeBuff = BytesHelp.subBytes(dataArea, count, 1);
+                count += 1;
+                String flagCode = BytesHelp.byte2HexStr(flagCodeBuff);
+                if (flagCode.equals(BaseSettingFlag.CENTER_ADD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.RTU_CODE.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.PASSWORD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.IP1.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    if (kind[0] != 0x00) {
+                        Map<String,Object> data = new HashMap<>();
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP1.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP1_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP2.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP2.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP2_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP3.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP3.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP3_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.IP4.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                    Map<String,Object> data = new HashMap<>();
+                    if (kind[0] != 0x00) {
+                        data.put("ip", BytesHelp.toIp(BytesHelp.subBytes(value, 0, 6)));
+                        data.put("port", String.format("%d", Integer.parseInt(BytesHelp.byte2HexStr(BytesHelp.subBytes(value, 6, 3)))));
+                        List<Map<String,Object>> list = new ArrayList<>();
+                        list.add(data);
+                        this.keyStore.put(BaseSettingFlag.IP4.getId(), list);
+                    }
+                } else if (flagCode.equals(BaseSettingFlag.IP4_SUB.getId())) {
+                    byte[] kind = BytesHelp.subBytes(dataArea, count, 1);
+                    count += 1;
+                    byte[] len = BytesHelp.subBytes(dataArea, count, 1);
+                    int dataTotalLen = (int) len[0];
+                    count += 1;
+                    byte[] value = BytesHelp.subBytes(dataArea, count, dataTotalLen);
+                    count += dataTotalLen;
+                } else if (flagCode.equals(BaseSettingFlag.WORK_TYPE.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.COLLECT_SETTING.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.SERVER_ADD.getId())) {
+
+                } else if (flagCode.equals(BaseSettingFlag.DEVICE_ID.getId())) {
+
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 E7 中心站设置遥测站IP和端口");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 139 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtStatusDatagramProcessor.java

@@ -0,0 +1,139 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.Sw2014DatagramTemplateHelp;
+import org.ts.ddcs.common.util.ValueLen;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:测站状态扩展报 0xF5
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyExtStatusDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_F5.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            //解析报文
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            // 发报时间
+            byte[] sendPacketTime = BytesHelp.subBytes(dataArea, count, 6);
+            byte tmp = sendPacketTime[5];
+            sendPacketTime[5] = sendPacketTime[0];
+            sendPacketTime[0] = tmp;
+            tmp = sendPacketTime[4];
+            sendPacketTime[4] = sendPacketTime[1];
+            sendPacketTime[1] = tmp;
+            tmp = sendPacketTime[3];
+            sendPacketTime[3] = sendPacketTime[2];
+            sendPacketTime[2] = tmp;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME_BYTE.getName(), sendPacketTime);
+            count += 6;
+            int readSize = 0;
+            //解析观测要素
+            if (dataArea.length - count > 0) {
+                byte[] content = BytesHelp.subBytes(dataArea, count, dataArea.length - count);
+                int index = 0;
+                int orgLen = content.length;
+                while (index < orgLen) {
+                    String func = BytesHelp.byte2HexStr(content, index, 1);
+                    int funcLen = 0;
+                    if ("FF".equals(func.toUpperCase())) {
+                        func = BytesHelp.byte2HexStr(content, index, 2).toUpperCase();
+                        funcLen = 2;
+                    } else {
+                        funcLen = 1;
+                    }
+                    if (itemTemplateMap.containsKey(func)) {
+                        DataItemTemplate itemTemplate = itemTemplateMap.get(func);
+                        readSize = itemTemplate.stream(content, index);
+                        index += readSize;
+                        if (itemTemplate.isMacth()) {
+                            itemTemplate.saveValue(this.keyStore);
+                        }
+                    } else {
+                        index += funcLen;
+                        ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(content, index);
+                        index += 1;
+                        index += valueLen.getByteLen();
+                    }
+                }
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到接收到水资源 F5 状态报");
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            List<Map<String, Object>> list = this.keyStore.get(key);
+            if (null != list) {
+                for (Map<String, Object> m : list) {
+                    log.info("item {} {}", key, JSONObject.toJSONString(m));
+                }
+            }
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 432 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyFixedTimeDatagramProcessor.java

@@ -0,0 +1,432 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.common.util.ToolUtil;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.*;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:定时报 0xC0
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyFixedTimeDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0);
+        this.keyStore.clear();
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_C0.getName().equals(datagramCode)) {
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int dataAreaLen = dataArea.length;
+            int count = 0;
+            int controlCode = this.dataStreamCache.getIntValue(DataStreamCacheMetadata.METADATA_SZY_CA_CODE.getName());
+            if (controlCode == ToolUtil.hexStrToInt(SzyElementCodeEnum.CODE_WATER_QUALITY.getCode())) {
+                //水质
+                DataItemTemplate itemTemplate = itemTemplateMap.get(SzyElementCodeEnum.CODE_WATER_QUALITY.getCode());
+                if (null != itemTemplate) {
+                    int readSize = itemTemplate.stream(dataArea, count, dataAreaLen - 9);
+                    if (itemTemplate.isMacth()) {
+                        itemTemplate.saveValue(this.keyStore);
+                    }
+                    count += readSize;
+                } else {
+                    count += dataAreaLen - 9;
+                }
+                //报警状态
+                DataItemTemplate itemTemplateWarn = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode());
+                int readSize = itemTemplateWarn.stream(dataArea, count);
+                if (itemTemplateWarn.isMacth()) {
+                    itemTemplateWarn.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //测站状态
+                DataItemTemplate itemTemplateStatus = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode());
+                readSize = itemTemplateStatus.stream(dataArea, count);
+                if (itemTemplateStatus.isMacth()) {
+                    itemTemplateStatus.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //发报时间
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                String st = now.format(timeFormat);
+                //采集时间
+                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+                if (dataArea.length - count == 7) {
+                    //SL 427 规约
+                    //采集时间为秒分时日月年
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT427.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String collectTime = "20" + itemTemplateTt.getStringValue();
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), collectTime);
+                    }
+                } else if (dataArea.length - count == 5) {
+                    //采集时间为秒分时日
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String ct = itemTemplateTt.getStringValue();
+                        LocalDateTime tm = now.withDayOfMonth(Integer.valueOf(ct.substring(0, 2))).withHour(Integer.valueOf(ct.substring(2, 4))).withMinute(Integer.valueOf(ct.substring(4, 6))).withSecond(0).withNano(0);
+                        if (tm.isBefore(now)) {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        } else if (tm.isAfter(now)) {
+                            LocalDateTime pretm = tm.minusMonths(1);
+                            Duration durationFirst = Duration.between(pretm, now);
+                            Duration durationSecend = Duration.between(now, tm);
+                            long tm1 = durationFirst.toMillis();
+                            long tm2 = durationSecend.toMillis();
+                            if (tm1 > tm2) {
+                                long hours = durationSecend.toHours();
+                                if (hours > 24) {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                                } else {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                                }
+                            } else if (tm1 < tm2) {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                            } else {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                            }
+                        } else {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        }
+                    }
+                }
+                count += readSize;
+            } else if (controlCode == ToolUtil.hexStrToInt(SzyElementCodeEnum.CODE_FLOW_SPEED.getCode())) {
+                //流速
+                boolean sl427 = false;
+                int dataLen = dataAreaLen - 5 - 4;
+                if (dataLen % 3 > 0) {
+                    //SL 427 规约
+                    dataLen = dataAreaLen - 7 - 4;
+                    sl427 = true;
+                }
+                DataItemTemplate itemTemplate = itemTemplateMap.get(SzyElementCodeEnum.CODE_FLOW_SPEED.getCode());
+                if (null != itemTemplate) {
+                    int readSize = itemTemplate.stream(dataArea, count, dataLen);
+                    if (itemTemplate.isMacth()) {
+                        itemTemplate.saveValue(this.keyStore);
+                    }
+                    count += readSize;
+                } else {
+                    count += dataLen;
+                }
+                //报警状态
+                DataItemTemplate itemTemplateWarn = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode());
+                int readSize = itemTemplateWarn.stream(dataArea, count);
+                if (itemTemplateWarn.isMacth()) {
+                    itemTemplateWarn.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //测站状态
+                DataItemTemplate itemTemplateStatus = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode());
+                readSize = itemTemplateStatus.stream(dataArea, count);
+                if (itemTemplateStatus.isMacth()) {
+                    itemTemplateStatus.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //发报时间
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                String st = now.format(timeFormat);
+                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+                //采集时间
+                if (sl427) {
+                    //SL 427 规约
+                    //采集时间为秒分时日月年
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT427.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String collectTime = "20" + itemTemplateTt.getStringValue();
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), collectTime);
+                    }
+                } else {
+                    //采集时间为秒分时日
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String ct = itemTemplateTt.getStringValue();
+                        LocalDateTime tm = now.withDayOfMonth(Integer.valueOf(ct.substring(0, 2))).withHour(Integer.valueOf(ct.substring(2, 4))).withMinute(Integer.valueOf(ct.substring(4, 6))).withSecond(0).withNano(0);
+                        if (tm.isBefore(now)) {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        } else if (tm.isAfter(now)) {
+                            LocalDateTime pretm = tm.minusMonths(1);
+                            Duration durationFirst = Duration.between(pretm, now);
+                            Duration durationSecend = Duration.between(now, tm);
+                            long tm1 = durationFirst.toMillis();
+                            long tm2 = durationSecend.toMillis();
+                            if (tm1 > tm2) {
+                                long hours = durationSecend.toHours();
+                                if (hours > 24) {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                                } else {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                                }
+                            } else if (tm1 < tm2) {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                            } else {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                            }
+                        } else {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        }
+                    }
+                }
+                count += readSize;
+            } else if (controlCode == ToolUtil.hexStrToInt(SzyElementCodeEnum.CODE_WATER_LEVEL.getCode())) {
+                //水位
+                DataItemTemplate itemTemplate = itemTemplateMap.get(SzyElementCodeEnum.CODE_WATER_LEVEL.getCode());
+                if (null != itemTemplate) {
+                    int readSize = itemTemplate.stream(dataArea, count);
+                    if (itemTemplate.isMacth()) {
+                        itemTemplate.saveValue(this.keyStore);
+                    }
+                    count += readSize;
+                } else {
+                    count += dataAreaLen - 9;
+                }
+                //报警状态
+                DataItemTemplate itemTemplateWarn = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode());
+                int readSize = itemTemplateWarn.stream(dataArea, count);
+                if (itemTemplateWarn.isMacth()) {
+                    itemTemplateWarn.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //测站状态
+                DataItemTemplate itemTemplateStatus = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode());
+                readSize = itemTemplateStatus.stream(dataArea, count);
+                if (itemTemplateStatus.isMacth()) {
+                    itemTemplateStatus.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //发报时间
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                String st = now.format(timeFormat);
+                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+                //采集时间
+                if (dataArea.length - count == 7) {
+                    //SL 427 规约
+                    //采集时间为秒分时日月年
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT427.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String collectTime = "20" + itemTemplateTt.getStringValue();
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), collectTime);
+                    }
+                } else if (dataArea.length - count == 5) {
+                    //采集时间为秒分时日
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String ct = itemTemplateTt.getStringValue();
+                        LocalDateTime tm = now.withDayOfMonth(Integer.valueOf(ct.substring(0, 2))).withHour(Integer.valueOf(ct.substring(2, 4))).withMinute(Integer.valueOf(ct.substring(4, 6))).withSecond(0).withNano(0);
+                        if (tm.isBefore(now)) {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        } else if (tm.isAfter(now)) {
+                            LocalDateTime pretm = tm.minusMonths(1);
+                            Duration durationFirst = Duration.between(pretm, now);
+                            Duration durationSecend = Duration.between(now, tm);
+                            long tm1 = durationFirst.toMillis();
+                            long tm2 = durationSecend.toMillis();
+                            if (tm1 > tm2) {
+                                long hours = durationSecend.toHours();
+                                if (hours > 24) {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                                } else {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                                }
+                            } else if (tm1 < tm2) {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                            } else {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                            }
+                        } else {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        }
+                    }
+                }
+                count += readSize;
+            } else if (controlCode == ToolUtil.hexStrToInt(SzyElementCodeEnum.CODE_FLOW_RATE.getCode())) {
+                //流量
+                boolean sl427 = false;
+                int dataLen = dataAreaLen - 5 - 4;
+                if (dataLen % 5 > 0) {
+                    //  //SL 427 规约
+                    dataLen = dataAreaLen - 7 - 4;
+                    sl427 = true;
+                }
+                DataItemTemplate itemTemplate = itemTemplateMap.get(SzyElementCodeEnum.CODE_FLOW_RATE.getCode());
+                if (null != itemTemplate) {
+                    int readSize = itemTemplate.stream(dataArea, count, dataLen);
+                    if (itemTemplate.isMacth()) {
+                        itemTemplate.saveValue(this.keyStore);
+                    }
+                    count += readSize;
+                } else {
+                    count += dataLen;
+                }
+                //报警状态
+                DataItemTemplate itemTemplateWarn = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode());
+                int readSize = itemTemplateWarn.stream(dataArea, count);
+                if (itemTemplateWarn.isMacth()) {
+                    itemTemplateWarn.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //测站状态
+                DataItemTemplate itemTemplateStatus = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode());
+                readSize = itemTemplateStatus.stream(dataArea, count);
+                if (itemTemplateStatus.isMacth()) {
+                    itemTemplateStatus.saveValue(this.keyStore);
+                }
+                count += readSize;
+                //发报时间
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                String st = now.format(timeFormat);
+                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+                //采集时间
+                if (sl427) {
+                    //SL 427 规约
+                    //采集时间为秒分时日月年
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT427.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String collectTime = "20" + itemTemplateTt.getStringValue();
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), collectTime);
+                    }
+                } else {
+                    //采集时间为秒分时日
+                    DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT.getCode());
+                    readSize = itemTemplateTt.stream(dataArea, count);
+                    if (itemTemplateTt.isMacth()) {
+                        String ct = itemTemplateTt.getStringValue();
+                        LocalDateTime tm = now.withDayOfMonth(Integer.valueOf(ct.substring(0, 2))).withHour(Integer.valueOf(ct.substring(2, 4))).withMinute(Integer.valueOf(ct.substring(4, 6))).withSecond(0).withNano(0);
+                        if (tm.isBefore(now)) {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        } else if (tm.isAfter(now)) {
+                            LocalDateTime pretm = tm.minusMonths(1);
+                            Duration durationFirst = Duration.between(pretm, now);
+                            Duration durationSecend = Duration.between(now, tm);
+                            long tm1 = durationFirst.toMillis();
+                            long tm2 = durationSecend.toMillis();
+                            if (tm1 > tm2) {
+                                long hours = durationSecend.toHours();
+                                if (hours > 24) {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                                } else {
+                                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                                }
+                            } else if (tm1 < tm2) {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                            } else {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                            }
+                        } else {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        }
+                    }
+                }
+                count += readSize;
+            }
+            if (count != dataAreaLen) {
+                log.error("CO报文", "数据解析发生异常!");
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 C0 定时报,回复报文");
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        byte[] ca = new byte[1];
+        byte[] byteBuff = this.dataStreamCache.getDatagramBuff();
+        ca[0] = byteBuff[3];
+        ca[0] = (byte) (ca[0] & 0x7F);
+        String content = BytesHelp.byte2HexStr(ca) + BytesHelp.byte2HexStr(rtuCodeByte) + "C0";
+        content += "00";
+        byte[] contenbuff = BytesHelp.hexStr2Bytes(content);
+        byte[] crc = new byte[1];
+        crc[0] = BytesHelp.GetCRCByte(contenbuff);
+        int datagramLen = 1 + 1 + 1 + contenbuff.length + 1 + 1;
+        byte[] datagram = new byte[datagramLen];
+        int count = 0;
+        datagram[count] = 0x68;
+        count += 1;
+        datagram[count] = (byte) contenbuff.length;
+        count += 1;
+        datagram[count] = 0x68;
+        count += 1;
+        System.arraycopy(contenbuff, 0, datagram, count, contenbuff.length);
+        count += contenbuff.length;
+        datagram[count] = crc[0];
+        count += 1;
+        datagram[count] = 0x16;
+        dataStreamAdapter.output(datagram);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> elementDataList = new ArrayList<>();
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            Map<String, Object> data = new HashMap<>();
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+            //data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+            data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+            List<Map<String, Object>> elements = this.keyStore.get(key);
+            data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+            elementDataList.add(data);
+        }
+        return elementDataList;
+    }
+}

+ 84 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyLinkCheckDatagramProcessor.java

@@ -0,0 +1,84 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:链接检测报 0x02
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyLinkCheckDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_02.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            //F0 登录,F1 退出登录,F2 在线保持
+            byte action = (byte) dataArea[0];
+            if (action == 0xF0) {
+
+            } else if (action == 0xF1) {
+
+            } else if (action == 0xF2) {
+
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 02 链接报");
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+//        Map<String, Object> data = new HashMap<>();
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//        datas.add(data);
+        return datas;
+    }
+
+}

+ 159 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyMatchDatagramProcessor.java

@@ -0,0 +1,159 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/9/4
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/9/4
+ * Title:水资源规约数据处理器模块
+ * Description:水资源报文检测处理器,主要负责检测出一个完整正确的报文
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyMatchDatagramProcessor extends DataStreamProcessor {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        this.dataStreamCache.setState(TestState.LOOK);
+        this.dataStreamCache.setMatchProcessor(this);
+        byte[] block = dataStreamAdapter.getBlock();
+        if (block.length == 0) {
+            this.next(false);
+        }
+        this.dataStreamCache.setDataBuff(block);
+        if (this.dataStreamCache.dataSize() < 3) {
+            this.next(false);
+        }
+        if (this.dataStreamCache.getByte(0) != 0x68 || this.dataStreamCache.getByte(2) != 0x68) {
+            this.dataStreamCache.setState(TestState.ERROR);
+            this.next(false);
+        }
+        // 报文正文长度,第2个字节
+        byte[] dataAreaLenBuff = new byte[1];
+        dataAreaLenBuff[0] = this.dataStreamCache.getByte(1);
+        int contentLen = dataAreaLenBuff[0] < 0 ? dataAreaLenBuff[0] + 256 : dataAreaLenBuff[0];
+        int datagramSize = 5 + contentLen;
+        if (this.dataStreamCache.dataSize() < datagramSize) {
+            this.next(false);
+        }
+        this.dataStreamCache.setDatagramSize(datagramSize);
+        byte[] datagramBuff = this.dataStreamCache.getBytes(datagramSize);
+        this.dataStreamCache.setDatagramBuff(datagramBuff);
+        int count = 0;
+        byte[] packetHeader = BytesHelp.subBytes(datagramBuff, count, 3);
+        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_PACKET_HEADER.getName(), packetHeader);
+        count += 3;
+        if (contentLen >= 7) {
+            //控制域 第4个字节
+            byte[] ca = this.dataStreamCache.getBytes(count, 1);
+            count += 1;
+            //传输方向位 0 下行报文 ,1 上行报文(RTU上报)
+            int dir = BytesHelp.bcdToInt(ca[0], 7, 7);
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_CA_DIR.getName(), dir);
+            //拆分标志位 0 单帧,1 多帧(控制域后增加一个字节,表示帧计数,255-1 ,1为最后一帧)
+            int div = BytesHelp.bcdToInt(ca[0], 6, 6);
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_CA_DIV.getName(), div);
+            //重试发送计数,可设定一个值,发一次减1,0时发送失败
+            int fcb = BytesHelp.bcdToInt(ca[0], 5, 4);
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_CA_FCB.getName(), fcb);
+            //控制功能码
+            int funCode = BytesHelp.bcdToInt(ca[0], 3, 0);
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_CA_CODE.getName(), funCode);
+            if (div == 1) {
+                byte[] divsBuff = this.dataStreamCache.getBytes(count, 1);
+                int divs = divsBuff[0] < 0 ? divsBuff[0] + 256 : divsBuff[0];
+                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_CA_DIV_COUNT.getName(), divs);
+                count += 1;
+            }
+            //地址域
+            byte[] rtuCodeByte = BytesHelp.subBytes(datagramBuff, count, 5);
+            count += 5;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName(), rtuCodeByte);
+            //应用功能码
+            byte[] command = BytesHelp.subBytes(datagramBuff, count, 1);
+            count += 1;
+            dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_SZY_AFN.getName(), command);
+            int headLen = 7;
+            if (div == 1) {
+                headLen += 1;
+            }
+            if (contentLen - headLen > 0) {
+                //报文正文
+                byte[] dataArea = BytesHelp.subBytes(datagramBuff, count, contentLen - headLen);
+                dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName(), dataArea);
+                count += dataArea.length;
+            }
+        }
+        //帧校验 包括控制域、地址域、用户数据
+        byte[] crc = BytesHelp.subBytes(datagramBuff, count, 1);
+        dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_CRC.getName(), crc);
+        count += 1;
+        //结束字符
+        byte[] endflag = BytesHelp.subBytes(datagramBuff, count, 1);
+        count += 1;
+        if (endflag[0] == 0x16) {
+            dataStreamCache.setReadSize(dataStreamCache.getDatagramSize());
+            dataStreamCache.setState(TestState.MATHCE);
+            this.next(true);
+        } else {
+            dataStreamCache.setState(TestState.ERROR);
+            this.next(false);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        if (dataStreamCache.getState() == TestState.ERROR) {
+            int size = this.dataStreamCache.dataSize();
+            int count = 0;
+            for (int i = 1; i < size; i++) {
+                byte v = dataStreamCache.getByte(i);
+                if (v == 0x68) {
+                    count = i;
+                    break;
+                }
+            }
+            if (count > 0) {
+                dataStreamCache.setReadSize(count);
+            } else {
+                dataStreamCache.setReadSize(size);
+            }
+        }
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+}

+ 155 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadBaseSettingDatagramProcessor.java

@@ -0,0 +1,155 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.dict.BaseSettingFlag;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 查询基本配置信息 0x87
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyReadBaseSettingDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_87.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+//                01  通讯方式
+            count += 1;
+//                00  是否招测
+            count += 1;
+//                08 发送起始时间
+            count += 1;
+//                18 定时发送次数
+            count += 1;
+//                05 发送时间间隔
+            count += 1;
+//                02  //发送服务器个数
+            count += 1;
+//                434D4E4554002020202020202020202020202020 20字节  APN接入点
+            count += 20;
+//                7573657200202020202020202020202020202020 20字节  APN用户名
+            count += 20;
+//                70617373776F7264002020202020202020202020 20字节 APN密码
+            count += 20;
+//                3131312E3230342E3232382E323237   服务器1IP地址
+            byte[] ip1buff = BytesHelp.subBytes(dataArea, count, 15);
+            count += 15;
+//                3131312E3230342E3232382E323237   服务器2IP地址
+            byte[] ip2buff = BytesHelp.subBytes(dataArea, count, 15);
+            count += 15;
+//                3231392E3233322E3131372E330303
+            byte[] ip3buff = BytesHelp.subBytes(dataArea, count, 15);
+            count += 15;
+//                3231392E3233322E3131372E303838 //服务器4IP地址
+            byte[] ip4buff = BytesHelp.subBytes(dataArea, count, 15);
+            count += 15;
+//                1F43 //服务器1端口号
+            byte[] port1buff = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+//                1F41  //服务器2端口号
+            byte[] port2buff = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+//                1770 //服务器1端口号
+            byte[] port3buff = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+//                046C  //服务器2端口号
+            byte[] port4buff = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+            List<Map<String,Object>> dataList = new ArrayList<>();
+            Map<String,Object> data = new HashMap<>();
+            String ip1Str = new String(ip1buff);
+            String ip2Str = new String(ip2buff);
+            String ip3Str = new String(ip3buff);
+            String ip4Str = new String(ip4buff);
+            data.put("ip1", ip1Str);
+            data.put("ip1port", String.format("%d", BytesHelp.bytes2Int(port1buff, 0, 2)));
+            data.put("code", BaseSettingFlag.IP1.getId());
+            dataList.add(data);
+            data = new HashMap<>();
+            data.put("ip2", ip2Str);
+            data.put("ip2port", String.format("%d", BytesHelp.bytes2Int(port2buff, 0, 2)));
+            data.put("code", BaseSettingFlag.IP2.getId());
+            dataList.add(data);
+            data = new HashMap<>();
+            data.put("ip3", ip3Str);
+            data.put("ip3port", String.format("%d", BytesHelp.bytes2Int(port3buff, 0, 2)));
+            data.put("code", BaseSettingFlag.IP3.getId());
+            dataList.add(data);
+            data = new HashMap<>();
+            data.put("ip4", ip4Str);
+            data.put("ip4port", String.format("%d", BytesHelp.bytes2Int(port4buff, 0, 2)));
+            data.put("code", BaseSettingFlag.IP4.getId());
+            dataList.add(data);
+//                3133373136313433333136   //服务器1中心卡号
+            count += 11;
+//                3133383130363239393538
+            count += 11;
+//                3135303131323035393639
+            count += 11;
+//                3137303530303639383633
+            count += 11;
+//                B8
+//                16
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 87 查询基本配置信息");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 93 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadRtuCodeDatagramProcessor.java

@@ -0,0 +1,93 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 查询遥测终端、中继站地址 0x50
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyReadRtuCodeDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_50.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            String setRtuCode = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 5));
+            count += 5;
+            Map<String, Object> value = new HashMap<>();
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), SzyElementCodeEnum.CODE_EXT_ST.getCode());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), SzyElementCodeEnum.CODE_EXT_ST.getName());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), "");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "测站编码");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), setRtuCode);
+
+            List<Map<String, Object>> list = new ArrayList<>();
+            list.add(value);
+            this.keyStore.put(SzyElementCodeEnum.CODE_EXT_ST.getCode(), list);
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 50 查询测站编码");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 147 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadUpModelDatagramProcessor.java

@@ -0,0 +1,147 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 查询遥测终端的数据自报种类及时间间隔 0x53
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyReadUpModelDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0);
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_53.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            byte[] buff = BytesHelp.subBytes(dataArea, count, 2);
+            byte tmpByte = buff[0];
+            buff[0] = buff[1];
+            buff[1] = tmpByte;
+            String binStr = BytesHelp.BytesToBinStr(buff);
+            binStr = new StringBuilder(binStr).reverse().toString();
+            count += 2;
+            List<Map<String, Object>> list = new ArrayList<>();
+            for (int i = 0; i < 14; i++) {
+                if (binStr.substring(i, i + 1).equals("1")) {
+                    Map<String, Object> data = new HashMap<>();
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), SzyElementCodeEnum.CODE_COUNT_RAIN.getCode());
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), "szy_intervalTime_setting");
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), String.format("%d", i));
+                    if (0 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报雨量数据");
+                    } else if (1 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报水位数据");
+                    } else if (2 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报流量(水量)数据");
+                    } else if (3 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报流速数据");
+                    } else if (4 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报闸位数据");
+                    } else if (5 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报功率数据");
+                    } else if (6 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报气压数据");
+                    } else if (7 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "出现上报风速(风向)数据");
+                    } else if (8 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报水温数据");
+                    } else if (9 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报水质数据");
+                    } else if (10 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报土壤含水率数据");
+                    } else if (11 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报蒸发量数据");
+                    } else if (12 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报报警或状态数据");
+                    } else if (13 == i) {
+                        data.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "主动上报水压数据");
+                    }
+
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), "");
+
+                    byte[] valueBuff = BytesHelp.subBytes(dataArea, count, 2);
+                    tmpByte = valueBuff[0];
+                    valueBuff[0] = valueBuff[1];
+                    valueBuff[1] = tmpByte;
+                    String value = BytesHelp.byte2HexStr(valueBuff);
+                    data.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), Integer.valueOf(value).toString());
+
+                    list.add(data);
+                }
+                count += 2;
+            }
+            this.keyStore.put(SzyElementCodeEnum.CODE_COUNT_RAIN.getCode(), list);
+            //发报时间
+            DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+            String st = now.format(timeFormat);
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+            //采集时间
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), st);
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 53 查询遥测终端的数据自报种类及时间间隔");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 81 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRebootDatagramProcessor.java

@@ -0,0 +1,81 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 重启 0x90
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyRebootDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_90.getName().equals(datagramCode)) {
+
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 90 重启");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 81 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRgzsDatagramProcessor.java

@@ -0,0 +1,81 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 人工置数 0x82
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyRgzsDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_82.getName().equals(datagramCode)) {
+
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+
+
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 82 人工置数,回复报文");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+}

+ 82 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetBaseSettingDatagramProcessor.java

@@ -0,0 +1,82 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 设置基本配置信息 0x88
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzySetBaseSettingDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_88.getName().equals(datagramCode)) {
+
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+
+
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 88 配置基本配置信息");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 120 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetClockDatagramProcessor.java

@@ -0,0 +1,120 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 设置时钟 0x11
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzySetClockDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_11.getName().equals(datagramCode)) {
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+
+            int count = 0;
+            String ss = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 1));
+            count += 1;
+            String min = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 1));
+            count += 1;
+            String hh = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 1));
+            count += 1;
+            String dd = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 1));
+            count += 1;
+
+            int month = dataArea[count] & 0x1F;
+            byte[] monthBuff = new byte[1];
+            monthBuff[0] = (byte) month;
+            String mm = BytesHelp.byte2HexStr(monthBuff);
+            count += 1;
+            String yy = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 1));
+            count += 1;
+
+            String clock = "20" + yy + mm + dd + hh + min + ss;
+
+
+            byte[] pw = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+            byte[] tm = BytesHelp.subBytes(dataArea, count, 4);
+            count += 4;
+            byte[] delay = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+
+
+            Map<String, Object> value = new HashMap<>();
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), SzyElementCodeEnum.CODE_EXT_TT.getCode());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), SzyElementCodeEnum.CODE_EXT_TT.getName());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), "");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "RTU时钟");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), clock);
+
+            List<Map<String, Object>> list = new ArrayList<>();
+            list.add(value);
+            this.keyStore.put(SzyElementCodeEnum.CODE_EXT_TT.getCode(), list);
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 11 设置时钟");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 101 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetRtuCodeDatagramProcessor.java

@@ -0,0 +1,101 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 设置IP 0x10
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzySetRtuCodeDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_10.getName().equals(datagramCode)) {
+
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+            String setRtuCode = BytesHelp.byte2HexStr(BytesHelp.subBytes(dataArea, count, 5));
+            count += 5;
+            byte[] pw = BytesHelp.subBytes(dataArea, count, 2);
+            count += 2;
+            byte[] tm = BytesHelp.subBytes(dataArea, count, 4);
+            count += 4;
+            byte[] delay = BytesHelp.subBytes(dataArea, count, 1);
+            count += 1;
+
+            Map<String, Object> value = new HashMap<>();
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), SzyElementCodeEnum.CODE_EXT_ST.getCode());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), SzyElementCodeEnum.CODE_EXT_ST.getName());
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), "");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), "测站编码");
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), setRtuCode);
+
+            List<Map<String, Object>> list = new ArrayList<>();
+            list.add(value);
+            this.keyStore.put(SzyElementCodeEnum.CODE_EXT_ST.getCode(), list);
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 10 设置终端地址");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 81 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetUpModelDatagramProcessor.java

@@ -0,0 +1,81 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.JsonPackMetadataEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 设置自报种类及时间间隔 0xA1
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzySetUpModelDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_A1.getName().equals(datagramCode)) {
+
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int count = 0;
+
+
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 A1 设置自报种类及时间间隔");
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> datas = new ArrayList<>();
+        Map<String, Object> data = new HashMap<>();
+        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        datas.add(data);
+        return datas;
+    }
+
+}

+ 69 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyUnknownProcessor.java

@@ -0,0 +1,69 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description: 水资源未定义报文处理器
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyUnknownProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) {
+        this.dataStreamCache.setMatchProcessor(this);
+        this.dataStreamCache.setState(TestState.UNKNOWN);
+        this.next(false);
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        byte[] datagram = this.dataStreamCache.getDatagramBuff();
+        log.info("未知报文 {}", BytesHelp.byte2HexStr(datagram));
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        return null;
+    }
+
+//    @Override
+//    public List<JSONObject> sinkJson(DataStreamAdapter dataStreamAdapter) {
+//        return null;
+//    }
+
+}

+ 206 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyWarnDatagramProcessor.java

@@ -0,0 +1,206 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2021/12/16
+ */
+package org.ts.ddcs.dataStream.processor.szy;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+import org.ts.ddcs.enums.SzyDatagramTypeCodeEnum;
+import org.ts.ddcs.common.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.dataStream.DataStreamProcessor;
+import org.ts.ddcs.datatemplate.TestState;
+import org.ts.ddcs.itemdatatemplate.DataItemTemplate;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+
+/***
+ * Date:2021/12/16
+ * Title:水资源规约数据处理器模块
+ * Description:水资源 随机自报报警数据 0x81
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyWarnDatagramProcessor extends DataStreamProcessor {
+
+    private DataStreamCache dataStreamCache;
+    private Map<String, List<Map<String, Object>>> keyStore = new HashMap<>();
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.context = context;
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void process(DataStreamAdapter dataStreamAdapter) throws UnsupportedEncodingException {
+        LocalDateTime now = LocalDateTime.now().withSecond(0).withNano(0);
+        this.dataStreamCache.setState(TestState.MATHCE);
+        this.dataStreamCache.setMatchProcessor(this);
+        String datagramCode = this.dataStreamCache.getDatagramCode();
+        if (SzyDatagramTypeCodeEnum.DATAGRAM_CODE_81.getName().equals(datagramCode)) {
+            this.keyStore.clear();
+            String agreement = dataStreamAdapter.getAgreement();
+            Map<String, DataItemTemplate> itemTemplateMap = this.context.getItemTemplate(agreement);
+            byte[] dataArea = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_DATA_AREA.getName());
+            int dataAreaLen = dataArea.length;
+            int count = 0;
+
+            /**报警状态*/
+            DataItemTemplate itemTemplateWarn = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode());
+            int readSize = itemTemplateWarn.stream(dataArea, count);
+            if (itemTemplateWarn.isMacth()) {
+                itemTemplateWarn.saveValue(this.keyStore);
+            }
+            count += readSize;
+
+            /**测站状态*/
+            DataItemTemplate itemTemplateStatus = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode());
+            readSize = itemTemplateStatus.stream(dataArea, count);
+            if (itemTemplateStatus.isMacth()) {
+                itemTemplateStatus.saveValue(this.keyStore);
+            }
+            count += readSize;
+
+            /**发报时间*/
+            DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+            String st = now.format(timeFormat);
+//            SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+//            String st = timeFormat.format(new Date());
+            // byte[] sendPacketTime = BytesHelp.hexStr2Bytes(dt.substring(2));
+            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName(), st);
+
+            if (dataArea.length - count == 7) {
+                //SL 427 规约
+                //采集时间为秒分时日月年
+                DataItemTemplate itemTemplateTt = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT427.getCode());
+                readSize = itemTemplateTt.stream(dataArea, count);
+                if (itemTemplateTt.isMacth()) {
+                    // itemTemplateTt.saveValue(this.keyStore);
+                    String collectTime = "20" + itemTemplateTt.getStringValue();
+                    this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), collectTime);
+                }
+
+            } else if (dataArea.length - count == 5) {
+                //采集时间为秒分时日
+                DataItemTemplate itemTemplateTT = itemTemplateMap.get(SzyElementCodeEnum.CODE_EXT_TT.getCode());
+                readSize = itemTemplateTT.stream(dataArea, count);
+                if (itemTemplateTT.isMacth()) {
+                    itemTemplateTT.saveValue(this.keyStore);
+                    String ct = itemTemplateTT.getStringValue();
+                    LocalDateTime tm = now.withDayOfMonth(Integer.valueOf(ct.substring(0, 2))).withHour(Integer.valueOf(ct.substring(2, 4))).withMinute(Integer.valueOf(ct.substring(4, 6))).withSecond(0).withNano(0);
+                    if (tm.isBefore(now)) {
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                    } else if (tm.isAfter(now)) {
+                        LocalDateTime pretm = tm.minusMonths(1);
+                        Duration durationFirst = Duration.between(pretm, now);
+                        Duration durationSecend = Duration.between(now, tm);
+                        long tm1 = durationFirst.toMillis();
+                        long tm2 = durationSecend.toMillis();
+                        if (tm1 > tm2) {
+                            long hours = durationSecend.toHours();
+                            if (hours > 24) {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                            } else {
+                                this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                            }
+                        } else if (tm1 < tm2) {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), pretm.format(timeFormat));
+                        } else {
+                            this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                        }
+                    } else {
+                        this.dataStreamCache.putValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName(), tm.format(timeFormat));
+                    }
+
+//                String collectTime = st.substring(0, 6) + itemTemplateTT.getStringValue();
+//                this.dataStreamCache.putValue(DatagramConstant.collectTime, collectTime);
+                }
+            }
+            count += readSize;
+            if (count != dataAreaLen) {
+                log.error("81报文", "数据解析发生异常!");
+            }
+            this.next(false);
+        } else {
+            this.next(true);
+        }
+    }
+
+    @Override
+    public void close(DataStreamAdapter dataStreamAdapter) {
+
+    }
+
+    @Override
+    public void batchComplete(DataStreamAdapter dataStreamAdapter) {
+        log.info("接收到水资源 81 随机自报报警数据,回复报文");
+        byte[] rtuCodeByte = this.dataStreamCache.getBytesValue(DataStreamCacheMetadata.METADATA_RTU_CODE.getName());
+        byte[] ca = new byte[1];
+        byte[] byteBuff = this.dataStreamCache.getDatagramBuff();
+        ca[0] = byteBuff[3];
+        ca[0] = (byte) (ca[0] & 0x7F);
+        String content = BytesHelp.byte2HexStr(ca) + BytesHelp.byte2HexStr(rtuCodeByte) + "81";
+        content += "00";
+        byte[] contenbuff = BytesHelp.hexStr2Bytes(content);
+        byte[] crc = new byte[1];
+        crc[0] = BytesHelp.GetCRCByte(contenbuff);
+        int datagramLen = 1 + 1 + 1 + contenbuff.length + 1 + 1;
+        byte[] datagram = new byte[datagramLen];
+        int count = 0;
+        datagram[count] = 0x68;
+        count += 1;
+        datagram[count] = (byte) contenbuff.length;
+        count += 1;
+        datagram[count] = 0x68;
+        count += 1;
+        System.arraycopy(contenbuff, 0, datagram, count, contenbuff.length);
+        count += contenbuff.length;
+        datagram[count] = crc[0];
+        count += 1;
+        datagram[count] = 0x16;
+        dataStreamAdapter.output(datagram);
+
+    }
+
+    @Override
+    public List<Map<String, Object>> sink(DataStreamAdapter dataStreamAdapter) {
+        List<Map<String, Object>> elementDataList = new ArrayList<>();
+        Set<String> keys = this.keyStore.keySet();
+        for (String key : keys) {
+            Map<String, Object> data = new HashMap<>();
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+            //data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getValue(DatagramConstant.pickPacketTime));
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.collectTime));
+            // data.put(JsonPackMetadataEnum.PACK_METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+            data.put(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName(), key);
+            List<Map<String, Object>> elements = this.keyStore.get(key);
+            data.put(DatagramMetadataEnum.CACHE_METADATA_DATA.getName(), elements);
+            elementDataList.add(data);
+        }
+        return elementDataList;
+//        List<Map<String, Object>> list = new ArrayList<>();
+//        Map<String, Object> data = new HashMap<>();
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+//        data.put(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//        list.add(data);
+//        return list;
+    }
+
+}

+ 55 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamKafkaSink.java

@@ -0,0 +1,55 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/8/28
+ */
+package org.ts.ddcs.dataStream.sink;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.KafkaConstants;
+import org.ts.ddcs.common.metadata.TaishanV1JsonPackMetadataEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.kafka.KafkaClient;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.text.SimpleDateFormat;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title: 报文转发,不重新封装数据
+ * Description:
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamKafkaSink extends DataStreamSink {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.setContext(context);
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void sink(DataStreamAdapter dataStreamAdapter, List<Map<String, Object>> elementDatas) {
+        log.info("sink {} 接收时间 {} ", dataStreamAdapter.getRtuCode(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        JSONObject body = new JSONObject();
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_DATAGRAM.getName(), BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_AGREEMENT_TYPE.getName(), dataStreamAdapter.getAgreement());
+        SimpleDateFormat timeFormat = new SimpleDateFormat("yyyyMMddHHmmss");
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), timeFormat.format(this.dataStreamCache.getPickPacketTime()));
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_DATAGRAM_TYPE.getName(), this.dataStreamCache.getDatagramCode());
+        log.info("data item :{}", body.toJSONString());
+        KafkaClient.messageSubmit(KafkaConstants.TOPIC_TS_V1_DATAGRAM, body.toJSONString());
+    }
+}

+ 40 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSink.java

@@ -0,0 +1,40 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/8/28
+ */
+package org.ts.ddcs.dataStream.sink;
+
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+@Data
+public abstract class DataStreamSink {
+    private String sinkName;
+    private String templateName;
+    private DataStreamLineManager context;
+
+    public abstract void init(DataStreamLineManager context);
+
+    public abstract void sink(DataStreamAdapter dataStreamAdapter, List<Map<String,Object>> elementDatas);
+
+    public void setContext(DataStreamLineManager context) {
+        this.context = context;
+    }
+}

+ 273 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwJpzKafkaSink.java

@@ -0,0 +1,273 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/8/28
+ */
+package org.ts.ddcs.dataStream.sink;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.constant.KafkaConstants;
+import org.ts.ddcs.common.enums.SwSiteKindEnum;
+import org.ts.ddcs.enums.SwElementCodeEnum;
+import org.ts.ddcs.metadata.sw.jpz.SwJpzFlowRateMetadataEnum;
+import org.ts.ddcs.metadata.sw.jpz.SwJpzWaterLevelMetadataEnum;
+import org.ts.ddcs.metadata.sw.jpz.SwJpzWaterQualityMetadataEnum;
+import org.ts.ddcs.metadata.sw.jpz.SwJpzWeatherMetadataEnum;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.kafka.KafkaClient;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+import org.ts.ddcs.tools.CloumnHelp;
+import org.ts.ddcs.tools.KeyStoreHelp;
+
+
+import java.time.LocalDateTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title:柬埔寨监测项目
+ * Description:输出气象站、水位站、水质站及流量站数据
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwJpzKafkaSink extends DataStreamSink {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.setContext(context);
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void sink(DataStreamAdapter dataStreamAdapter, List<Map<String, Object>> elementDatas) {
+        log.info("sink {} 接收时间 {}", dataStreamAdapter.getRtuCode(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+        Date dt = Date.from(this.dataStreamCache.getPickPacketTime().atZone(ZoneId.systemDefault()).toInstant());
+
+        JSONObject jsonBody = new JSONObject();
+        String siteKind = this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_SITE_KIND.getName());
+        if (SwSiteKindEnum.RTU_KIND_I.getCode() == Integer.valueOf(siteKind,16)) {
+            //流量站
+            //for (Map<String, Object> data : elementDatas) {
+            jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_ST.getName(), SwSiteKindEnum.RTU_KIND_I.getName());
+            jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), dt.getTime());
+
+            //观测时间
+            Map<String, Object> cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzFlowRateMetadataEnum.METADATA_COLLECT_TIME.getCode()));
+            if (null != cloumn) {
+                String tmText = CloumnHelp.getString(cloumn);
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                LocalDateTime tm = LocalDateTime.parse(tmText, timeFormat);
+                jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(),Date.from(tm.atZone(ZoneId.systemDefault()).toInstant()).getTime());
+            }
+
+            //累计流量
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzFlowRateMetadataEnum.METADATA_ACCF.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_ACCF.getName(), CloumnHelp.getLong(cloumn));
+            }
+
+
+            //  jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(),data.get(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName()));
+
+
+            //  List<JSONObject> keyStore = (List<JSONObject>) data.get(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName());
+            //累计流量
+//                    JSONObject cloumn = KeyStoreHelp.getOne(keyStore, Sw2014DatagramElementEnum.ELEMENT_ACCF.getName());
+//                    if (null != cloumn) {
+//                        jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_ACCF.getName(), CloumnHelp.getLong(cloumn));
+//                    }
+            //瞬时流量、抽水流量
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzFlowRateMetadataEnum.METADATA_Q.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_Q.getName(), CloumnHelp.getDouble(cloumn));
+            }
+
+
+//                    cloumn = KeyStoreHelp.getOne(keyStore, Sw2014DatagramElementEnum.ELEMENT_Q.getName());
+//                    if (null != cloumn) {
+//                        jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_Q.getName(), CloumnHelp.getDouble(cloumn));
+//                    }
+            //当前瞬时流速
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzFlowRateMetadataEnum.METADATA_VJ.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_VJ.getName(), CloumnHelp.getDouble(cloumn));
+            }
+
+//                    cloumn = KeyStoreHelp.getOne(keyStore, Sw2014DatagramElementEnum.ELEMENT_VJ.getName());
+//                    if (null != cloumn) {
+//                        jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_VJ.getName(), CloumnHelp.getDouble(cloumn));
+//                    }
+            //瞬时水位
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzFlowRateMetadataEnum.METADATA_Z.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_Z.getName(), CloumnHelp.getDouble(cloumn));
+            }
+
+//                     cloumn = KeyStoreHelp.getOne(keyStore, Sw2014DatagramElementEnum.ELEMENT_Z.getName());
+//                    if (null != cloumn) {
+//                        jsonBody.put(SwJpzFlowRateMetadataEnum.METADATA_Z.getName(), CloumnHelp.getDouble(cloumn));
+//                    }
+
+            // }
+
+        } else if (SwSiteKindEnum.RTU_KIND_H.getCode() == Integer.valueOf(siteKind,16)) {
+            //水位站
+            jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_ST.getName(), SwSiteKindEnum.RTU_KIND_H.getName());
+            jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_FROM_TIME.getName(), dt.getTime());
+
+
+            //  for (Map<String, Object> data : elementDatas) {
+//                jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_RTU_CODE.getName(), data.get(JsonPackMetadataEnum.PACK_METADATA_RTU_CODE.getName()));
+//                jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_ST.getName(), "H");
+//                jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_FROM_TIME.getName(), data.get(JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName()));
+            //jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_COLLECT_TIME.getName(), data.get(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName()));
+            //  if (data.containsKey(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName())) {
+            //List<JSONObject> keyStore = (List<JSONObject>) data.get(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName());
+            //观测时间
+            Map<String, Object> cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterLevelMetadataEnum.METADATA_COLLECT_TIME.getCode()));
+            if (null != cloumn) {
+               // jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_COLLECT_TIME.getName(), CloumnHelp.getString(cloumn));
+
+                String tmText = CloumnHelp.getString(cloumn);
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                LocalDateTime tm = LocalDateTime.parse(tmText, timeFormat);
+                jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_COLLECT_TIME.getName(),Date.from(tm.atZone(ZoneId.systemDefault()).toInstant()).getTime());
+            }
+            //瞬时水位
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterLevelMetadataEnum.METADATA_Z.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWaterLevelMetadataEnum.METADATA_Z.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //}
+            //  }
+        } else if (SwSiteKindEnum.RTU_KIND_P.getCode() == Integer.valueOf(siteKind,16)) {
+            //气象站
+            // for (Map<String, Object> data : elementDatas) {
+            jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_ST.getName(), SwSiteKindEnum.RTU_KIND_P.getName());
+            jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_FROM_TIME.getName(), dt.getTime());
+            //jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_COLLECT_TIME.getName(), data.get(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName()));
+            //if (data.containsKey(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName())) {
+            //  List<JSONObject> keyStore = (List<JSONObject>) data.get(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName());
+            //观测时间
+            Map<String, Object> cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_COLLECT_TIME.getCode()));
+            if (null != cloumn) {
+                String tmText = CloumnHelp.getString(cloumn);
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                LocalDateTime tm = LocalDateTime.parse(tmText, timeFormat);
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_COLLECT_TIME.getName(),Date.from(tm.atZone(ZoneId.systemDefault()).toInstant()).getTime());
+
+                //jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_COLLECT_TIME.getName(), CloumnHelp.getString(cloumn));
+            }
+            //5 分钟时段降水量
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_PN_05.getCode()));
+            if (null != cloumn) {
+                // log.info("5 分钟时段降水量 {}", cloumn.toJSONString());
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_PN_05.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //降水量累计值
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_PT.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_PT.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //瞬时气温
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_AI.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_AI.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //湿度
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_MST.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_MST.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //PM2.5
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_PM_25.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_PM_25.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //气压
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_FL.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_FL.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //风速
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_US.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_US.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //风向
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_UC.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_UC.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //紫外线
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_UV.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_UV.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //太阳总辐射
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_RAD.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_RAD.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //二氧化氮
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWeatherMetadataEnum.METADATA_ND.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWeatherMetadataEnum.METADATA_ND.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            // }
+            // }
+        } else if (SwSiteKindEnum.RTU_KIND_Q.getCode() == Integer.valueOf(siteKind,16)) {
+            //水质站
+            // for (Map<String, Object> data : elementDatas) {
+            jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+            jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_ST.getName(), SwSiteKindEnum.RTU_KIND_Q.getName());
+
+            jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_FROM_TIME.getName(), dt.getTime());
+            //jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_COLLECT_TIME.getName(), data.get(JsonPackMetadataEnum.PACK_METADATA_COLLECT_TIME.getName()));
+            // if (data.containsKey(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName())) {
+            // List<JSONObject> keyStore = (List<JSONObject>) data.get(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName());
+            //观测时间
+            Map<String, Object> cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterQualityMetadataEnum.METADATA_COLLECT_TIME.getCode()));
+            if (null != cloumn) {
+                String tmText = CloumnHelp.getString(cloumn);
+                DateTimeFormatter timeFormat = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+                LocalDateTime tm = LocalDateTime.parse(tmText, timeFormat);
+                jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_COLLECT_TIME.getName(),Date.from(tm.atZone(ZoneId.systemDefault()).toInstant()).getTime());
+               // jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_COLLECT_TIME.getName(), CloumnHelp.getString(cloumn));
+            }
+            //电导率
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterQualityMetadataEnum.METADATA_COND.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_COND.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //瞬时水温
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterQualityMetadataEnum.METADATA_C.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_C.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            //PH值
+            cloumn = KeyStoreHelp.getOne(elementDatas, SwElementCodeEnum.getCode(SwJpzWaterQualityMetadataEnum.METADATA_PH.getCode()));
+            if (null != cloumn) {
+                jsonBody.put(SwJpzWaterQualityMetadataEnum.METADATA_PH.getName(), CloumnHelp.getDouble(cloumn));
+            }
+            // }
+            //  }
+        }
+        log.info("data item :{}", jsonBody.toJSONString());
+        KafkaClient.messageSubmit(KafkaConstants.TOPIC_TSYWXT_DATAGRAM_MESSAGE, jsonBody.toJSONString());
+    }
+}

+ 71 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwKafkaSink.java

@@ -0,0 +1,71 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/8/28
+ */
+package org.ts.ddcs.dataStream.sink;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title:水文输出
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwKafkaSink extends DataStreamSink {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.setContext(context);
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void sink(DataStreamAdapter dataStreamAdapter, List<Map<String, Object>> elementDatas) {
+        log.info("sink {} 接收时间 {}", dataStreamAdapter.getRtuCode(),this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+//        JSONObject jsonBody = new JSONObject();
+//        String datagramCode = this.dataStreamCache.getDatagramCode();
+//        jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_DATAGRAM_KIND.getName(), datagramCode);
+//        jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getPickPacketTime());
+//        jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DatagramConstant.sendPacketTime));
+//        String collectTime= this.dataStreamCache.getStringValue(DatagramConstant.collectTime);
+//        if (null != collectTime){
+//            jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_COLLECT_TIME.getName(), collectTime);
+//        }
+//        jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+//        jsonBody.put(SwDatagramHeaderMetadataEnum.METADATA_DATAGRAM.getName(),BytesHelp.byte2HexStr(this.dataStreamCache.getDatagramBuff()));
+//        for (Map<String, Object> data : elementDatas) {
+//            List<JSONObject> keyStore = (List<JSONObject>) data.get(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_DATA.getName());
+//            if (null != keyStore&&keyStore.size()>0){
+//                String  cloumnName =keyStore.get(0).getString(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName());
+//                List<JSONObject> cloumns = new ArrayList<>(keyStore.size());
+//                for (JSONObject item:keyStore){
+//                    JSONObject cloumn = new JSONObject();
+//                    if (item.containsKey(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName())){
+//                        cloumn.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(),item.getString(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName()));
+//                    }else{
+//                        cloumn.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(),cloumnName);
+//                    }
+//                    cloumn.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(),item.getString(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName()));
+//                    cloumns.add(cloumn);
+//                }
+//                jsonBody.put(cloumnName,cloumns);
+//            }
+//        }
+//        log.info("data item :{}", jsonBody.toJSONString());
+//        KafkaClient.messageSubmit(KafkaConstants.TOPIC_TSYWXT_DATAGRAM_MESSAGE, jsonBody.toJSONString());
+    }
+}

+ 39 - 0
tsddcs-datacollect-simple/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwMqttSink.java

@@ -0,0 +1,39 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/8/28
+ */
+package org.ts.ddcs.dataStream.sink;
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.dataStream.DataStreamAdapter;
+import org.ts.ddcs.dataStream.DataStreamCache;
+import org.ts.ddcs.dataStream.DataStreamLineManager;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSwMqttSink extends DataStreamSink {
+    private DataStreamCache dataStreamCache;
+
+    @Override
+    public void init(DataStreamLineManager context) {
+        this.setContext(context);
+        this.dataStreamCache = context.getCache();
+    }
+
+    @Override
+    public void sink(DataStreamAdapter dataStreamAdapter, List<Map<String,Object>> elementDatas){
+
+    }
+}

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