Browse Source

提交采集服务代码

dylan 2 năm trước cách đây
mục cha
commit
1a7b51e2f7
100 tập tin đã thay đổi với 12728 bổ sung0 xóa
  1. 109 0
      tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/TaishanV2JsonPackMetadataEnum.java
  2. 78 0
      tsddcs-datacollect/pom.xml
  3. 21 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/DataCollectApplication.java
  4. 25 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/config/Config.java
  5. 21 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/config/ServerConfig.java
  6. 78 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/constant/BusinessConstant.java
  7. 6 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/constant/NetPortStatusConstant.java
  8. 166 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/controller/TestController.java
  9. 87 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataItemTemplateCache.java
  10. 54 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStream.java
  11. 201 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamAdapter.java
  12. 130 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamCache.java
  13. 243 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamLineManager.java
  14. 19 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamManageHolder.java
  15. 374 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamManager.java
  16. 105 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DataStreamProcessor.java
  17. 52 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/DatagramHelp.java
  18. 79 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/SwDataStreamCache.java
  19. 74 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/TcpDataStreamAdapter.java
  20. 82 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/UdpDataStreamAdapter.java
  21. 80 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuDatagramProcessor.java
  22. 83 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/dtu/DataStreamDtuLinkDatagramProcessor.java
  23. 86 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwConfigDatagramProcessor.java
  24. 100 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwCrcCheckProcessor.java
  25. 162 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtMatchProcessor.java
  26. 304 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwExtraDatagramProcessor.java
  27. 87 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFileDatagramProcessor.java
  28. 296 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwFixedTimeDatagramProcessor.java
  29. 230 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwHourDatagramProcessor.java
  30. 192 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwImageDatagramProcessor.java
  31. 89 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwLinkHeartProcessor.java
  32. 156 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwMatchProcessor.java
  33. 316 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadRunSettingDatagramProcessor.java
  34. 420 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwReadSettingDatagramProcessor.java
  35. 88 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRebootDatagramProcessor.java
  36. 195 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwRgzsDatagramProcessor.java
  37. 174 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwStatusDatagramProcessor.java
  38. 227 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTestDatagramProcessor.java
  39. 238 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwTimeIntervalDatagramProcessor.java
  40. 62 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/sw/DataStreamSwUnknownProcessor.java
  41. 91 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyCrcCheckProcessor.java
  42. 77 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtConfigFileDatagramProcessor.java
  43. 80 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtFileDatagramProcessor.java
  44. 77 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtLinkHeartDatagramProcessor.java
  45. 196 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtReadIpDatagramProcessor.java
  46. 77 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtRebootDatagramProcessor.java
  47. 195 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtSetIpDatagramProcessor.java
  48. 139 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyExtStatusDatagramProcessor.java
  49. 432 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyFixedTimeDatagramProcessor.java
  50. 84 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyLinkCheckDatagramProcessor.java
  51. 159 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyMatchDatagramProcessor.java
  52. 155 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadBaseSettingDatagramProcessor.java
  53. 93 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadRtuCodeDatagramProcessor.java
  54. 147 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyReadUpModelDatagramProcessor.java
  55. 81 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRebootDatagramProcessor.java
  56. 81 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyRgzsDatagramProcessor.java
  57. 82 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetBaseSettingDatagramProcessor.java
  58. 120 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetClockDatagramProcessor.java
  59. 101 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetRtuCodeDatagramProcessor.java
  60. 81 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzySetUpModelDatagramProcessor.java
  61. 69 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyUnknownProcessor.java
  62. 206 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/processor/szy/DataStreamSzyWarnDatagramProcessor.java
  63. 71 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamKafkaSink.java
  64. 40 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSink.java
  65. 273 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwJpzKafkaSink.java
  66. 71 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwKafkaSink.java
  67. 39 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwMqttSink.java
  68. 40 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSwRtuSink.java
  69. 45 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyKafkaSink.java
  70. 41 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyRtuSink.java
  71. 205 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyXamKafkaSink.java
  72. 18 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/DataTemplateManageHolder.java
  73. 235 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/DataTemplateManager.java
  74. 26 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/Template.java
  75. 23 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/TestState.java
  76. 25 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/AgreementVersion.java
  77. 103 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/DatagramEntity.java
  78. 118 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/DeviceDataDTO.java
  79. 99 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwDatagramHeaderMetadataEnum.java
  80. 212 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwDatagramTypeCodeEnum.java
  81. 734 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwElementCodeEnum.java
  82. 177 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/Szy2012DatagramElementEnum.java
  83. 347 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SzyDatagramTypeCodeEnum.java
  84. 233 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SzyElementCodeEnum.java
  85. 183 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/DataItemTemplate.java
  86. 89 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/DataItemTemplateCache.java
  87. 44 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/ItemTemplate.java
  88. 115 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate58.java
  89. 70 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate70.java
  90. 72 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate71.java
  91. 58 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate72.java
  92. 61 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate73.java
  93. 57 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate74.java
  94. 57 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate75.java
  95. 58 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateAC.java
  96. 56 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateAI.java
  97. 56 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateC.java
  98. 56 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCHLA.java
  99. 55 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCODMN.java
  100. 54 0
      tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCOND.java

+ 109 - 0
tsddcs-commonservice/src/main/java/org/ts/ddcs/common/metadata/TaishanV2JsonPackMetadataEnum.java

@@ -0,0 +1,109 @@
+/**
+ * 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 TaishanV2JsonPackMetadataEnum {
+    /**
+     * 接收时间
+     */
+    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_SITE_TYPE(6, "site_type"),
+    /**
+     * 观测时间
+     */
+    PACK_METADATA_COLLECT_TIME(7, "collect_time"),
+    /**
+     * 数据项
+     */
+    PACK_METADATA_DATA(8, "data");
+
+    private int code;
+
+    private String name;
+
+    TaishanV2JsonPackMetadataEnum(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 (TaishanV2JsonPackMetadataEnum point : TaishanV2JsonPackMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (TaishanV2JsonPackMetadataEnum point : TaishanV2JsonPackMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 78 - 0
tsddcs-datacollect/pom.xml

@@ -0,0 +1,78 @@
+<?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>tsddcs-datacollect</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>
+        <!--<dependency>-->
+            <!--<groupId>org.springframework.data</groupId>-->
+            <!--<artifactId>spring-data-redis</artifactId>-->
+        <!--</dependency>-->
+        <!--REDIS-->
+        <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 21 - 0
tsddcs-datacollect/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/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/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;
+}

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

@@ -0,0 +1,78 @@
+/**
+ * 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 final static String  BASE_KEY_RTU ="rtuCode";
+
+
+
+    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";
+
+	/**
+	 * 数据流工作线程数量
+	 */
+	public static final int STREAM_THREAD_NUM = 4;
+}

+ 6 - 0
tsddcs-datacollect/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/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/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/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];
+    }
+
+}

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

@@ -0,0 +1,201 @@
+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 void clear(){
+
+    }
+
+    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/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/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/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;
+}

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

@@ -0,0 +1,374 @@
+package org.ts.ddcs.dataStream;
+
+import lombok.extern.slf4j.Slf4j;
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+
+import org.rocksdb.RocksDB;
+import org.springframework.data.redis.core.HashOperations;
+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 org.ts.ddcs.main.MainProcessorHolder;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.*;
+
+
+/**
+ * 数据流主模块
+ *
+ * @author dylan
+ */
+@Slf4j
+public class DataStreamManager {
+
+    private RocksDB storeCache;
+
+
+//    private int taskIdelCount = 0;
+
+    /**
+     * 连接适配器
+     */
+    private Map<String, DataStreamAdapter> dataStreamAdapterCache = new ConcurrentHashMap<>(2048);
+
+
+    /**
+     * 数据流队列
+     */
+//    private int currentQueue=0;
+    private LinkedBlockingQueue<String> streamQueue = new LinkedBlockingQueue<>(2048);
+
+    private LinkedBlockingQueue<String> joinQueue = new LinkedBlockingQueue<>(2048);
+
+    private LinkedBlockingQueue<String> runningCacheQueue = new LinkedBlockingQueue<>(2048);
+
+    private LinkedBlockingQueue<String> removeCacheQueue = new LinkedBlockingQueue<>(2048);
+
+    /**
+     * 模板处理器链
+     */
+    private Map<Integer, DataStreamLineManager> streamLineCache = new ConcurrentHashMap<>(BusinessConstant.STREAM_THREAD_NUM);
+
+    /**
+     * 线程池
+     **/
+    private static ThreadFactory batchThreadFactory = new ThreadFactoryBuilder().setNameFormat("batch-thread-pool-%d").build();
+    private static ExecutorService batchThreadPool = new ThreadPoolExecutor(4, 8,
+            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()));
+
+//    private void putAdapter(String key) {
+//        this.readQueue.offer(key);
+//    }
+//
+//    private String getNextAdapter() {
+//        return readQueue.poll();
+//    }
+
+    /**
+     * 创建数据流处理链
+     *
+     * @throws IllegalAccessException
+     * @throws InstantiationException
+     * @throws ClassNotFoundException
+     */
+    private void createDataStreamLine(String templates) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
+        for (int i = 1; i <= BusinessConstant.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 storeCache) throws IllegalAccessException, ClassNotFoundException, InstantiationException {
+        //  try {
+        //数据缓存器
+        this.storeCache = storeCache;
+        //初始化数据流处理器
+        this.createDataStreamLine(templates);
+        //任务定时器
+        this.scheduleExecutor.scheduleWithFixedDelay(() -> {
+            try {
+                //清除数据
+                while (!removeCacheQueue.isEmpty()) {
+                    String key = removeCacheQueue.poll();
+                    DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.remove(key);
+                    dataStreamAdapter.clear();
+                }
+                //处理新进入流处理器
+                while (!joinQueue.isEmpty()) {
+                    String key = joinQueue.poll();
+                    streamQueue.offer(Objects.requireNonNull(key));
+                }
+                //处理上一批次流处理器
+                while (!runningCacheQueue.isEmpty()) {
+                    String key = runningCacheQueue.poll();
+                    streamQueue.offer(Objects.requireNonNull(key));
+                }
+                //生成处理任务
+                boolean idel = false;
+                for (int i = 1; i <= BusinessConstant.STREAM_THREAD_NUM; i++) {
+                    DataStreamLineManager lineManager = streamLineCache.get(i);
+                    if (!lineManager.lock()) {
+                        //有空闲处理器
+                        idel = true;
+                        while (!streamQueue.isEmpty()) {
+                            String key = streamQueue.poll();
+                            DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.get(key);
+                            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);
+                                }
+                            }
+                            if (dataStreamAdapter.isClose() && !dataStreamAdapter.isLock()) {
+                                removeCacheQueue.offer(key);
+                            } else {
+                                runningCacheQueue.offer(key);
+                            }
+                            if (lineManager.lock()) {
+                                break;
+                            }
+                        }
+                    } else {
+                        log.info("数据流处理器已被锁住 {}", i);
+                    }
+                }
+                if (!idel) {
+                    log.info("数据流处理器性能故障!!");
+                    //报警
+                }
+
+
+//                    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, 100, 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);
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                String rtuCode = dataStreamAdapter.getRtuCode();
+                HashOperations<String, String, String> ops = MainProcessorHolder.newInstance().dataProcess.redisTemplate.opsForHash();
+                ops.put(rtuCode, "last_connect_id", dataStreamAdapter.getAdapterKey());
+                ops.put(rtuCode, "last_connect_time", sdf.format(new Date(batchTime)));
+                dataStreamAdapter.setLock(false);
+                dataStreamLineManager.lock(false);
+            } catch (Exception e) {
+                log.error(this.getClass().getName(), e);
+            }
+            return 0;
+        }
+    }
+
+
+    /**
+     * 注册连接
+     *
+     * @param adapter
+     */
+    public void regConnect(DataStreamAdapter adapter) {
+        this.dataStreamAdapterCache.put(adapter.getAdapterKey(), adapter);
+        this.joinQueue.offer(adapter.getAdapterKey());
+    }
+
+//    /**
+//     * 关闭连接
+//     *
+//     * @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 boolean responseEvent(String key, byte[] respBlock) {
+        if (this.dataStreamAdapterCache.containsKey(key)) {
+            DataStreamAdapter dataStreamAdapter = this.dataStreamAdapterCache.get(key);
+            if (!dataStreamAdapter.isClose()) {
+                dataStreamAdapter.output(respBlock);
+                return true;
+            } else {
+                log.info("运行错误,链接已经提前关闭: {}", key);
+            }
+        }
+        return false;
+    }
+
+//    public DataStreamAdapter getAdapter(String rtuCode) {
+//        Set<String> keySet = dataStreamAdapterCache.keySet();
+//        for (String key : keySet) {
+//            DataStreamAdapter dataStreamAdapter = dataStreamAdapterCache.get(key);
+//            if (!dataStreamAdapter.isClose()) {
+//                String stcd = dataStreamAdapter.getRtuCode();
+//                if (null != stcd && stcd.equals(rtuCode)) {
+//                    return dataStreamAdapter;
+//                }
+//            }
+//        }
+//        return null;
+//    }
+}

