From 1f2c3a31d9652b5d07f852b6d8d2b1b378adcfc2 Mon Sep 17 00:00:00 2001
From: YYC <1833023622@qq.com>
Date: 星期二, 27 六月 2023 20:04:12 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2MessageConsumer.java |   57 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/package-info.java                      |    4 
 igds-web/src/main/resources/logback-spring.xml                                                            |    2 
 igds-core/src/main/java/com/ld/igds/io/constant/ProtocolEnum.java                                         |    3 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/IoMessage.java             |   20 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/ServerRunner.java                      |   34 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/ReMessageBuilder.java      |   51 +
 igds-protocol-bhzn/pom.xml                                                                                |   49 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/Content.java               |   43 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/CommandBuild.java          |  178 +++
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2SessionListener.java |   65 +
 pom.xml                                                                                                   |    2 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/ReMessageBuilder.java      |   51 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/Content.java               |   43 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerUtils.java     |  103 ++
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/IoMessage.java             |   20 
 igds-web/src/main/resources/application.yml                                                               |    2 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/RemoteGrainV2ServiceImpl.java          |   70 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1HeartbeatImpl.java   |   42 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerEngine.java    |  131 ++
 igds-core/src/main/java/com/ld/igds/view/Depot.view.xml                                                   |    2 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/AnalysisService.java               |  474 ++++++++++
 igds-web/src/main/resources/application-pro5324.yml                                                       |   80 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/ServerRunner.java                      |   34 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1SessionListener.java |   68 +
 igds-web/src/main/resources/application-dev.yml                                                           |    2 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerUtils.java     |  103 ++
 igds-web/src/main/resources/static/img/aerial-5326_001.png                                                |    0 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/AnalysisService.java               |  474 ++++++++++
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerEngine.java    |  131 ++
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1MessageConsumer.java |   57 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2HeartbeatImpl.java   |   42 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/RemoteGrainV1ServiceImpl.java          |   70 +
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/package-info.java                      |    4 
 igds-web/pom.xml                                                                                          |   16 
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/CommandBuild.java          |  178 +++
 igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/package-info.java                              |    8 
 igds-web/src/main/resources/application-pro5326.yml                                                       |   80 +
 38 files changed, 2,787 insertions(+), 6 deletions(-)

diff --git a/igds-core/src/main/java/com/ld/igds/io/constant/ProtocolEnum.java b/igds-core/src/main/java/com/ld/igds/io/constant/ProtocolEnum.java
index c2ae7cf..2538bf0 100644
--- a/igds-core/src/main/java/com/ld/igds/io/constant/ProtocolEnum.java
+++ b/igds-core/src/main/java/com/ld/igds/io/constant/ProtocolEnum.java
@@ -27,7 +27,8 @@
     TCP_FZZY_N2_V3("TCP_FZZY_N2_V3", "FZZY-鍒舵爱鏈哄崗璁�"),
     TCP_LT_SAMPLE_V3("TCP_LT_SAMPLE_V3", "鎵︽牱鏈哄崗璁�"),
     TCP_FZZY_QUANTITY_V35("TCP_FZZY_QUANTITY_V35", "鏁伴噺妫�娴媀35"),
-    TCP_BHZH_GRAIN_FM_V1("TCP_BHZH_GRAIN_FM_V1", "閭︽捣鏅鸿兘鏃犵嚎涓绘満鐗圴1");
+    TCP_BHZH_GRAIN_FM_V1("TCP_BHZH_GRAIN_FM_V1", "閭︽捣鏅鸿兘鏃犵嚎涓绘満鐗圴1"),
+    TCP_BHZH_GRAIN_V2("TCP_BHZH_GRAIN_V2", "閭︽捣鏅鸿兘鏈夌嚎鐗圴2");
     private String code;
     private String msg;
 
diff --git a/igds-core/src/main/java/com/ld/igds/view/Depot.view.xml b/igds-core/src/main/java/com/ld/igds/view/Depot.view.xml
index 361906c..e75fd55 100644
--- a/igds-core/src/main/java/com/ld/igds/view/Depot.view.xml
+++ b/igds-core/src/main/java/com/ld/igds/view/Depot.view.xml
@@ -480,7 +480,7 @@
       <Property name="minWidth">500</Property>
       <Container layout="regionPadding:5">
         <DataSet id="dsFoodOrigin">
-          <Property name="dataProvider">dicTriggerPR#pagFoodLocationData</Property>
+          <Property name="dataProvider"></Property>
           <Property name="dataType">[dtFoodOrigin]</Property>
           <Property name="parameter"></Property>
           <Property name="pageSize">30</Property>
