소스 검색

增加102相关文件

xusl 3 년 전
부모
커밋
925fdf9b14
13개의 변경된 파일819개의 추가작업 그리고 112개의 파일을 삭제
  1. 0 83
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/constant/enums/TunnelType.java
  2. 75 0
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/ChannelDisconLog.java
  3. 42 0
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/UploadFileCode.java
  4. 29 0
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/ChannelDisconLogRepository.java
  5. 13 0
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/UploadFileCodeRepository.java
  6. 22 0
      ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/UploadFileLogDetailRepository.java
  7. 44 0
      ipfcst-console/src/main/java/com/jiayue/ipfcst/console/service/ChannelDisconLogService.java
  8. 1 4
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/Base102Service.java
  9. 7 15
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/ServerFor102StandardService.java
  10. 4 10
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/ServerFor102TransitHandler.java
  11. 104 0
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/service/UploadFileCodeService.java
  12. 399 0
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/util/ByteUtil.java
  13. 79 0
      ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/util/IEC102Uitl.java

+ 0 - 83
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/constant/enums/TunnelType.java

@@ -1,83 +0,0 @@
-package com.jiayue.ipfcst.common.data.constant.enums;
-
-import com.jiayue.ipfcst.common.data.entity.BaseTunnelInfo;
-import com.jiayue.ipfcst.common.data.entity.gathertunnelinfo.*;
-import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.Sender104TcpTunnelInfo;
-import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderCdtRtuTunnelInfo;
-import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusRtuTunnelInfo;
-import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusTcpTunnelInfo;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-/**
- * 通道的类型
- *
- * @author 修唯xiuwei
- * @version 3.0
- */
-@Getter
-@AllArgsConstructor
-public enum TunnelType {
-
-
-  /**
-   * 通道类型枚举
-   */
-  MODBUSTCPMASTER("modbusTCP采集", "in", GatherModbusTcpTunnelInfo.class),
-  /**
-   * modbusRTU采集
-   */
-  MODBUSRTUMASTER("modbusRTU采集", "in", GatherModbusRtuTunnelInfo.class),
-  /**
-   * IEC104TCP采集
-   */
-  IEC104TCPMASTER("IEC104TCP采集", "in", Gather104TcpTunnelInfo.class),
-  /**
-   * CDTRTU采集
-   */
-  CDTRTUMASTER("CDTRTU采集", "in",GatherCdtRtuTunnelInfo.class),
-  /**
-   * modbusTCP转发
-   */
-  MODBUSTCPSLAVE("modbusTCP转发", "out", SenderModbusTcpTunnelInfo.class),
-  /**
-   * modbusRTU转发
-   */
-  MODBUSRTUSLAVE("modbusRTU转发", "out", SenderModbusRtuTunnelInfo.class),
-  /**
-   * IEC104TCP转发
-   */
-  IEC104TCPSLAVE("IEC104TCP转发", "out", Sender104TcpTunnelInfo.class),
-  /**
-   * CDTRTU转发
-   */
-  CDTRTUSLAVE("CDTRTU转发", "out", SenderCdtRtuTunnelInfo.class),
-
-  /**
-   * 隔离文件解析 暂时将这种传输方式视为一种通道
-   * 因为如果视为另一种数据源 点表页面将很难展示
-   */
-  FILEPARSE("穿隔离文件解析", "in", FileParseTunnelInfo.class),
-
-
-  TCPSERVERASMODBUSMASTER("TcpServer扮演RtuMaster","in",GatherModbusRtuWithTcpServerTunnelInfo.class),
-
-  TCPCLIENTASMODBUSMASTER("TcpClient扮演RtuMaster","in",GatherModbusRtuWithTcpClientTunnelInfo.class);
-
-
-  /**
-   * 通道的类型描述
-   */
-  private String cnDescribe;
-
-
-  /**
-   * 流向
-   */
-  private String flow;
-
-
-  private  Class<? extends BaseTunnelInfo>  tunnelInfoClazz;
-
-
-}

+ 75 - 0
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/ChannelDisconLog.java