+ 105 - 0
tsddcs-datacollect/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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;
+    }
+
+}

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

@@ -0,0 +1,71 @@
+/**
+ * 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.rocksdb.RocksDBException;
+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.main.MainProcessorHolder;
+import org.ts.ddcs.metadata.DataStreamCacheMetadata;
+
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.time.ZoneId;
+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 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");
+        Date dt = Date.from(this.dataStreamCache.getPickPacketTime().atZone(ZoneId.systemDefault()).toInstant());
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_FROM_TIME.getName(), timeFormat.format(dt));
+        body.put(TaishanV1JsonPackMetadataEnum.PACK_METADATA_DATAGRAM_TYPE.getName(), this.dataStreamCache.getDatagramCode());
+        log.info("data item :{}", body.toJSONString());
+        String key = "topic."+KafkaConstants.TOPIC_TS_V1_DATAGRAM;
+        try {
+            byte[] topicBuff = MainProcessorHolder.newInstance().dataProcess.getStoreCache(key);
+            String topic = new String(topicBuff,"utf-8");
+            log.info("topic {}",topic);
+            KafkaClient.messageSubmit(KafkaConstants.TOPIC_TS_V1_DATAGRAM, body.toJSONString());
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace();
+        } catch (RocksDBException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 40 - 0
tsddcs-datacollect/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/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/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/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){
+
+    }
+}

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

@@ -0,0 +1,40 @@
+/**
+ * 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 DataStreamSwRtuSink 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 to rtu {}  ", dataStreamAdapter.getRtuCode());
+
+    }
+}

+ 45 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyKafkaSink.java

@@ -0,0 +1,45 @@
+/**
+ * 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 DataStreamSzyKafkaSink 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()));
+          // for (JSONObject jsonObject : jsonObjects){
+              // log.info("data item :{}",jsonObject.toJSONString());
+               //KafkaClient.messageSubmit("queue-waiting-process-datagram",jsonObject.toJSONString());
+         //  }
+    }
+}

+ 41 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyRtuSink.java

@@ -0,0 +1,41 @@
+/**
+ * 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 DataStreamSzyRtuSink 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()));
+
+    }
+}

+ 205 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/dataStream/sink/DataStreamSzyXamKafkaSink.java

@@ -0,0 +1,205 @@
+/**
+ * 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.metadata.DatagramMetadataEnum;
+import org.ts.ddcs.enums.SzyElementCodeEnum;
+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 org.ts.ddcs.metadata.szy.*;
+import org.ts.ddcs.tools.CloumnHelp;
+import org.ts.ddcs.tools.KeyStoreHelp;
+
+import java.util.List;
+import java.util.Map;
+
+/***
+ * Date:2023/8/28
+ * Title: 兴安盟水资源项目
+ * Description:输出流量、累计流量和小时流量
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Slf4j
+public class DataStreamSzyXamKafkaSink 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()));
+        for (Map<String, Object> data : elementDatas) {
+            JSONObject jsonBody = new JSONObject();
+            //  if (data.containsKey(JsonPackMetadataEnum.PACK_METADATA_ELEMENT_TYPE.getName())) {
+            String elementCode = (String) data.get(DatagramMetadataEnum.CACHE_METADATA_ELEMENT_CODE.getName());
+            if (elementCode.equals(SzyElementCodeEnum.CODE_FLOW_RATE.getCode())) {
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+                //   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, SzyElementCodeEnum.CODE_FLOW_RATE.getCode(), SzyFlowRateMetadataEnum.METADATA_CODE_Q.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyFlowRateMetadataEnum.METADATA_CODE_Q.getName(), CloumnHelp.getDouble(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_FLOW_RATE.getCode(), SzyFlowRateMetadataEnum.METADATA_CODE_ACC_Q.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyFlowRateMetadataEnum.METADATA_CODE_ACC_Q.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_FLOW_RATE.getCode(), SzyFlowRateMetadataEnum.METADATA_CODE_HOUR_Q.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyFlowRateMetadataEnum.METADATA_CODE_HOUR_Q.getName(), CloumnHelp.getLong(cloumn));
+                }
+                //  }
+                log.info("data item :{}", jsonBody.toJSONString());
+               // KafkaClient.messageSubmit("topic-szy-water-flow-rate", jsonBody.toJSONString());
+            } else if (elementCode.equals(SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode())) {
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName()));
+                jsonBody.put(SzyStatusMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+                // 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, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_WORK_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_WORK_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_IC_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_IC_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_VALUE_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_VALUE_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_WATER_PUMP_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_WATER_PUMP_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_DOOR_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_DOOR_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_STATUS.getCode(), SzyStatusMetadataEnum.METADATA_POWER_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyStatusMetadataEnum.METADATA_POWER_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                //  }
+                log.info("data item :{}", jsonBody.toJSONString());
+                //KafkaClient.messageSubmit("topic-szy-rtu-status", jsonBody.toJSONString());
+            } else if (elementCode.equals(SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode())) {
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName()));
+                jsonBody.put(SzyWarnMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+                //  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, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_AC_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_AC_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_BT_V_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_BT_V_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_WATER_LEVEL_OUT_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_WATER_LEVEL_OUT_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_FLOW_OUT_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_FLOW_OUT_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_WATER_QUALITY_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_WATER_QUALITY_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_FLOW_SENSOR_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_FLOW_SENSOR_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_WATER_PUMP_STATUS.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_WATER_PUMP_STATUS.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_WATER_LEVEL_SENSOR_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_WATER_LEVEL_SENSOR_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_WATER_PRESURE.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_WATER_PRESURE.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_RESERVE.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_RESERVE.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_IC_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_IC_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_CONTROL_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_CONTROL_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_SURPLUS_WATER.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_SURPLUS_WATER.getName(), CloumnHelp.getLong(cloumn));
+                }
+                cloumn = KeyStoreHelp.getOne(elementDatas, SzyElementCodeEnum.CODE_EXT_RTU_WARN.getCode(), SzyWarnMetadataEnum.METADATA_DOOR_WARN.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWarnMetadataEnum.METADATA_DOOR_WARN.getName(), CloumnHelp.getLong(cloumn));
+                }
+
+                //  }
+                log.info("data item :{}", jsonBody.toJSONString());
+              //  KafkaClient.messageSubmit("topic-szy-rtu-warn", jsonBody.toJSONString());
+
+            } else if (elementCode.equals(SzyElementCodeEnum.CODE_WATER_LEVEL.getCode())) {
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName()));
+                jsonBody.put(SzyWaterLevelMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+                //   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, SzyElementCodeEnum.CODE_WATER_LEVEL.getCode(), SzyWaterLevelMetadataEnum.METADATA_CODE_LEVEL.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyWaterLevelMetadataEnum.METADATA_CODE_LEVEL.getName(), CloumnHelp.getDouble(cloumn));
+                }
+                //  }
+                log.info("data item :{}", jsonBody.toJSONString());
+               // KafkaClient.messageSubmit("topic-szy-water-level", jsonBody.toJSONString());
+            } else if (elementCode.equals(SzyElementCodeEnum.CODE_FLOW_SPEED.getCode())) {
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_FROM_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_PICK_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_UP_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_UP_TIME.getName()));
+                jsonBody.put(SzyFlowRateMetadataEnum.METADATA_COLLECT_TIME.getName(), this.dataStreamCache.getStringValue(DataStreamCacheMetadata.METADATA_COLLECT_TIME.getName()));
+                jsonBody.put(SzyFlowSpeedMetadataEnum.METADATA_RTU_CODE.getName(), this.dataStreamCache.getRtuCode());
+                //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, SzyElementCodeEnum.CODE_FLOW_SPEED.getCode(), SzyFlowSpeedMetadataEnum.METADATA_CODE_FLOWSPEED.getName());
+                if (null != cloumn) {
+                    jsonBody.put(SzyFlowSpeedMetadataEnum.METADATA_CODE_FLOWSPEED.getName(), CloumnHelp.getDouble(cloumn));
+                }
+                //  }
+                log.info("data item :{}", jsonBody.toJSONString());
+               // KafkaClient.messageSubmit("topic-szy-flow-speed", jsonBody.toJSONString());
+            }
+            // }
+        }
+    }
+}

+ 18 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/DataTemplateManageHolder.java

@@ -0,0 +1,18 @@
+package  org.ts.ddcs.datatemplate;
+
+/**
+ * 数据模板实例
+ *
+ * @author dylan
+ */
+public class DataTemplateManageHolder {
+    private static class InstanceHolder {
+        static DataTemplateManageHolder instance = new DataTemplateManageHolder();
+    }
+
+    public static DataTemplateManageHolder newInstance() {
+        return DataTemplateManageHolder.InstanceHolder.instance;
+    }
+
+    public DataTemplateManager dataTemplateManager;
+}

+ 235 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/DataTemplateManager.java