diff --git a/igds-protocol-bhzn/pom.xml b/igds-protocol-bhzn/pom.xml
new file mode 100644
index 0000000..13c9edc
--- /dev/null
+++ b/igds-protocol-bhzn/pom.xml
@@ -0,0 +1,49 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.ld.igds</groupId>
+	<artifactId>igds-protocol-bhzn</artifactId>
+	<version>4.0.0-RELEASE</version>
+	<packaging>jar</packaging>
+
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+		<java.version>1.8</java.version>
+		<igds.version>4.0.0-RELEASE</igds.version>
+	</properties>
+
+	<dependencies>
+
+		<!-- 寮曞叆涔夊姟鏍稿績鍖� -->
+		<dependency>
+			<groupId>com.ld.igds</groupId>
+			<artifactId>igds-core</artifactId>
+			<version>${igds.version}</version>
+		</dependency>
+
+		<!-- 寮曞叆IO鍖� -->
+		<dependency>
+			<groupId>com.ld.base.io</groupId>
+			<artifactId>base-io-netty</artifactId>
+			<version>1.0.0-SNAPSHOT</version>
+		</dependency>
+
+	</dependencies>
+
+ 	<build>
+ 		<plugins>
+ 			<plugin>
+ 				<groupId>org.apache.maven.plugins</groupId>
+ 				<artifactId>maven-compiler-plugin</artifactId>
+ 				<configuration>
+ 					<source>1.8</source>
+ 					<target>1.8</target>
+ 					<compilerArguments>
+ 						<extdirs>src\main\webapp\WEB-INF\lib</extdirs>
+ 					</compilerArguments>
+ 				</configuration>
+ 			</plugin>
+ 		</plugins>
+ 	</build>
+
+</project>
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/RemoteGrainV1ServiceImpl.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/RemoteGrainV1ServiceImpl.java
new file mode 100644
index 0000000..fd347b0
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/RemoteGrainV1ServiceImpl.java
@@ -0,0 +1,70 @@
+package com.ld.igds.protocol.bhzn.grainv1;
+
+import com.ld.igds.common.CoreSerService;
+import com.ld.igds.io.RemoteGrainService;
+import com.ld.igds.io.constant.OrderRespEnum;
+import com.ld.igds.io.constant.ProtocolEnum;
+import com.ld.igds.io.request.CheckGrainRequest;
+import com.ld.igds.io.response.GrainResponse;
+import com.ld.igds.protocol.bhzn.grainv1.msg.builder.CommandBuild;
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerEngine;
+import com.ld.io.api.InvokeResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @Desc: 绮儏涓氬姟鎺ュ彛
+ * @author: Andy
+ * @update-time: 2023/5/11
+ */
+@Slf4j
+@Component(RemoteGrainV1ServiceImpl.BEAN_ID)
+public class RemoteGrainV1ServiceImpl implements RemoteGrainService {
+
+    public static final String BEAN_ID = "bhznGrain.remoteGrainService";
+
+    @Autowired
+    private CoreSerService coreSerService;
+    @Autowired
+    private BhznGrainV1ServerEngine bhznGrainServerEngine;
+
+    @Override
+    public String getProtocol() {
+        return ProtocolEnum.TCP_BHZH_GRAIN_FM_V1.getCode();
+    }
+
+    @Override
+    public GrainResponse checkGrain(CheckGrainRequest request) {
+        try {
+            // 鐢熸垚绮儏淇℃伅
+            String hexStr = CommandBuild.getInstance().getMsgCheck(request.getSerId(), request.getDepotId());
+
+
+//            //閫氳浣跨敤鐨勬槸涓绘満閫氳
+//            DeviceSer mainSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+//            request.setIp(mainSer.getIp());
+//            request.setPort(mainSer.getPort());
+
+            // 鍙戦�佸懡浠�
+            InvokeResult result = bhznGrainServerEngine.pushByMin(hexStr);
+
+            log.error("骞冲彴------>>>>鎺у埗鏌滐細绮儏妫�娴�-{}", hexStr);
+
+            // 灏佽杩斿洖淇℃伅
+            if (InvokeResult.SUCCESS == result) {
+                return new GrainResponse(OrderRespEnum.ORDER_SUCCESS.getCode(),
+                        "绮儏绮儏鍙戦�佹垚鍔燂紒");
+            } else {
+                log.error("骞冲彴------>>>>鎺у埗鏌滐細绮儏妫�娴�-澶辫触{}", result.getMessage());
+                return new GrainResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                        "鍛戒护鍙戦�佸紓甯革細" + result.getMessage());
+            }
+
+        } catch (Exception e) {
+            log.error("绮儏妫�娴嬪紓甯革細{}", e);
+            return new GrainResponse(OrderRespEnum.ORDER_ERROR.getCode(), "鍚庣寮傚父锛�" + e.getMessage());
+        }
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/ServerRunner.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/ServerRunner.java
new file mode 100644
index 0000000..7bd0868
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/ServerRunner.java
@@ -0,0 +1,34 @@
+package com.ld.igds.protocol.bhzn.grainv1;
+
+import com.ld.igds.data.ConfigData;
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerEngine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * 閰嶇疆闅忕郴缁熻嚜鍔ㄥ惎鍔ㄦ湇鍔� -- 鎵ц椤哄簭20-29
+ */
+@Component(ServerRunner.BEAN_ID)
+@Order(value = 24)
+public class ServerRunner implements CommandLineRunner {
+
+    public static final String BEAN_ID = "bhzn.serverRunnerV1";
+
+    @Autowired
+    private ConfigData configData;
+    @Autowired
+    private BhznGrainV1ServerEngine bhznGrainServerEngine;
+
+    @Override
+    public void run(String... strings) throws Exception {
+
+        if (configData.getActive().indexOf("pro") >= 0) {
+            //bhznGrainServerEngine.start(BhznGrainServerEngine.PORT);
+        }
+        if (configData.getActive().indexOf("dev") >= 0) {
+            //bhznGrainServerEngine.start(BhznGrainServerEngine.PORT);
+        }
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/AnalysisService.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/AnalysisService.java
new file mode 100644
index 0000000..41a7547
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/AnalysisService.java
@@ -0,0 +1,474 @@
+package com.ld.igds.protocol.bhzn.grainv1.msg;
+
+import com.ld.igds.common.CoreCommonService;
+import com.ld.igds.common.CoreSerService;
+import com.ld.igds.common.dto.THDto;
+import com.ld.igds.constant.BizType;
+import com.ld.igds.constant.Constant;
+import com.ld.igds.grain.GrainUtil;
+import com.ld.igds.grain.dto.GrainItemInfo;
+import com.ld.igds.io.notify.NotifyGrainInvoker;
+import com.ld.igds.models.DepotConf;
+import com.ld.igds.models.DeviceSer;
+import com.ld.igds.models.DicSysConf;
+import com.ld.igds.models.Grain;
+import com.ld.igds.order.ExeOrderService;
+import com.ld.igds.order.data.ExeRequest;
+import com.ld.igds.protocol.bhzn.grainv1.msg.builder.CommandBuild;
+import com.ld.igds.protocol.bhzn.grainv1.msg.builder.ReMessageBuilder;
+import com.ld.igds.protocol.bhzn.grainv1.msg.message.IoMessage;
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerEngine;
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerUtils;
+import com.ld.igds.util.BytesUtil;
+import com.ld.igds.util.ContextUtil;
+import com.ld.igds.warn.WarnUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+/**
+ * 鍗忚瑙f瀽
+ *
+ * @author vince
+ */
+@Slf4j
+@Component(AnalysisService.BEAN_ID)
+public class AnalysisService {
+
+
+    /**
+     * 閽堝鍒嗗寘绮儏鎶ユ枃杩涜灏佽
+     */
+    public static Map<String, String> contextMapGrain = new HashMap<>();
+
+    /**
+     * 鐢ㄤ簬瀛樻斁杩斿洖鐨勪粨娓╀粨婀夸俊鎭�
+     */
+    public static Map<String, THDto> contextMapTH = new HashMap<>();
+
+    public static final String BEAN_ID = "bhznGrainv1.analysisService";
+
+    @Autowired
+    private CoreSerService coreSerService;
+    @Autowired
+    private BhznGrainV1ServerEngine serverEngine;
+    @Autowired
+    private CoreCommonService commonService;
+    @Autowired
+    private NotifyGrainInvoker notifyGrainInvoker;
+    @Autowired
+    private GrainUtil grainUtil;
+    @Autowired
+    private WarnUtils warnUtils;
+    @Autowired
+    private ExeOrderService exeOrderService;
+
+    /**
+     * @param sessionKey ip:port
+     */
+    public void analysis(String sessionKey, IoMessage message) throws Exception {
+
+        //娉ㄥ唽
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_F1.equals(message.getFunctionId())) {
+            //DO NOTHING
+
+            log.info("涓绘満------->>骞冲彴锛氭敞鍐屼俊鎭姤鏂�={}", message);
+            DeviceSer ser = coreSerService.getCacheSerBySn(ContextUtil.getDefaultCompanyId(),message.getAddr());
+            if(ser!= null ){
+                ser.setIp(message.getIp());
+                ser.setPort(message.getPort());
+                ser.setStatus(Constant.YN_Y);
+                coreSerService.updateByData(ser);
+            }
+            return;
+        }
+
+        //蹇冭烦
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_F2.equals(message.getFunctionId())) {
+            String hexStr = CommandBuild.getMsgHeartReply(message.getAddr());
+            log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炲績璺虫敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+            serverEngine.pushByMin(hexStr);
+            return;
+        }
+
+        // 93 瑙f瀽浠撴俯浠撴箍锛屽苟杩斿洖鏀跺埌鎶ユ枃
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_93.equals(message.getFunctionId())) {
+            log.info("涓绘満------->>骞冲彴锛氭俯婀垮害淇℃伅鎶ユ枃={}", message);
+            analysisTh(message);
+            return;
+        }
+
+        // 92 瑙f瀽绮俯锛屽苟杩斿洖鏀跺埌鎶ユ枃
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_92.equals(message.getFunctionId())) {
+            log.info("涓绘満------->>骞冲彴锛氱伯鎯呬俊鎭姤鏂�={}", message);
+            analysisGrain(message);
+        }
+    }
+
+
+    private void analysisGrain(IoMessage message) {
+        try {
+
+            //鏍规嵁鍒嗘満鍦板潃鑾峰彇鍒嗘満淇℃伅
+
+            DeviceSer ser = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), message.getAddr());
+            if (ser == null) {
+                replayGrain(message);
+                log.error("涓绘満-------->>骞冲彴锛岃В鏋愮伯鎯呭け璐ワ紝鏈幏鍙栧埌绯荤粺绮儏涓绘満閰嶇疆锛�" + message.getAddr());
+                return;
+            }
+
+            // 棣栧厛鑾峰彇鍒扮郴缁熷弬鏁帮紝鍒ゆ柇鏄惁闇�瑕佹壒娆¤嚜鍔ㄤ紭鍖�
+            DicSysConf sysConf = commonService.getCacheSysConf(ser.getCompanyId());
+            List<ExeRequest> list = exeOrderService.getInProgressOrderBySerId(BizType.GRAIN.getCode(), ser.getId());
+
+            if (null == list || list.isEmpty()) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍒版墍灞炰粨搴撲俊鎭��";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            //鑾峰彇閽堝褰撳墠浠撳簱鐨勫懡浠�
+            ExeRequest exeRequest = list.get(0);
+            if (null == exeRequest) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍘嗗彶鍛戒护銆�";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            DepotConf depotConf = commonService.getCacheDepotConf(exeRequest.getCompanyId(), exeRequest.getDepotId());
+
+            if (null == depotConf) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍒扮伯鎯呭弬鏁伴厤缃俊鎭��";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            // 绮儏鐨勬壒娆″彿閲嶆柊鏍规嵁棰戠巼璋冩暣
+            String batchId = ContextUtil.getBatchIdByFireq(depotConf.getGrainFreq());
+
+            // 鍒ゆ柇鏁版嵁鏈夋病鏈夋敹鍙栧畬鏁�
+            String[] attCable = depotConf.getCableRule().split("-");
+            int cableZ = Integer.valueOf(attCable[0]);
+            int cableY = Integer.valueOf(attCable[1]);
+            int cableX = Integer.valueOf(attCable[2]);
+            int sumPoint = cableZ * cableY * cableX;
+
+            //鑾峰彇褰撳墠绮儏娓╁害鎶ユ枃
+            String grainHex = message.getContent().substring(16);
+
+            //褰撳墠鎶ユ枃娓╁害鐐规暟
+            int curPoint = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(4, 8)));
+
+            //濡傛灉褰撳墠鍖呯殑鏁版嵁涓暟澶т簬绛変簬褰撳墠浠撳簱鐨勯厤缃偣浣嶅垯琛ㄧず鍗曞寘杩斿洖
+            if (curPoint >= sumPoint) {
+
+                //杩斿洖绮儏鎺ユ敹淇℃伅
+                replayGrain(message);
+
+                analysisGrain2(ser, message, exeRequest, depotConf, sysConf, batchId, grainHex);
+                return;
+            }
+
+            //琛ㄧず鍒嗗寘浼犻��
+            String key = "GRAIN_" + message.getAddr();
+            String oldGrainHex = contextMapGrain.get(key) == null ? "" : contextMapGrain.get(key);
+
+            //鑾峰彇褰撳墠鍖呰捣濮嬬偣鐨勫眰琛屽垪
+            int hang = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(8, 10)));
+            int lie = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(10, 12)));
+            int ceng = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(12, 14)));
+            if (hang > 0 || lie > 0 || ceng > 0) {
+                //璇存槑闈炵涓�鍖呮暟鎹�
+                grainHex = oldGrainHex + grainHex;
+            }
+
+            if (grainHex.length() >= sumPoint * 4) {
+                //杩斿洖绮儏鎺ユ敹淇℃伅
+                replayGrain(message);
+
+                analysisGrain2(ser, message, exeRequest, depotConf, sysConf, batchId, grainHex);
+                return;
+
+            } else {
+                contextMapGrain.put(key, grainHex);
+                replayGrain(message);
+            }
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 杩斿洖绮儏鏀跺埌鎶ユ枃淇℃伅锛岄渶瑕佹敞鎰忥細濡傛灉瀛樺湪鍒嗗寘鎯呭喌涓嬶紝闇�瑕佺瓑鎵�鏈夊寘鏀跺埌鍚庤繑鍥�
+     *
+     * @param message
+     */
+    private void replayGrain(IoMessage message) {
+        String hexStr = CommandBuild.getMsgGrainReply(message.getAddr());
+        log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炵伯鎯呮姤鏂囨敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+        serverEngine.pushByMin(hexStr);
+    }
+
+    private void analysisGrain2(DeviceSer ser, IoMessage message, ExeRequest exeRequest, DepotConf depotConf, DicSysConf sysConf, String batchId, String grainStr) {
+        // 鑾峰彇瀹屾暣鐨勭伯鎯呭寘淇℃伅
+        String[] attCable = depotConf.getCableRule().split("-");
+        int cableZ = Integer.valueOf(attCable[0]);
+        int cableY = Integer.valueOf(attCable[1]);
+        int cableX = Integer.valueOf(attCable[2]);
+
+        // 鏍规嵁灞傝鍒楄幏鍙栨寚瀹氶暱搴�
+        int start = 4 * (depotConf.getCableStart() - ser.getCableStart())
+                * cableZ * cableY;
+        int len = 4 * cableZ * cableY * cableX;
+
+        log.info("鍒嗘満------>>>骞冲彴锛氳繑鍥炵伯鎯呭畬鏁翠俊鎭紝鎵�灞炵粍缁�={}锛屽垎鏈�={}", ser.getCompanyId(), ser.getName());
+
+        String strPoints = grainStr.substring(start, start + len);
+
+        // 灏嗙伯鎯呰В鏋愭垚鏁扮粍
+        List<Double> temps = new ArrayList<>();
+        double tempValue;
+        String temp;
+        for (int i = 0; i < strPoints.length() / 4; i++) {
+            temp = strPoints.substring(i * 4, i * 4 + 4);
+            if (temp == null) {
+                temp = "0000";
+            }
+            if (ReMessageBuilder.ERROR_TAG.equals(temp)) {
+                tempValue = Constant.ERROR_TEMP;
+            } else {
+                tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
+            }
+            // 鏁呴殰鍊煎鐞�
+            if (tempValue >= ReMessageBuilder.FAULT_CHECK_TAG) {
+                tempValue = Constant.FAULT_TEMP;
+            }
+            temps.add(tempValue);
+        }
+
+        log.debug("-------CheckGrainRequest--={}", exeRequest.toString());
+
+
+        THDto thDto = this.getTH(message);
+        if (null != thDto) {
+            log.debug("-------THDto--={}", thDto.toString());
+        }
+        //娓呯┖
+        String key = "GRAIN_" + message.getAddr();
+        contextMapGrain.put(key, null);
+        // 灏嗛泦鍚堣В鏋愭垚鍧愭爣鏁版嵁
+        addPoint1(temps, depotConf, ser, exeRequest, thDto, sysConf, batchId);
+
+    }
+
+
+    /**
+     * 骞虫埧浠擄紝瑙f瀽绗簩姝ワ紝瑙f瀽鍒板潗鏍囨暟鎹�
+     *
+     * @param temps
+     * @throws Exception
+     */
+    private void addPoint1(List<Double> temps,
+                           DepotConf depotConf, DeviceSer ser, ExeRequest exeRequest,
+                           THDto thDto, DicSysConf sysConf, String batchId) {
+
+        //鏍规嵁鐢电紗璧峰鏂逛綅鍜屽竷绾挎柟鍚戯紝瀵圭伯鎯呮暟鎹繘琛岃皟鏁�
+        if (null != depotConf.getStartOrientation()) {
+            temps = reversalGrainPoint(temps, depotConf);
+        }
+
+        //鑻ヨ捣鐐圭偣浣嶄负搴曢儴锛屽垯灏嗙伯鎯呮暟鎹繘琛岀炕杞�
+        if (null != depotConf.getStartPoint()
+                && Constant.GRAIN_START_POINT_BELOW.equals(depotConf.getStartPoint())) {
+            temps = grainUtil.reversalUpAndDown(temps, depotConf.getCableRule());
+        }
+
+        String[] attCable = depotConf.getCableRule().split("-");
+        int cableZ = Integer.valueOf(attCable[0]);
+        int cableY = Integer.valueOf(attCable[1]);
+        int cableX = Integer.valueOf(attCable[2]);
+
+        Grain grain = new Grain();
+        grain.setDepotId(depotConf.getDepotId());
+        grain.setCompanyId(depotConf.getCompanyId());
+        grain.setCable(depotConf.getCableRule());
+        grain.setBatchId(batchId);
+        grain.setTempIn(Constant.ERROR_TEMP);
+        grain.setHumidityIn(Constant.ERROR_TEMP);
+
+        if (null != thDto) {
+            log.debug("绮儏瑙f瀽涓幏鍙栧埌鐨勬俯婀垮害淇℃伅={}", thDto.toString());
+            grain.setHumidityIn(thDto.getHumidityIn());
+            grain.setTempIn(thDto.getTempIn());
+        }
+        grain.setReceiveDate(new Date());
+        grain.setRemark("绮俯姝e父");
+
+        // 鑾峰彇缂撳瓨涓殑鍛戒护淇℃伅
+        grain.setCheckUser(exeRequest.getExeUser());
+
+        double max = ReMessageBuilder.MAX_TEMP, min = ReMessageBuilder.MIN_TEMP, sumT = 0.0, sumNum = cableX
+                * cableY * cableZ;
+
+        // 鏍¢獙鍜屽疄鐜扮粺璁★紝鐢熸垚閲囬泦鐐逛俊鎭�
+        List<GrainItemInfo> listGrainItems = new ArrayList<>();
+        int i = 1;
+        for (Double temp : temps) {
+            if (temp == Constant.ERROR_TEMP || temp == Constant.FAULT_TEMP || temp == Constant.ADD_TEMP) {
+                sumNum--;
+            } else {
+                sumT += temp;
+                if (temp > max) {
+                    max = temp;
+                }
+                if (temp < min) {
+                    min = temp;
+                }
+            }
+            listGrainItems.add(new GrainItemInfo(i, temp));
+            i++;
+        }
+
+        if (sumNum == 0) {
+            sumNum = 1;
+            grain.setRemark("褰撳墠绮儏閲囬泦寮傚父");
+        }
+        //杩囨护姣旇緝鐢ㄧ殑鏈�澶ф渶灏忓��
+        if (max == ReMessageBuilder.MAX_TEMP) {
+            max = 0.0;
+        }
+        if (min == ReMessageBuilder.MIN_TEMP) {
+            min = 0.0;
+        }
+        if (null != depotConf.getTempMax() && max > depotConf.getTempMax()) {
+            grain.setRemark("浠撳簱閰嶇疆楂樻俯璀﹀憡鍊硷細" + depotConf.getTempMax() + "锛屽綋鍓嶆娴嬮珮娓╁�硷細"
+                    + max);
+            warnUtils.addGrainWarn(depotConf, grain);
+        }
+
+        grain.setTempAve(sumT / sumNum);
+        grain.setTempMax(max);
+        grain.setTempMin(min);
+        grain.setPoints(org.apache.commons.lang3.StringUtils.join(temps, ","));
+
+        String depotIds = exeRequest.getDepotIds();
+
+        boolean notifyWeb = true;
+        if (null != depotIds && depotIds.indexOf(depotConf.getDepotId()) == -1) {
+            notifyWeb = false;
+        }
+        // 鐢ㄦ埛灏佽濂芥暟鎹嵆鍙�
+        notifyGrainInvoker.analysisSuccess(grain, listGrainItems, depotConf,
+                sysConf, notifyWeb, exeRequest);
+    }
+
+    private List<Double> reversalGrainPoint(List<Double> temps, DepotConf conf) {
+        if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartOrientation())) {
+            //鑻ヨ捣濮嬫柟浣嶄负绌猴紝鍒欓粯璁よ捣濮嬫柟浣嶅拰鏂瑰悜锛岀洿鎺ヨ繑鍥�
+            return temps;
+        }
+        //璧峰鏂逛綅涓哄彸杈规椂
+        if (Constant.GRAIN_START_ORIENTATION_RIGHT.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //鍙宠竟璧峰锛岄粯璁ょ旱鍚戝竷绾匡紝鐩存帴杩斿洖
+                return temps;
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //鍙宠竟璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalRight1(temps, conf.getCableRule());
+            }
+            //鍙宠竟璧峰锛岄粯璁ょ旱鍚戝竷绾匡紝鐩存帴杩斿洖
+            return temps;
+        }
+        //璧峰鏂逛綅涓哄彸涓婃椂
+        if (Constant.GRAIN_START_ORIENTATION_RIGHT_UP.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //鍙充笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalRightUp2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //鍙充笂璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalRightUp1(temps, conf.getCableRule());
+            }
+            //鍙充笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalRightUp2(temps, conf.getCableRule());
+        }
+        //璧峰鏂逛綅涓哄乏杈规椂
+        if (Constant.GRAIN_START_ORIENTATION_LEFT.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //宸﹁竟璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalLeft2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //宸﹁竟璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalLeft1(temps, conf.getCableRule());
+            }
+            //宸﹁竟璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalLeft2(temps, conf.getCableRule());
+        }
+        //璧峰鏂逛綅涓哄乏涓婃椂
+        if (Constant.GRAIN_START_ORIENTATION_LEFT_UP.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //宸︿笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalLeftUp2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //宸︿笂璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalLeftUp1(temps, conf.getCableRule());
+            }
+            //宸︿笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalLeftUp2(temps, conf.getCableRule());
+        }
+
+        return temps;
+    }
+
+    private void analysisTh(IoMessage message) {
+        try {
+            THDto th = new THDto();
+            th.setCompanyId(ContextUtil.getDefaultCompanyId());
+            String data = message.getContent();
+            String houseNo = data.substring(0, 2);
+            String t = data.substring(4, 8);
+            String h = data.substring(8, 12);
+            double temp, humy;
+            if (ReMessageBuilder.ERROR_TAG.equals(t)) {
+                temp = 0.0;
+            } else {
+                temp = (double) BytesUtil.hexToBigInt(BytesUtil.tran_LH(t)) / 10;
+            }
+            if (ReMessageBuilder.ERROR_TAG.equals(h)) {
+                humy = 0.0;
+            } else {
+                humy = (double) BytesUtil.hexToBigInt(BytesUtil.tran_LH(h)) / 10;
+            }
+
+            th.setTempIn(temp);
+            th.setHumidityIn(humy);
+            log.info("涓绘満--------->>>骞冲彴锛岃В鏋愪粨娓╀粨婀夸俊鎭紝浠撳簱={},缁撴灉={}", houseNo, th.toString());
+
+            String key = "TH_" + houseNo;
+            contextMapTH.put(key, th);
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            String hexStr = CommandBuild.getMsgTHReply(message.getAddr());
+            log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炰粨娓╀粨婀挎敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+            serverEngine.pushByMin(hexStr);
+        }
+    }
+
+    private THDto getTH(IoMessage message) {
+        String data = message.getContent();
+        String houseNo = data.substring(0, 2);
+
+        String key = "TH_" + houseNo;
+
+        return contextMapTH.get(key);
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/CommandBuild.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/CommandBuild.java
new file mode 100644
index 0000000..28bf15d
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/CommandBuild.java
@@ -0,0 +1,178 @@
+package com.ld.igds.protocol.bhzn.grainv1.msg.builder;
+
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerUtils;
+import com.ld.igds.util.BytesUtil;
+
+/**
+ * 鍛戒护鐢熸垚
+ *
+ * @author vince
+ */
+public class CommandBuild {
+
+    private final static CommandBuild instance = new CommandBuild();
+
+    private CommandBuild() {
+    }
+
+    public static CommandBuild getInstance() {
+        return instance;
+    }
+
+    /**
+     * PC鍥炲 蹇冭烦鍟� 鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgHeartReply(String grainAddr) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_F2);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * 绮儏閲囬泦鍛戒护
+     *
+     * @param grainAddr 绮儏鍒嗘満鍦板潃
+     * @param deptId    浠撳簱缂栧彿鍦板潃
+     * @return
+     */
+    public static String getMsgCheck(String grainAddr, String deptId) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_83);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--涓绘満閲岄潰閰嶇疆鐨勪粨搴撶紪鐮�
+        i = Integer.parseInt(deptId);
+        sb.append(BytesUtil.intToHexStr1(i));
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * PC鍥炲 浠撴俯浠撴箍 鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgTHReply(String grainAddr) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_93);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * PC鍥炲绮俯鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgGrainReply(String grainAddr) {
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_92);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/ReMessageBuilder.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/ReMessageBuilder.java
new file mode 100644
index 0000000..017db54
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/builder/ReMessageBuilder.java
@@ -0,0 +1,51 @@
+package com.ld.igds.protocol.bhzn.grainv1.msg.builder;
+
+import com.ld.igds.protocol.bhzn.grainv1.msg.message.IoMessage;
+import com.ld.igds.util.BytesUtil;
+
+/**
+ * 鏍规嵁鎺ユ敹鍒扮殑淇℃伅杩涜灏佽
+ *
+ * @author vince
+ */
+public class ReMessageBuilder {
+
+
+    public final static String ERROR_TAG = "3CF6";
+    public static double FAULT_CHECK_TAG = 85.0;
+    public static double MAX_TEMP = -50.0;
+    public static double MIN_TEMP = 50.0;
+    private final static ReMessageBuilder instance = new ReMessageBuilder();
+
+    private ReMessageBuilder() {
+    }
+
+    public static ReMessageBuilder getInstance() {
+        return instance;
+    }
+
+    /**
+     * @param message
+     * @return
+     */
+    public IoMessage buildMessage(String message) throws Exception {
+        IoMessage ioMessage = new IoMessage();
+
+        //杞崲涓烘暟瀛楋紝楂樹綆浣嶈浆鎹�(4浣�)
+        int i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(2, 6)));
+        ioMessage.setPcAddr(i + "");
+        i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(6, 10)));//楂樹綆浣嶈浆鎹�(4浣�)
+        ioMessage.setAddr(i + "");
+
+        ioMessage.setFunctionId(message.substring(10, 12));//鍔熻兘鐮�(2浣�)锛屼笉鐢ㄩ珮浣庝綅杞崲
+
+        i = BytesUtil.hexToBigInt(message.substring(12, 14));//闀垮害(1浣�)
+        ioMessage.setLength(i);
+
+        //鑾峰彇娑堟伅浣�
+        ioMessage.setContent(message.substring(14, 14 + (i * 2)));
+
+        ioMessage.setCheck(message.substring(message.length() - 2));
+        return ioMessage;
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/Content.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/Content.java
new file mode 100644
index 0000000..016f953
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/Content.java
@@ -0,0 +1,43 @@
+package com.ld.igds.protocol.bhzn.grainv1.msg.message;
+
+import lombok.Data;
+
+/**
+ * @author vince.xu
+ * @Title: Content
+ * @ProjectName igds-35
+ * @Description: TODO
+ * @date 2022-12-715:48
+ */
+@Data
+public class Content {
+    /**
+     * 鐘舵�佸弽鍥�
+     */
+    public  String result;
+    /**
+     * 绾害
+     */
+    public String purity;
+    /**
+     * 娴侀噺
+     */
+    public String flow;
+    /**
+     * 鍘嬪姏
+     */
+    public String pressure;
+    /**
+     * 娓╁害
+     */
+    public String temperature;
+    /**
+     * 娴侀噺绱
+     */
+    public String flowAll;
+    /**
+     * 杩愯鐘舵��
+     */
+    public String isRun;
+
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/IoMessage.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/IoMessage.java
new file mode 100644
index 0000000..d453ca3
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/msg/message/IoMessage.java
@@ -0,0 +1,20 @@
+package com.ld.igds.protocol.bhzn.grainv1.msg.message;
+
+import lombok.Data;
+
+@Data
+public class IoMessage {
+
+
+    private String ip;
+
+    private int port;
+
+    private String pcAddr;
+    private String addr;
+    private String functionId;
+    private int length;
+    private String content;
+    private String check;
+
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/package-info.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/package-info.java
new file mode 100644
index 0000000..02e5005
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 閭︽捣鏃犵嚎绾伯鎯呭崗璁�
+ */
+package com.ld.igds.protocol.bhzn.grainv1;
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1HeartbeatImpl.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1HeartbeatImpl.java
new file mode 100644
index 0000000..80f8ffb
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1HeartbeatImpl.java
@@ -0,0 +1,42 @@
+package com.ld.igds.protocol.bhzn.grainv1.server;
+
+
+import com.ld.io.api.HeartbeatProvider;
+import com.ld.io.api.IoSession;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 鎻愪緵蹇冭烦淇℃伅
+ *
+ * @author Andy
+ */
+@Slf4j
+@Service
+public class BhznGrainV1HeartbeatImpl implements HeartbeatProvider {
+
+    @Override
+    public byte[] provide(IoSession session) {
+
+
+        //鐩存帴鏍规嵁涓绘満SESSIOn鍒ゆ柇
+        IoSession session1 = BhznGrainV1ServerUtils.getSession();
+
+        Long lastBeatTime = BhznGrainV1ServerUtils.getHearBeat(session1);
+
+        if (null == lastBeatTime) {
+            return null;
+        }
+
+        //濡傛灉鏈�鍚庝竴娆$粓绔績璺虫椂闂磋窛绂诲綋鍓嶆椂闂村ぇ浜� 缁堢蹇冭烦鏃堕棿鐨�3娆★紝鍒欏垽鏂负绂荤嚎
+        long deTime = System.currentTimeMillis() - lastBeatTime;
+
+        if (deTime > (BhznGrainV1ServerUtils.HEART_BEAT_TIME * 3 * 1000)) {
+            log.info("-----------瓒呰繃{}绉掓湭鑾峰彇鍒板績璺充俊鎭紝鍒ゅ畾缁堢绂荤嚎锛岃涪鍑鸿繛鎺�------------{}-{}", deTime, session.getAddress(), session.getPort());
+
+            session.destroy();
+        }
+
+        return null;
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1MessageConsumer.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1MessageConsumer.java
new file mode 100644
index 0000000..0c1acb8
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1MessageConsumer.java
@@ -0,0 +1,57 @@
+package com.ld.igds.protocol.bhzn.grainv1.server;
+
+import com.ld.igds.protocol.bhzn.grainv1.msg.AnalysisService;
+import com.ld.igds.protocol.bhzn.grainv1.msg.builder.ReMessageBuilder;
+import com.ld.igds.protocol.bhzn.grainv1.msg.message.IoMessage;
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.IoMsgConsumer;
+import com.ld.io.api.IoSession;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Slf4j
+@Service
+public class BhznGrainV1MessageConsumer implements IoMsgConsumer {
+
+
+    @Autowired
+    private AnalysisService analysisService;
+
+    /**
+     * 澶勭悊娑堟伅
+     *
+     * @param ioSession
+     * @param bytes
+     */
+    @Override
+    public void consume(IoSession ioSession, byte[] bytes) {
+        if (null == bytes) {
+            log.error("Reply bytes is null");
+            return;
+        }
+
+        //娣诲姞淇℃伅蹇冭烦鏍囪
+        BhznGrainV1ServerUtils.addHeartBeat(ioSession);
+
+        //榛樿璁剧疆涓婚�氳鏈嶅姟
+        BhznGrainV1ServerUtils.addSession(ioSession);
+
+        try {
+            String hexStr = BytesUtil.bytesToString(bytes);
+            log.info("涓绘満杩斿洖鎶ユ枃------->>骞冲彴锛�" + hexStr);
+            hexStr = hexStr.substring(BhznGrainV1ServerUtils.MSG_START.length());
+
+            IoMessage ioMessage = ReMessageBuilder.getInstance().buildMessage(hexStr);
+            ioMessage.setIp(ioSession.getAddress());
+            ioMessage.setPort(ioSession.getPort());
+
+            analysisService.analysis(ioSession.getBusinessKey(), ioMessage);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerEngine.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerEngine.java
new file mode 100644
index 0000000..48fab2c
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerEngine.java
@@ -0,0 +1,131 @@
+package com.ld.igds.protocol.bhzn.grainv1.server;
+
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.*;
+import com.ld.io.netty.NettyServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Desc: 閭︽捣鏅鸿兘绾伯鎯呭崗璁�
+ * @author: Andy
+ * @update-time: 2023/5/11
+ */
+@Slf4j
+@Service
+public class BhznGrainV1ServerEngine {
+
+    public static final Integer PORT = 9309;
+
+    @Autowired
+    private BhznGrainV1MessageConsumer defaultMessageConsumer;
+    @Autowired
+    private BhznGrainV1SessionListener defaultSessionListener;
+    // 蹇冭烦鎻愪緵
+    private static HeartbeatProvider heartbeatProvider = new BhznGrainV1HeartbeatImpl();
+
+    private IoSessionQuery sessionQuery;
+
+    public void start(Integer port) {
+        IoServerOption ioServerOption = new IoServerOption();
+
+        if (null != port) {
+            ioServerOption.setPort(port);
+        } else {
+            ioServerOption.setPort(PORT);
+        }
+
+        //纭缁撳熬鏍囧織
+        ioServerOption.setDelimiter(BhznGrainV1ServerUtils.MSG_END.getBytes());
+
+        // 閰嶇疆绯荤粺蹇冭烦闂撮殧
+        ioServerOption.setReaderIdleTime(5 * 60);
+
+        NettyServer ioServer = new NettyServer(ioServerOption, defaultMessageConsumer, defaultSessionListener, heartbeatProvider);
+        ioServer.startup();
+
+        sessionQuery = ioServer.getSessionQuery();
+
+
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+        log.info("* [GRAIN-SERVER锛欱HZN_GRAIN,PORT={}]", PORT);
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+
+        System.out.println("* ========================");
+        System.out.println("* ");
+        System.out.println("* [GRAIN-SERVER锛欱HZN_GRAIN,PORT={}]" + port);
+        System.out.println("* ");
+        System.out.println("* ========================");
+    }
+
+    public IoSessionQuery getSessionQuery() {
+        return sessionQuery;
+    }
+
+    /**
+     * 鍙戦�佷俊鎭�
+     *
+     * @param ip
+     * @param port
+     * @param msg
+     * @return
+     */
+    public InvokeResult push(String ip, int port, byte[] msg) {
+        IoSessionQuery sessionFactory = getSessionQuery();
+        List<IoSession> sessions = sessionFactory.getAllSession();
+        IoSession session = null;
+        for (IoSession ioSession : sessions) {
+            if (BhznGrainV1ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+                session = ioSession;
+                break;
+            }
+        }
+        if (null == session) {
+            return InvokeResult.CHANNEL_CLOSED;
+        }
+        return session.invoke(msg);
+    }
+
+
+//    public InvokeResult push(String ip, int port, String hexStr) {
+//
+//        byte[] msg = BytesUtil.hexStrToBytes(hexStr);
+//
+//        IoSessionQuery sessionFactory = getSessionQuery();
+//        List<IoSession> sessions = sessionFactory.getAllSession();
+//        IoSession session = null;
+//        for (IoSession ioSession : sessions) {
+//            if (BhznGrainV1ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+//                session = ioSession;
+//                break;
+//            }
+//        }
+//
+//        if (null == session) {
+//            return InvokeResult.CHANNEL_CLOSED;
+//        }
+//        return session.invoke(msg);
+//    }
+
+    /**
+     * 鐩存帴浣跨敤鍐呭瓨鐨凷ession鎵ц
+     */
+    public InvokeResult pushByMin(String hexStr) {
+
+        IoSession session = BhznGrainV1ServerUtils.getSession();
+
+        if (null == session) {
+            return InvokeResult.CHANNEL_CLOSED;
+        }
+        byte[] msg = BytesUtil.hexStrToBytes(hexStr);
+        return session.invoke(msg);
+    }
+
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerUtils.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerUtils.java
new file mode 100644
index 0000000..c74bbc2
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1ServerUtils.java
@@ -0,0 +1,103 @@
+package com.ld.igds.protocol.bhzn.grainv1.server;
+
+
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.IoSession;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 宸ュ叿绫�
+ *
+ * @author vince
+ */
+public class BhznGrainV1ServerUtils {
+
+
+    /**
+     * 璁板綍姣忎釜杩炴帴鐨勬渶鍚庝竴娆′俊鎭椂闂� key = 杩炴帴鐨凨YE锛宒ata =褰撳墠鏃堕棿鎴�
+     */
+    public static Map<String, Long> contextMapHeart = new HashMap<>();
+
+    public static Map<String, IoSession> contextIoSession = new HashMap<>();
+
+
+    public static int HEART_BEAT_TIME = 30;//蹇冭烦闂撮殧鏃堕棿
+
+
+    public static String MSG_START = "3C42485A4E3E";//<BHZN>
+    public static String MSG_START2 = "AA";
+    public static String MSG_END = "<END>";//<END>
+    public static String MSG_END_16 = "3C454E443E";//<END>
+    public static final String CHARSET = "UTF-8";
+
+
+    /**
+     * 閽堝鏃犵嚎绮儏涓绘満鐨勯粯璁D閰嶇疆
+     */
+    public static String DEFAULT_MAC_ID = "53681";
+
+    public static String FUNCTION_ID_00 = "00";
+    public static String FUNCTION_ID_F1 = "F1";
+    public static String FUNCTION_ID_F2 = "F2";
+    public static String FUNCTION_ID_83 = "83";
+    public static String FUNCTION_ID_93 = "93";
+    public static String FUNCTION_ID_92 = "92";
+
+
+    /**
+     * 鐢熸垚TCP杩炴帴鐨凨EY
+     *
+     * @param ip
+     * @param port
+     * @return
+     */
+    public static String getServerKey(String ip, Integer port) {
+        return ip + ":" + port;
+    }
+
+
+    /**
+     * 娣诲姞鏈�鏂板績璺虫椂闂存埑
+     *
+     * @param session
+     */
+    public static void addHeartBeat(IoSession session) {
+        contextMapHeart.put(getServerKey(session.getAddress(), session.getPort()), System.currentTimeMillis());
+    }
+
+    public static Long getHearBeat(IoSession session) {
+        return contextMapHeart.get(getServerKey(session.getAddress(), session.getPort()));
+    }
+
+
+    /**
+     * 璁$畻鏍¢獙
+     *
+     * @param content
+     * @return
+     */
+    public static String getCheck(String content) {
+        int start = BhznGrainV1ServerUtils.MSG_START.length() + BhznGrainV1ServerUtils.MSG_START2.length();
+        content = content.substring(start);
+        int sum = 0;
+        String hex;
+        for (int i = 0; i < content.length() / 2; i++) {
+            hex = content.substring(i * 2, i * 2 + 2);
+            sum += BytesUtil.hexToInt(hex);
+        }
+        String hexSum = BytesUtil.intToHexStr(sum);
+        int check = BytesUtil.hexToInt(hexSum.substring(hexSum.length() - 2));
+
+        return BytesUtil.intToHexStr(256 - check).substring(2);
+    }
+
+    public static void addSession(IoSession session) {
+        contextIoSession.put(DEFAULT_MAC_ID, session);
+    }
+
+    public static IoSession getSession() {
+        return contextIoSession.get(DEFAULT_MAC_ID);
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1SessionListener.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1SessionListener.java
new file mode 100644
index 0000000..dfba6d2
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv1/server/BhznGrainV1SessionListener.java
@@ -0,0 +1,68 @@
+package com.ld.igds.protocol.bhzn.grainv1.server;
+
+import com.ld.igds.common.CoreSerService;
+import com.ld.igds.constant.Constant;
+import com.ld.igds.models.DeviceSer;
+import com.ld.igds.util.ContextUtil;
+import com.ld.io.api.IoSession;
+import com.ld.io.api.IoSessionListener;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Slf4j
+@Service
+public class BhznGrainV1SessionListener implements IoSessionListener {
+
+    @Autowired
+    private CoreSerService coreSerService;
+
+    /**
+     * 璁惧鍒涘缓鍦ㄧ嚎锛岄渶瑕佹敞鎰忓綋鍓嶄娇鐢ㄤ富鏈烘ā寮忥紝涓绘満涓婄嚎榛樿鎵�鏈夌浉鍚孲N閰嶇疆鐨勫垎鏈哄叏閮ㄤ笂绾�
+     *
+     * @param session
+     */
+    @Override
+    public void onCreate(IoSession session) {
+
+        //娣诲姞鍒板唴瀛�
+        BhznGrainV1ServerUtils.addSession(session);
+
+        log.info("++++鏂板缓杩炴帴++++-IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+
+        // 娣诲姞鑷畾涔変笟鍔D
+        session.setBusinessKey(BhznGrainV1ServerUtils.getServerKey(session.getAddress(), session.getPort()));
+
+        //椤圭洰閲囩敤鏃犵嚎涓绘満妯″紡锛岀洿鎺ヨ幏鍙栭粯璁よ澶�
+        DeviceSer deviceSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+
+        if (null == deviceSer) return;
+
+        coreSerService.onlineBySn(session.getAddress(), session.getPort(), deviceSer.getSn(), Constant.YN_Y);
+        //鏇存柊缂撳瓨
+        coreSerService.refreshCache(deviceSer.getCompanyId());
+    }
+
+    /**
+     * 娉ㄦ剰锛屽綋鍓嶉噰鐢ㄤ富鏈烘ā寮忥紝涓绘満绂荤嚎鎵�鏈夌浉鍚孲N閰嶇疆鐨勫垎鏈哄叏閮ㄧ绾�
+     *
+     * @param session
+     */
+    @Override
+    public void onDestroy(IoSession session) {
+        log.info("----杩炴帴鏂紑-----IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+
+        //椤圭洰閲囩敤鏃犵嚎涓绘満妯″紡锛岀洿鎺ヨ幏鍙栭粯璁よ澶�
+        DeviceSer deviceSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+
+        if (null == deviceSer) return;
+
+        //鐢变簬璁惧鎺夌嚎鍚庤嚜鍔ㄨ皟鏁�
+//        coreSerService.onlineBySn(session.getAddress(), session.getPort(), deviceSer.getSn(), Constant.YN_N);
+//        //鏇存柊缂撳瓨
+//        coreSerService.refreshCache(deviceSer.getCompanyId());
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/RemoteGrainV2ServiceImpl.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/RemoteGrainV2ServiceImpl.java
new file mode 100644
index 0000000..f696c7c
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/RemoteGrainV2ServiceImpl.java
@@ -0,0 +1,70 @@
+package com.ld.igds.protocol.bhzn.grainv2;
+
+import com.ld.igds.common.CoreSerService;
+import com.ld.igds.io.RemoteGrainService;
+import com.ld.igds.io.constant.OrderRespEnum;
+import com.ld.igds.io.constant.ProtocolEnum;
+import com.ld.igds.io.request.CheckGrainRequest;
+import com.ld.igds.io.response.GrainResponse;
+import com.ld.igds.protocol.bhzn.grainv2.msg.builder.CommandBuild;
+import com.ld.igds.protocol.bhzn.grainv2.server.BhznGrainV2ServerEngine;
+import com.ld.io.api.InvokeResult;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * @Desc: 绮儏涓氬姟鎺ュ彛
+ * @author: Andy
+ * @update-time: 2023/5/11
+ */
+@Slf4j
+@Component(RemoteGrainV2ServiceImpl.BEAN_ID)
+public class RemoteGrainV2ServiceImpl implements RemoteGrainService {
+
+    public static final String BEAN_ID = "bhznGrainv2.remoteGrainService";
+
+    @Autowired
+    private CoreSerService coreSerService;
+    @Autowired
+    private BhznGrainV2ServerEngine bhznGrainServerEngine;
+
+    @Override
+    public String getProtocol() {
+        return ProtocolEnum.TCP_BHZH_GRAIN_V2.getCode();
+    }
+
+    @Override
+    public GrainResponse checkGrain(CheckGrainRequest request) {
+        try {
+            // 鐢熸垚绮儏淇℃伅
+            String hexStr = CommandBuild.getInstance().getMsgCheck(request.getSerId(), request.getDepotId());
+
+
+//            //閫氳浣跨敤鐨勬槸涓绘満閫氳
+//            DeviceSer mainSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+//            request.setIp(mainSer.getIp());
+//            request.setPort(mainSer.getPort());
+
+            // 鍙戦�佸懡浠�
+            InvokeResult result = bhznGrainServerEngine.pushByMin(hexStr);
+
+            log.error("骞冲彴------>>>>鎺у埗鏌滐細绮儏妫�娴�-{}", hexStr);
+
+            // 灏佽杩斿洖淇℃伅
+            if (InvokeResult.SUCCESS == result) {
+                return new GrainResponse(OrderRespEnum.ORDER_SUCCESS.getCode(),
+                        "绮儏绮儏鍙戦�佹垚鍔燂紒");
+            } else {
+                log.error("骞冲彴------>>>>鎺у埗鏌滐細绮儏妫�娴�-澶辫触{}", result.getMessage());
+                return new GrainResponse(OrderRespEnum.ORDER_ERROR.getCode(),
+                        "鍛戒护鍙戦�佸紓甯革細" + result.getMessage());
+            }
+
+        } catch (Exception e) {
+            log.error("绮儏妫�娴嬪紓甯革細{}", e);
+            return new GrainResponse(OrderRespEnum.ORDER_ERROR.getCode(), "鍚庣寮傚父锛�" + e.getMessage());
+        }
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/ServerRunner.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/ServerRunner.java
new file mode 100644
index 0000000..c3c0f92
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/ServerRunner.java
@@ -0,0 +1,34 @@
+package com.ld.igds.protocol.bhzn.grainv2;
+
+import com.ld.igds.data.ConfigData;
+import com.ld.igds.protocol.bhzn.grainv2.server.BhznGrainV2ServerEngine;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+/**
+ * 閰嶇疆闅忕郴缁熻嚜鍔ㄥ惎鍔ㄦ湇鍔� -- 鎵ц椤哄簭20-29
+ */
+@Component(ServerRunner.BEAN_ID)
+@Order(value = 24)
+public class ServerRunner implements CommandLineRunner {
+
+    public static final String BEAN_ID = "bhzn.serverRunnerV2";
+
+    @Autowired
+    private ConfigData configData;
+    @Autowired
+    private BhznGrainV2ServerEngine bhznGrainServerEngine;
+
+    @Override
+    public void run(String... strings) throws Exception {
+
+        if (configData.getActive().indexOf("pro") >= 0) {
+            bhznGrainServerEngine.start(BhznGrainV2ServerEngine.PORT);
+        }
+        if (configData.getActive().indexOf("dev") >= 0) {
+            bhznGrainServerEngine.start(BhznGrainV2ServerEngine.PORT);
+        }
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/AnalysisService.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/AnalysisService.java
new file mode 100644
index 0000000..5d4e413
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/AnalysisService.java
@@ -0,0 +1,474 @@
+package com.ld.igds.protocol.bhzn.grainv2.msg;
+
+import com.ld.igds.common.CoreCommonService;
+import com.ld.igds.common.CoreSerService;
+import com.ld.igds.common.dto.THDto;
+import com.ld.igds.constant.BizType;
+import com.ld.igds.constant.Constant;
+import com.ld.igds.grain.GrainUtil;
+import com.ld.igds.grain.dto.GrainItemInfo;
+import com.ld.igds.io.notify.NotifyGrainInvoker;
+import com.ld.igds.models.DepotConf;
+import com.ld.igds.models.DeviceSer;
+import com.ld.igds.models.DicSysConf;
+import com.ld.igds.models.Grain;
+import com.ld.igds.order.ExeOrderService;
+import com.ld.igds.order.data.ExeRequest;
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerUtils;
+import com.ld.igds.protocol.bhzn.grainv2.msg.builder.CommandBuild;
+import com.ld.igds.protocol.bhzn.grainv2.msg.builder.ReMessageBuilder;
+import com.ld.igds.protocol.bhzn.grainv2.msg.message.IoMessage;
+import com.ld.igds.protocol.bhzn.grainv2.server.BhznGrainV2ServerEngine;
+import com.ld.igds.util.BytesUtil;
+import com.ld.igds.util.ContextUtil;
+import com.ld.igds.warn.WarnUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+/**
+ * 鍗忚瑙f瀽
+ *
+ * @author vince
+ */
+@Slf4j
+@Component(AnalysisService.BEAN_ID)
+public class AnalysisService {
+
+
+    /**
+     * 閽堝鍒嗗寘绮儏鎶ユ枃杩涜灏佽
+     */
+    public static Map<String, String> contextMapGrain = new HashMap<>();
+
+    /**
+     * 鐢ㄤ簬瀛樻斁杩斿洖鐨勪粨娓╀粨婀夸俊鎭�
+     */
+    public static Map<String, THDto> contextMapTH = new HashMap<>();
+
+    public static final String BEAN_ID = "bhznGrainv2.analysisService";
+
+    @Autowired
+    private CoreSerService coreSerService;
+    @Autowired
+    private BhznGrainV2ServerEngine serverEngine;
+    @Autowired
+    private CoreCommonService commonService;
+    @Autowired
+    private NotifyGrainInvoker notifyGrainInvoker;
+    @Autowired
+    private GrainUtil grainUtil;
+    @Autowired
+    private WarnUtils warnUtils;
+    @Autowired
+    private ExeOrderService exeOrderService;
+
+    /**
+     * @param sessionKey ip:port
+     */
+    public void analysis(String sessionKey, IoMessage message) throws Exception {
+
+        //娉ㄥ唽
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_F1.equals(message.getFunctionId())) {
+            //DO NOTHING
+
+            log.info("涓绘満------->>骞冲彴锛氭敞鍐屼俊鎭姤鏂�={}", message);
+            DeviceSer ser = coreSerService.getCacheSerBySn(ContextUtil.getDefaultCompanyId(),message.getAddr());
+            if(ser!= null ){
+                ser.setIp(message.getIp());
+                ser.setPort(message.getPort());
+                ser.setStatus(Constant.YN_Y);
+                coreSerService.updateByData(ser);
+            }
+            return;
+        }
+
+        //蹇冭烦
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_F2.equals(message.getFunctionId())) {
+            //String hexStr = CommandBuild.getMsgHeartReply(message.getAddr());
+            //log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炲績璺虫敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+           // serverEngine.pushByMin(hexStr);
+            return;
+        }
+
+        // 93 瑙f瀽浠撴俯浠撴箍锛屽苟杩斿洖鏀跺埌鎶ユ枃
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_93.equals(message.getFunctionId())) {
+            log.info("涓绘満------->>骞冲彴锛氭俯婀垮害淇℃伅鎶ユ枃={}", message);
+            analysisTh(message);
+            return;
+        }
+
+        // 92 瑙f瀽绮俯锛屽苟杩斿洖鏀跺埌鎶ユ枃
+        if (BhznGrainV1ServerUtils.FUNCTION_ID_92.equals(message.getFunctionId())) {
+            log.info("涓绘満------->>骞冲彴锛氱伯鎯呬俊鎭姤鏂�={}", message);
+            analysisGrain(message);
+        }
+    }
+
+
+    private void analysisGrain(IoMessage message) {
+        try {
+
+            //鏍规嵁鍒嗘満鍦板潃鑾峰彇鍒嗘満淇℃伅
+
+            DeviceSer ser = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), message.getAddr());
+            if (ser == null) {
+                replayGrain(message);
+                log.error("涓绘満-------->>骞冲彴锛岃В鏋愮伯鎯呭け璐ワ紝鏈幏鍙栧埌绯荤粺绮儏涓绘満閰嶇疆锛�" + message.getAddr());
+                return;
+            }
+
+            // 棣栧厛鑾峰彇鍒扮郴缁熷弬鏁帮紝鍒ゆ柇鏄惁闇�瑕佹壒娆¤嚜鍔ㄤ紭鍖�
+            DicSysConf sysConf = commonService.getCacheSysConf(ser.getCompanyId());
+            List<ExeRequest> list = exeOrderService.getInProgressOrderBySerId(BizType.GRAIN.getCode(), ser.getId());
+
+            if (null == list || list.isEmpty()) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍒版墍灞炰粨搴撲俊鎭��";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            //鑾峰彇閽堝褰撳墠浠撳簱鐨勫懡浠�
+            ExeRequest exeRequest = list.get(0);
+            if (null == exeRequest) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍘嗗彶鍛戒护銆�";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            DepotConf depotConf = commonService.getCacheDepotConf(exeRequest.getCompanyId(), exeRequest.getDepotId());
+
+            if (null == depotConf) {
+                String info = "绮儏瑙f瀽澶辫触:鍒嗘満=" + ser.getName() + "娌℃湁鑾峰彇鍒扮伯鎯呭弬鏁伴厤缃俊鎭��";
+                log.error("鍒嗘満------>>>骞冲彴锛�" + info);
+                return;
+            }
+
+            // 绮儏鐨勬壒娆″彿閲嶆柊鏍规嵁棰戠巼璋冩暣
+            String batchId = ContextUtil.getBatchIdByFireq(depotConf.getGrainFreq());
+
+            // 鍒ゆ柇鏁版嵁鏈夋病鏈夋敹鍙栧畬鏁�
+            String[] attCable = depotConf.getCableRule().split("-");
+            int cableZ = Integer.valueOf(attCable[0]);
+            int cableY = Integer.valueOf(attCable[1]);
+            int cableX = Integer.valueOf(attCable[2]);
+            int sumPoint = cableZ * cableY * cableX;
+
+            //鑾峰彇褰撳墠绮儏娓╁害鎶ユ枃
+            String grainHex = message.getContent().substring(16);
+
+            //褰撳墠鎶ユ枃娓╁害鐐规暟
+            int curPoint = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(4, 8)));
+
+            //濡傛灉褰撳墠鍖呯殑鏁版嵁涓暟澶т簬绛変簬褰撳墠浠撳簱鐨勯厤缃偣浣嶅垯琛ㄧず鍗曞寘杩斿洖
+            if (curPoint >= sumPoint) {
+
+                //杩斿洖绮儏鎺ユ敹淇℃伅
+                replayGrain(message);
+
+                analysisGrain2(ser, message, exeRequest, depotConf, sysConf, batchId, grainHex);
+                return;
+            }
+
+            //琛ㄧず鍒嗗寘浼犻��
+            String key = "GRAIN_" + message.getAddr();
+            String oldGrainHex = contextMapGrain.get(key) == null ? "" : contextMapGrain.get(key);
+
+            //鑾峰彇褰撳墠鍖呰捣濮嬬偣鐨勫眰琛屽垪
+            int hang = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(8, 10)));
+            int lie = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(10, 12)));
+            int ceng = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(12, 14)));
+            if (hang > 0 || lie > 0 || ceng > 0) {
+                //璇存槑闈炵涓�鍖呮暟鎹�
+                grainHex = oldGrainHex + grainHex;
+            }
+
+            if (grainHex.length() >= sumPoint * 4) {
+                //杩斿洖绮儏鎺ユ敹淇℃伅
+                replayGrain(message);
+
+                analysisGrain2(ser, message, exeRequest, depotConf, sysConf, batchId, grainHex);
+                return;
+
+            } else {
+                contextMapGrain.put(key, grainHex);
+                replayGrain(message);
+            }
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 杩斿洖绮儏鏀跺埌鎶ユ枃淇℃伅锛岄渶瑕佹敞鎰忥細濡傛灉瀛樺湪鍒嗗寘鎯呭喌涓嬶紝闇�瑕佺瓑鎵�鏈夊寘鏀跺埌鍚庤繑鍥�
+     *
+     * @param message
+     */
+    private void replayGrain(IoMessage message) {
+        String hexStr = CommandBuild.getMsgGrainReply(message.getAddr());
+        log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炵伯鎯呮姤鏂囨敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+        serverEngine.pushByMin(hexStr);
+    }
+
+    private void analysisGrain2(DeviceSer ser, IoMessage message, ExeRequest exeRequest, DepotConf depotConf, DicSysConf sysConf, String batchId, String grainStr) {
+        // 鑾峰彇瀹屾暣鐨勭伯鎯呭寘淇℃伅
+        String[] attCable = depotConf.getCableRule().split("-");
+        int cableZ = Integer.valueOf(attCable[0]);
+        int cableY = Integer.valueOf(attCable[1]);
+        int cableX = Integer.valueOf(attCable[2]);
+
+        // 鏍规嵁灞傝鍒楄幏鍙栨寚瀹氶暱搴�
+        int start = 4 * (depotConf.getCableStart() - ser.getCableStart())
+                * cableZ * cableY;
+        int len = 4 * cableZ * cableY * cableX;
+
+        log.info("鍒嗘満------>>>骞冲彴锛氳繑鍥炵伯鎯呭畬鏁翠俊鎭紝鎵�灞炵粍缁�={}锛屽垎鏈�={}", ser.getCompanyId(), ser.getName());
+
+        String strPoints = grainStr.substring(start, start + len);
+
+        // 灏嗙伯鎯呰В鏋愭垚鏁扮粍
+        List<Double> temps = new ArrayList<>();
+        double tempValue;
+        String temp;
+        for (int i = 0; i < strPoints.length() / 4; i++) {
+            temp = strPoints.substring(i * 4, i * 4 + 4);
+            if (temp == null) {
+                temp = "0000";
+            }
+            if (ReMessageBuilder.ERROR_TAG.equals(temp)) {
+                tempValue = Constant.ERROR_TEMP;
+            } else {
+                tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
+            }
+            // 鏁呴殰鍊煎鐞�
+            if (tempValue >= ReMessageBuilder.FAULT_CHECK_TAG) {
+                tempValue = Constant.FAULT_TEMP;
+            }
+            temps.add(tempValue);
+        }
+
+        log.debug("-------CheckGrainRequest--={}", exeRequest.toString());
+
+
+        THDto thDto = this.getTH(message);
+        if (null != thDto) {
+            log.debug("-------THDto--={}", thDto.toString());
+        }
+        //娓呯┖
+        String key = "GRAIN_" + message.getAddr();
+        contextMapGrain.put(key, null);
+        // 灏嗛泦鍚堣В鏋愭垚鍧愭爣鏁版嵁
+        addPoint1(temps, depotConf, ser, exeRequest, thDto, sysConf, batchId);
+
+    }
+
+
+    /**
+     * 骞虫埧浠擄紝瑙f瀽绗簩姝ワ紝瑙f瀽鍒板潗鏍囨暟鎹�
+     *
+     * @param temps
+     * @throws Exception
+     */
+    private void addPoint1(List<Double> temps,
+                           DepotConf depotConf, DeviceSer ser, ExeRequest exeRequest,
+                           THDto thDto, DicSysConf sysConf, String batchId) {
+
+        //鏍规嵁鐢电紗璧峰鏂逛綅鍜屽竷绾挎柟鍚戯紝瀵圭伯鎯呮暟鎹繘琛岃皟鏁�
+        if (null != depotConf.getStartOrientation()) {
+            temps = reversalGrainPoint(temps, depotConf);
+        }
+
+        //鑻ヨ捣鐐圭偣浣嶄负搴曢儴锛屽垯灏嗙伯鎯呮暟鎹繘琛岀炕杞�
+        if (null != depotConf.getStartPoint()
+                && Constant.GRAIN_START_POINT_BELOW.equals(depotConf.getStartPoint())) {
+            temps = grainUtil.reversalUpAndDown(temps, depotConf.getCableRule());
+        }
+
+        String[] attCable = depotConf.getCableRule().split("-");
+        int cableZ = Integer.valueOf(attCable[0]);
+        int cableY = Integer.valueOf(attCable[1]);
+        int cableX = Integer.valueOf(attCable[2]);
+
+        Grain grain = new Grain();
+        grain.setDepotId(depotConf.getDepotId());
+        grain.setCompanyId(depotConf.getCompanyId());
+        grain.setCable(depotConf.getCableRule());
+        grain.setBatchId(batchId);
+        grain.setTempIn(Constant.ERROR_TEMP);
+        grain.setHumidityIn(Constant.ERROR_TEMP);
+
+        if (null != thDto) {
+            log.debug("绮儏瑙f瀽涓幏鍙栧埌鐨勬俯婀垮害淇℃伅={}", thDto.toString());
+            grain.setHumidityIn(thDto.getHumidityIn());
+            grain.setTempIn(thDto.getTempIn());
+        }
+        grain.setReceiveDate(new Date());
+        grain.setRemark("绮俯姝e父");
+
+        // 鑾峰彇缂撳瓨涓殑鍛戒护淇℃伅
+        grain.setCheckUser(exeRequest.getExeUser());
+
+        double max = ReMessageBuilder.MAX_TEMP, min = ReMessageBuilder.MIN_TEMP, sumT = 0.0, sumNum = cableX
+                * cableY * cableZ;
+
+        // 鏍¢獙鍜屽疄鐜扮粺璁★紝鐢熸垚閲囬泦鐐逛俊鎭�
+        List<GrainItemInfo> listGrainItems = new ArrayList<>();
+        int i = 1;
+        for (Double temp : temps) {
+            if (temp == Constant.ERROR_TEMP || temp == Constant.FAULT_TEMP || temp == Constant.ADD_TEMP) {
+                sumNum--;
+            } else {
+                sumT += temp;
+                if (temp > max) {
+                    max = temp;
+                }
+                if (temp < min) {
+                    min = temp;
+                }
+            }
+            listGrainItems.add(new GrainItemInfo(i, temp));
+            i++;
+        }
+
+        if (sumNum == 0) {
+            sumNum = 1;
+            grain.setRemark("褰撳墠绮儏閲囬泦寮傚父");
+        }
+        //杩囨护姣旇緝鐢ㄧ殑鏈�澶ф渶灏忓��
+        if (max == ReMessageBuilder.MAX_TEMP) {
+            max = 0.0;
+        }
+        if (min == ReMessageBuilder.MIN_TEMP) {
+            min = 0.0;
+        }
+        if (null != depotConf.getTempMax() && max > depotConf.getTempMax()) {
+            grain.setRemark("浠撳簱閰嶇疆楂樻俯璀﹀憡鍊硷細" + depotConf.getTempMax() + "锛屽綋鍓嶆娴嬮珮娓╁�硷細"
+                    + max);
+            warnUtils.addGrainWarn(depotConf, grain);
+        }
+
+        grain.setTempAve(sumT / sumNum);
+        grain.setTempMax(max);
+        grain.setTempMin(min);
+        grain.setPoints(org.apache.commons.lang3.StringUtils.join(temps, ","));
+
+        String depotIds = exeRequest.getDepotIds();
+
+        boolean notifyWeb = true;
+        if (null != depotIds && depotIds.indexOf(depotConf.getDepotId()) == -1) {
+            notifyWeb = false;
+        }
+        // 鐢ㄦ埛灏佽濂芥暟鎹嵆鍙�
+        notifyGrainInvoker.analysisSuccess(grain, listGrainItems, depotConf,
+                sysConf, notifyWeb, exeRequest);
+    }
+
+    private List<Double> reversalGrainPoint(List<Double> temps, DepotConf conf) {
+        if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartOrientation())) {
+            //鑻ヨ捣濮嬫柟浣嶄负绌猴紝鍒欓粯璁よ捣濮嬫柟浣嶅拰鏂瑰悜锛岀洿鎺ヨ繑鍥�
+            return temps;
+        }
+        //璧峰鏂逛綅涓哄彸杈规椂
+        if (Constant.GRAIN_START_ORIENTATION_RIGHT.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //鍙宠竟璧峰锛岄粯璁ょ旱鍚戝竷绾匡紝鐩存帴杩斿洖
+                return temps;
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //鍙宠竟璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalRight1(temps, conf.getCableRule());
+            }
+            //鍙宠竟璧峰锛岄粯璁ょ旱鍚戝竷绾匡紝鐩存帴杩斿洖
+            return temps;
+        }
+        //璧峰鏂逛綅涓哄彸涓婃椂
+        if (Constant.GRAIN_START_ORIENTATION_RIGHT_UP.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //鍙充笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalRightUp2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //鍙充笂璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalRightUp1(temps, conf.getCableRule());
+            }
+            //鍙充笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalRightUp2(temps, conf.getCableRule());
+        }
+        //璧峰鏂逛綅涓哄乏杈规椂
+        if (Constant.GRAIN_START_ORIENTATION_LEFT.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //宸﹁竟璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalLeft2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //宸﹁竟璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalLeft1(temps, conf.getCableRule());
+            }
+            //宸﹁竟璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalLeft2(temps, conf.getCableRule());
+        }
+        //璧峰鏂逛綅涓哄乏涓婃椂
+        if (Constant.GRAIN_START_ORIENTATION_LEFT_UP.equals(conf.getStartOrientation())) {
+            if (org.apache.commons.lang3.StringUtils.isEmpty(conf.getStartDirection())) {
+                //宸︿笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+                return grainUtil.reversalLeftUp2(temps, conf.getCableRule());
+            }
+            if (Constant.GRAIN_START_DIRECTION_TRANSVERSE.equals(conf.getStartDirection())) {
+                //宸︿笂璧峰锛屾í鍚戝竷绾�
+                return grainUtil.reversalLeftUp1(temps, conf.getCableRule());
+            }
+            //宸︿笂璧峰锛岄粯璁ょ旱鍚戝竷绾�
+            return grainUtil.reversalLeftUp2(temps, conf.getCableRule());
+        }
+
+        return temps;
+    }
+
+    private void analysisTh(IoMessage message) {
+        try {
+            THDto th = new THDto();
+            th.setCompanyId(ContextUtil.getDefaultCompanyId());
+            String data = message.getContent();
+            String houseNo = data.substring(0, 2);
+            String t = data.substring(4, 8);
+            String h = data.substring(8, 12);
+            double temp, humy;
+            if (ReMessageBuilder.ERROR_TAG.equals(t)) {
+                temp = 0.0;
+            } else {
+                temp = (double) BytesUtil.hexToBigInt(BytesUtil.tran_LH(t)) / 10;
+            }
+            if (ReMessageBuilder.ERROR_TAG.equals(h)) {
+                humy = 0.0;
+            } else {
+                humy = (double) BytesUtil.hexToBigInt(BytesUtil.tran_LH(h)) / 10;
+            }
+
+            th.setTempIn(temp);
+            th.setHumidityIn(humy);
+            log.info("涓绘満--------->>>骞冲彴锛岃В鏋愪粨娓╀粨婀夸俊鎭紝浠撳簱={},缁撴灉={}", houseNo, th.toString());
+
+            String key = "TH_" + houseNo;
+            contextMapTH.put(key, th);
+
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        } finally {
+            String hexStr = CommandBuild.getMsgTHReply(message.getAddr());
+            log.info("骞冲彴--------->>>涓绘満锛岃繑鍥炰粨娓╀粨婀挎敹鍒颁俊鎭紝鎶ユ枃={}", hexStr);
+            serverEngine.pushByMin(hexStr);
+        }
+    }
+
+    private THDto getTH(IoMessage message) {
+        String data = message.getContent();
+        String houseNo = data.substring(0, 2);
+
+        String key = "TH_" + houseNo;
+
+        return contextMapTH.get(key);
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/CommandBuild.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/CommandBuild.java
new file mode 100644
index 0000000..ddacfb6
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/CommandBuild.java
@@ -0,0 +1,178 @@
+package com.ld.igds.protocol.bhzn.grainv2.msg.builder;
+
+import com.ld.igds.protocol.bhzn.grainv1.server.BhznGrainV1ServerUtils;
+import com.ld.igds.util.BytesUtil;
+
+/**
+ * 鍛戒护鐢熸垚
+ *
+ * @author vince
+ */
+public class CommandBuild {
+
+    private final static CommandBuild instance = new CommandBuild();
+
+    private CommandBuild() {
+    }
+
+    public static CommandBuild getInstance() {
+        return instance;
+    }
+
+    /**
+     * PC鍥炲 蹇冭烦鍟� 鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgHeartReply(String grainAddr) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_F2);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * 绮儏閲囬泦鍛戒护
+     *
+     * @param grainAddr 绮儏鍒嗘満鍦板潃
+     * @param deptId    浠撳簱缂栧彿鍦板潃
+     * @return
+     */
+    public static String getMsgCheck(String grainAddr, String deptId) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_83);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--涓绘満閲岄潰閰嶇疆鐨勪粨搴撶紪鐮�
+        i = Integer.parseInt(deptId);
+        sb.append(BytesUtil.intToHexStr1(i));
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * PC鍥炲 浠撴俯浠撴箍 鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgTHReply(String grainAddr) {
+
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_93);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+
+    /**
+     * PC鍥炲绮俯鏀跺埌淇℃伅
+     *
+     * @param grainAddr
+     * @return
+     */
+    public static String getMsgGrainReply(String grainAddr) {
+        StringBuffer sb = new StringBuffer();
+
+        //寮�濮嬬鍙�
+        sb.append(BhznGrainV1ServerUtils.MSG_START);
+        sb.append(BhznGrainV1ServerUtils.MSG_START2);
+
+        //鍒嗘満鍦板潃
+        int i = Integer.parseInt(grainAddr);
+        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
+
+        //鍙戦�佹柟鍦板潃
+        sb.append("0000");
+
+        //鍛戒护ID
+        sb.append(BhznGrainV1ServerUtils.FUNCTION_ID_92);
+
+        //鏁版嵁闀垮害-01
+        sb.append("01");
+
+        //鏁版嵁鍖�--浠绘剰鍊�
+        sb.append("01");
+
+        //鑾峰彇鏍¢獙鐮�
+        sb.append(BhznGrainV1ServerUtils.getCheck(sb.toString()));
+
+        //缁撳熬绗�
+        sb.append(BhznGrainV1ServerUtils.MSG_END_16);
+
+        return sb.toString();
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/ReMessageBuilder.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/ReMessageBuilder.java
new file mode 100644
index 0000000..9447214
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/builder/ReMessageBuilder.java
@@ -0,0 +1,51 @@
+package com.ld.igds.protocol.bhzn.grainv2.msg.builder;
+
+import com.ld.igds.protocol.bhzn.grainv2.msg.message.IoMessage;
+import com.ld.igds.util.BytesUtil;
+
+/**
+ * 鏍规嵁鎺ユ敹鍒扮殑淇℃伅杩涜灏佽
+ *
+ * @author vince
+ */
+public class ReMessageBuilder {
+
+
+    public final static String ERROR_TAG = "3CF6";
+    public static double FAULT_CHECK_TAG = 85.0;
+    public static double MAX_TEMP = -50.0;
+    public static double MIN_TEMP = 50.0;
+    private final static ReMessageBuilder instance = new ReMessageBuilder();
+
+    private ReMessageBuilder() {
+    }
+
+    public static ReMessageBuilder getInstance() {
+        return instance;
+    }
+
+    /**
+     * @param message
+     * @return
+     */
+    public IoMessage buildMessage(String message) throws Exception {
+        IoMessage ioMessage = new IoMessage();
+
+        //杞崲涓烘暟瀛楋紝楂樹綆浣嶈浆鎹�(4浣�)
+        int i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(2, 6)));
+        ioMessage.setPcAddr(i + "");
+        i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(6, 10)));//楂樹綆浣嶈浆鎹�(4浣�)
+        ioMessage.setAddr(i + "");
+
+        ioMessage.setFunctionId(message.substring(10, 12));//鍔熻兘鐮�(2浣�)锛屼笉鐢ㄩ珮浣庝綅杞崲
+
+        i = BytesUtil.hexToBigInt(message.substring(12, 14));//闀垮害(1浣�)
+        ioMessage.setLength(i);
+
+        //鑾峰彇娑堟伅浣�
+        ioMessage.setContent(message.substring(14, 14 + (i * 2)));
+
+        ioMessage.setCheck(message.substring(message.length() - 2));
+        return ioMessage;
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/Content.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/Content.java
new file mode 100644
index 0000000..c40244b
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/Content.java
@@ -0,0 +1,43 @@
+package com.ld.igds.protocol.bhzn.grainv2.msg.message;
+
+import lombok.Data;
+
+/**
+ * @author vince.xu
+ * @Title: Content
+ * @ProjectName igds-35
+ * @Description: TODO
+ * @date 2022-12-715:48
+ */
+@Data
+public class Content {
+    /**
+     * 鐘舵�佸弽鍥�
+     */
+    public  String result;
+    /**
+     * 绾害
+     */
+    public String purity;
+    /**
+     * 娴侀噺
+     */
+    public String flow;
+    /**
+     * 鍘嬪姏
+     */
+    public String pressure;
+    /**
+     * 娓╁害
+     */
+    public String temperature;
+    /**
+     * 娴侀噺绱
+     */
+    public String flowAll;
+    /**
+     * 杩愯鐘舵��
+     */
+    public String isRun;
+
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/IoMessage.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/IoMessage.java
new file mode 100644
index 0000000..5a48b22
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/msg/message/IoMessage.java
@@ -0,0 +1,20 @@
+package com.ld.igds.protocol.bhzn.grainv2.msg.message;
+
+import lombok.Data;
+
+@Data
+public class IoMessage {
+
+
+    private String ip;
+
+    private int port;
+
+    private String pcAddr;
+    private String addr;
+    private String functionId;
+    private int length;
+    private String content;
+    private String check;
+
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/package-info.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/package-info.java
new file mode 100644
index 0000000..4cbda7a
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * 閭︽捣鏈夌嚎绾伯鎯呭崗璁�
+ */
+package com.ld.igds.protocol.bhzn.grainv2;
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2HeartbeatImpl.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2HeartbeatImpl.java
new file mode 100644
index 0000000..4c0b514
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2HeartbeatImpl.java
@@ -0,0 +1,42 @@
+package com.ld.igds.protocol.bhzn.grainv2.server;
+
+
+import com.ld.io.api.HeartbeatProvider;
+import com.ld.io.api.IoSession;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/**
+ * 鎻愪緵蹇冭烦淇℃伅
+ *
+ * @author Andy
+ */
+@Slf4j
+@Service
+public class BhznGrainV2HeartbeatImpl implements HeartbeatProvider {
+
+    @Override
+    public byte[] provide(IoSession session) {
+
+
+        //鐩存帴鏍规嵁涓绘満SESSIOn鍒ゆ柇
+        IoSession session1 = BhznGrainV2ServerUtils.getSession();
+
+        Long lastBeatTime = BhznGrainV2ServerUtils.getHearBeat(session1);
+
+        if (null == lastBeatTime) {
+            return null;
+        }
+
+        //濡傛灉鏈�鍚庝竴娆$粓绔績璺虫椂闂磋窛绂诲綋鍓嶆椂闂村ぇ浜� 缁堢蹇冭烦鏃堕棿鐨�3娆★紝鍒欏垽鏂负绂荤嚎
+        long deTime = System.currentTimeMillis() - lastBeatTime;
+
+        if (deTime > (BhznGrainV2ServerUtils.HEART_BEAT_TIME * 3 * 1000)) {
+            log.info("-----------瓒呰繃{}绉掓湭鑾峰彇鍒板績璺充俊鎭紝鍒ゅ畾缁堢绂荤嚎锛岃涪鍑鸿繛鎺�------------{}-{}", deTime, session.getAddress(), session.getPort());
+
+            session.destroy();
+        }
+
+        return null;
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2MessageConsumer.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2MessageConsumer.java
new file mode 100644
index 0000000..ca3a4cd
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2MessageConsumer.java
@@ -0,0 +1,57 @@
+package com.ld.igds.protocol.bhzn.grainv2.server;
+
+import com.ld.igds.protocol.bhzn.grainv2.msg.AnalysisService;
+import com.ld.igds.protocol.bhzn.grainv2.msg.builder.ReMessageBuilder;
+import com.ld.igds.protocol.bhzn.grainv2.msg.message.IoMessage;
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.IoMsgConsumer;
+import com.ld.io.api.IoSession;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Slf4j
+@Service
+public class BhznGrainV2MessageConsumer implements IoMsgConsumer {
+
+
+    @Autowired
+    private AnalysisService analysisService;
+
+    /**
+     * 澶勭悊娑堟伅
+     *
+     * @param ioSession
+     * @param bytes
+     */
+    @Override
+    public void consume(IoSession ioSession, byte[] bytes) {
+        if (null == bytes) {
+            log.error("Reply bytes is null");
+            return;
+        }
+
+        //娣诲姞淇℃伅蹇冭烦鏍囪
+        BhznGrainV2ServerUtils.addHeartBeat(ioSession);
+
+        //榛樿璁剧疆涓婚�氳鏈嶅姟
+        BhznGrainV2ServerUtils.addSession(ioSession);
+
+        try {
+            String hexStr = BytesUtil.bytesToString(bytes);
+            log.info("銆�"+ioSession.getAddress()+"銆戜富鏈鸿繑鍥炴姤鏂�------->>骞冲彴锛�" + hexStr);
+            hexStr = hexStr.substring(BhznGrainV2ServerUtils.MSG_START.length());
+
+            IoMessage ioMessage = ReMessageBuilder.getInstance().buildMessage(hexStr);
+            ioMessage.setIp(ioSession.getAddress());
+            ioMessage.setPort(ioSession.getPort());
+
+            analysisService.analysis(ioSession.getBusinessKey(), ioMessage);
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+        }
+    }
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerEngine.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerEngine.java
new file mode 100644
index 0000000..02b6f13
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerEngine.java
@@ -0,0 +1,131 @@
+package com.ld.igds.protocol.bhzn.grainv2.server;
+
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.*;
+import com.ld.io.netty.NettyServer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @Desc: 閭︽捣鏅鸿兘绾伯鎯呭崗璁�
+ * @author: Andy
+ * @update-time: 2023/5/11
+ */
+@Slf4j
+@Service
+public class BhznGrainV2ServerEngine {
+
+    public static final Integer PORT = 9309;
+
+    @Autowired
+    private BhznGrainV2MessageConsumer defaultMessageConsumer;
+    @Autowired
+    private BhznGrainV2SessionListener defaultSessionListener;
+    // 蹇冭烦鎻愪緵
+    private static HeartbeatProvider heartbeatProvider = new BhznGrainV2HeartbeatImpl();
+
+    private IoSessionQuery sessionQuery;
+
+    public void start(Integer port) {
+        IoServerOption ioServerOption = new IoServerOption();
+
+        if (null != port) {
+            ioServerOption.setPort(port);
+        } else {
+            ioServerOption.setPort(PORT);
+        }
+
+        //纭缁撳熬鏍囧織
+        ioServerOption.setDelimiter(BhznGrainV2ServerUtils.MSG_END.getBytes());
+
+        // 閰嶇疆绯荤粺蹇冭烦闂撮殧
+        ioServerOption.setReaderIdleTime(5 * 60);
+
+        NettyServer ioServer = new NettyServer(ioServerOption, defaultMessageConsumer, defaultSessionListener, heartbeatProvider);
+        ioServer.startup();
+
+        sessionQuery = ioServer.getSessionQuery();
+
+
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+        log.info("* [GRAIN-SERVER锛欱HZN_GRAIN,PORT={}]", PORT);
+        log.info("* ");
+        log.info("* ========================");
+        log.info("* ");
+
+        System.out.println("* ========================");
+        System.out.println("* ");
+        System.out.println("* [GRAIN-SERVER锛欱HZN_GRAIN,PORT={}]" + port);
+        System.out.println("* ");
+        System.out.println("* ========================");
+    }
+
+    public IoSessionQuery getSessionQuery() {
+        return sessionQuery;
+    }
+
+    /**
+     * 鍙戦�佷俊鎭�
+     *
+     * @param ip
+     * @param port
+     * @param msg
+     * @return
+     */
+    public InvokeResult push(String ip, int port, byte[] msg) {
+        IoSessionQuery sessionFactory = getSessionQuery();
+        List<IoSession> sessions = sessionFactory.getAllSession();
+        IoSession session = null;
+        for (IoSession ioSession : sessions) {
+            if (BhznGrainV2ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+                session = ioSession;
+                break;
+            }
+        }
+        if (null == session) {
+            return InvokeResult.CHANNEL_CLOSED;
+        }
+        return session.invoke(msg);
+    }
+
+
+//    public InvokeResult push(String ip, int port, String hexStr) {
+//
+//        byte[] msg = BytesUtil.hexStrToBytes(hexStr);
+//
+//        IoSessionQuery sessionFactory = getSessionQuery();
+//        List<IoSession> sessions = sessionFactory.getAllSession();
+//        IoSession session = null;
+//        for (IoSession ioSession : sessions) {
+//            if (BhznGrainV1ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
+//                session = ioSession;
+//                break;
+//            }
+//        }
+//
+//        if (null == session) {
+//            return InvokeResult.CHANNEL_CLOSED;
+//        }
+//        return session.invoke(msg);
+//    }
+
+    /**
+     * 鐩存帴浣跨敤鍐呭瓨鐨凷ession鎵ц
+     */
+    public InvokeResult pushByMin(String hexStr) {
+
+        IoSession session = BhznGrainV2ServerUtils.getSession();
+
+        if (null == session) {
+            return InvokeResult.CHANNEL_CLOSED;
+        }
+        byte[] msg = BytesUtil.hexStrToBytes(hexStr);
+        return session.invoke(msg);
+    }
+
+}
\ No newline at end of file
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerUtils.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerUtils.java
new file mode 100644
index 0000000..da16dc7
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2ServerUtils.java
@@ -0,0 +1,103 @@
+package com.ld.igds.protocol.bhzn.grainv2.server;
+
+
+import com.ld.igds.util.BytesUtil;
+import com.ld.io.api.IoSession;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 宸ュ叿绫�
+ *
+ * @author vince
+ */
+public class BhznGrainV2ServerUtils {
+
+
+    /**
+     * 璁板綍姣忎釜杩炴帴鐨勬渶鍚庝竴娆′俊鎭椂闂� key = 杩炴帴鐨凨YE锛宒ata =褰撳墠鏃堕棿鎴�
+     */
+    public static Map<String, Long> contextMapHeart = new HashMap<>();
+
+    public static Map<String, IoSession> contextIoSession = new HashMap<>();
+
+
+    public static int HEART_BEAT_TIME = 30;//蹇冭烦闂撮殧鏃堕棿
+
+
+    public static String MSG_START = "3C42485A4E3E";//<BHZN>
+    public static String MSG_START2 = "AA";
+    public static String MSG_END = "<END>";//<END>
+    public static String MSG_END_16 = "3C454E443E";//<END>
+    public static final String CHARSET = "UTF-8";
+
+
+    /**
+     * 閽堝鏃犵嚎绮儏涓绘満鐨勯粯璁D閰嶇疆
+     */
+    public static String DEFAULT_MAC_ID = "53681";
+
+    public static String FUNCTION_ID_00 = "00";
+    public static String FUNCTION_ID_F1 = "F1";
+    public static String FUNCTION_ID_F2 = "F2";
+    public static String FUNCTION_ID_83 = "83";
+    public static String FUNCTION_ID_93 = "93";
+    public static String FUNCTION_ID_92 = "92";
+
+
+    /**
+     * 鐢熸垚TCP杩炴帴鐨凨EY
+     *
+     * @param ip
+     * @param port
+     * @return
+     */
+    public static String getServerKey(String ip, Integer port) {
+        return ip + ":" + port;
+    }
+
+
+    /**
+     * 娣诲姞鏈�鏂板績璺虫椂闂存埑
+     *
+     * @param session
+     */
+    public static void addHeartBeat(IoSession session) {
+        contextMapHeart.put(getServerKey(session.getAddress(), session.getPort()), System.currentTimeMillis());
+    }
+
+    public static Long getHearBeat(IoSession session) {
+        return contextMapHeart.get(getServerKey(session.getAddress(), session.getPort()));
+    }
+
+
+    /**
+     * 璁$畻鏍¢獙
+     *
+     * @param content
+     * @return
+     */
+    public static String getCheck(String content) {
+        int start = BhznGrainV2ServerUtils.MSG_START.length() + BhznGrainV2ServerUtils.MSG_START2.length();
+        content = content.substring(start);
+        int sum = 0;
+        String hex;
+        for (int i = 0; i < content.length() / 2; i++) {
+            hex = content.substring(i * 2, i * 2 + 2);
+            sum += BytesUtil.hexToInt(hex);
+        }
+        String hexSum = BytesUtil.intToHexStr(sum);
+        int check = BytesUtil.hexToInt(hexSum.substring(hexSum.length() - 2));
+
+        return BytesUtil.intToHexStr(256 - check).substring(2);
+    }
+
+    public static void addSession(IoSession session) {
+        contextIoSession.put(DEFAULT_MAC_ID, session);
+    }
+
+    public static IoSession getSession() {
+        return contextIoSession.get(DEFAULT_MAC_ID);
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2SessionListener.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2SessionListener.java
new file mode 100644
index 0000000..eab5872
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/grainv2/server/BhznGrainV2SessionListener.java
@@ -0,0 +1,65 @@
+package com.ld.igds.protocol.bhzn.grainv2.server;
+
+import com.ld.igds.common.CoreSerService;
+import com.ld.io.api.IoSession;
+import com.ld.io.api.IoSessionListener;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ */
+@Slf4j
+@Service
+public class BhznGrainV2SessionListener implements IoSessionListener {
+
+    @Autowired
+    private CoreSerService coreSerService;
+
+    /**
+     * 璁惧鍒涘缓鍦ㄧ嚎锛岄渶瑕佹敞鎰忓綋鍓嶄娇鐢ㄤ富鏈烘ā寮忥紝涓绘満涓婄嚎榛樿鎵�鏈夌浉鍚孲N閰嶇疆鐨勫垎鏈哄叏閮ㄤ笂绾�
+     *
+     * @param session
+     */
+    @Override
+    public void onCreate(IoSession session) {
+
+        //娣诲姞鍒板唴瀛�
+        BhznGrainV2ServerUtils.addSession(session);
+
+        log.info("++++鏂板缓杩炴帴++++-IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+
+        // 娣诲姞鑷畾涔変笟鍔D
+        session.setBusinessKey(BhznGrainV2ServerUtils.getServerKey(session.getAddress(), session.getPort()));
+
+        //椤圭洰閲囩敤鏃犵嚎涓绘満妯″紡锛岀洿鎺ヨ幏鍙栭粯璁よ澶�
+       // DeviceSer deviceSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+
+        //if (null == deviceSer) return;
+
+        //coreSerService.onlineBySn(session.getAddress(), session.getPort(), deviceSer.getSn(), Constant.YN_Y);
+        //鏇存柊缂撳瓨
+       // coreSerService.refreshCache(deviceSer.getCompanyId());
+    }
+
+    /**
+     * 娉ㄦ剰锛屽綋鍓嶉噰鐢ㄤ富鏈烘ā寮忥紝涓绘満绂荤嚎鎵�鏈夌浉鍚孲N閰嶇疆鐨勫垎鏈哄叏閮ㄧ绾�
+     *
+     * @param session
+     */
+    @Override
+    public void onDestroy(IoSession session) {
+        log.info("----杩炴帴鏂紑-----IP={}锛孭ORT={}", session.getAddress(), session.getPort());
+
+//        //椤圭洰閲囩敤鏃犵嚎涓绘満妯″紡锛岀洿鎺ヨ幏鍙栭粯璁よ澶�
+//        DeviceSer deviceSer = coreSerService.getCacheSer(ContextUtil.getDefaultCompanyId(), BhznGrainV1ServerUtils.DEFAULT_MAC_ID);
+//
+//        if (null == deviceSer) return;
+
+        //鐢变簬璁惧鎺夌嚎鍚庤嚜鍔ㄨ皟鏁�
+//        coreSerService.onlineBySn(session.getAddress(), session.getPort(), deviceSer.getSn(), Constant.YN_N);
+//        //鏇存柊缂撳瓨
+//        coreSerService.refreshCache(deviceSer.getCompanyId());
+    }
+}
diff --git a/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/package-info.java b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/package-info.java
new file mode 100644
index 0000000..befc99a
--- /dev/null
+++ b/igds-protocol-bhzn/src/main/java/com/ld/igds/protocol/bhzn/package-info.java
@@ -0,0 +1,8 @@
+
+
+/**
+ * @Desc: 閭︽捣鏅鸿兘鍏徃鐩稿叧鍗忚
+ * @author: Andy
+ * @update-time: 2023/5/11
+ */
+package com.ld.igds.protocol.bhzn;
\ No newline at end of file
diff --git a/igds-web/pom.xml b/igds-web/pom.xml
index 0201d50..6c3a3d2 100644
--- a/igds-web/pom.xml
+++ b/igds-web/pom.xml
@@ -167,7 +167,21 @@
                 </exclusion>
             </exclusions>
         </dependency>-->
-
+        <dependency>
+            <groupId>com.ld.igds</groupId>
+            <artifactId>igds-protocol-bhzn</artifactId>
+            <version>${igds.version}</version>
+            <exclusions>
+                <exclusion>
+                    <artifactId>slf4j-log4j12</artifactId>
+                    <groupId>org.slf4j</groupId>
+                </exclusion>
+                <exclusion>
+                    <artifactId>log4j</artifactId>
+                    <groupId>log4j</groupId>
+                </exclusion>
+            </exclusions>
+        </dependency>
 
     </dependencies>
 
diff --git a/igds-web/src/main/resources/application-dev.yml b/igds-web/src/main/resources/application-dev.yml
index 3fb2357..83a0a76 100644
--- a/igds-web/src/main/resources/application-dev.yml
+++ b/igds-web/src/main/resources/application-dev.yml
@@ -46,7 +46,7 @@
     database: 1
     host: 127.0.0.1
     port: 6379
-    password: Abc123..
+    password:
     pool:
       max-active: 200
       max-wait: -1
diff --git a/igds-web/src/main/resources/application-pro5324.yml b/igds-web/src/main/resources/application-pro5324.yml
new file mode 100644
index 0000000..1a1074b
--- /dev/null
+++ b/igds-web/src/main/resources/application-pro5324.yml
@@ -0,0 +1,80 @@
+##########################  骞夸笢楂樺窞-閭︽捣鏅鸿兘   ##########################
+server:
+  port: 8888
+  context-path: /
+  connection-timeout: 5000
+  tomcat:
+    uri-encoding: UTF-8
+
+##########################  datasourcec   ##########################
+spring:
+  datasource:
+    db-base:
+      name: db-base
+      type: com.alibaba.druid.pool.DruidDataSource
+      url: jdbc:mysql://127.0.0.1:3306/igds_master?useUnicode=true&characterEncoding=utf-8
+      driver-class-name: com.mysql.jdbc.Driver
+      username: root
+      password: ukJp12Qf+elyBvGHkJ5MQMa95pfVm0oFBHefdEgDFKoFSjbgYa9PYfv5vlem5nvoXjQsP9tIIo53DvSbsl160Q==
+      public-key:
+      config-decrypt: true
+      initial-size:  5
+      min-idle:  5
+      max-active:  50
+      max-wait: 60000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select 1 from dual
+      test-whileIdle: true
+      test-on-borrow: false
+      test-on-return: false
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      filters: stat
+      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+      use-global-data-source-stat: true
+      removeAbandoned: true
+      removeAbandonedTimeout: 90
+      logAbandoned: true
+      poolPreparedStatements: true
+      maxPoolPreparedStatementPerConnectionSize: 20
+    db-sqlite:
+      name: db-sqlite
+      url: jdbc:sqlite:D:/app/igds/db/iot_cfg.db
+      driver-class-name: org.sqlite.JDBC
+      type: com.alibaba.druid.pool.DruidDataSource
+      username:
+      password:
+
+  # Redis鐩稿叧閰嶇疆
+  redis:
+    database: 0
+    host: 127.0.0.1
+    port: 6379
+    password: Abc123..
+    # 杩炴帴姹犳渶澶ц繛鎺ユ暟锛堜娇鐢ㄨ礋鍊艰〃绀烘病鏈夐檺鍒讹級
+    pool:
+      max-active: 200
+      max-wait: -1
+      max-idle: 10
+      min-idle: 0
+      timeout: 6000
+
+license:
+  subject: ld_license
+  publicAlias: publicCert
+  storePass: PUBLICFZZYXXJSGFYXGS888888
+  licensePath: D:/IGDS/license/license.lic
+  publicKeysStorePath: D:/IGDS/license/publicCerts.keystore
+
+##########################  IGDS   ##########################
+## 绯荤粺鎺ュ彛璺敱閰嶇疆 娉ㄦ剰鏁板瓧濡傛灉浠�0寮�澶寸殑璇濓紝鍚庡彴浼氬嚭鐜拌浆涔夛紝璇锋坊鍔�""
+igds:
+  default:
+    companyId: 5324
+    sys-name: 鏅烘収绮簱绠$悊绯荤粺
+    logo: logo-default.png
+    logo-title: logo-title-default.png
+    support: 鏅烘収绮簱缁煎悎绠$悊骞冲彴
+    grian-add-point: N
+  file-path: D:/IGDS/FILE/
\ No newline at end of file
diff --git a/igds-web/src/main/resources/application-pro5326.yml b/igds-web/src/main/resources/application-pro5326.yml
new file mode 100644
index 0000000..8fd7582
--- /dev/null
+++ b/igds-web/src/main/resources/application-pro5326.yml
@@ -0,0 +1,80 @@
+##########################  骞夸笢鎯犲窞鎯犳柊绮簱椤圭洰   ##########################
+server:
+  port: 8888
+  context-path: /
+  connection-timeout: 5000
+  tomcat:
+    uri-encoding: UTF-8
+
+##########################  datasourcec   ##########################
+spring:
+  datasource:
+    db-base:
+      name: db-base
+      type: com.alibaba.druid.pool.DruidDataSource
+      url: jdbc:mysql://127.0.0.1:3306/igds_master?useUnicode=true&characterEncoding=utf-8
+      driver-class-name: com.mysql.jdbc.Driver
+      username: root
+      password: ukJp12Qf+elyBvGHkJ5MQMa95pfVm0oFBHefdEgDFKoFSjbgYa9PYfv5vlem5nvoXjQsP9tIIo53DvSbsl160Q==
+      public-key:
+      config-decrypt: true
+      initial-size:  5
+      min-idle:  5
+      max-active:  50
+      max-wait: 60000
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      validation-query: select 1 from dual
+      test-whileIdle: true
+      test-on-borrow: false
+      test-on-return: false
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      filters: stat
+      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
+      use-global-data-source-stat: true
+      removeAbandoned: true
+      removeAbandonedTimeout: 90
+      logAbandoned: true
+      poolPreparedStatements: true
+      maxPoolPreparedStatementPerConnectionSize: 20
+    db-sqlite:
+      name: db-sqlite
+      url: jdbc:sqlite:D:/app/igds/db/iot_cfg.db
+      driver-class-name: org.sqlite.JDBC
+      type: com.alibaba.druid.pool.DruidDataSource
+      username:
+      password:
+
+  # Redis鐩稿叧閰嶇疆
+  redis:
+    database: 0
+    host: 127.0.0.1
+    port: 6379
+    password: Abc123..
+    # 杩炴帴姹犳渶澶ц繛鎺ユ暟锛堜娇鐢ㄨ礋鍊艰〃绀烘病鏈夐檺鍒讹級
+    pool:
+      max-active: 200
+      max-wait: -1
+      max-idle: 10
+      min-idle: 0
+      timeout: 6000
+
+license:
+  subject: ld_license
+  publicAlias: publicCert
+  storePass: PUBLICFZZYXXJSGFYXGS888888
+  licensePath: D:/IGDS/license/license.lic
+  publicKeysStorePath: D:/IGDS/license/publicCerts.keystore
+
+##########################  IGDS   ##########################
+## 绯荤粺鎺ュ彛璺敱閰嶇疆 娉ㄦ剰鏁板瓧濡傛灉浠�0寮�澶寸殑璇濓紝鍚庡彴浼氬嚭鐜拌浆涔夛紝璇锋坊鍔�""
+igds:
+  default:
+    companyId: 5326
+    sys-name: 鏅烘収绮簱绠$悊绯荤粺
+    logo: logo-default.png
+    logo-title: logo-title-default.png
+    support: 鏅烘収绮儏绮儏浜戠鐞嗗钩鍙�
+    grian-add-point: N
+  file-path: D:/IGDS/FILE/
\ No newline at end of file
diff --git a/igds-web/src/main/resources/application.yml b/igds-web/src/main/resources/application.yml
index 31a4c91..7383301 100644
--- a/igds-web/src/main/resources/application.yml
+++ b/igds-web/src/main/resources/application.yml
@@ -1,7 +1,7 @@
 ##########################  Server   ##########################
 spring:
   profiles:
-    active: dev
+    active: pro5324
   application:
     name: igds
   main:
diff --git a/igds-web/src/main/resources/logback-spring.xml b/igds-web/src/main/resources/logback-spring.xml
index 8a83600..1d8ecec 100644
--- a/igds-web/src/main/resources/logback-spring.xml
+++ b/igds-web/src/main/resources/logback-spring.xml
@@ -74,7 +74,7 @@
 	</springProfile>
 
 	<!-- 鐢熶骇鐜 -->
-	<springProfile name="pro">
+	<springProfile name="pro5324">
 		<!-- 姣忓ぉ浜х敓涓�涓枃浠� -->
 		<appender name="PRO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
 			<!-- 鏂囦欢璺緞 -->
diff --git a/igds-web/src/main/resources/static/img/aerial-5326_001.png b/igds-web/src/main/resources/static/img/aerial-5326_001.png
new file mode 100644
index 0000000..9bfa615
--- /dev/null
+++ b/igds-web/src/main/resources/static/img/aerial-5326_001.png
Binary files differ
diff --git a/pom.xml b/pom.xml
index 1aad490..fd0d4e8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,8 @@
         <module>igds-warn</module>
         <module>igds-protocol-block</module>
         <module>igds-protocol-fzzy3</module>
+        <!--閭︽捣鏅鸿兘-->
+        <module>igds-protocol-bhzn</module>
         <!--鐗╄仈缃戞嫇灞曡澶囧寘-->
         <module>igds-protocol-iot</module>
         <!--	鎵嬫満鍖�	-->

--
Gitblit v1.9.3