@@ -0,0 +1,75 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import com.jiayue.ipfcst.common.data.abst.AbstractBaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.hibernate.annotations.GenericGenerator;
+import org.springframework.core.annotation.Order;
+
+import javax.persistence.*;
+
+/**
+ * 通道断开日志
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@Entity
+public class ChannelDisconLog extends AbstractBaseEntity {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @Order(1)
+    @GeneratedValue(strategy = GenerationType.AUTO, generator = "myid")
+    @GenericGenerator(name = "myid", strategy = "com.jiayue.ipfcst.common.data.entity.id.CustomIDGenerator")
+    private Integer id;
+
+    /**
+     * 通道ID
+     */
+    @Column
+    private String channelId;
+
+    /**
+     * 通道名称
+     */
+    @Column
+    private String channelName;
+
+    /**
+     * 断开时间
+     */
+    @Column
+    private Long disconnectTime;
+
+    /**
+     * 重连时间
+     */
+    @Column
+    private Long reconnectTime;
+
+    /**
+     * 时长
+     */
+    @Column
+    private String duration;
+
+
+    /**
+     * 计算并配置持续时间
+     */
+    public void countAndSetDuration(){
+        if(this.reconnectTime==null || this.disconnectTime==null || this.reconnectTime <= this.disconnectTime){
+            return;
+        }
+        Long durationL = this.reconnectTime-this.disconnectTime;
+        if (durationL/1000>=60){
+            setDuration(durationL/(1000*60)+"分");
+        }
+        else{
+           setDuration(durationL/1000+"秒");
+        }
+    }
+}

+ 42 - 0
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/entity/UploadFileCode.java

@@ -0,0 +1,42 @@
+package com.jiayue.ipfcst.common.data.entity;
+
+import com.jiayue.ipfcst.common.data.constant.enums.FileTypeEnum;
+import lombok.Data;
+import org.hibernate.annotations.GenericGenerator;
+import org.springframework.core.annotation.Order;
+
+import javax.persistence.*;
+
+/**
+ * 上报文件CODE码
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@Data
+@Entity
+public class UploadFileCode {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    @Order(1)
+    @GeneratedValue(strategy = GenerationType.AUTO, generator = "myid")
+    @GenericGenerator(name = "myid", strategy = "com.jiayue.ipfcst.common.data.entity.id.CustomIDGenerator")
+    private Integer id;
+
+    /**
+     * 上报文件类型
+     */
+    @Column
+    @Enumerated(EnumType.STRING)
+    private FileTypeEnum fileTypeEnum;
+
+    /**
+     * 102文件CODE码
+     */
+    @Column
+    private Integer fileTypeCode;
+
+    @Column
+    private String stationCode;
+}

+ 29 - 0
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/ChannelDisconLogRepository.java

@@ -0,0 +1,29 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.ChannelDisconLog;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 通道断开日志仓储
+ *
+ * @author xsl
+ * @version 3.0
+ */
+public interface ChannelDisconLogRepository extends BaseRepository<ChannelDisconLog, Integer> {
+    /**
+     * 根据通道ID获取需要更新重连的
+     * @param channelId
+     * @return
+     */
+    List<ChannelDisconLog> findByChannelIdAndDisconnectTimeIsNotNullAndReconnectTimeIsNull(String channelId);
+
+    /**
+     * 根据创建时间段查询通道断开日志
+     * @param startTime
+     * @param endTime
+     * @return
+     */
+    List<ChannelDisconLog> findByCreateTimeBetween(Date startTime, Date endTime);
+}

+ 13 - 0
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/UploadFileCodeRepository.java

@@ -0,0 +1,13 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.UploadFileCode;
+
+/**
+ * 文件CODE码表仓储
+ *
+ * @author xsl
+ * @version 3.0
+ */
+public interface UploadFileCodeRepository extends BaseRepository<UploadFileCode, Integer> {
+    void deleteAllById(Integer uploadObjectId);
+}

+ 22 - 0
ipfcst-common/ipfcst-common-data/src/main/java/com/jiayue/ipfcst/common/data/repository/UploadFileLogDetailRepository.java

@@ -0,0 +1,22 @@
+package com.jiayue.ipfcst.common.data.repository;
+
+import com.jiayue.ipfcst.common.data.entity.UploadFileLogDetail;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.Date;
+
+/**
+ * 上报文件日志明细表仓储
+ *
+ * @author xsl
+ * @version 3.0
+ */
+public interface UploadFileLogDetailRepository extends BaseRepository<UploadFileLogDetail, Integer> {
+    /**
+     * 删除指定日期之前的日志
+     */
+    @Modifying
+    @Query(value = "delete from UploadFileLogDetail t where t.createTime < ?1")
+    void deleteLessCreateTime(Date date);
+}

+ 44 - 0
ipfcst-console/src/main/java/com/jiayue/ipfcst/console/service/ChannelDisconLogService.java