@@ -0,0 +1,235 @@
+package org.ts.ddcs.datatemplate;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.enums.AgreementEnum;
+import org.ts.ddcs.itemdatatemplate.ItemTemplate;
+import org.dom4j.Document;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.dom4j.io.SAXReader;
+
+import java.io.File;
+import java.util.*;
+
+
+/**
+ * 数据报文模板管理主模块
+ *
+ * @author swp
+ */
+@Data
+@Slf4j
+public class DataTemplateManager {
+
+    private Map<String, List<Template>> templateMap = new HashMap<>(10);
+    private Map<String, List<ItemTemplate>> itemTemplateMap = new HashMap<>(200);
+
+    /**
+     * 初始化模板
+     *
+     * @param dir       模板文档目录
+     * @param templates 模板名称
+     */
+    public boolean init(String dir, String templates) {
+        try {
+            String[] list = templates.split(",");
+            if (list.length > 0) {
+                for (String t : list) {
+                    if (AgreementEnum.AGREEMENT_SW.getName().equals(t)) {
+                        //加载模板配置文件
+                        String templateDoc = dir + File.separator + t.toLowerCase() + ".xml";
+                        File templateFile = new File(templateDoc);
+                        if (!templateFile.exists()) {
+                            return false;
+                        }
+                        List<Template> templateList = this.loadTemplateConfig(templateDoc);
+                        this.templateMap.put(AgreementEnum.AGREEMENT_SW.getName(), templateList);
+                        //加载编码要素配置文件
+                        String itemTemplateDoc = dir + File.separator + t.toLowerCase() + "-item.xml";
+                        File itemTemplateFile = new File(itemTemplateDoc);
+                        if (itemTemplateFile.exists()) {
+                            List<ItemTemplate> itemTemplateList = this.loadItemTemplateConfig(itemTemplateDoc);
+                            this.itemTemplateMap.put(AgreementEnum.AGREEMENT_SW.getName(), itemTemplateList);
+                        }
+                    } else if (AgreementEnum.AGREEMENT_SW_EXT.getName().equals(t)) {
+                        //加载模板配置文件
+                        String templateDoc = dir + File.separator + t.toLowerCase() + ".xml";
+                        File templateFile = new File(templateDoc);
+                        if (!templateFile.exists()) {
+                            return false;
+                        }
+                        List<Template> templateList = this.loadTemplateConfig(templateDoc);
+                        this.templateMap.put(AgreementEnum.AGREEMENT_SW_EXT.getName(), templateList);
+                        //加载编码要素配置文件
+                        String itemTemplateDoc = dir + File.separator + t.toLowerCase() + "-item.xml";
+                        File itemTemplateFile = new File(itemTemplateDoc);
+                        if (itemTemplateFile.exists()) {
+                            List<ItemTemplate> itemTemplateList = this.loadItemTemplateConfig(itemTemplateDoc);
+                            this.itemTemplateMap.put(AgreementEnum.AGREEMENT_SW_EXT.getName(), itemTemplateList);
+                        }
+                    } else if (AgreementEnum.AGREEMENT_SZY.getName().equals(t)) {
+                        //加载模板配置文件
+                        String templateDoc = dir + File.separator + t.toLowerCase() + ".xml";
+                        File templateFile = new File(templateDoc);
+                        if (!templateFile.exists()) {
+                            return false;
+                        }
+                        List<Template> templateList = this.loadTemplateConfig(templateDoc);
+                        this.templateMap.put(AgreementEnum.AGREEMENT_SZY.getName(), templateList);
+                        //加载编码要素配置文件
+                        String itemTemplateDoc = dir + File.separator + t.toLowerCase() + "-item.xml";
+                        File itemTemplateFile = new File(itemTemplateDoc);
+                        if (itemTemplateFile.exists()) {
+                            List<ItemTemplate> itemTemplateList = this.loadItemTemplateConfig(itemTemplateDoc);
+                            this.itemTemplateMap.put(AgreementEnum.AGREEMENT_SZY.getName(), itemTemplateList);
+                        }
+                    }
+                }
+            }
+            return true;
+        } catch (Exception e) {
+            log.error("error", e);
+            return false;
+        }
+    }
+
+//    public boolean hasTemplate(String agreement) {
+//        if (this.templateMap.containsKey(agreement.toUpperCase())) {
+//            return true;
+//        }
+//        return false;
+//    }
+
+    /**
+     * 加载配置文件
+     *
+     * @param templates
+     * @return
+     * @throws DocumentException
+     */
+    private List<Template> loadTemplateConfig(String templates) throws DocumentException {
+        List<Template> templateList = new LinkedList<>();
+        SAXReader reader = new SAXReader();
+        Document document = reader.read(new File(templates));
+        Element root = document.getRootElement();
+        Element templateNode = root.element("Templates");
+        List items = templateNode.elements("Item");
+        for (Object o : items
+        ) {
+            Element e = (Element) o;
+            String enable = e.element("Enable").getTextTrim();
+            if ("1".equals(enable)) {
+                Template template = new Template();
+                template.setType(e.element("Type").getTextTrim());
+                template.setStreamProcessorClass(e.element("StreamProcessor").getTextTrim());
+                template.setProcessorName(e.element("ProcessorName").getTextTrim());
+                template.setTemplateName(e.element("TemplateName").getTextTrim());
+                templateList.add(template);
+            }
+        }
+        return templateList;
+    }
+
+    /**
+     * 导入编码要素配置模板
+     *
+     * @param templates
+     * @return
+     * @throws DocumentException
+     */
+    private List<ItemTemplate> loadItemTemplateConfig(String templates) throws DocumentException {
+        List<ItemTemplate> templateList = new LinkedList<>();
+        SAXReader reader = new SAXReader();
+        Document document = reader.read(new File(templates));
+        Element root = document.getRootElement();
+        Element templatesNode = root.element("Templates");
+        List items = templatesNode.elements("Item");
+        for (Object o : items
+        ) {
+            Element e = (Element) o;
+            String enable = e.element("Enable").getTextTrim();
+            if ("1".equals(enable)) {
+                ItemTemplate t = new ItemTemplate();
+                String dataTemplateClass = e.element("DataTemplate").getTextTrim();
+                t.setItemTemplateClass(dataTemplateClass);
+                String func = e.element("Func").getTextTrim();
+                t.setFunc(func);
+                String desc = e.element("Desc").getTextTrim();
+                t.setDesc(desc);
+                String funcName = e.element("FuncName").getTextTrim();
+                t.setFuncName(funcName);
+                String unit = e.element("Unit").getTextTrim();
+                t.setUnit(unit);
+                templateList.add(t);
+            }
+        }
+        return templateList;
+    }
+
+    /**
+     * 返回指定规约的模板配置
+     *
+     * @param agreement
+     * @return
+     */
+    public List<Template> cloneTemplateLine(String agreement) {
+        if (this.templateMap.containsKey(agreement)) {
+            return this.templateMap.get(agreement);
+        }
+        return null;
+    }
+
+    /**
+     * 生成模板配置实例
+     *
+     * @param template
+     * @return
+     */
+//    private Template cloneTemplate(Template template) {
+//        Template newTemplate = new Template();
+//        newTemplate.setTemplateName(template.getTemplateName());
+//        newTemplate.setDataTemplateClass(template.getDataTemplateClass());
+//        newTemplate.setStreamProcessorClass(template.getStreamProcessorClass());
+//        newTemplate.setDataProcessorClass(template.getDataProcessorClass());
+//        newTemplate.setFeatureWeight(template.getFeatureWeight());
+//        if (null != template.getFeatureKey()) {
+//            byte[] featureKey = new byte[template.getFeatureKey().length];
+//            System.arraycopy(template.getFeatureKey(), 0, featureKey, 0, featureKey.length);
+//            newTemplate.setFeatureKey(featureKey);
+//        }
+//        if (null != template.getFeatureIndex()) {
+//            byte[] featureIndex = new byte[template.getFeatureIndex().length];
+//            System.arraycopy(template.getFeatureIndex(), 0, featureIndex, 0, featureIndex.length);
+//            newTemplate.setFeatureIndex(featureIndex);
+//        }
+//        return newTemplate;
+//    }
+
+    /**
+     * 返回编码要素配置模板
+     *
+     * @param agreement
+     * @return
+     */
+    public List<ItemTemplate> cloneItemTemplateLine(String agreement) {
+        if (this.itemTemplateMap.containsKey(agreement)) {
+            return this.itemTemplateMap.get(agreement);
+        }
+        return null;
+    }
+
+    /**
+     * 生成编码要素配置模板
+     *
+     * @param itemTemplate
+     * @return
+     */
+//    private ItemTemplate cloneItemTemplate(ItemTemplate itemTemplate) {
+//        ItemTemplate newTemplate = new ItemTemplate();
+//        newTemplate.setFunc(itemTemplate.getFunc());
+//        newTemplate.setDesc(itemTemplate.getDesc());
+//        newTemplate.setItemTemplateClass(itemTemplate.getItemTemplateClass());
+//        return newTemplate;
+//    }
+}

+ 26 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/Template.java

@@ -0,0 +1,26 @@
+package org.ts.ddcs.datatemplate;
+
+
+import lombok.Data;
+/**
+ * created by swp on 2017/8/29
+ */
+@Data
+public class Template {
+    /**
+     * 模板类型
+     */
+    public String type;
+    /**
+     * 流处理器类名
+     */
+    public String streamProcessorClass;
+    /**
+     * 数据处理器名称
+     */
+    public String processorName;
+    /**
+     * 模板名称
+     */
+    public String templateName;
+}

+ 23 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/datatemplate/TestState.java

@@ -0,0 +1,23 @@
+package org.ts.ddcs.datatemplate;
+
+/**
+ * created by swp on 2017/8/22
+ */
+public enum TestState {
+    /**
+     * 未知
+     */
+    UNKNOWN,
+    /**
+     * 查找
+     */
+    LOOK,
+    /**
+     * 匹配
+     */
+    MATHCE,
+    /**
+     * 错误
+     */
+    ERROR
+}

+ 25 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/AgreementVersion.java