@@ -0,0 +1,44 @@
+package com.jiayue.ipfcst.console.service;
+
+import com.jiayue.ipfcst.common.data.entity.ChannelDisconLog;
+import com.jiayue.ipfcst.common.data.repository.ChannelDisconLogRepository;
+import com.jiayue.ipfcst.common.data.service.BaseService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * 通道断开日志
+ *
+ * @author xsl
+ * @version 3.0
+ */
+@Service
+@Slf4j
+public class ChannelDisconLogService extends BaseService {
+  @Autowired
+  ChannelDisconLogRepository channelDisconLogRepository;
+
+  /**
+   * 保存
+   *
+   * @param channelDisconLog 通道断开日志
+   */
+  @Transactional(propagation = Propagation.REQUIRED)
+  public ChannelDisconLog save(ChannelDisconLog channelDisconLog) {
+    return channelDisconLogRepository.save(channelDisconLog);
+  }
+
+  /**
+   * 根据通道ID获取需要更新重连的
+   *
+   * @param channelId 通道ID
+   */
+  public List<ChannelDisconLog> get(String channelId) {
+    return channelDisconLogRepository.findByChannelIdAndDisconnectTimeIsNotNullAndReconnectTimeIsNull(channelId);
+  }
+}

+ 1 - 4
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/Base102Service.java

@@ -2,10 +2,7 @@ package com.jiayue.ipfcst.fileupload.IEC102;
 
 import com.jiayue.ipfcst.common.data.constant.enums.FileStatusEnum;
 import com.jiayue.ipfcst.common.data.constant.enums.FileTypeEnum;
-import com.jiayue.ipfcst.common.data.entity.UploadFileChannel;
-import com.jiayue.ipfcst.common.data.entity.UploadFileLog;
-import com.jiayue.ipfcst.common.data.entity.UploadFileLogDetail;
-import com.jiayue.ipfcst.common.data.entity.UploadObject;
+import com.jiayue.ipfcst.common.data.entity.*;
 import com.jiayue.ipfcst.common.data.repository.UploadFileLogDetailRepository;
 import com.jiayue.ipfcst.common.data.repository.UploadFileLogRepository;
 import com.jiayue.ipfcst.console.service.SysParameterService;

+ 7 - 15
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/ServerFor102StandardService.java

@@ -8,9 +8,7 @@ import com.jiayue.ipfcst.common.data.entity.UploadFileChannel;
 import com.jiayue.ipfcst.common.data.entity.UploadFileLog;
 import com.jiayue.ipfcst.common.data.entity.UploadObject;
 import com.jiayue.ipfcst.fileupload.dto.Validate102Dto;
-import com.jiayue.ipfcst.fileupload.util.FileConstant;
-import com.jiayue.ipfcst.fileupload.util.FileMutableInteger;
-import com.jiayue.ipfcst.fileupload.util.FileUtil;
+import com.jiayue.ipfcst.fileupload.util.*;
 import io.netty.channel.ChannelHandlerContext;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -33,7 +31,7 @@ import java.util.stream.Collectors;
 @Service
 public class ServerFor102StandardService extends Base102Service {
   @Transactional(propagation = Propagation.REQUIRED)
-  public String handlerMessage(String receiveMessage, UploadObject uploadObject, UploadFileChannel uploadFileChannel, ElectricField electricField, Logger log, ChannelHandlerContext ctx) {
+  public String handlerMessage(String receiveMessage, UploadObject uploadObject, UploadFileChannel uploadFileChannel, Logger log, ChannelHandlerContext ctx) {
     String[] rmArray = IEC102Uitl.stingToArray(receiveMessage);
     String sendMessage = "";
     String sendCtrlChinese = "";
@@ -43,7 +41,7 @@ public class ServerFor102StandardService extends Base102Service {
       // 需要校验接收的帧是否正确
       Validate102Dto validate102Dto = FileConstant.validateMessage.get(uploadFileChannel.getId()+"");
       if (!validate102Dto.getMessageFirst().equals(rmArray[0])){
-        log.info(ctx.channel().remoteAddress()+" - "+"调度应该传"+validate102Dto.getMessageFirst()+"帧并且原因是"+validate102Dto.getMessageReason()+",实际传"+IEC102Uitl.delimiterStringBySpace(receiveMessage)+",断开通道重启");
+        log.info(ctx.channel().remoteAddress()+" - "+"调度应该传"+validate102Dto.getMessageFirst()+"帧并且原因是"+validate102Dto.getMessageReason()+",实际传"+ IEC102Uitl.delimiterStringBySpace(receiveMessage)+",断开通道重启");
         super.totalFileUploadNums(uploadObject,uploadFileChannel, "调度应该传"+validate102Dto.getMessageFirst()+"帧,实际传"+IEC102Uitl.delimiterStringBySpace(receiveMessage), log);
         channelCloseConnect(ctx,uploadObject,uploadFileChannel);
         return "";
@@ -111,7 +109,7 @@ public class ServerFor102StandardService extends Base102Service {
           FileConstant.validateMessage.remove(uploadFileChannel.getId()+"");
         } else {
           // 生成传输文件的68帧
-          sendMessage = uploadFile68(fileNameKey, electricField, uploadObject, uploadFileChannel, log);
+          sendMessage = uploadFile68(fileNameKey, uploadObject, uploadFileChannel, log);
           sendCtrlChinese = "通道:"+uploadFileChannel.getChannelName()+"上报:"+fileNameKey;
         }
       } else if ("B".equals(fc)) {
@@ -231,7 +229,7 @@ public class ServerFor102StandardService extends Base102Service {
    *
    * @return 68帧报文
    */
-  private String uploadFile68(String fileNameKey, ElectricField electricField, UploadObject uploadObject, UploadFileChannel uploadFileChannel, Logger log) {
+  private String uploadFile68(String fileNameKey, UploadObject uploadObject, UploadFileChannel uploadFileChannel, Logger log) {
     String[] returnMessage = {"68", "mlLow", "mlHeight", "68", "ctrl", "FF", "FF", "typeCode", "01", "reason", "FF", "FF", "00", "fileNameByte", "fileContentByte", "crc", "16"};
     String[] tempKey = new String[3];
     String tempFileName = fileNameKey;
@@ -243,14 +241,8 @@ public class ServerFor102StandardService extends Base102Service {
     // 生成文件名及内容
     String fileName = tempKey[2];
     byte[] tempFileNameBytes = null;
-    String charsetName = "";
-    if ("E42".equals(electricField.getProvinceEnum().toString()) && ("E9".equals(tempKey[1]) || "E74".equals(tempKey[1])|| "E92".equals(tempKey[1]))){
-      // 湖北省新风机文件用GBK上报,其他用UTF-8
-      charsetName = "GBK";
-    }
-    else{
-      charsetName = uploadObject.getUploadFileCharSetEnum().getMessage();
-    }
+    String charsetName = uploadObject.getUploadFileCharSetEnum().getMessage();
+
     try {
       tempFileNameBytes = fileName.getBytes(charsetName);
     } catch (Exception e) {

+ 4 - 10
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/IEC102/ServerFor102TransitHandler.java

@@ -2,6 +2,7 @@ package com.jiayue.ipfcst.fileupload.IEC102;
 
 import ch.qos.logback.classic.Logger;
 import com.jiayue.ipfcst.common.core.util.SpringContextHolder;
+import com.jiayue.ipfcst.common.data.entity.ChannelDisconLog;
 import com.jiayue.ipfcst.common.data.entity.ElectricField;
 import com.jiayue.ipfcst.common.data.entity.UploadFileChannel;
 import com.jiayue.ipfcst.common.data.entity.UploadObject;
@@ -107,18 +108,11 @@ public class ServerFor102TransitHandler extends ChannelInboundHandlerAdapter {
   public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
     // 设置通道状态正常
     FileConstant.channelStatusMap.put(uploadObject.getId() + "-" + uploadFileChannel.getId(), "1");
-    // 获取场站信息
-    ElectricField electricField = electricFieldService.get();
     // 返回的报文
     String receiveMessage = "";
-    String province = electricField.getProvinceEnum().name().toString();
-    if ("E15".equals(province)) {
-      // 蒙东102服务端
-      receiveMessage = serverFor102NMService.handlerMessage(msg.toString(), uploadObject, uploadFileChannel, electricField, uploadLogger,ctx);
-    } else {
-      // 标准102服务端
-      receiveMessage = serverFor102StandardService.handlerMessage(msg.toString(), uploadObject, uploadFileChannel, electricField, uploadLogger,ctx);
-    }
+    // 标准102服务端
+    receiveMessage = serverFor102StandardService.handlerMessage(msg.toString(), uploadObject, uploadFileChannel, uploadLogger,ctx);
+
     ctx.channel().writeAndFlush(receiveMessage);
   }
 

+ 104 - 0
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/service/UploadFileCodeService.java

@@ -0,0 +1,104 @@
+package com.jiayue.ipfcst.fileupload.service;
+
+import com.jiayue.ipfcst.common.data.entity.UploadFileCode;
+import com.jiayue.ipfcst.common.data.repository.UploadFileCodeRepository;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.search.*;
+import net.sf.ehcache.search.Results;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+
+/**
+ * 上报文件CODE码服务类
+ * @author xsl
+ * @version 3.0
+ */
+@Service
+public class UploadFileCodeService {
+  @Autowired
+  UploadFileCodeRepository uploadFileCodeRepository;
+  @Autowired
+  EhCacheCacheManager ehCacheCacheManager;
+
+  /**
+   * 保存CODE码
+   *
+   * @param uploadFileCode CODE信息
+   */
+  @Transactional(propagation = Propagation.REQUIRED)
+  public UploadFileCode save(UploadFileCode uploadFileCode) {
+    uploadFileCodeRepository.save(uploadFileCode);
+    clearFileCodeCache();
+    return uploadFileCode;
+  }
+
+  @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
+  public void saveCloud(List<UploadFileCode> beans) {
+    if(beans != null && beans.size() > 0){
+      clearFileCodeCache();
+      uploadFileCodeRepository.deleteAll();
+      uploadFileCodeRepository.saveAll(beans);
+    }
+  }
+
+  /**
+   * 删除通道信息
+   *
+   * @param uploadFileCode CODE信息
+   */
+  @Transactional(propagation = Propagation.REQUIRED)
+  public void delete(UploadFileCode uploadFileCode) {
+    clearFileCodeCache();
+    uploadFileCodeRepository.delete(uploadFileCode);
+  }
+
+  /**
+   * 移除缓存中的CODE信息
+   */
+  public void clearFileCodeCache() {
+    List<UploadFileCode> uploadFileCodeList = this.get();
+    Cache cache = ehCacheCacheManager.getCacheManager().getCache("searchablecache");
+    for (UploadFileCode uploadFileCode : uploadFileCodeList) {
+      cache.remove("code" + uploadFileCode.getId());
+    }
+  }
+
+  /**
+   * 查询通道信息
+   *
+   * @return 通道信息
+   */
+  public List<UploadFileCode> get() {
+    Cache cache = ehCacheCacheManager.getCacheManager().getCache("searchablecache");
+    Query query = cache.createQuery();
+    //查询结果中包含Key和value
+    query.includeKeys().includeValues();
+    Attribute<String> keyName = cache.getSearchAttribute("key");
+    query.addCriteria(keyName.ilike("*code*"));
+    Results results = query.execute();
+    List<Result> resultList = results.all();
+
+    List<UploadFileCode> list = new ArrayList();
+    if (resultList != null && !resultList.isEmpty()) {
+      for (Result result : resultList) {
+        UploadFileCode e = (UploadFileCode) result.getValue();
+        list.add(e);
+      }
+      results.discard();
+    } else {
+      //查询数据库
+      list = uploadFileCodeRepository.findAll();
+      for (UploadFileCode uploadFileCode : list) {
+        //将结果存入缓存
+        cache.put(new Element("code" + uploadFileCode.getId(), uploadFileCode));
+      }
+    }
+    return list;
+  }
+}

+ 399 - 0
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/util/ByteUtil.java

@@ -0,0 +1,399 @@
+package com.jiayue.ipfcst.fileupload.util;
+
+import com.sun.istack.internal.NotNull;
+import io.netty.buffer.ByteBuf;
+
+import javax.xml.bind.DatatypeConverter;
+import java.math.BigInteger;
+import java.util.Formatter;
+
+/**
+ * 字节转换工具类
+ *
+ * @author xsl
+ * @version 3.0
+ */
+public abstract class ByteUtil {
+
+  /**
+   * int类型转换byte[4]数组,数组内字节由高到低
+   *
+   * @param n 被转换int
+   * @return byte[4]
+   */
+  public static byte[] intToBytesFromHighToLow(@NotNull int n) {
+    byte[] result = new byte[4];
+    result[0] = (byte) ((n >> 24) & 0xFF);
+    result[1] = (byte) ((n >> 16) & 0xFF);
+    result[2] = (byte) ((n >> 8) & 0xFF);
+    result[3] = (byte) (n & 0xFF);
+    return result;
+  }
+
+  /**
+   * byte[4]数组类型转换int,数组内字节由高到低
+   *
+   * @param b 被转换的字节数组
+   * @return int
+   */
+  public static int bytesToIntFromHighToLow(@NotNull byte[] b) {
+
+    return (b[(0)] & 0xFF) << 24 | (b[(1)] & 0xFF) << 16 |
+      (b[(2)] & 0xFF) << 8 | b[3] & 0xFF;
+  }
+
+
+  /**
+   * int类型转换byte[4]数组,数组内字节由低到高
+   *
+   * @param n 被转换int
+   * @return byte[4]
+   */
+  public static byte[] intToBytesFromLowToHigh(@NotNull int n) {
+    byte[] targets = new byte[4];
+
+    targets[0] = ((byte) (n & 0xFF));
+    targets[1] = ((byte) (n >> 8 & 0xFF));
+    targets[2] = ((byte) (n >> 16 & 0xFF));
+    targets[3] = ((byte) (n >> 24 & 0xFF));
+    return targets;
+  }
+
+  /**
+   * byte[4]数组类型转换int,数组内字节由低到高
+   *
+   * @param b 被转换的字节数组
+   * @return int
+   */
+  public static int bytesToIntFromLowToHigh(@NotNull byte[] b) {
+    return (b[(3)] & 0xFF) << 24 | (b[(2)] & 0xFF) << 16 |
+      (b[(1)] & 0xFF) << 8 | b[0] & 0xFF;
+  }
+
+  /**
+   * 二进制转十六进制,数组内字节由高到低
+   *
+   * @param b 二进制数组
+   * @return 十六进制字符串
+   */
+  public static String bytesToHexStringFromHighToLow(@NotNull byte[] b) {
+    return DatatypeConverter.printHexBinary(b);
+  }
+
+  /**
+   * 十六进制转二进制,数组内字节由高到低
+   *
+   * @param hexString 十六进制字符串
+   * @return 二进制数组
+   */
+  public static byte[] hexStringToBytesFromHighToLow(@NotNull String hexString) {
+    return DatatypeConverter.parseHexBinary(hexString);
+  }
+
+  /**
+   * 二进制转十六进制,数组内字节由低到高
+   *
+   * @param b 二进制数组
+   * @return 十六进制字符串
+   */
+  public static String bytesToHexStringFromLowToHigh(@NotNull byte[] b) {
+
+    byte[] dest = ByteUtil.bytesFlipping(b);
+    return DatatypeConverter.printHexBinary(dest);
+  }
+
+  /**
+   * 十六进制转二进制,数组内字节由低到高
+   *
+   * @param hexString 十六进制字符串
+   * @return 二进制数组
+   */
+  public static byte[] hexStringToBytesFromLowToHigh(@NotNull String hexString) {
+    byte[] dest = DatatypeConverter.parseHexBinary(hexString);
+    return ByteUtil.bytesFlipping(dest);
+  }
+
+  /**
+   * float转换byte[4]数组,数组内字节由低到高
+   *
+   * @param f 被转换float
+   * @return byte[4]
+   */
+  public static byte[] floatToBytesFromLowToHigh(@NotNull float f) {
+    int fbit = Float.floatToIntBits(f);
+
+    byte[] b = new byte[4];
+    for (int i = 0; i < 4; i++) {
+      b[i] = ((byte) (fbit >> 24 - i * 8));
+    }
+    // 翻转数组
+    return ByteUtil.bytesFlipping(b);
+  }
+
+  /**
+   * byte[4]数组转换float,数组内字节由低到高
+   *
+   * @param b 被转换字节数组
+   * @return float
+   */
+  public static float bytesToFloatFromLowToHigh(@NotNull byte[] b) {
+    int l = b[(0)];
+    l &= 255;
+    l = l | b[(1)] << 8;
+    l &= 65535;
+    l = l | b[(2)] << 16;
+    l &= 16777215;
+    l = l | b[(3)] << 24;
+    return Float.intBitsToFloat(l);
+  }
+
+  /**
+   * float转换byte[4]数组,数组内字节由高到低
+   *
+   * @param f 被转换float
+   * @return byte[4]
+   */
+  public static byte[] floatToBytesFromHighToLow(@NotNull float f) {
+    int fbit = Float.floatToIntBits(f);
+
+    byte[] b = new byte[4];
+    for (int i = 0; i < 4; i++) {
+      b[i] = ((byte) (fbit >> 24 - i * 8));
+    }
+    return b;
+  }
+
+  /**
+   * byte[4]数组转换float,数组内字节由高到低
+   *
+   * @param b 被转换字节数组
+   * @return float
+   */
+  public static float bytesToFloatFromHighToLow(@NotNull byte[] b) {
+    byte[] dest = ByteUtil.bytesFlipping(b);
+    return ByteUtil.bytesToFloatFromLowToHigh(dest);
+  }
+
+  /**
+   * 数组翻转
+   *
+   * @param res 原数组
+   * @return 翻转后的数组
+   */
+  public static byte[] bytesFlipping(@NotNull byte[] res) {
+    // 翻转数组
+    int len = res.length;
+    // 建立一个与源数组元素类型相同的数组
+    byte[] dest = new byte[len];
+    // 为了防止修改源数组,将源数组拷贝一份副本
+    System.arraycopy(res, 0, dest, 0, len);
+    // 将顺位第i个与倒数第i个交换
+    for (int i = 0; i < len / 2; i++) {
+      byte temp = dest[i];
+      dest[i] = dest[(len - i - 1)];
+      dest[(len - i - 1)] = temp;
+    }
+    return dest;
+  }
+
+  /**
+   * 强制转换字符串为字节数组
+   *
+   * @param s 字符串
+   * @return 字节数组
+   */
+  public static byte[] parseByte(String s) {
+    char[] c = s.toCharArray();
+    byte[] b = new byte[c.length];
+    for (int i = 0; i < c.length; i++) {
+      b[i] = Byte.parseByte(String.valueOf(c[i]));
+    }
+    return b;
+  }
+
+  /**
+   * 16进制转10进制
+   *
+   * @param hex 字符串
+   * @return int
+   */
+  public static int hexToDec(String hex) {
+    BigInteger bigint = new BigInteger(hex, 16);
+    return bigint.intValue();
+  }
+
+  /**
+   * 10进制转16进制字符串低位在前高位在后
+   *
+   * @param dec
+   * @return
+   */
+  public static String decToHex(int dec) {
+    int var1 = 1;
+    int var2 = dec >> 8;
+    int var3 = dec & 255;
+    String var4 = Integer.toHexString(var2);
+    String var5 = Integer.toHexString(var3);
+    if(var4.length() > 2) {
+      do {
+        if(var1 > 1) {
+          var2 >>= 8;
+        }
+        var4 = Integer.toHexString(var2 >> 8);
+        var5 = var5 + Integer.toHexString(var2 & 255);
+        ++var1;
+      } while(var4.length() > 2);
+    }
+    if(var4.length() < 2) {
+      var4 = "0" + var4;
+    }
+    if(var5.length() < 2) {
+      var5 = "0" + var5;
+    }
+    return var5 + var4;
+  }
+
+  /**
+   * 把byte[]数组转换成十六进制字符串表示形式
+   *
+   * @param tmp 要转换的byte[]
+   * @return 十六进制字符串表示形式
+   */
+  public static String byteToHexString(byte[] tmp) {
+    char hexdigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+    String s;
+    // 用字节表示就是 16 个字节
+    char str[] = new char[16 * 2]; // 每个字节用 16 进制表示的话,使用两个字符,
+    // 所以表示成 16 进制需要 32 个字符
+    int k = 0; // 表示转换结果中对应的字符位置
+    for (int i = 0; i < 16; i++) { // 从第一个字节开始,对 MD5 的每一个字节
+      // 转换成 16 进制字符的转换
+      byte byte0 = tmp[i]; // 取第 i 个字节
+      str[k++] = hexdigits[byte0 >>> 4 & 0xf]; // 取字节中高 4 位的数字转换,
+      // >>> 为逻辑右移,将符号位一起右移
+      str[k++] = hexdigits[byte0 & 0xf]; // 取字节中低 4 位的数字转换
+    }
+    s = new String(str); // 换后的结果转换为字符串
+    return s;
+  }
+
+  /**
+   * 16进制的字符串表示转成字节数组
+   *
+   * @param hexString
+   *            16进制格式的字符串
+   * @return 转换后的字节数组
+   **/
+  public static byte[] toByteArray(String hexString) {
+    final byte[] byteArray = new byte[hexString.length() / 2];
+    int k = 0;
+    for (int i = 0; i < byteArray.length; i++) {//因为是16进制,最多只会占用4位,转换成字节需要两个16进制的字符,高位在先
+      byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
+      byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
+      byteArray[i] = (byte) (high << 4 | low);
+      k += 2;
+    }
+    return byteArray;
+  }
+
+  /**
+   * 字节数字转16进制字符串
+   *
+   * @param ba ba
+   * @return string
+   */
+  public static String Byte2String(byte[] ba){
+    if(ba == null || ba.length == 0)
+    { return null;}
+    Formatter f = new Formatter();
+    for(int i = 0; i < ba.length; ++i){
+      f.format("%02x ", ba[i]);
+    }
+    return f.toString();
+  }
+
+  /**
+   * 字节数缓冲区字转16进制字符串
+   *
+   * @param buf buf
+   * @return string
+   */
+  public static String ByteBuf2String(ByteBuf buf){
+    if(!buf.isReadable()){
+      return null;
+    }
+    ByteBuf b1=buf.copy();
+    byte []bs=new byte[b1.readableBytes()];
+    b1.readBytes(bs);
+    b1.release();
+    return Byte2String(bs);
+  }
+
+  public static void main(String[] args) {
+//    byte[] b = {73,2};
+//    byte[] c = bytesFlipping(b);
+//    String info = DatatypeConverter.printHexBinary(c);
+//    BigInteger bigint=new BigInteger(info, 16);
+//    int numb=bigint.intValue();
+//    System.out.println(numb);
+
+//    String[] returnMessage = {"10", "ctrl", "FF", "FF", "crc", "16"};
+
+//    Long a=1589130920L;
+//    ByteArrayOutputStream baos = new ByteArrayOutputStream();
+//    DataOutputStream dos = new DataOutputStream(baos);
+//    try {
+//      dos.writeLong(a);
+//    } catch (IOException e) {
+//      e.printStackTrace();
+//    }
+////再读出来
+//    byte[] buf = baos.toByteArray();
+//    System.out.println(bytesToHexStringFromHighToLow(intToBytesFromLowToHigh(bytesToIntFromHighToLow(buf))));
+//
+//
+//    System.out.println(bytesToHexStringFromHighToLow(floatToBytesFromLowToHigh(a.floatValue())));
+//
+//    System.out.println(bytesToHexStringFromHighToLow(intToBytesFromLowToHigh(a.intValue())));
+//
+//
+//
+//    System.out.println(bytesToHexStringFromHighToLow(intToBytesFromLowToHigh(hexToDec(Long.toHexString(a)))));
+
+//    System.out.println(bytesToIntFromLowToHigh(hexStringToBytesFromLowToHigh(Long.toHexString(a))));
+// A8 36 B8 5E
+//    byte[] b = {(byte)0x3c,(byte)0x00,(byte)0x00,(byte)0x00};
+//    System.out.println(a.intValue());
+
+
+//    int a=145;
+//    System.out.println(decToHex(183));
+//
+//    int var1 = 1;
+//    int var2 = 183 >> 8;
+//    int var3 = 183 & 255;
+//    String var4 = Integer.toHexString(var2);
+//    String var5 = Integer.toHexString(var3);
+//    if(var4.length() > 2) {
+//      do {
+//        if(var1 > 1) {
+//          var2 >>= 8;
+//        }
+//        var4 = Integer.toHexString(var2 >> 8);
+//        var5 = var5 + Integer.toHexString(var2 & 255);
+//        ++var1;
+//      } while(var4.length() > 2);
+//    }
+//    if(var4.length() < 2) {
+//      var4 = "0" + var4;
+//    }
+//    if(var5.length() < 2) {
+//      var5 = "0" + var5;
+//    }
+//    System.out.println(var5 + var4);
+
+
+    int a=10;
+    System.out.println(decToHex(a));
+  }
+}

+ 79 - 0
ipfcst-console/src/main/java/com/jiayue/ipfcst/fileupload/util/IEC102Uitl.java

@@ -0,0 +1,79 @@
+package com.jiayue.ipfcst.fileupload.util;
+
+/**
+ * 102工具类
+ *
+ * @author xsl
+ * @version 3.0
+ */
+public class IEC102Uitl {
+  /**
+   * 取得是低位校验和
+   *
+   * @param data 需要计算校验和的16进制串
+   * @return 校验和
+   */
+  public static String makeChecksum(String data) {
+    int iTotal = 0;
+    int iLen = data.length();
+    int iNum = 0;
+
+    while (iNum < iLen) {
+      String s = data.substring(iNum, iNum + 2);
+      iTotal += Integer.parseInt(s, 16);
+      iNum = iNum + 2;
+    }
+
+    /**
+     * 用256求余最大是255,即16进制的FF
+     */
+    int iMod = iTotal % 256;
+    String sHex = Integer.toHexString(iMod);
+    iLen = sHex.length();
+    //如果不够校验位的长度,补0,这里用的是两位校验
+    if (iLen < 2) {
+      sHex = "0" + sHex;
+    }
+    return sHex;
+  }
+
+  /**
+   * 将字符串每2个放到一个数组中
+   *
+   * @param str
+   * @return
+   */
+  public static String[] stingToArray(String str) {
+    int m = str.length() / 2;
+    if (m * 2 < str.length()) {
+      m++;
+    }
+    String[] strs = new String[m];
+    int j = 0;
+    for (int i = 0; i < str.length(); i++) {
+      if (i % 2 == 0) {//每隔两zd个
+        strs[j] = "" + str.charAt(i);
+      } else {
+        strs[j] = strs[j] + str.charAt(i);//将字符加上两个空格
+        j++;
+      }
+    }
+    return strs;
+  }
+
+  /**
+   * 空格分割符字符串
+   * 每两位添加一个空格分隔符
+   *
+   * @param str str
+   * @return string
+   */
+  public static String delimiterStringBySpace(String str) {
+    if (str == null || "".equals(str.trim())) {
+      return null;
+    }
+    String regex = "(.{2})";
+    String result = str.replaceAll(regex, "$1 ");
+    return result;
+  }
+}