@@ -0,0 +1,25 @@
+package  org.ts.ddcs.entity;
+
+public enum AgreementVersion {
+    AGREEMENT_KIND_SW("1","2014水文"),
+    AGREEMENT_KIND_SZY("2","2012水资源"),
+    AGREEMENT_KIND_DTU("3","DTU透传"),
+    AGREEMENT_KIND_SW_EXT("4","DTU透传"),
+    AGREEMENT_KIND_JT("5","DTU透传");
+
+    private final String id;
+    private final String name;
+
+    AgreementVersion(String id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 103 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/DatagramEntity.java

@@ -0,0 +1,103 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/13
+ */
+package org.ts.ddcs.entity;
+
+import lombok.Data;
+
+import java.util.Date;
+
+/***
+ * Date:2023/10/13
+ * Title:文件所属模块(必须填写)
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Data
+public class DatagramEntity {
+    /**
+     * 测站分类码
+     */
+    private String st;
+    /**
+     * 服务器接收时间
+     */
+    private Date fromTime;
+    /**
+     * 测站采集时间
+     */
+    private Date tm;
+    /**
+     * 测站编码
+     */
+    private String stcd;
+    /**
+     * 瞬时水位
+     */
+    private Double z;
+    /**
+     * 累计流量
+     */
+    private Long accf;
+    /**
+     * 当前瞬时流速
+     */
+    private Double vj;
+    /**
+     * 瞬时流量、抽水流量
+     */
+    private Double q;
+    /**
+     * 瞬时气温
+     */
+    private Double ai;
+    /**
+     * 湿度
+     */
+    private Double mst;
+    /**
+     * PM2.5
+     */
+    private Long pm;
+    /**
+     * 气压
+     */
+    private Long fl;
+    /**
+     * 风速
+     */
+    private Double us;
+    /**
+     * 风向
+     */
+    private Long uc;
+    /**
+     * 紫外线
+     */
+    private Double uv;
+    /**
+     * 太阳总辐射
+     */
+    private Long rad;
+    /**
+     * 二氧化氮
+     */
+    private Double nd;
+    /**
+     * 电导率
+     */
+    private Long cond;
+    /**
+     * 瞬时水温
+     */
+    private Double c;
+    /**
+     * PH值
+     */
+    private Double ph;
+}

+ 118 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/entity/DeviceDataDTO.java

@@ -0,0 +1,118 @@
+package  org.ts.ddcs.entity;
+
+public class DeviceDataDTO {
+    private double  airHumidity;// (number, optional): 空气湿度 ,
+    private double  airTemp;//number, optional): 空气温度 ,
+   // private float  ammonia;//number, optional): 氨气 ,
+  //  private float  apar;//number, optional): 光合有效辐射 ,
+    private double  atmosphericPressure;//number, optional): 大气压力 ,
+   // private  int bugsNum;//integer, optional): 虫情数量 ,
+  //  private String  classify="";//string, optional): 类型 ,
+ //   private float  co2;//number, optional): 二氧化碳 ,
+    private String deviceSn="";//string, optional): SN ,
+  //  private float  dewPoint;//number, optional): 空气露点 ,
+    private long genTime2;//integer, optional): 采集时间 ,
+//   private float  illumination;//number, optional): 光照强度 ,
+ //   private float  leadacidVoltage;//number, optional): 铅酸电池电压 ,
+//    private String paramJson="";//string, optional): 其他参数JSON ,
+ //   private float   pm25;//number, optional): PM25 ,
+    private double  rainfall;//number, optional): 雨量 ,
+   // private float   rainfalls;//number, optional): 日雨量 ,
+  //  private float  residualChlorine;//number, optional): 余氯 ,
+   // private float  soilEc;//number, optional): 土壤EC ,
+   // private float  soilHumidity;//number, optional): 土壤湿度 ,
+//    private float  soilHumidity1;//number, optional): 土壤深度1湿度 ,
+//    private float  soilHumidity2;//number, optional): 土壤深度2湿度 ,
+//    private float  soilHumidity3;//number, optional): 土壤深度3湿度 ,
+//    private float  soilHumidity4;//number, optional): 土壤深度4湿度 ,
+//    private float  soilHumidity5;//number, optional): 土壤深度5湿度 ,
+//    private float  soilHumidity6;//number, optional): 土壤深度6湿度 ,
+//    private float   soilPh;//number, optional): 土壤PH ,
+//    private float  soilTemp;//number, optional): 土壤温度 ,
+//    private float  soilTemp1;//number, optional): 土壤深度1温度 ,
+//    private float  soilTemp2;//number, optional): 土壤深度2温度 ,
+//    private float  soilTemp3;//number, optional): 土壤深度3温度 ,
+//    private float  soilTemp4;//number, optional): 土壤深度4温度 ,
+//    private float   soilTemp5;//number, optional): 土壤深度5温度 ,
+//    private float  soilTemp6;//number, optional): 土壤深度6温度 ,
+//    private float   solarRadiation;//number, optional): 太阳辐射 ,
+//    private float   voltage;//number, optional): 电压 ,
+//    private float   waterAnmonia;//number, optional): 氨氮 ,
+//    private float    waterConductivity;//number, optional): 电导率 ,
+//    private float   waterDo;//number, optional): 溶解氧 ,
+//    private float   waterEc;//number, optional): 水EC ,
+//    private float   waterOxygen;//number, optional): 水痒含量 ,
+//    private float   waterPh;//number, optional): PH ,
+//    private float  waterSalinity;//number, optional): 水质盐度 ,
+//    private float  waterTemp;//number, optional): 水温 ,
+//    private float   waterTu;//number, optional): 浊度 ,
+    private double  windDirection;//number, optional): 风向 ,
+    private double   windVelocity;//number, optional): 风速 ,
+//    private float  windd2m;//number, optional): 2分钟风向 ,
+//    private float   winds2m;//number, optional): 2分钟风速
+
+
+    public double getAirHumidity() {
+        return airHumidity;
+    }
+
+    public void setAirHumidity(double airHumidity) {
+        this.airHumidity = airHumidity;
+    }
+
+    public double getAirTemp() {
+        return airTemp;
+    }
+
+    public void setAirTemp(double airTemp) {
+        this.airTemp = airTemp;
+    }
+
+    public double getAtmosphericPressure() {
+        return atmosphericPressure;
+    }
+
+    public void setAtmosphericPressure(double atmosphericPressure) {
+        this.atmosphericPressure = atmosphericPressure;
+    }
+
+    public String getDeviceSn() {
+        return deviceSn;
+    }
+
+    public void setDeviceSn(String deviceSn) {
+        this.deviceSn = deviceSn;
+    }
+
+    public long getGenTime2() {
+        return genTime2;
+    }
+
+    public void setGenTime2(long genTime2) {
+        this.genTime2 = genTime2;
+    }
+
+    public double getRainfall() {
+        return rainfall;
+    }
+
+    public void setRainfall(double rainfall) {
+        this.rainfall = rainfall;
+    }
+
+    public double getWindDirection() {
+        return windDirection;
+    }
+
+    public void setWindDirection(double windDirection) {
+        this.windDirection = windDirection;
+    }
+
+    public double getWindVelocity() {
+        return windVelocity;
+    }
+
+    public void setWindVelocity(double windVelocity) {
+        this.windVelocity = windVelocity;
+    }
+}

+ 99 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwDatagramHeaderMetadataEnum.java

@@ -0,0 +1,99 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.enums;
+
+/*** 
+ * Date:2023/10/31
+ * Title:水文报文头元数据定义
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum SwDatagramHeaderMetadataEnum {
+    /**
+     * 接收时间
+     */
+    METADATA_FROM_TIME(0, "from_time"),
+
+    /**
+     * 采集时间
+     */
+    METADATA_COLLECT_TIME(1, "tm"),
+
+    /**
+     * 上报时间
+     */
+    METADATA_UP_TIME(2, "up_time"),
+    /**
+     * 测站编码
+     */
+    METADATA_RTU_CODE(3, "rtu_code"),
+    /**
+     * 原始报文
+     */
+    METADATA_DATAGRAM(4, "datagram"),
+    /**
+     * 报文类型
+     */
+    METADATA_DATAGRAM_KIND(5, "datagram_kind");
+
+    private int code;
+
+    private String name;
+
+    SwDatagramHeaderMetadataEnum(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 (SwDatagramHeaderMetadataEnum point : SwDatagramHeaderMetadataEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (SwDatagramHeaderMetadataEnum point : SwDatagramHeaderMetadataEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 212 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwDatagramTypeCodeEnum.java

@@ -0,0 +1,212 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.enums;
+
+/*** 
+ * Date:2023/10/31
+ * Title:水文规约报文类型定义
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum SwDatagramTypeCodeEnum {
+    /**
+     * 链路检测
+     */
+    DATAGRAM_CODE_2F(0x2F, "2F"),
+    /**
+     * 测试报
+     */
+    DATAGRAM_CODE_30(0x30, "30"),
+    /**
+     * 均匀时段水文信息报
+     */
+    DATAGRAM_CODE_31(0x31, "31"),
+    /**
+     * 定时报
+     */
+    DATAGRAM_CODE_32(0x32, "32"),
+    /**
+     * 加报
+     */
+    DATAGRAM_CODE_33(0x33, "33"),
+    /**
+     * 小时报
+     */
+    DATAGRAM_CODE_34(0x34, "34"),
+    /**
+     * 人工置数
+     */
+    DATAGRAM_CODE_35(0x35, "35"),
+    /**
+     * 遥测站图片报或中心站查询遥测站图片采集
+     * 信息
+     */
+    DATAGRAM_CODE_36(0x36, "36"),
+    /**
+     * 中心站查询遥测站实时数据
+     */
+    DATAGRAM_CODE_37(0x37, "37"),
+    /**
+     * 中心站查询遥测站时段数据
+     */
+    DATAGRAM_CODE_38(0x38, "38"),
+    /**
+     * 中心站查询遥测站人工置数
+     */
+    DATAGRAM_CODE_39(0x39, "39"),
+    /**
+     * 中心站查询遥测站指定要素数据
+     */
+    DATAGRAM_CODE_3A(0x3A, "3A"),
+    /**
+     * 中心站修改遥测站基本配置表
+     */
+    DATAGRAM_CODE_40(0x40, "40"),
+    /**
+     * 中心站读取遥测站基本配置表/遥测站自报
+     * 基本配置表
+     */
+    DATAGRAM_CODE_41(0x41, "41"),
+    /**
+     * 中心站修改遥测站运行参数配置表
+     */
+    DATAGRAM_CODE_42(0x42, "42"),
+    /**
+     * 中心站读取遥测站运行参数配置表/遥测站
+     * 自报运行参数配置表
+     */
+    DATAGRAM_CODE_43(0x43, "43"),
+    /**
+     * 查询水泵电机实时工作数据
+     */
+    DATAGRAM_CODE_44(0x44, "44"),
+    /**
+     *查询遥测终端软件版本
+     */
+    DATAGRAM_CODE_45(0x45, "45"),
+    /**
+     * 查询遥测站状态和报警信息
+     */
+    DATAGRAM_CODE_46(0x46, "46"),
+    /**
+     *初始化固态存储数据
+     */
+    DATAGRAM_CODE_47(0x47, "47"),
+    /**
+     *恢复终端出厂设置
+     */
+    DATAGRAM_CODE_48(0x48, "48"),
+    /**
+     *修改密码
+     */
+    DATAGRAM_CODE_49(0x49, "49"),
+    /**
+     *设置遥测站时钟
+     */
+    DATAGRAM_CODE_4A(0x4A, "4A"),
+    /**
+     * 设置遥测终端 IC 卡状态
+     */
+    DATAGRAM_CODE_4B(0x4B, "4B"),
+    /**
+     *控制水泵开关命令/水泵状态信息自报
+     */
+    DATAGRAM_CODE_4C(0x4C, "4C"),
+    /**
+     *控制阀门开关命令/阀门状态信息自报
+     */
+    DATAGRAM_CODE_4D(0x4D, "4D"),
+    /**
+     *控制闸门开关命令/闸门状态信息自报
+     */
+    DATAGRAM_CODE_4E(0x4E, "4E"),
+    /**
+     * 水量定值控制命令
+     */
+    DATAGRAM_CODE_4F(0x4F, "4F"),
+    /**
+     *中心站查询遥测站事件记录
+     */
+    DATAGRAM_CODE_50(0x50, "50"),
+    /**
+     *中心站查询遥测站时钟
+     */
+    DATAGRAM_CODE_51(0x51, "51"),
+    /**
+     * 上传文件
+     */
+    DATAGRAM_CODE_EX_F1(0xF1, "F1"),
+    /**
+     * 重启
+     */
+    DATAGRAM_CODE_EX_F3(0xF3, "F3"),
+    /**
+     * 上传配置文件更新
+     */
+    DATAGRAM_CODE_EX_F4(0xF4, "F4"),
+    /**
+     * 状态报
+     */
+    DATAGRAM_CODE_EX_F5(0xF5, "F5");
+
+    private int code;
+
+    private String name;
+
+    SwDatagramTypeCodeEnum(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 (SwDatagramTypeCodeEnum point : SwDatagramTypeCodeEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     *
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (SwDatagramTypeCodeEnum point : SwDatagramTypeCodeEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 734 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SwElementCodeEnum.java

@@ -0,0 +1,734 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2023/10/31
+ */
+package org.ts.ddcs.enums;
+
+/*** 
+ * Date:2023/10/31
+ * Title:水文规约编码要素元数据定义
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum SwElementCodeEnum {
+    /**
+     * 观测时间引导符
+     */
+    CODE_TT("F0", "TT"),
+
+    /**
+     * 测站编码引导符
+     */
+    CODE_ST("F1", "ST"),
+
+    /**
+     * 人工置数
+     */
+    CODE_RGZS("F2", "RGZS"),
+
+    /**
+     * 图片信息
+     */
+    CODE_PIC("F3", "PIC"),
+
+    /**
+     * 1 小时内每 5 分钟时段雨量 e(每组雨量占 1 字节
+     * HEX,最大值 25.4 毫米,数据中不含小数点;FFH
+     * 表示非法数据。)
+     */
+    CODE_DRP("F4", "DRP"),
+
+    /**
+     * 1 小时内 5 分钟间隔相对水位 1(每组水位占 2 字节
+     * HEX,分辨力是为厘米,最大值为 655.34 米,数
+     * 据中不含小数点;FFFFH 表示非法数据);对于河道、
+     * 闸坝(泵)站分别表示河道水位、闸(站)上水位。
+     */
+    CODE_DRZ1("F5", "DRZ1"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 2;对于闸坝(泵)
+     * 站表示闸(站)下水位。
+     */
+    CODE_DRZ2("F6", "DRZ2"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 3
+     */
+    CODE_DRZ3("F7", "DRZ3"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 4
+     */
+    CODE_DRZ4("F8", "DRZ4"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 5
+     */
+    CODE_DRZ5("F9", "DRZ5"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 6
+     */
+    CODE_DRZ6("FA", "DRZ6"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 7
+     */
+    CODE_DRZ7("FB", "DRZ7"),
+    /**
+     * 1 小时内 5 分钟间隔相对水位 8
+     */
+    CODE_DRZ8("FC", "DRZ8"),
+    /**
+     * 流速批量数据传输
+     */
+    CODE_DATA("FD", "DATA"),
+    /**
+     * 断面面积
+     */
+    CODE_AC("01", "AC"),
+    /**
+     * 瞬时气温
+     */
+    CODE_AI("02", "AI"),
+    /**
+     * 瞬时水温
+     */
+    CODE_C("03", "C"),
+    /**
+     * 时间步长码
+     */
+    CODE_DRxnn("04", "DRxnn"),
+    /**
+     * 时段长,降水、引排水、抽水历时
+     */
+    CODE_DT("05", "DT"),
+    /**
+     * 日蒸发量
+     */
+    CODE_ED("06", "ED"),
+    /**
+     * 当前蒸发
+     */
+    CODE_EJ("07", "EJ"),
+    /**
+     * 气压
+     */
+    CODE_FL("08", "FL"),
+    /**
+     * 闸坝、水库闸门开启高度
+     */
+    CODE_GH("09", "GH"),
+    /**
+     * 输水设备、闸门(组)编号
+     */
+    CODE_GN("0A", "GN"),
+    /**
+     * 输水设备类别
+     */
+    CODE_GS("0B", "GS"),
+    /**
+     * 水库、闸坝闸门开启孔数
+     */
+    CODE_GT("0C", "GT"),
+    /**
+     * 地温
+     */
+    CODE_GTP("0D", "GTP"),
+    /**
+     * 地下水瞬时埋深
+     */
+    CODE_H("0E", "H"),
+    /**
+     * 波浪高度
+     */
+    CODE_HW("0F", "HW"),
+    /**
+     * 10 厘米处土壤含水量
+     */
+    CODE_M10("10", "M10"),
+    /**
+     * 20 厘米处土壤含水量
+     */
+    CODE_M20("11", "M20"),
+    /**
+     * 30 厘米处土壤含水量
+     */
+    CODE_M30("12", "M30"),
+    /**
+     * 40 厘米处土壤含水量
+     */
+    CODE_M40("13", "M40"),
+    /**
+     * 50 厘米处土壤含水量
+     */
+    CODE_M50("14", "M50"),
+    /**
+     * 60 厘米处土壤含水量
+     */
+    CODE_M60("15", "M60"),
+    /**
+     * 80 厘米处土壤含水量
+     */
+    CODE_M80("16", "M80"),
+    /**
+     * 100 厘米处土壤含水量
+     */
+    CODE_M100("17", "M100"),
+    /**
+     * 湿度
+     */
+    CODE_MST("18", "MST"),
+    /**
+     * 开机台数
+     */
+    CODE_NS("19", "NS"),
+    /**
+     * 1 小时时段降水量
+     */
+    CODE_P1("1A", "P1"),
+    /**
+     * 2 小时时段降水量
+     */
+    CODE_P2("1B", "P2"),
+    /**
+     * 3 小时时段降水量
+     */
+    CODE_P3("1C", "P3"),
+    /**
+     * 6 小时时段降水量
+     */
+    CODE_P6("1D", "P6"),
+    /**
+     * 12 小时时段降水量
+     */
+    CODE_P12("1E", "P12"),
+    /**
+     * 日降水量
+     */
+    CODE_PD("1F", "PD"),
+    /**
+     * 当前降水量
+     */
+    CODE_PJ("20", "PJ"),
+    /**
+     * 1 分钟时段降水量
+     */
+    CODE_PN01("21", "PN01"),
+    /**
+     * 5 分钟时段降水量
+     */
+    CODE_PN05("22", "PN05"),
+    /**
+     * 10 分钟时段降水量
+     */
+    CODE_PN10("23", "PN10"),
+    /**
+     * 30 分钟时段降水量
+     */
+    CODE_PN30("24", "PN30"),
+    /**
+     * 暴雨量
+     */
+    CODE_PR("25", "PR"),
+    /**
+     * 降水量累计值
+     */
+    CODE_PT("26", "PT"),
+    /**
+     * 瞬时流量、抽水流量
+     */
+    CODE_Q("27", "Q"),
+    /**
+     * 取(排)水口流量 1
+     */
+    CODE_Q1("28", "Q1"),
+    /**
+     * 取(排)水口流量 2
+     */
+    CODE_Q2("29", "Q2"),
+    /**
+     * 取(排)水口流量 3
+     */
+    CODE_Q3("2A", "Q3"),
+    /**
+     * 取(排)水口流量 4
+     */
+    CODE_Q4("2B", "Q4"),
+    /**
+     * 取(排)水口流量 5
+     */
+    CODE_Q5("2C", "Q5"),
+    /**
+     * 取(排)水口流量 6
+     */
+    CODE_Q6("2D", "Q6"),
+    /**
+     * 取(排)水口流量 7
+     */
+    CODE_Q7("2E", "Q7"),
+    /**
+     * 取(排)水口流量 8
+     */
+    CODE_Q8("2F", "Q8"),
+    /**
+     * 总出库流量、过闸总流量
+     */
+    CODE_QA("30", "QA"),
+    /**
+     * 输水设备流量、过闸(组)流量
+     */
+    CODE_QZ("31", "QZ"),
+    /**
+     * 输沙量
+     */
+    CODE_SW("32", "SW"),
+    /**
+     * 风向
+     */
+    CODE_UC("33", "UC"),
+    /**
+     * 风力(级)
+     */
+    CODE_UE("34", "UE"),
+    /**
+     * 风速
+     */
+    CODE_US("35", "US"),
+    /**
+     * 断面平均流速
+     */
+    CODE_VA("36", "VA"),
+    /**
+     * 当前瞬时流速
+     */
+    CODE_VJ("37", "VJ"),
+    /**
+     * 电源电压
+     */
+    CODE_VT("38", "VT"),
+    /**
+     * 瞬时河道水位、潮位
+     */
+    CODE_Z("39", "Z"),
+    /**
+     * 库(闸、站)下水位
+     */
+    CODE_ZB("3A", "ZB"),
+    /**
+     * 库(闸、站)上水位
+     */
+    CODE_ZU("3B", "ZU"),
+    /**
+     * 取(排)水口水位 1
+     */
+    CODE_Z1("3C", "Z1"),
+    /**
+     * 取(排)水口水位 2
+     */
+    CODE_Z2("3D", "Z2"),
+    /**
+     * 取(排)水口水位 3
+     */
+    CODE_Z3("3E", "Z3"),
+    /**
+     * 取(排)水口水位 4
+     */
+    CODE_Z4("3F", "Z4"),
+    /**
+     * 取(排)水口水位 5
+     */
+    CODE_Z5("40", "Z5"),
+    /**
+     * 取(排)水口水位 6
+     */
+    CODE_Z6("41", "Z6"),
+    /**
+     * 取(排)水口水位 7
+     */
+    CODE_Z7("42", "Z7"),
+    /**
+     * 取(排)水口水位 8
+     */
+    CODE_Z8("43", "Z8"),
+    /**
+     * 含沙量
+     */
+    CODE_SQ("44", "SQ"),
+    /**
+     * 遥测站状态及报警信息
+     */
+    CODE_ZT("45", "ZT"),
+    /**
+     * pH 值
+     */
+    CODE_PH("46", "pH"),
+    /**
+     * 溶解氧
+     */
+    CODE_DO("47", "DO"),
+    /**
+     * 电导率
+     */
+    CODE_COND("48", "COND"),
+    /**
+     * 浊度
+     */
+    CODE_TURB("49", "TURB"),
+    /**
+     * 高锰酸盐指数
+     */
+    CODE_CODMN("4A", "CODMN"),
+    /**
+     * 氧化还原电位
+     */
+    CODE_REDOX("4B", "REDOX"),
+    /**
+     * 氨氮
+     */
+    CODE_NH4N("4C", "NH4N"),
+    /**
+     * 总磷
+     */
+    CODE_TP("4D", "TP"),
+    /**
+     * 总氮
+     */
+    CODE_TN("4E", "TN"),
+    /**
+     * 总有机碳
+     */
+    CODE_TOC("4F", "TOC"),
+    /**
+     * 铜
+     */
+    CODE_CU("50", "CU"),
+    /**
+     * 锌
+     */
+    CODE_ZN("51", "ZN"),
+    /**
+     * 硒
+     */
+    CODE_SE("52", "SE"),
+    /**
+     * 砷
+     */
+    CODE_AS("53", "AS"),
+    /**
+     * 总汞
+     */
+    CODE_THG("54", "THG"),
+    /**
+     * 镉
+     */
+    CODE_CD("55", "CD"),
+    /**
+     * 铅
+     */
+    CODE_PB("56", "PB"),
+    /**
+     * 叶绿素 a
+     */
+    CODE_CHLA("57", "CHLA"),
+    /**
+     * 水压 1
+     */
+    CODE_WP1("58", "WP1"),
+    /**
+     * 水压 2
+     */
+    CODE_WP2("59", "WP2"),
+    /**
+     * 水压 3
+     */
+    CODE_WP3("5A", "WP3"),
+    /**
+     * 水压 4
+     */
+    CODE_WP4("5B", "WP4"),
+    /**
+     * 水压 5
+     */
+    CODE_WP5("5C", "WP5"),
+    /**
+     * 水压 6
+     */
+    CODE_WP6("5D", "WP6"),
+    /**
+     * 水压 7
+     */
+    CODE_WP7("5E", "WP7"),
+    /**
+     * 水压 8
+     */
+    CODE_WP8("5F", "WP8"),
+    /**
+     * 水表 1 剩余水量
+     */
+    CODE_SYL1("60", "SYL1"),
+    /**
+     * 水表 2b剩余水量
+     */
+    CODE_SYL2("61", "SYL2"),
+    /**
+     * 水表 3 剩余水量
+     */
+    CODE_SYL3("62", "SYL3"),
+    /**
+     * 水表 4 剩余水量
+     */
+    CODE_SYL4("63", "SYL4"),
+    /**
+     * 水表 5 剩余水量
+     */
+    CODE_SYL5("64", "SYL5"),
+    /**
+     * 水表 6 剩余水量
+     */
+    CODE_SYL6("65", "SYL6"),
+    /**
+     * 水表 7 剩余水量
+     */
+    CODE_SYL7("66", "SYL7"),
+    /**
+     * 水表 8 剩余水量
+     */
+    CODE_SYL8("67", "SYL8"),
+    /**
+     * 水表 1 每小时水量
+     */
+    CODE_SBL1("68", "SBL1"),
+    /**
+     * 水表 2 每小时水量
+     */
+    CODE_SBL2("69", "SBL2"),
+    /**
+     * 水表 3 每小时水量
+     */
+    CODE_SBL3("6A", "SBL3"),
+    /**
+     * 水表 4 每小时水量
+     */
+    CODE_SBL4("6B", "SBL4"),
+    /**
+     * 水表 5 每小时水量
+     */
+    CODE_SBL5("6C", "SBL5"),
+    /**
+     * 水表 6 每小时水量
+     */
+    CODE_SBL6("6D", "SBL6"),
+    /**
+     * 水表 7 每小时水量
+     */
+    CODE_SBL7("6E", "SBL7"),
+    /**
+     * 水表 8 每小时水量
+     */
+    CODE_SBL8("6F", "SBL8"),
+    /**
+     * 交流 A 相电压
+     */
+    CODE_VTA("70", "VTA"),
+    /**
+     * 交流 B 相电压
+     */
+    CODE_VTB("71", "VTB"),
+    /**
+     * 交流 C 相电压
+     */
+    CODE_VTC("72", "VTC"),
+    /**
+     * 交流 A 相电流
+     */
+    CODE_VIA("73", "VIA"),
+    /**
+     * 交流 B 相电流
+     */
+    CODE_VIB("74", "VIB"),
+    /**
+     * 交流 C 相电流
+     */
+    CODE_VIC("75", "VIC"),
+    /**
+     * 累计流量
+     */
+    CODE_SUM_FLOW_RATE("FF01", "SUM_FLOW_RATE"),
+    /**
+     * 年累计流量
+     */
+    CODE_YEAR_SUM_FLOW_RATE("FF04", "YEAR_SUM_FLOW_RATE"),
+    /**
+     * 累计电量
+     */
+    CODE_SUM_EV("FF05", "SUM_EV"),
+    /**
+     * 用户号
+     */
+    CODE_USER_NO("FF06", "USER_NO"),
+    /**
+     * 测站编码 ,扩展,16位长
+     */
+    CODE_EXT_RTU_CODE("FF0B", "EXT_RTU_CODE"),
+    /**
+     * 信号强度
+     */
+    CODE_EXT_STATUS_SIGNAL("FF50", "EXT_STATUS_SIGNAL"),
+    /**
+     * 电源电压
+     */
+    CODE_EXT_STATUS_BV("FF51", "EXT_STATUS_BV"),
+    /**
+     * RTU温度
+     */
+    CODE_EXT_STATUS_RTU_TEMPERATURE("FF52", "EXT_STATUS_RTU_TEMPERATURE"),
+    /**
+     * 唯一识别码
+     */
+    CODE_EXT_STATUS_UUID("FF53", "EXT_STATUS_UUID"),
+    /**
+     * 物联卡CCID
+     */
+    CODE_EXT_STATUS_CCID("FF54", "EXT_STATUS_CCID"),
+    /**
+     * 设备状态,1字节HEX	0 - SD卡正常   1 - SD卡损坏
+     */
+    CODE_EXT_STATUS_RUN("FF55", "EXT_STATUS_RUN"),
+    /**
+     * 异常值 , 0 设备正常 , 1  设备异常 代码:
+     */
+    CODE_EXT_STATUS_ERROR("FF56", "EXT_STATUS_ERROR"),
+    /**
+     * 上报状态(每一路的上报状态)
+     */
+    CODE_EXT_STATUS_UP("FF57", "EXT_STATUS_UP"),
+    /**
+     * 上报时间
+     */
+    CODE_UP_TIME("FF58", "UP_TIME"),
+    /**
+     * 电池状态
+     */
+    CODE_EXT_STATUS_BT("FF59", "EXT_STATUS_BT"),
+    /**
+     * 充电状态
+     */
+    CODE_EXT_STATUS_BT_IN("FF60", "EXT_STATUS_BT_IN"),
+    /**
+     * 放电状态
+     */
+    CODE_EXT_STATUS_BT_OUT("FF61", "EXT_STATUS_BT_OUT"),
+    /**
+     * 电池电量
+     */
+    CODE_EXT_STATUS_BT_PERCENT("FF62", "EXT_STATUS_BT_PERCENT"),
+    /**
+     * 电池温度
+     */
+    CODE_EXT_STATUS_BT_TEMPERATURE("FF63", "EXT_STATUS_BT_TEMPERATURE"),
+    /**
+     * 阵列电压
+     */
+    CODE_EXT_STATUS_SUN_EV("FF64", "EXT_STATUS_SUN_EV"),
+    /**
+     * 阵列电流
+     */
+    CODE_EXT_STATUS_SUN_EA("FF65", "EXT_STATUS_SUN_EA"),
+    /**
+     * PM2.5
+     */
+    CODE_EXT_PM("FF69", "EXT_PM"),
+    /**
+     * 紫外线
+     */
+    CODE_EXT_UV("FF6A", "EXT_UV"),
+    /**
+     * 太阳总辐射
+     */
+    CODE_EXT_RAD("FF6B", "EXT_RAD"),
+    /**
+     * 二氧化氮
+     */
+    CODE_EXT_ND("FF6C", "EXT_ND"),
+    /**
+     * 累计流量
+     */
+    CODE_EXT_SUM_FLOW_RATE("FF6D", "EXT_SUM_FLOW_RATE"),
+    /**
+     * 山脉设备温度标识
+     */
+    CODE_EXT_SM_RTU_TEMPERATURE("FF80", "SM_RTU_TEMPERATURE"),
+    /**
+     * 山脉设备故障码标识
+     */
+    CODE_EXT_SM_RTU_ERROR("FF81", "SM_RTU_ERROR"),
+    /**
+     * 山脉设备信号强度标识
+     */
+    CODE_EXT_SM_RTU_SIGNAL("FF85", "SM_RTU_SIGNAL"),
+    /**
+     * 经度
+     */
+    CODE_EXT_LNG("FFB1", "LNG"),
+    /**
+     * 纬度
+     */
+    CODE_EXT_LAT("FFB2", "LAT"),
+    /**
+     * 版本号
+     */
+    CODE_EXT_RTU_VERSION("FFFE", "RTU_VERSION");
+
+    private String code;
+
+    private String name;
+
+    SwElementCodeEnum(String code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    /**
+     * Function:根据code来获取对应的name
+     * Author: Admin
+     * Date:2021/6/26
+     *
+     * @param code
+     * @return java.lang.String
+     * @throws Exception
+     */
+    public static String getName(String code) {
+        for (SwElementCodeEnum type : SwElementCodeEnum.values()) {
+            if (type.code.equals(code)) {
+                return type.name;
+            }
+        }
+        return null;
+    }
+
+
+    public static String getCode(String name) {
+        for (SwElementCodeEnum point : SwElementCodeEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return null;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 177 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/Szy2012DatagramElementEnum.java

@@ -0,0 +1,177 @@
+package org.ts.ddcs.enums;
+
+/***
+ * Date:2022/3/9
+ * Title: 水资源2012报文观测要素
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author swp
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+public enum Szy2012DatagramElementEnum {
+
+
+    /**
+     * 命令
+     */
+    ELEMENT_COMMAND_F00(0, "00"),
+
+    /**
+     * 雨量参数
+     */
+    ELEMENT_RAIN_F01(1, "01"),
+
+    /**
+     * 水位参数
+     */
+    ELEMENT_WATER_LEVEL_F02(2, "02"),
+
+    /**
+     * 流量(水量)参数
+     */
+    ELEMENT_FLOW_RATE_F03(3, "03"),
+
+    /**
+     * 流速参数
+     */
+    ELEMENT_FLOW_SPEED_F04(4, "04"),
+
+    /**
+     * 闸位参数
+     */
+    ELEMENT_WATER_GATE_F05(5, "05"),
+
+    /**
+     * 功率参数
+     */
+    ELEMENT_POWER_F06(6, "06"),
+
+    /**
+     * 气压参数
+     */
+    ELEMENT_AIR_PRESSURE_F07(7, "07"),
+
+    /**
+     * 风速参数
+     */
+    ELEMENT_WIND_SPEED_F08(8, "08"),
+
+    /**
+     * 水温参数
+     */
+    ELEMENT_WATER_TEMPERATURE_F09(9, "09"),
+
+    /**
+     * 水质参数
+     */
+    ELEMENT_WATER_QUALITY_F10(10, "10"),
+
+    /**
+     * 土壤含水率参数
+     */
+    ELEMENT_GROUND_MOISTURE_F11(11, "11"),
+
+    /**
+     * 蒸发量参数
+     */
+    ELEMENT_EVAPORATION_CAPACITY_F12(12, "12"),
+
+    /**
+     * 报警或状态参数
+     */
+    ELEMENT_WARN_F13(13, "13"),
+
+    /**
+     * 统计雨量
+     */
+    ELEMENT_SYNTHETICAL_F14(14, "14"),
+
+    /**
+     * 水压参数
+     */
+    ELEMENT_WATER_PRESSURE_F15(15, "15"),
+
+    /**
+     *  观测时间
+     */
+//    ELEMENT_TT_FF0(16, "F0"),
+    /**
+     * 测站编码
+     */
+    ELEMENT_ST_FF1(17, "F1"),
+    /**
+     * 测站状态
+     */
+    ELEMENT_RTU_STATUS_FF2(18, "F2"),
+    /**
+     * 报警状态
+     */
+    ELEMENT_RTU_WARN_FF3(19, "F3"),
+    /**
+     *  扩展观测时间
+     */
+//    ELEMENT_EXT_TT_FF4(20, "FFF0"),
+    /**
+     * 累计流量(水量)参数
+     */
+    ELEMENT_SUM_FLOW_RATE_FF4(21, "FFF1"),
+    /**
+     *  小时流量
+     */
+    ELEMENT_HOUR_FLOW_RATE_FF5(22, "FFF2")
+    ;
+
+    private int code;
+
+    private String name;
+
+    Szy2012DatagramElementEnum(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 (Szy2012DatagramElementEnum point : Szy2012DatagramElementEnum.values()) {
+            if (point.code == code) {
+                return point.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * 根据名称查代码
+     * @param name
+     * @return
+     */
+    public static int getCode(String name) {
+        for (Szy2012DatagramElementEnum point : Szy2012DatagramElementEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return -1;
+    }
+}

+ 347 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SzyDatagramTypeCodeEnum.java

@@ -0,0 +1,347 @@
+package org.ts.ddcs.enums;
+
+/**
+ * 水资源规约报文类型定义
+ */
+public enum SzyDatagramTypeCodeEnum {
+
+    /**
+     * 链路检测
+     */
+    DATAGRAM_CODE_02(0x02, "02"),
+    /**
+     * 设置遥测终端、中继站地址
+     */
+    DATAGRAM_CODE_10(0x10, "10"),
+    /**
+     * 设置遥测终端、中继站时钟
+     */
+    DATAGRAM_CODE_11(0x11, "11"),
+    /**
+     * 设置遥测终端工作模式
+     */
+    DATAGRAM_CODE_12(0x12, "12"),
+    /**
+     * 设置遥测终端本次充值量
+     */
+    DATAGRAM_CODE_15(0x15, "15"),
+    /**
+     * 设置遥测终端剩余水量报警值
+     */
+    DATAGRAM_CODE_16(0x16, "16"),
+    /**
+     * 设置遥测终端的水位基值、水位上下限
+     */
+    DATAGRAM_CODE_17(0x17, "17"),
+    /**
+     * 设置遥测终端水压上、下限
+     */
+    DATAGRAM_CODE_18(0x18, "18"),
+    /**
+     * 设置遥测终端水质参数种类、上限值
+     */
+    DATAGRAM_CODE_19(0x19, "19"),
+    /**
+     * 设置遥测终端水质参数种类、下限值
+     */
+    DATAGRAM_CODE_1A(0x1A, "1A"),
+    /**
+     * 设置终端站水量的表底(初始)值
+     */
+    DATAGRAM_CODE_1B(0x1B, "1B"),
+    /**
+     * 设置遥测终端转发中继引导码长
+     */
+    DATAGRAM_CODE_1C(0x1C, "1C"),
+    /**
+     * 设置中继站转发终端地址
+     */
+    DATAGRAM_CODE_1D(0x1D, "1D"),
+    /**
+     * 设置中继站工作机自动切换,自报状态
+     */
+    DATAGRAM_CODE_1E(0x1E, "1E"),
+    /**
+     * 设置遥测终端流量参数上限值
+     */
+    DATAGRAM_CODE_1F(0x1F, "1F"),
+    /**
+     * 设置遥测终端检测参数启报阈值及固态存储时
+     * 间段间隔
+     */
+    DATAGRAM_CODE_20(0x20, "20"),
+    /**
+     * 置遥测终端 IC 卡功能有效
+     */
+    DATAGRAM_CODE_30(0x30, "30"),
+    /**
+     * 取消遥测终端 IC 卡功能
+     */
+    DATAGRAM_CODE_31(0x31, "31"),
+    /**
+     * 定值控制投入
+     */
+    DATAGRAM_CODE_32(0x32, "32"),
+    /**
+     * 定值控制退出
+     */
+    DATAGRAM_CODE_33(0x33, "33"),
+    /**
+     * 定值量设定
+     */
+    DATAGRAM_CODE_34(0x34, "34"),
+
+    /**
+     * 水资源查询测站编码
+     */
+    DATAGRAM_CODE_50(0x50, "50"),
+    /**
+     * 查询遥测终端、中继站时钟
+     */
+    DATAGRAM_CODE_51(0x51, "51"),
+    /**
+     * 查询遥测终端工作模式
+     */
+    DATAGRAM_CODE_52(0x52, "52"),
+    /**
+     * 查询自报种类及时间间隔
+     */
+    DATAGRAM_CODE_53(0x53, "53"),
+    /**
+     * 查询遥测终端需查询的实时数据种类 中心站 遥测终端
+     */
+    DATAGRAM_CODE_54(0x54, "54"),
+    /**
+     * 查询遥测终端最近成功充值量和现有剩余水量
+     */
+    DATAGRAM_CODE_55(0x55, "55"),
+    /**
+     * 查询遥测终端剩余水量和报警值
+     */
+    DATAGRAM_CODE_56(0x56, "56"),
+    /**
+     * 查询遥测终端水位基值、水位上下限
+     */
+    DATAGRAM_CODE_57(0x57, "57"),
+    /**
+     * 查询遥测终端水压上、下限
+     */
+    DATAGRAM_CODE_58(0x58, "58"),
+    /**
+     * 查询遥测终端水质参数种类、上限值
+     */
+    DATAGRAM_CODE_59(0x59, "59"),
+    /**
+     * 查询遥测终端水质参数种类、下限值
+     */
+    DATAGRAM_CODE_5A(0x5A, "5A"),
+    /**
+     * 查询遥测终端的事件记录
+     */
+    DATAGRAM_CODE_5D(0x5D, "5D"),
+    /**
+     * 查询遥测终端状态和报警状态
+     */
+    DATAGRAM_CODE_5E(0x5E, "5E"),
+    /**
+     * 查询水泵电机实时工作数据
+     */
+    DATAGRAM_CODE_5F(0x5F, "5F"),
+    /**
+     * 查询遥测终端转发中继引导码长
+     */
+    DATAGRAM_CODE_60(0x60, "60"),
+    /**
+     * 查询遥测终端图像记录
+     */
+    DATAGRAM_CODE_61(0x61, "61"),
+    /**
+     * 查询中继站转发终端地址
+     */
+    DATAGRAM_CODE_62(0x62, "62"),
+    /**
+     * 查询中继站工作机状态和切换记录
+     */
+    DATAGRAM_CODE_63(0x53, "63"),
+    /**
+     * 查询遥测终端流量参数上限值
+     */
+    DATAGRAM_CODE_64(0x64, "64"),
+    /**
+     * 自报预警
+     */
+    DATAGRAM_CODE_81(0x81, "81"),
+    /**
+     * 人工置数
+     */
+    DATAGRAM_CODE_82(0x82, "82"),
+    /**
+     * 查询基本配置信息
+     */
+    DATAGRAM_CODE_87(0x87, "87"),
+    /**
+     * 配置基本配置信息
+     */
+    DATAGRAM_CODE_88(0x88, "88"),
+    /**
+     * 重启,复位遥测终端参数和状态
+     */
+    DATAGRAM_CODE_90(0x90, "90"),
+    /**
+     * 清空遥测终端历史数据单元
+     */
+    DATAGRAM_CODE_91(0x91, "91"),
+    /**
+     * 遥控启动水泵或阀门/闸门
+     */
+    DATAGRAM_CODE_92(0x92, "92"),
+    /**
+     * 遥控关闭水泵或阀门/闸门
+     */
+    DATAGRAM_CODE_93(0x93, "93"),
+    /**
+     * 遥控终端或中继站通信机切换
+     */
+    DATAGRAM_CODE_94(0x94, "94"),
+    /**
+     * 遥控中继站工作机切换
+     */
+    DATAGRAM_CODE_95(0x95, "95"),
+    /**
+     * 修改遥测终端密码
+     */
+    DATAGRAM_CODE_96(0x96, "96"),
+    /**
+     * 设置遥测站需查询的实时数据种类
+     */
+    DATAGRAM_CODE_A0(0xA0, "A0"),
+    /**
+     * 设置遥测终端的数据自报种类及时间间隔
+     */
+    DATAGRAM_CODE_A1(0xA1, "A1"),
+    /**
+     * 查询遥测终端实时值
+     */
+    DATAGRAM_CODE_B0(0xB0, "B0"),
+    /**
+     * 查询遥测终端固态存储数据
+     */
+    DATAGRAM_CODE_B1(0xB1, "B1"),
+    /**
+     * 查询遥测终端内存自报数据
+     */
+    DATAGRAM_CODE_B2(0xB2, "B2"),
+    /**
+     * 定时报
+     */
+    DATAGRAM_CODE_C0(0xC0, "C0"),
+    /**
+     * 扩展链路报
+     */
+    DATAGRAM_CODE_E1(0xE1, "E1"),
+    /**
+     * 中心站设置遥测站IP和端口
+     */
+    DATAGRAM_CODE_E7(0xE7, "E7"),
+    /**
+     * 中心站查询遥测站IP和端口
+     */
+    DATAGRAM_CODE_E8(0xE8, "E8"),
+    /**
+     * 下行文件
+     */
+    DATAGRAM_CODE_F1(0xF1, "F1"),
+    /**
+     * 重启
+     */
+    DATAGRAM_CODE_F3(0xF3, "F3"),
+    /**
+     * 发送升级配置文件
+     */
+    DATAGRAM_CODE_F4(0xF4, "F4"),
+    /**
+     * RTU自身状态上报
+     */
+    DATAGRAM_CODE_F5(0xF5, "F5");
+
+    private int code;
+
+    private String name;
+
+    private SzyDatagramTypeCodeEnum(int code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    /**
+     * Function:根据code来获取对应的name
+     * Author: Admin
+     * Date:2021/6/26
+     *
+     * @param code
+     * @return java.lang.String
+     * @throws Exception
+     */
+    public static String getName(int code) {
+        for (SzyDatagramTypeCodeEnum type : SzyDatagramTypeCodeEnum.values()) {
+            if (type.code == code) {
+                return type.name;
+            }
+        }
+        return "";
+    }
+
+    /**
+     * Function:根据code来获取对应的枚举常量
+     * Author: Admin
+     * Date:2021/6/26
+     *
+     * @param code
+     * @return com.zhgzjg.web.enums.DeleteFlag
+     * @throws Exception
+     */
+    public static SzyDatagramTypeCodeEnum getEnumByCode(int code) {
+        for (SzyDatagramTypeCodeEnum type : SzyDatagramTypeCodeEnum.values()) {
+            if (type.code == code) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Function:根据name来获取对应的枚举常量
+     * Author: Admin
+     * Date:2021/6/26
+     *
+     * @param name
+     * @return com.zhgzjg.web.enums.DeleteFlag
+     * @throws Exception
+     */
+    public static SzyDatagramTypeCodeEnum getEnumByName(String name) {
+        for (SzyDatagramTypeCodeEnum type : SzyDatagramTypeCodeEnum.values()) {
+            if (type.name.equals(name)) {
+                return type;
+            }
+        }
+        return null;
+    }
+
+
+    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;
+    }
+}

+ 233 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/enums/SzyElementCodeEnum.java

@@ -0,0 +1,233 @@
+package org.ts.ddcs.enums;
+
+/**
+ * 水资源规约-元素编码定义
+ */
+public enum SzyElementCodeEnum {
+    /**
+     * 确认
+     */
+    CODE_CMD("00", "CMD"),
+
+    /**
+     * 雨量参数
+     */
+    CODE_RAIN("01", "RAIN"),
+
+    /**
+     * 水位参数
+     */
+    CODE_WATER_LEVEL("02", "water_level"),
+
+    /**
+     * 流量(水量)参数
+     */
+    CODE_FLOW_RATE("03", "FLOWRATE"),
+
+    /**
+     * 流速参数
+     */
+    CODE_FLOW_SPEED("04", "FLOWSPEED"),
+
+    /**
+     * 闸位参数
+     */
+    CODE_GATE("05", "GATE"),
+
+    /**
+     * 功率参数
+     */
+    CODE_POWER("06", "POWER"),
+
+    /**
+     * 气压参数
+     */
+    CODE_AIR_PRESSURE("07", "AIR_PRESSURE"),
+
+    /**
+     * 风速参数
+     */
+    CODE_WIND_SPEED("08", "WIND_SPEED"),
+
+    /**
+     * 水温参数
+     */
+    CODE_WATER_TEMPERATURE("09", "WATER_TEMPERATURE"),
+
+    /**
+     * 水质参数
+     */
+    CODE_WATER_QUALITY("0A", "WQ"),
+
+    /**
+     * 土壤含水率参数
+     */
+    CODE_GROUND_MOISTRUE("0B", "GROUND_MOISTRUE"),
+
+    /**
+     * 蒸发量参数
+     */
+    CODE_EVAPORATION("0C", "EVAPORATION"),
+
+    /**
+     * 报警或状态参数
+     */
+    CODE_WARN("0D", "WARN"),
+
+    /**
+     * 统计雨量
+     */
+    CODE_COUNT_RAIN("0E", "COUNT_RAIN"),
+
+    /**
+     * 水压参数
+     */
+    CODE_WATER_PRESSURE("0F", "WATER_PRESSURE"),
+    /**
+     * 观测时间
+     */
+    CODE_EXT_TT("F0", "EXT_TT"),
+    /**
+     * 测站编码
+     */
+    CODE_EXT_ST("F1", "EXT_ST"),
+    /**
+     * 扩展观测时间
+     */
+    CODE_EXT_TT427("FFF0", "EXT_TT427"),
+    /**
+     * 测站状态
+     */
+    CODE_EXT_RTU_STATUS("F2", "EXT_RTU_STATUS"),
+    /**
+     * 报警状态
+     */
+    CODE_EXT_RTU_WARN("F3", "EXT_RTU_WARN"),
+    /**
+     * 信号强度
+     */
+    CODE_EXT_STATUS_SIGNAL("FF50", "EXT_STATUS_SIGNAL"),
+    /**
+     * 电源电压
+     */
+    CODE_EXT_STATUS_BV("FF51", "EXT_STATUS_BV"),
+    /**
+     * RTU温度
+     */
+    CODE_EXT_STATUS_RTU_TEMPERATURE("FF52", "EXT_STATUS_RTU_TEMPERATURE"),
+    /**
+     * 唯一识别码
+     */
+    CODE_EXT_STATUS_UUID("FF53", "EXT_STATUS_UUID"),
+    /**
+     * 物联卡CCID
+     */
+    CODE_EXT_STATUS_CCID("FF54", "EXT_STATUS_CCID"),
+    /**
+     * 设备状态,1字节HEX	0 - SD卡正常   1 - SD卡损坏
+     */
+    CODE_EXT_STATUS_RUN("FF55", "EXT_STATUS_RUN"),
+    /**
+     * 异常值 , 0 设备正常 , 1  设备异常 代码:
+     */
+    CODE_EXT_STATUS_ERROR("FF56", "EXT_STATUS_ERROR"),
+    /**
+     * 上报状态(每一路的上报状态)
+     */
+    CODE_EXT_STATUS_UP("FF57", "EXT_STATUS_UP"),
+    /**
+     * 上报时间
+     */
+    CODE_EXT_UP_TIME("FF58", "EXT_UP_TIME"),
+    /**
+     * 电池状态
+     */
+    CODE_EXT_STATUS_BT("FF59", "EXT_STATUS_BT"),
+    /**
+     * 充电状态
+     */
+    CODE_EXT_STATUS_BT_IN("FF60", "EXT_STATUS_BT_IN"),
+    /**
+     * 放电状态
+     */
+    CODE_EXT_STATUS_BT_OUT("FF61", "EXT_STATUS_BT_OUT"),
+    /**
+     * 电池电量
+     */
+    CODE_EXT_STATUS_BT_PERCENT("FF62", "EXT_STATUS_BT_PERCENT"),
+    /**
+     * 电池温度
+     */
+    CODE_EXT_STATUS_BT_TEMPERATURE("FF63", "EXT_STATUS_BT_TEMPERATURE"),
+    /**
+     * 阵列电压
+     */
+    CODE_EXT_STATUS_SUN_EV("FF64", "EXT_STATUS_SUN_EV"),
+    /**
+     * 阵列电流
+     */
+    CODE_EXT_STATUS_SUN_EA("FF65", "EXT_STATUS_SUN_EA"),
+
+    /**
+     * 累计流量(水量)参数
+     */
+    CODE_SUM_FLOW_RATE_FF4("FFF1", "EXT_SUM_FLOW_RATE"),
+    /**
+     * 小时流量
+     */
+    CODE_HOUR_FLOW_RATE_FF5("FFF2", "EXT_HOUR_FLOW_RATE");
+
+
+    private String code;
+
+    private String name;
+
+    SzyElementCodeEnum(String code, String name) {
+        this.code = code;
+        this.name = name;
+    }
+
+    /**
+     * Function:根据code来获取对应的name
+     * Author: Admin
+     * Date:2021/6/26
+     *
+     * @param code
+     * @return java.lang.String
+     * @throws Exception
+     */
+    public static String getName(String code) {
+        for (SzyElementCodeEnum type : SzyElementCodeEnum.values()) {
+            if (type.code.equals(code)) {
+                return type.name;
+            }
+        }
+        return null;
+    }
+
+
+    public static String getCode(String name) {
+        for (SzyElementCodeEnum point : SzyElementCodeEnum.values()) {
+            if (point.name.equals(name)) {
+                return point.code;
+            }
+        }
+        return null;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 183 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/DataItemTemplate.java

@@ -0,0 +1,183 @@
+package org.ts.ddcs.itemdatatemplate;
+
+
+import lombok.Data;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+import org.ts.ddcs.common.util.BytesHelp;
+import org.ts.ddcs.common.util.ValueLen;
+
+import java.io.UnsupportedEncodingException;
+import java.math.BigDecimal;
+import java.util.*;
+
+@Data
+public abstract class DataItemTemplate {
+    protected String feture;
+    protected String name;
+    protected String desc;
+    protected String unit;
+    protected boolean macth = false;
+    protected String varcharValue;
+    protected byte[] valueBuff = new byte[0];
+    protected List<BigDecimal> bigDecimalValues = new ArrayList<>();
+    protected List<Integer> intValues = new ArrayList<>();
+    protected Map<String, Object> datas = new HashMap<>();
+    protected List<Map<String, Object>> dataList = new ArrayList<>();
+    protected boolean outlierData = false;
+    protected ValueLen valueLen;
+    protected List<Map<String, Object>> valueList = new ArrayList<>();
+
+    public void clear() {
+        this.varcharValue = "";
+        this.valueBuff = new byte[0];
+        this.bigDecimalValues = new ArrayList<>();
+        this.intValues = new ArrayList<>();
+        this.datas.clear();
+    }
+
+    public abstract int stream(byte[] data, int index) throws UnsupportedEncodingException;
+
+    public abstract int stream(byte[] data, int index, int batchSize);
+
+    public abstract String getStringValue();
+
+    public abstract void saveValue(Map<String, List<Map<String, Object>>> keyStore);
+
+    public String toStringValue() {
+        StringBuilder builder = new StringBuilder();
+        for (Map<String, Object> item : this.valueList) {
+            if (builder.length() > 0) {
+                builder.append(",");
+            }
+            builder.append(item.get(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName()));
+        }
+        return builder.toString();
+    }
+
+    private boolean isErrorData(byte[] bytes) {
+        boolean isError = true;
+        for (int i = 0; i < bytes.length; i++) {
+            byte[] byteBuff = BytesHelp.subBytes(bytes, i, 1);
+            String hexStr = BytesHelp.byte2HexStr(byteBuff);
+            if (!"FF".equals(hexStr)) {
+                isError = false;
+            }
+        }
+        return isError;
+    }
+
+    protected BigDecimal readBigDecimalValue(byte[] data, int pos, ValueLen len) {
+        byte[] buff = BytesHelp.subBytes(data, pos, len.getByteLen());
+        if (!isErrorData(buff)) {
+            String hexStr = BytesHelp.byte2HexStr(buff);
+            BigDecimal value = BytesHelp.toDecimal(hexStr, len.getDecimalLen());
+            this.bigDecimalValues.add(value);
+            return value;
+        }
+        return null;
+    }
+
+    protected BigDecimal readBigDecimalValue(byte[] data, int pos, int byteLen, int decimalLen) {
+        byte[] buff = BytesHelp.subBytes(data, pos, byteLen);
+        if (!isErrorData(buff)) {
+            String hexStr = BytesHelp.byte2HexStr(buff);
+            BigDecimal value = BytesHelp.toDecimal(hexStr, decimalLen);
+            this.bigDecimalValues.add(value);
+        }
+        return null;
+    }
+
+    protected void readIntValue(byte[] data, int pos, ValueLen len) {
+        byte[] buff = BytesHelp.subBytes(data, pos, len.getByteLen());
+        if (!isErrorData(buff)) {
+            String hexStr = BytesHelp.byte2HexStr(buff);
+            this.intValues.add(BytesHelp.toInt(hexStr));
+        }
+    }
+
+    protected void readVarcharValue(byte[] data, int pos, ValueLen len) {
+        byte[] buff = BytesHelp.subBytes(data, pos, len.getByteLen());
+        this.varcharValue = BytesHelp.byte2HexStr(buff);
+    }
+
+    protected void saveBigDecimalValues(Map<String, List<Map<String, Object>>> keyStore, int scale) {
+        if (keyStore.containsKey(this.feture)) {
+            List<Map<String, Object>> values = keyStore.get(this.feture);
+            for (BigDecimal decimal : this.bigDecimalValues) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), decimal.setScale(scale, BigDecimal.ROUND_DOWN).toPlainString());
+                values.add(value);
+            }
+        } else {
+            List<Map<String, Object>> values = new LinkedList<>();
+            for (BigDecimal decimal : this.bigDecimalValues) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), decimal.setScale(scale, BigDecimal.ROUND_DOWN).toPlainString());
+                values.add(value);
+            }
+            keyStore.put(this.feture, values);
+        }
+    }
+
+    protected void saveIntValues(Map<String, List<Map<String, Object>>> keyStore) {
+        if (keyStore.containsKey(this.feture)) {
+            List<Map<String, Object>> values = keyStore.get(this.feture);
+            for (Integer v : this.intValues) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), v.toString());
+                values.add(value);
+            }
+        } else {
+            List<Map<String, Object>> values = new LinkedList<>();
+            for (Integer v : this.intValues) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), v.toString());
+                values.add(value);
+            }
+            keyStore.put(this.feture, values);
+        }
+    }
+
+    protected void saveVarcharValues(Map<String, List<Map<String, Object>>> keyStore) {
+        if (keyStore.containsKey(this.feture)) {
+            List<Map<String, Object>> values = keyStore.get(this.feture);
+            Map<String, Object> value = new HashMap<>();
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+            if (null != this.varcharValue) {
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), this.varcharValue);
+            }
+            values.add(value);
+        } else {
+            List<Map<String, Object>> values = new LinkedList<>();
+            Map<String, Object> value = new HashMap<>();
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+            value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+            if (null != this.varcharValue) {
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), this.varcharValue);
+            }
+            values.add(value);
+            keyStore.put(this.feture, values);
+        }
+    }
+}

+ 89 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/DataItemTemplateCache.java

@@ -0,0 +1,89 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/12/27
+ */
+package org.ts.ddcs.itemdatatemplate;
+
+import org.ts.ddcs.common.util.BytesHelp;
+
+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);
+    }
+}

+ 44 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/ItemTemplate.java

@@ -0,0 +1,44 @@
+/**
+ * Copyright 2019 DH
+ * All right reserved.
+ * 项目名称: 大恒泰山系统
+ * 创建日期:2022/12/28
+ */
+package org.ts.ddcs.itemdatatemplate;
+
+import lombok.Data;
+
+/***
+ * Date:2022/12/28
+ * Title:编码要素引导符配置类
+ * Description:对本文件的详细描述,原则上不能少于30字
+ * @author dylan
+ * @version 1.0
+ * Remark:认为有必要的其他信息
+ */
+@Data
+public class ItemTemplate {
+    /**
+     * 引导符
+     */
+    private String func;
+
+    /**
+     * 编码要素说明
+     */
+    private String desc;
+
+    /**
+     * 单位
+     */
+    private String unit;
+
+    /**
+     * 引导符名称
+     */
+    private String funcName;
+    /**
+     * 模板类名
+     */
+    private String itemTemplateClass;
+}

+ 115 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate58.java

@@ -0,0 +1,115 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import lombok.extern.slf4j.Slf4j;
+import org.ts.ddcs.common.metadata.ElementDataMetadataEnum;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * funcode 0x58
+ * 管道水压 N(5,2)
+ */
+@Slf4j
+public class DataItemTemplate58 extends DataItemTemplate {
+
+    @Override
+    public int stream(byte[] data, int index) {
+        log.info("item template name{}", this.getClass().getName());
+        this.macth = false;
+        this.valueList.clear();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            Map<String, Object> item = new HashMap<>();
+            item.put(ElementDataMetadataEnum.ELEMENT_METADATA_ERROR.getName(), false);
+            BigDecimal value = this.readBigDecimalValue(data, index + count, valueLen);
+            if (null != value) {
+                String valueText = value.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
+                item.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), valueText);
+            }
+            this.valueList.add(item);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        this.macth = false;
+        this.valueList.clear();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            for (int i = 0; i < batchSize; i++) {
+                Map<String, Object> item = new HashMap<>();
+                item.put(ElementDataMetadataEnum.ELEMENT_METADATA_ERROR.getName(), false);
+                BigDecimal value = this.readBigDecimalValue(data, index + count, valueLen);
+                if (null != value) {
+                    String valueText = value.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
+                    item.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), valueText);
+                }
+                this.valueList.add(item);
+                count += valueLen.getByteLen();
+            }
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public String getStringValue() {
+        StringBuilder builder = new StringBuilder();
+        for (Map<String, Object> item : this.valueList) {
+            if (builder.length() > 0) {
+                builder.append(",");
+            }
+            builder.append(item.get(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName()));
+        }
+        return builder.toString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String, Object>>> keyStore) {
+        if (keyStore.containsKey(this.feture)) {
+            List<Map<String, Object>> values = keyStore.get(this.feture);
+            for (Map<String, Object> item : this.valueList) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), item.get(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName()));
+                values.add(value);
+            }
+        } else {
+            List<Map<String, Object>> values = new LinkedList<>();
+            for (Map<String, Object> item : this.valueList) {
+                Map<String, Object> value = new HashMap<>();
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_CODE.getName(), this.feture);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_NAME.getName(), this.name);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_UNIT.getName(), this.unit);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_DESC.getName(), this.desc);
+                value.put(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName(), item.get(ElementDataMetadataEnum.ELEMENT_METADATA_VALUE.getName()));
+                values.add(value);
+            }
+            keyStore.put(this.feture, values);
+        }
+    }
+}

+ 70 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate70.java

@@ -0,0 +1,70 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x70
+ * A相电压 N(4,1)
+ */
+@Slf4j
+public class DataItemTemplate70 extends DataItemTemplate {
+    @Override
+    public int stream(byte[] data, int index) {
+        log.info("template {}",this.getClass().getName());
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            for (int i = 0; i < batchSize; i++) {
+                this.readBigDecimalValue(data, index + count, valueLen);
+                count += valueLen.getByteLen();
+            }
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 72 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate71.java

@@ -0,0 +1,72 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x71
+ * B相电压 N(4,1)
+ */
+@Slf4j
+public class DataItemTemplate71 extends DataItemTemplate {
+    @Override
+    public int stream(byte[] data, int index) {
+        log.info("template {}",this.getClass().getName());
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            for (int i = 0; i < batchSize; i++) {
+                this.readBigDecimalValue(data, index + count, valueLen);
+                count += valueLen.getByteLen();
+            }
+            this.macth = true;
+        }
+        return count;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 58 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate72.java

@@ -0,0 +1,58 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x72
+ * C相电压 N(4,1)
+ */
+@Slf4j
+public class DataItemTemplate72 extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        log.info("template {}",this.getClass().getName());
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 61 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate73.java

@@ -0,0 +1,61 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x73
+ * A相电流 N(4,1)
+ */
+@Slf4j
+public class DataItemTemplate73 extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        log.info("template {}",this.getClass().getName());
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 57 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate74.java

@@ -0,0 +1,57 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x74
+ * B相电流 N(4,1)
+ */
+public class DataItemTemplate74 extends DataItemTemplate {
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 57 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplate75.java

@@ -0,0 +1,57 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x75
+ * C相电流 N(4,1)
+ */
+public class DataItemTemplate75 extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 58 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateAC.java

@@ -0,0 +1,58 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x01
+ * 断面面积 N(8,2)2  平方米
+ */
+public class DataItemTemplateAC extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 2);
+    }
+}

+ 56 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateAI.java

@@ -0,0 +1,56 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x02
+ * 瞬时气温 N(3,1) 摄氏度
+ */
+public class DataItemTemplateAI extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 56 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateC.java

@@ -0,0 +1,56 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x03
+ * 瞬时水温 N(3,1)  摄氏度
+ */
+public class DataItemTemplateC extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 1);
+    }
+}

+ 56 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCHLA.java

@@ -0,0 +1,56 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x57
+ * 叶绿素 a N(4,2) 毫克/升
+ */
+public class DataItemTemplateCHLA extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(2, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore, 2);
+    }
+}

+ 55 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCODMN.java

@@ -0,0 +1,55 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x4A
+ * 高锰酸盐指数 毫克/升 N(4,1)
+ */
+public class DataItemTemplateCODMN extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.bigDecimalValues = new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readBigDecimalValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+    @Override
+    public String getStringValue() {
+        BigDecimal value = this.bigDecimalValues.get(0);
+        return value.setScale(1, BigDecimal.ROUND_DOWN).toPlainString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveBigDecimalValues(keyStore,1);
+    }
+}

+ 54 - 0
tsddcs-datacollect/src/main/java/org/ts/ddcs/itemdatatemplate/sw/DataItemTemplateCOND.java

@@ -0,0 +1,54 @@
+package org.ts.ddcs.itemdatatemplate.sw;
+
+
+import com.alibaba.fastjson.JSONObject;
+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.itemdatatemplate.DataItemTemplate;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 0x48
+ * 电导率 微西门/厘米 N(5)
+ */
+public class DataItemTemplateCOND extends DataItemTemplate {
+
+
+    @Override
+    public int stream(byte[] data, int index) {
+        this.macth = false;
+        this.intValues=new ArrayList<>();
+        int count = 0;
+        String flag = BytesHelp.byte2HexStr(data, index + count, 1);
+        if (flag.toUpperCase().equals(this.feture)) {
+            count += 1;
+            ValueLen valueLen = Sw2014DatagramTemplateHelp.getValueLen(data, index + count);
+            count += 1;
+            this.readIntValue(data, index + count, valueLen);
+            count += valueLen.getByteLen();
+            this.macth = true;
+        }
+        return count;
+    }
+
+    @Override
+    public int stream(byte[] data, int index, int batchSize) {
+        return 0;
+    }
+
+
+    @Override
+    public String getStringValue() {
+        Integer value = this.intValues.get(0);
+        return value.toString();
+    }
+
+    @Override
+    public void saveValue(Map<String, List<Map<String,Object>>> keyStore) {
+        this.saveIntValues(keyStore);
+    }
+}

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác