jiazx0107@163.com
2023-12-14 8435cf1d25d07b09e2a9937d39bed1c1a422e4f0
提交正来电子协议解析-1
已重命名1个文件
已删除1个文件
已修改13个文件
已添加24个文件
2390 ■■■■■ 文件已修改
src/main/java/com/fzzy/api/data/ApiCommonDevice.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/data/GatewayDeviceProtocol.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/utils/BytesUtil.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/utils/ContextUtil.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/entity/GatewayDevice.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/service/GatewayDeviceService.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/ConstantProtocol.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/ProtocolUtils.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/analysis/AnalysisService.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/server/BhznGrainV2ServerEngine.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/server/BhznGrainV2ServerUtils.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/service/Bhzn2GatewayGrainService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/data/THDto.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/fzzy/analysis/AnalysisGrain.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/fzzy/server/ServerUtils.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/fzzy/service/FzzyGatewayGrainService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisConf.java 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisGrain.java 384 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisService.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisTH.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder1115.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder8815.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder8817.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/cmd/ReMessageBuilder.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/data/Message.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/data/MessageBody.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/data/Metadata.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/data/ReMessage.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/data/ReMessageBody.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/package-info.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/server/HeartbeatProviderImpl.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/server/MsgConsumer.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/server/SessionListener.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/server/ZldzServerEngine.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/server/ZldzServerUtil.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/service/ZldzGatewayGrainService.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/util/CRC16.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/util/CRC8.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/data/ApiCommonDevice.java
@@ -20,6 +20,8 @@
    private Integer port;
    private String orgId;
    //状态是否在线
    private String status = Constant.YN_Y;
src/main/java/com/fzzy/api/data/GatewayDeviceProtocol.java
@@ -13,7 +13,8 @@
    TCP_FZZY_V3("TCP_FZZY_V3", "粮情-风正致远控制柜协议V3"),
    GRAIN_FZZY_IGDS_V40("GRAIN_FZZY_IGDS_V40", "粮情-风正致远系统V40"),
    GRAIN_FZZY_BHZN_WEB("GRAIN_FZZY_BHZN_WEB", "粮情-风正致远邦海网口协议"),
    GRAIN_FZZY_BHZN_WEB("GRAIN_FZZY_BHZN_WEB", "粮情-FZZY-邦海智能网口协议"),
    GRAIN_FZZY_ZLDZ_WEB("GRAIN_FZZY_ZLDZ_WEB", "粮情-FZZY-正来电子网口协议"),
    DEVICE_WEIGHT_HTTP("DEVICE_WEIGHT_HTTP", "地磅-HTTP协议"),
    DEVICE_WEIGHT_TCP_YH("DEVICE_WEIGHT_TCP_YH", "地磅-耀华TCP协议"),
    DEVICE_IDCARD_HTTP("DEVICE_IDCARD_HTTP", "身份证-HTTP协议"),
@@ -30,6 +31,7 @@
        list.add(new ApiTrigger(TCP_FZZY_V3.getCode(), TCP_FZZY_V3.getName()));
        list.add(new ApiTrigger(GRAIN_FZZY_IGDS_V40.getCode(), GRAIN_FZZY_IGDS_V40.getName()));
        list.add(new ApiTrigger(GRAIN_FZZY_BHZN_WEB.getCode(), GRAIN_FZZY_BHZN_WEB.getName()));
        list.add(new ApiTrigger(GRAIN_FZZY_ZLDZ_WEB.getCode(), GRAIN_FZZY_ZLDZ_WEB.getName()));
        list.add(new ApiTrigger(DEVICE_WEIGHT_HTTP.getCode(), DEVICE_WEIGHT_HTTP.getName()));
        list.add(new ApiTrigger(DEVICE_WEIGHT_TCP_YH.getCode(), DEVICE_WEIGHT_TCP_YH.getName()));
        list.add(new ApiTrigger(DEVICE_IDCARD_HTTP.getCode(), DEVICE_IDCARD_HTTP.getName()));
src/main/java/com/fzzy/api/utils/BytesUtil.java
@@ -461,4 +461,12 @@
        }
        return biannary2Decimal(two) + 1;
    }
    public static String byteToHex(byte b) {
        String hex = Integer.toHexString(b & 0xFF);
        if (hex.length() < 2) {
            hex = "0" + hex;
        }
        return hex;
    }
}
src/main/java/com/fzzy/api/utils/ContextUtil.java
@@ -3,6 +3,7 @@
import com.fzzy.api.Constant;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.util.*;
@@ -189,4 +190,9 @@
    public static String buildDeviceStatusKey(String companyId, String serId, int passCode) {
        return companyId + "_" + serId + "_STATUS_" + passCode;
    }
    public static String getDefaultBatchId() {
        return DateFormatUtils.format(new Date(), "yyyyMMddHHmm");
    }
}
src/main/java/com/fzzy/gateway/entity/GatewayDevice.java
@@ -107,9 +107,7 @@
    @PropertyDef(label = "位置")
    private String position;
    @Column(name = "REMARK_", length = 200)
    @PropertyDef(label = "备注", description = "备注信息")
    private String remark;
    @Column(name = "CABLE_RULE_", length = 20)
    @PropertyDef(label = "布线规则", description = "平方仓表示层行列,筒仓表示每圈的列数")
@@ -123,8 +121,32 @@
    @PropertyDef(label = "在线状态")
    private String status = Constant.YN_Y;
    @Column(name = "CABLE_START_")
    @PropertyDef(label = "电缆开始")
    private int cableStart;
    @Column(name = "CABLE_END_")
    @PropertyDef(label = "电缆截至")
    private int cableEnd;
    @Column(name = "TH_ADDR_")
    @PropertyDef(label = "温湿度地址")
    private String thAddr;
    @Column(name = "CABLE_FORMAT", length = 4)
    @PropertyDef(label = "电缆制式")
    private String cableFormat;
    @Column(name = "CABLE_TYPE", length = 4)
    @PropertyDef(label = "电缆类型")
    private String cableType;
    @Transient
    @PropertyDef(label = "设备上线时间")
    private Date onlineTime;
    @Column(name = "REMARK_", length = 200)
    @PropertyDef(label = "备注", description = "备注信息")
    private String remark;
}
src/main/java/com/fzzy/gateway/service/GatewayDeviceService.java
@@ -92,6 +92,15 @@
        flushCache();
    }
    public void updateData(GatewayDevice device) {
        device.setStatus(Constant.YN_Y);
        gatewayDeviceRep.save(device);
        flushCacheOne(device);
    }
    /**
     * gatewayDeviceService#delData
     *
@@ -115,6 +124,10 @@
        for (GatewayDevice device : list) {
            GatewayUtils.add2Cache(device);
        }
    }
    private void flushCacheOne(GatewayDevice device) {
        GatewayUtils.add2Cache(device);
    }
@@ -154,4 +167,6 @@
            GatewayUtils.add2Cache(device);
        }
    }
}
src/main/java/com/fzzy/protocol/ConstantProtocol.java
ÎļþÒÑɾ³ý
src/main/java/com/fzzy/protocol/ProtocolUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,55 @@
package com.fzzy.protocol;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.protocol.data.THDto;
import java.util.HashMap;
import java.util.Map;
/**
 * åè®®è§£æžå…¨å±€å¸¸é‡
 */
public class ProtocolUtils {
    /**
     * è¯·æ±‚缓存 key = deviceId,value = requData
     */
    private static Map<String, BaseReqData> contextSyncReqMap = new HashMap<>();
    /**
     * è¯·æ±‚缓存 key = deviceId,value = thDto
     */
    private static Map<String, THDto> contextThMap = new HashMap<>();
    //-粮温备用点
    public static final double ERROR_TEMP = -100;
    //-粮温故障点
    public static final double FAULT_TEMP = -101;
    //-粮温补偿点-针对锥形仓补点使用
    public static final double ADD_TEMP = -102;
    /**
     * å°†æ‰§è¡Œå‘½ä»¤ä¿¡æ¯å­˜æ”¾åœ¨ç¼“å­˜
     *
     * @param depotId ä»“库编码
     * @param reqData è¯·æ±‚参数信息
     */
    public static void addSyncReq2Map(String depotId, BaseReqData reqData) {
        contextSyncReqMap.put(depotId, reqData);
    }
    public static BaseReqData getSyncReq(String depotId) {
        return contextSyncReqMap.get(depotId);
    }
    public static void addTh2Map(String deviceId, THDto thDto) {
        contextThMap.put(deviceId, thDto);
    }
    public static THDto getCacheTh(String deviceId) {
        return contextThMap.get(deviceId);
    }
}
src/main/java/com/fzzy/protocol/bhzn/analysis/AnalysisService.java
@@ -14,14 +14,13 @@
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.hx2023.ScConstant;
import com.fzzy.gateway.hx2023.data.*;
import com.fzzy.protocol.ConstantProtocol;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.bhzn.cmd.CommandBuild;
import com.fzzy.protocol.bhzn.cmd.ReMessageBuilder;
import com.fzzy.protocol.bhzn.data.IoMessage;
import com.fzzy.protocol.bhzn.data.THDto;
import com.fzzy.protocol.data.THDto;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerEngine;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerUtils;
import com.fzzy.protocol.fzzy.server.ServerUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -116,7 +115,7 @@
            }
            //获取请求信息
            BaseReqData reqData = BhznGrainV2ServerUtils.getSyncReq(gatewayDevice.getDepotIdSys());
            BaseReqData reqData = ProtocolUtils.getSyncReq(gatewayDevice.getDepotIdSys());
            if (null == reqData) {
                replayGrain(message);
                log.error("主机-------->>平台,解析粮情失败,未获取到粮情请求信息:" + message.getAddr());
@@ -216,13 +215,13 @@
                temp = "0000";
            }
            if (ReMessageBuilder.ERROR_TAG.equals(temp)) {
                tempValue = ConstantProtocol.ERROR_TEMP;
                tempValue = ProtocolUtils.ERROR_TEMP;
            } else {
                tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
            }
            // æ•…障值处理
            if (tempValue >= ReMessageBuilder.FAULT_CHECK_TAG) {
                tempValue = ConstantProtocol.FAULT_TEMP;
                tempValue = ProtocolUtils.FAULT_TEMP;
            }
            temps.add(tempValue);
        }
src/main/java/com/fzzy/protocol/bhzn/server/BhznGrainV2ServerEngine.java
@@ -17,7 +17,7 @@
@Service
public class BhznGrainV2ServerEngine {
    public static final Integer PORT = 19309;
    public static final Integer PORT = 19301;
    public static NettyServer ioServer = null;
src/main/java/com/fzzy/protocol/bhzn/server/BhznGrainV2ServerUtils.java
@@ -21,10 +21,6 @@
     */
    public static Map<String, Long> contextMapHeart = new HashMap<>();
    /**
     * è¯·æ±‚缓存 key = deviceId,value = requData
     */
    private static Map<String, BaseReqData> contextSyncReqMap = new HashMap<>();
@@ -49,21 +45,6 @@
    public static String FUNCTION_ID_83 = "83";
    public static String FUNCTION_ID_93 = "93";
    public static String FUNCTION_ID_92 = "92";
    /**
     * å°†æ‰§è¡Œå‘½ä»¤ä¿¡æ¯å­˜æ”¾åœ¨ç¼“å­˜
     *
     * @param depotId ä»“库编码
     * @param reqData è¯·æ±‚参数信息
     */
    public static void addSyncReq2Map(String depotId, BaseReqData reqData) {
        contextSyncReqMap.put(depotId, reqData);
    }
    public static BaseReqData getSyncReq(String depotId) {
        return contextSyncReqMap.get(depotId);
    }
    /**
src/main/java/com/fzzy/protocol/bhzn/service/Bhzn2GatewayGrainService.java
@@ -8,15 +8,18 @@
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.bhzn.cmd.CommandBuild;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerEngine;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerUtils;
import com.fzzy.protocol.zldz.data.Message;
import com.ld.io.api.InvokeResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * é£Žæ­£è‡´è¿œæŽ§åˆ¶æŸœåè®®
 * é‚¦æµ·æ™ºèƒ½ç²®æƒ…协议-网口设备
 */
@Slf4j
@Component
@@ -58,7 +61,7 @@
        try {
            //Step è¯·æ±‚信息放入内存
            BhznGrainV2ServerUtils.addSyncReq2Map(device.getDepotIdSys(), reqData);
            ProtocolUtils.addSyncReq2Map(device.getDepotIdSys(), reqData);
            // ç”Ÿæˆç²®æƒ…信息
            String hexStr = CommandBuild.getInstance().getMsgCheck(device.getDeviceSn(), device.getDepotIdSys());
src/main/java/com/fzzy/protocol/data/THDto.java
ÎļþÃû´Ó src/main/java/com/fzzy/protocol/bhzn/data/THDto.java ÐÞ¸Ä
@@ -1,4 +1,4 @@
package com.fzzy.protocol.bhzn.data;
package com.fzzy.protocol.data;
import com.bstek.dorado.annotation.PropertyDef;
import lombok.Data;
@@ -20,7 +20,7 @@
    private String serId;//所属分机
    private String thConf = "1";//所属通道
    private String thAddr = "1";//所属通道
    @PropertyDef(label = "所属仓库", description = "仓库编号")
    private String depotId;
@@ -31,7 +31,7 @@
    @PropertyDef(label = "仓内湿度", description = "单位%RH")
    private Double humidityIn;
    
    @PropertyDef(label = "接收时间", description = "")
    @PropertyDef(label = "接收时间")
    private Date receiveDate = new Date();
    private String remark;
src/main/java/com/fzzy/protocol/fzzy/analysis/AnalysisGrain.java
@@ -13,6 +13,7 @@
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.hx2023.ScConstant;
import com.fzzy.gateway.hx2023.data.*;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.fzzy.builder.SimpleCommandBuilder;
import com.fzzy.protocol.fzzy.cmd.BaseRemoteImpl;
import com.fzzy.protocol.fzzy.data.ReMessage;
@@ -93,7 +94,7 @@
    private void buildBizInfo1(Response2102 response) {
        //获取请求信息
        BaseReqData reqData = ServerUtils.getSyncReq(response.getHouseId());
        BaseReqData reqData = ProtocolUtils.getSyncReq(response.getHouseId());
        if (null == reqData) {
            log.error("--粮情封装解析,未获取到请求相关参数----");
src/main/java/com/fzzy/protocol/fzzy/server/ServerUtils.java
@@ -16,25 +16,6 @@
    private static Map<String, Integer> contextOrder = new HashMap<>();
    /**
     * è¯·æ±‚缓存 key = deviceId,value = requData
     */
    private static Map<String, BaseReqData> contextSyncReqMap = new HashMap<>();
    /**
     * å°†æ‰§è¡Œå‘½ä»¤ä¿¡æ¯å­˜æ”¾åœ¨ç¼“å­˜
     *
     * @param depotId ä»“库编码
     * @param reqData è¯·æ±‚参数信息
     */
    public static void addSyncReq2Map(String depotId, BaseReqData reqData) {
        contextSyncReqMap.put(depotId, reqData);
    }
    public static BaseReqData getSyncReq(String depotId) {
        return contextSyncReqMap.get(depotId);
    }
    public static final String MSG_BEGIN = "<FZZY>";
    public static final String MSG_END = "<END>";
src/main/java/com/fzzy/protocol/fzzy/service/FzzyGatewayGrainService.java
@@ -7,6 +7,7 @@
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.fzzy.builder.GrainCommandBuilder;
import com.fzzy.protocol.fzzy.cmd.BaseRemoteImpl;
import com.fzzy.protocol.fzzy.data.SendMessage;
@@ -60,7 +61,7 @@
        try {
            //Step è¯·æ±‚信息放入内存
            ServerUtils.addSyncReq2Map(device.getDepotIdSys(), reqData);
            ProtocolUtils.addSyncReq2Map(device.getDepotIdSys(), reqData);
            // Step1 ç”Ÿæˆç²®æƒ…信息
            SendMessage message = GrainCommandBuilder.getInstance().buildMessage(device,apiCommonDevice);
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisConf.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,184 @@
package com.fzzy.protocol.zldz.analysis;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.service.GatewayDeviceService;
import com.fzzy.protocol.zldz.data.ReMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * @author vince
 */
@Slf4j
@Component(AnalysisConf.BEAN_ID)
public class AnalysisConf {
    public static final String BEAN_ID = "zldz.analysisConf";
    @Resource
    private GatewayDeviceService gatewayDeviceService;
    /**
     * è§£æžåˆ†æœºé…ç½®ä¿¡æ¯
     *
     * @param message
     * @param ser
     */
    public void analysis8816(ReMessage message, GatewayDevice ser) {
        log.debug("分机---->>>平台:消息类型=8816-----{}", ser.getDeviceName());
        String content = message.getBody().getContent();
        // è¯»å†™æ ‡å¿—
        int start = 0, len = 1;
        String temp = content.substring(start * 2, start * 2 + len * 2);
        int readTag = BytesUtil.hexToInt(temp);
        // è®¾å¤‡ID,全局唯一
        start = 1;
        len = 2;
        temp = content.substring(start * 2, start * 2 + len * 2);
        // ç½‘络ID
        start = 3;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        // ä¿¡é“
        start = 4;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        // é€Ÿçއ
        start = 5;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        // å±‚æ•°
        String cable = "";
        start = 6;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        cable += BytesUtil.hexToInt(temp);
        // è¡Œæ•°
        start = 7;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        cable += "-" + BytesUtil.hexToInt(temp);
        // åˆ—æ•°
        start = 8;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        cable += "-" + BytesUtil.hexToInt(temp);
        //层 - è¡Œ - åˆ— é…ç½®
        ser.setCableRule(cable);
        // ç”µç¼†åˆ¶å¼
        start = 9;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        ser.setCableFormat("0" + BytesUtil.hexToInt(temp));
        // ç”µç¼†ç±»åž‹
        start = 10;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        ser.setCableType("0" + BytesUtil.hexToInt(temp));
        // ä¾›ç”µæ¨¡å¼
        start = 11;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        //ser.setPowerModel("0" + BytesUtil.hexToInt(temp));
        String msg = ser.getDeviceName() + " è¿œç¨‹èŽ·å–é…ç½®æˆåŠŸï¼Œè¯·åˆ·æ–°æ•°æ®æŸ¥çœ‹ï¼";
        // ç»„织编码
        start = 12;
        temp = content.substring(start * 2);
        if (readTag == 1) {// è¡¨ç¤ºå†™çš„æˆåŠŸè¿”å›ž
            ser.setOrgId(ser.getOrgId());
            msg = ser.getDeviceName() + " è¿œç¨‹å†™å…¥æˆåŠŸï¼Œè¯·åˆ·æ–°æ•°æ®æŸ¥çœ‹ï¼";
        } else {
            ser.setOrgId(BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) + "");
        }
        if (null == ser.getDeviceSn()) {
            ser.setDeviceSn(ser.getId());
        }
        ser.setIp(message.getIp());
        ser.setPort(message.getPort());
        // å¼€å§‹åˆ—默认=1
        if (ser.getCableStart() == 0) {
            ser.setCableStart(1);
        }
        log.info("分机---->>>平台:分机配置解析完成---{},更新到服服务器",
                ser.getDeviceName());
        //更新设备信息
        gatewayDeviceService.updateData(ser);
    }
    /**
     * ç”µç¼†åˆå§‹åŒ–成功
     *
     * @param reMessage
     * @param ser
     */
    public void analysis8822(ReMessage reMessage, GatewayDevice ser) {
        log.info("--------电缆初始化成功------------{}", ser.getDeviceName());
    }
    /**
     * ç”µç¼†ä¿®æ”¹è¿”回,
     *
     * @param reMessage
     * @param ser
     */
    public void analysis8826(ReMessage reMessage, GatewayDevice ser) {
        log.info("--------修改电缆信息返回------------{}", ser.getDeviceName());
    }
    /**
     * é€šé“电缆获取返回,分机返回收到命令信息,实际返回值在8829中说明
     *
     * @param reMessage
     * @param ser
     */
    public void analysis8825(ReMessage reMessage, GatewayDevice ser) {
        log.info("--------通道电缆获取返回------------{}", ser.getDeviceName());
    }
    /**
     * ç»ˆç«¯å‘送通道电缆数据给后台,分机主动推送
     *
     * @param reMessage
     * @param ser
     */
    @SuppressWarnings("unchecked")
    public void analysis1129(ReMessage reMessage, GatewayDevice ser) {
        log.info("--------终端发送通道电缆数据给后台------------{}", ser.getDeviceName());
    }
    /**
     * ç”µç¼†æ±‡æ€»åº”ç­”
     *
     * @param reMessage
     * @param ser
     */
    public void analysis8823(ReMessage reMessage, GatewayDevice ser) {
        // å¼€å§‹è§£æž
        String content = reMessage.getBody().getContent();
        //DO NOTHING
    }
}
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisGrain.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,384 @@
package com.fzzy.protocol.zldz.analysis;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.ContextUtil;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.zldz.data.ReMessage;
import com.fzzy.protocol.zldz.service.ZldzGatewayGrainService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * ç²®æƒ…解析
 *
 * @author Andy
 */
@Slf4j
@Component(AnalysisGrain.BEAN_ID)
public class AnalysisGrain {
    public static final String BEAN_ID = "zldz.analysisGrain";
    @Resource
    private ZldzGatewayGrainService zldzGatewayGrainService;
    public static Map<String, Map<String, String>> contextMap = new HashMap<>();
    public static double ERROR_CHECK_TAG = -100.0;
    public static double FAULT_CHECK_TAG = 85.0;
    public static double ERROR_CHECK_TAG2 = 50;
    public static double MAX_TEMP = -50.0;
    public static double MIN_TEMP = 50.0;
    /**
     * åŽå°å‘送请求后,终端的响应
     *
     * @param reMessage
     * @param device
     */
    public void analysis8815(ReMessage reMessage, GatewayDevice device) {
        BaseRequest request = new BaseRequest();
        request.setSerId(device.getId());
        request.setCompanyId(device.getOrgId());
        request.setIp(reMessage.getIp());
        request.setPort(reMessage.getPort());
        request.setSerName(device.getDeviceName());
        zldzGatewayGrainService.reply8815(request);
    }
    /**
     * æŽ¥æ”¶åˆ°ç²®æƒ…的回复
     *
     * @param reMessage
     * @param device
     */
    public void reply8817(ReMessage reMessage, GatewayDevice device) {
        String bodyMsg = reMessage.getBody().getContent();
        log.info("分机------>>>平台:收到的粮情信息-{}-{}",
                device.getDeviceName(), reMessage.getStrMsg());
        // Step1根据需要简化需要的信息
        String ua = bodyMsg.substring(0 * 2, 1 * 2);
        log.debug("获取到的电压信息,系统不保留={}", ua);
        // æ€»åŒ…æ•°
        // int sumPacket = BytesUtil.hexToInt(bodyMsg.substring(1 * 2, 1 * 2 + 1
        // * 2));
        // å½“前包
        String hexCurPacket = bodyMsg.substring(2 * 2, 2 * 2 + 1 * 2);
        // int curPacket = BytesUtil.hexToInt(hexCurPacket);
        BaseRequest request = new BaseRequest();
        request.setSerId(device.getDeviceSn());
        request.setCompanyId(device.getOrgId());
        request.setIp(reMessage.getIp());
        request.setPort(reMessage.getPort());
        request.setSerName(device.getDeviceName());
        zldzGatewayGrainService.reply8817(request, hexCurPacket);
    }
    public void analysis8817(ReMessage msg, GatewayDevice device) {
        // æŽ¥åˆ°ä¿¡æ¯å›žå¤--主机
        reply8817(msg, device);
        BaseReqData reqData = ProtocolUtils.getSyncReq(device.getDepotIdSys());
        if (null == reqData) {
            log.warn("---------没有获取到当前仓库的请求,不执行解析-----{}", device.getDeviceName());
            return;
        }
        analysisStep(msg, device, reqData);
    }
    /**
     * å¼€å§‹è§£æž
     *
     * @param device
     * @param msg
     * @throws Exception
     */
    private void analysisStep(ReMessage msg, GatewayDevice device, BaseReqData reqData) {
        // ç²®æƒ…的批次号重新根据频率调整
        msg.setBatchId(ContextUtil.getDefaultBatchId());
        String bodyMsg = msg.getBody().getContent();
        log.debug("{}=收到的粮情信息={}", device.getDeviceName(),
                msg.getStrMsg());
        // Step1根据需要简化需要的信息
        String ua = bodyMsg.substring(0 * 2, 1 * 2);
        log.debug("获取到的电压信息,系统不保留={}", ua);
        // æ€»åŒ…æ•°
        int sumPacket = BytesUtil.hexToInt(bodyMsg.substring(1 * 2,
                1 * 2 + 1 * 2));
        // å½“前包
        String hexCurPacket = bodyMsg.substring(2 * 2, 2 * 2 + 1 * 2);
        int curPacket = BytesUtil.hexToInt(hexCurPacket);
        log.debug("分机={},包总数={},当前包={}", device.getDeviceName(), sumPacket, curPacket);
        // ç²®é£Ÿæ¸©åº¦ä¿¡æ¯
        String grainStr = bodyMsg.substring(3 * 2);
        String contextKey = this.buildContextKey(msg, device.getDepotIdSys());
        String curKey = this.buildCurKey(msg, curPacket);
        Map<String, String> curMap = contextMap.get(contextKey);
        if (null == curMap) {
            curMap = new HashMap<>();
            contextMap.put(contextKey, curMap);
        }
        contextMap.get(contextKey).put(curKey, grainStr);
        // æ•°æ®å‡†å¤‡å¥½ï¼Œå¼€å§‹æ‰§è¡Œè§£æž
        if (curPacket == sumPacket) {
            analysisStep0(msg, device, reqData, contextKey, sumPacket);
            log.info("分机------>>>平台:命令类型=8817--粮情全部收到,开始解析-{}",
                    device.getDeviceName());
        }
    }
    private void analysisStep0(ReMessage msg, GatewayDevice device, BaseReqData reqData, String contextKey, int sumPacket) {
        Map<String, String> curMap = contextMap.get(contextKey);
        if (StringUtils.isEmpty(device.getCableCir())) {
            analysisStep1(msg, device, reqData, curMap, sumPacket);
        } else {
            analysisStep2(msg, device, reqData, curMap, sumPacket);
        }
    }
    /**
     * åœ†ç­’仓的粮情解析
     *
     * @param packetMap
     * @param sumPackets
     */
    private void analysisStep2(ReMessage msg,
                               GatewayDevice device, BaseReqData reqData,
                               Map<String, String> packetMap, int sumPackets) {
        String[] cableRuleAtt = device.getCableRule().split("-");
        String[] cableCirAtt = device.getCableCir().split("-");
        if (cableRuleAtt.length != cableCirAtt.length) {
            log.error("分机------>>>平台:当前仓库:{},布线规则不正确,无法解析粮情信息……", device.getDeviceName());
            return;
        }
        // èŽ·å–æœ€å¤§çš„å±‚é…ç½®--默认每一圈都一样
        int layMax = Integer.valueOf(cableCirAtt[0]);
        for (int i = 0; i < cableCirAtt.length; i++) {
            if (Integer.valueOf(cableCirAtt[i]) >= layMax) layMax = Integer.valueOf(cableCirAtt[i]);
        }
        // èŽ·å–å®Œæ•´çš„ç²®æƒ…åŒ…ä¿¡æ¯
        String strPoints = "";
        for (int i = 1; i <= sumPackets; i++) {
            strPoints += packetMap.get(buildCurKey(msg, i));
        }
        log.info("------筒仓完整的粮情报文={}------", strPoints);
        int sumNum = 0, cableZ = 1;// sumNum å…±å¤šå°‘根电缆;cableZ å±‚的最大值,锥形仓补齐最大层
        for (int i = 0; i < cableCirAtt.length; i++) {
            if (Integer.valueOf(cableCirAtt[i]) > cableZ) {
                cableZ = Integer.valueOf(cableCirAtt[i]);
            }
            sumNum += Integer.valueOf(cableRuleAtt[i]);
        }
        // æ ¹æ®å±‚行列获取指定长度
        int start = 0;
        int len = 4 * cableZ * sumNum;
        strPoints = strPoints.substring(start, start + len);
        log.info("分机------>>>平台:返回粮情完整信息,分机={}", device.getDeviceName());
        // å°†ç²®æƒ…解析成数组
        List<Double> temps = new ArrayList<>();
        double tempValue;
        String temp;
        int curLay = 1;//所在层从1开始
        int curRoot = 1;//所在根
        int curCir = 1;//所在圈
        int cirLay = 1;//当前圈的层
        for (int i = 0; i < strPoints.length() / 4; i++) {
            temp = strPoints.substring(i * 4, i * 4 + 4);
            if (temp == null) {
                temp = "0000";
            }
            tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
            //非正常值
            if (tempValue > ERROR_CHECK_TAG2) {
                tempValue = ProtocolUtils.ERROR_TEMP;
            }
            // æ•…障值处理
            if (tempValue >= FAULT_CHECK_TAG) {
                tempValue = ProtocolUtils.FAULT_TEMP;
            }
            // å¤‡ç”¨å€¼
            if (tempValue == ERROR_CHECK_TAG) {
                tempValue = ProtocolUtils.ERROR_TEMP;
                //验证是不是锥形仓补偿值
                curLay = (i % layMax) + 1;
                curRoot = (i / layMax) + 1;
                curCir = getCurCir(curRoot, cableRuleAtt);
                cirLay = Integer.valueOf(cableCirAtt[curCir - 1]);
                //比如配置了5层但是当前是6层,说明当前点为补偿点
                if (curLay > cirLay) {
                    tempValue = ProtocolUtils.ADD_TEMP;
                } else {
                    temps.add(tempValue);
                }
            } else {
                temps.add(tempValue);
            }
        }
        // å°†é›†åˆè§£æžæˆåæ ‡æ•°æ®
        addPoint2(temps, msg, device, reqData);
    }
    /**
     * èŽ·å–å½“å‰è·Ÿæ‰€åœ¨åœˆ
     *
     * @param curRoot
     * @param cableRuleAtt
     * @return
     */
    private int getCurCir(int curRoot, String[] cableRuleAtt) {
        int sum = 0;
        for (int i = 0; i < cableRuleAtt.length; i++) {
            sum += Integer.valueOf(cableRuleAtt[i]);
            if (curRoot <= sum) return i + 1;
        }
        return 1;
    }
    /**
     * å¹³æ–¹ä»“的解析,解析需要考虑当前是否启用的一分机多仓
     *
     * @param depotConf
     * @param msg
     * @param ser
     * @param exeRequest
     * @param packetMap
     * @param sumPackets
     */
    private void analysisStep1(ReMessage msg,
                               GatewayDevice device, BaseReqData reqData,
                               Map<String, String> packetMap, int sumPackets) {
        // èŽ·å–å®Œæ•´çš„ç²®æƒ…åŒ…ä¿¡æ¯
        String strPoints = "";
        for (int i = 1; i <= sumPackets; i++) {
            strPoints += packetMap.get(buildCurKey(msg, i));
        }
        String[] attCable = device.getCableRule().split("-");
        int cableZ = Integer.valueOf(attCable[0]);
        int cableY = Integer.valueOf(attCable[1]);
        int cableX = Integer.valueOf(attCable[2]);
        // æ ¹æ®å±‚行列获取指定长度
        int start = 4 * (device.getCableStart() - 1) * cableZ * cableY;
        int len = 4 * cableZ * cableY * cableX;
        log.info("分机------>>>平台:返回粮情完整信息,分机={}", device.getDeviceName());
        strPoints = strPoints.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";
            }
            tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
            // è¯´æ˜Žè§£æžçš„æ•°æ®æœ‰é—®é¢˜
            if (tempValue == ERROR_CHECK_TAG || tempValue == ERROR_CHECK_TAG2) {
                tempValue = ProtocolUtils.ERROR_TEMP;
            }
            // æ•…障值处理
            if (tempValue >= FAULT_CHECK_TAG) {
                tempValue = ProtocolUtils.FAULT_TEMP;
            }
            temps.add(tempValue);
        }
        // å°†é›†åˆè§£æžæˆåæ ‡æ•°æ®
        addPoint1(temps, msg, device, reqData);
    }
    private String buildCurKey(ReMessage msg, int curPacket) {
        return msg.getSourceId() + "_" + curPacket;
    }
    private String buildContextKey(ReMessage msg, String depotId) {
        return msg.getCompanyId() + "_" + msg.getSourceId() + "_" + depotId;
    }
    /**
     * å¹³æˆ¿ä»“,解析第二步,解析到坐标数据
     *
     * @param temps
     * @throws Exception
     */
    private void addPoint1(List<Double> temps, ReMessage msg,
                           GatewayDevice device, BaseReqData reqData) {
        //TODO
    }
    /**
     * åœ†ç­’仓解析步骤
     *
     * @param temps
     * @param msg
     */
    private void addPoint2(List<Double> temps, ReMessage msg,
                           GatewayDevice device, BaseReqData reqData) {
        //TODO
    }
}
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,169 @@
package com.fzzy.protocol.zldz.analysis;
import com.fzzy.api.Constant;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.protocol.zldz.cmd.ReMessageBuilder;
import com.fzzy.protocol.zldz.data.ReMessage;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import com.fzzy.protocol.zldz.util.*;
import javax.annotation.Resource;
/**
 * åè®®è§£æžå…¥å£
 *
 * @author jiazx
 */
@Slf4j
@Component(AnalysisService.BEAN_ID)
public class AnalysisService {
    public static final String BEAN_ID = "zldz.analysisService";
    @Resource
    private AnalysisGrain analysisGrain;
    @Resource
    private AnalysisTH analysisTH;
    @Resource
    private AnalysisConf analysisConf;
    public void analysis(String ip, Integer port, String strMsg) {
        ApiCommonDevice commonDevice = Constant.getCommonDeviceCacheByIp(ip);
        ReMessage reMessage = ReMessageBuilder.getInstance().buildMessage(null, commonDevice, strMsg);
        if (null == reMessage) {
            log.error("分机----->>>平台:返回信息没有获取组织编码信息,无法继续解析----{}", commonDevice.getIp());
            return;
        }
        //获取设备信息
        GatewayDevice device = GatewayUtils.getCacheByDeviceSn(commonDevice.getSn());
        if (null == device) {
            log.error("分机----->>>平台:为获取到设备配置信息,无法继续解析----{}", commonDevice.getIp());
            return;
        }
        String checkMsg = this.checkMsg(reMessage, device);
        if (null != checkMsg) {
            log.error("分机----->>>平台:命令验证异常:异常信息-{},报文信息-{}", checkMsg, reMessage.getStrMsg());
            return;
        }
        switch (reMessage.getMessageType()) {
            case ZldzServerUtil.MSG_TYPE_8828:// æ¸©æ¹¿åº¦è§£æž
                analysisTH.analysis8828(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8815:// ç»ˆç«¯åº”答粮情请求
                analysisGrain.analysis8815(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_1117:// ç²®æƒ…数据信息
                analysisGrain.analysis8817(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_1129:// ç»ˆç«¯å‘送通道电缆数据给后台
                analysisConf.analysis1129(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8816:// è§£æžé…ç½®
                analysisConf.analysis8816(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8822:// ç”µç¼†åˆå§‹åŒ–成功
                analysisConf.analysis8822(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8823:// ç”µç¼†æ±‡æ€»åº”ç­”
                analysisConf.analysis8823(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8825:// è¯»å–通道电缆配置
                analysisConf.analysis8825(reMessage, device);
                break;
            case ZldzServerUtil.MSG_TYPE_8826:// ä¿®æ”¹ç”µç¼†çš„返回
                analysisConf.analysis8826(reMessage, device);
                break;
            default:
                break;
        }
    }
    /**
     * æ ¡éªŒï¼Œæ­£å¸¸è¿”回NULL,异常返回异常原因,正常异常原因返回不踢掉重新连接
     *
     * @param message
     * @param device
     * @return
     * @throws Exception
     */
    private String checkMsg(ReMessage message, GatewayDevice device) {
        String result;
        if (message.getResult() == 1) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šæŽ¥æ”¶çš„åº”ç­”æ ¡éªŒå¼‚å¸¸";
            return result;
        }
        if (message.getResult() == 2) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šå‘é€çš„æ•°æ®æ ¡éªŒå¼‚å¸¸";
            return result;
        }
        if (message.getResult() == 3) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šæŽ’é˜Ÿä¸­";
            return result;
        }
        if (message.getResult() == 4) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šå‘é€è¶…æ—¶é”™è¯¯";
            return result;
        }
        if (message.getResult() == 9) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šIo模块不在线";
            return result;
        }
        if (message.getResult() == 10) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šå‘é€ä¸­";
            return result;
        }
        if (message.getResult() == 11) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šæ— çº¿æ¨¡å—æ•…éšœ";
            return result;
        }
        if (message.getResult() == 12) {
            result = "分机=" + device.getDeviceName()
                    + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šä¸»è¦æ˜¯åé¦ˆåæ ‡ç‚¹äº¤æ¢å‘½ä»¤æˆ–è€…æ˜¯ç”µç¼†ä¿®æ”¹å‘½ä»¤çš„é”™è¯¯ï¼Œæˆ–è€…ç²®æƒ…é‡‡é›†çš„å‚æ•°ä¸å¯¹";
            return result;
        }
        if (message.getResult() == 13) {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šç½‘å…³æœªæ³¨å†Œ";
            return result;
        }
        // èŽ·å–æ ¡éªŒçš„æŠ¥æ–‡ä¿¡æ¯
        int end = 4 + 18 * 2 + message.getBody().getLength() * 2;
        String checkStr = message.getStrMsg().substring(4, end);
        byte[] byteCrc16 = BytesUtil.hexStrToBytes(checkStr);
        short crc16Hex2 = CRC8.calculateCrc16(byteCrc16, (short) 0,
                (short) (byteCrc16.length));
        byte[] crc16Hex2Bytes = BytesUtil.shortToByte(crc16Hex2);
        int crc16 = BytesUtil.bytesToInt(crc16Hex2Bytes);
        String hexCrc16 = BytesUtil.intToHexStr(crc16);
        if (message.getHexCrc16().equals(hexCrc16)) {
            return null;
        } else {
            result = "分机=" + device.getDeviceName() + " åè®®è§£æžå¤±è´¥ï¼ŒåŽŸå› ï¼šCRC16校验异常";
            return result;
        }
    }
}
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisTH.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,87 @@
package com.fzzy.protocol.zldz.analysis;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.data.THDto;
import com.fzzy.protocol.zldz.data.ReMessage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * è§£æžæ¸©æ¹¿åº¦ä¿¡æ¯
 *
 * @author Andy
 */
@Slf4j
@Component(AnalysisTH.BEAN_ID)
public class AnalysisTH {
    public static final String BEAN_ID = "zldz.analysisTH";
    public static int ERROR_TH_TAG = -50;
    /**
     * è§£æžä»“库温湿度信息,将信息放在缓存中,以便粮情使用
     *
     * @param msg
     * @param ser
     */
    public void analysis8828(ReMessage msg, GatewayDevice ser) {
        log.debug("-----------analysis8828------------{}.{}", ser.getIp(), ser.getPort());
        String content = msg.getBody().getContent();
        //温湿度地址,截取4位
        String temp = content.substring(0, 0 + 2 * 2);
        //高低位转换
        temp = BytesUtil.tran_LH(temp);
        int thAddr = BytesUtil.hexToInt(temp);
        int t, h;
        THDto th = new THDto();
        th.setTempIn(ProtocolUtils.ERROR_TEMP);
        th.setHumidityIn(ProtocolUtils.ERROR_TEMP);
        //温度
        int start = 2, len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        t = BytesUtil.hexToInt(temp);
        if (t > 127) {//说明是负数
            t = BytesUtil.hexToInt("FF" + temp);
        }
        if (t == ERROR_TH_TAG) {
            log.error("{}温湿度解析异常,原因:没有检测到传感器", ser.getDeviceName());
            th.setRemark(ser.getDeviceName() + "温湿度解析异常,原因:没有检测到传感器");
        } else {
            th.setTempIn(Double.valueOf(t));
        }
        //湿度
        start = 3;
        len = 1;
        temp = content.substring(start * 2, start * 2 + len * 2);
        h = BytesUtil.hexToInt(temp);
        if (h > 127) {//说明是负数
            h = BytesUtil.hexToInt("FF" + temp);
        }
        if (h == ERROR_TH_TAG) {
            log.error("{}温湿度解析异常,原因:没有检测到传感器", ser.getDeviceName());
            th.setRemark(ser.getDeviceName() + "温湿度解析异常,原因:没有检测到传感器");
        } else {
            th.setHumidityIn(Double.valueOf(h));
        }
        th.setSerId(ser.getId());
        th.setThAddr(thAddr + "");
        //存放缓存
        ProtocolUtils.addTh2Map(ser.getDeviceId(), th);
        log.info("仓温仓湿解析完成={}", th);
    }
}
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,144 @@
package com.fzzy.protocol.zldz.cmd;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.zldz.data.Message;
import com.fzzy.protocol.zldz.data.MessageBody;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
import com.fzzy.protocol.zldz.util.*;
/**
 * å‘½ä»¤ç”Ÿæˆå™¨
 *
 * @author Andy
 */
public abstract class CommandBuilder {
    /*
     * å‘½ä»¤åˆ›å»º
     *
     * @param order
     */
    public Message buildMessage(BaseRequest request) {
        Message message = new Message();
        message.setBegin(ZldzServerUtil.MSG_START);
        // è°ƒæ•´Message头部信息
        buildHeader(message, request);
        //包头校验
        buildCrc8(message);
        // åˆ›å»ºæ¶ˆæ¯ä½“
        buildBody(message, request);
        // æ·»åŠ æ ¡éªŒ
        buildCrc16(message);
        message.setEnd(ZldzServerUtil.MSG_END);
        // ç”Ÿæˆæ•´ä½“命令信息和BYte信息
        build(message);
        return message;
    }
    public void buildHeader(Message message, BaseRequest request) {
        String hexCompanyId = BytesUtil.getTargetId(request.getCompanyId(),true);
        hexCompanyId = BytesUtil.tran_LH(hexCompanyId);
        message.setSourceId(hexCompanyId);
        message.setSendId(hexCompanyId);
        message.setCompanyId(hexCompanyId);
        message.setSourceId(BytesUtil.getTargetId(request.getSerId(), true));
        message.setMessageType(ZldzServerUtil.MSG_TYPE_1116);
    }
    public void buildBody(Message message, BaseRequest request) {
        MessageBody body = new MessageBody();
        body.setContent("");
        body.setLength(0);
        message.setBody(body);
    }
    public void buildCrc8(Message message) {
        StringBuffer hexSbCrc8 = new StringBuffer();
        hexSbCrc8.append(message.getSourceId());
        hexSbCrc8.append(message.getTargetId());
        hexSbCrc8.append(message.getSendId());
        hexSbCrc8.append(message.getGateway1());
        hexSbCrc8.append(message.getGateway2());
        hexSbCrc8.append(message.getMessageType());
        hexSbCrc8.append(message.getResult());
        hexSbCrc8.append(message.getCompanyId());
        byte[] bytes = BytesUtil.hexStrToBytes(hexSbCrc8.toString());
        byte crc8 = CRC8.calcCrc8(bytes, (short) 0, (short) (bytes.length),
                (byte) 0);
        message.setHexCrc8(BytesUtil.byteToHex(crc8));
    }
    public void buildCrc16(Message message) {
        StringBuffer hexSbCrc16 = new StringBuffer();
        hexSbCrc16.append(message.getSourceId());
        hexSbCrc16.append(message.getTargetId());
        hexSbCrc16.append(message.getSendId());
        hexSbCrc16.append(message.getGateway1());
        hexSbCrc16.append(message.getGateway2());
        hexSbCrc16.append(message.getMessageType());
        hexSbCrc16.append(message.getResult());
        hexSbCrc16.append(message.getCompanyId());
        hexSbCrc16.append(message.getHexCrc8());
        hexSbCrc16.append(BytesUtil.tran_LH(BytesUtil
                .getHex2LenStr(message.getBody().getLength())));
        hexSbCrc16.append(message.getBody().getContent());
        byte[] byteCrc16 = BytesUtil.hexStrToBytes(hexSbCrc16.toString());
        short crc16Hex2 = CRC8.calculateCrc16(byteCrc16, (short) 0, (short) (byteCrc16.length));
        byte[] crc16Hex2Bytes = BytesUtil.shortToByte(crc16Hex2);
        int crc16 = BytesUtil.bytesToInt(crc16Hex2Bytes);
        message.setHexCrc16(BytesUtil.intToHexStr(crc16));
    }
    /**
     * æ ¹æ®ç”Ÿæˆçš„命令,进行调整
     *
     * @param message
     */
    public void build(Message message) {
        StringBuffer hexSb = new StringBuffer();
        hexSb.append(message.getBegin());
        hexSb.append(message.getSourceId());
        hexSb.append(message.getTargetId());
        hexSb.append(message.getSendId());
        hexSb.append(message.getGateway1());
        hexSb.append(message.getGateway2());
        hexSb.append(message.getMessageType());
        hexSb.append(message.getResult());
        hexSb.append(message.getCompanyId());
        hexSb.append(message.getHexCrc8());
        hexSb.append(BytesUtil.tran_LH(BytesUtil
                .getHex2LenStr(message.getBody().getLength())));
        hexSb.append(message.getBody().getContent());
        hexSb.append(message.getHexCrc16());
        hexSb.append(message.getEnd());
        message.setStrMsg(hexSb.toString());
        message.setByteMsg(BytesUtil.hexStrToBytes(message.getStrMsg()));
    }
}
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder1115.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.fzzy.protocol.zldz.cmd;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.protocol.zldz.data.Message;
import com.fzzy.protocol.zldz.data.MessageBody;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
/**
 * ç²®æƒ…信息命令
 *
 * @author Andy
 */
public class CommandBuilder1115 extends CommandBuilder {
    private final static CommandBuilder1115 instance = new CommandBuilder1115();
    private CommandBuilder1115() {
    }
    public static CommandBuilder1115 getInstance() {
        return instance;
    }
    public Message buildMessage(BaseReqData reqData, ApiCommonDevice commonDevice) {
        //request.setCompanyId("1");
        Message message = new Message();
        message.setBegin(ZldzServerUtil.MSG_START);
        // è°ƒæ•´Message头部信息
        buildHeader(message, reqData, commonDevice);
        //包头校验
        buildCrc8(message);
        // åˆ›å»ºæ¶ˆæ¯ä½“
        buildBody(message, reqData, commonDevice);
        // æ·»åŠ æ ¡éªŒ
        buildCrc16(message);
        message.setEnd(ZldzServerUtil.MSG_END);
        // ç”Ÿæˆæ•´ä½“命令信息和BYte信息
        build(message);
        return message;
    }
    public void buildHeader(Message message, BaseReqData reqData, ApiCommonDevice commonDevice) {
        GatewayDevice device = reqData.getDevice();
        String hexCompanyId = BytesUtil.getTargetId(commonDevice.getOrgId(), true);
        hexCompanyId = BytesUtil.tran_LH(hexCompanyId);
        message.setSourceId(hexCompanyId);
        message.setSendId(hexCompanyId);
        message.setCompanyId(hexCompanyId);
        message.setTargetId(BytesUtil.tran_LH(BytesUtil.getTargetId(device.getDeviceSn(), true)));
        message.setMessageType(BytesUtil.tran_LH(ZldzServerUtil.MSG_TYPE_1115));
    }
    public void buildBody(Message message, BaseReqData reqData, ApiCommonDevice commonDevice) {
        GatewayDevice device = reqData.getDevice();
        MessageBody body = new MessageBody();
        body.setLength(2);
        int start = device.getCableStart();
        int end = device.getCableEnd();
        body.setContent(BytesUtil.toHexString(start) + BytesUtil.toHexString(end));
        message.setBody(body);
    }
}
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder8815.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,41 @@
package com.fzzy.protocol.zldz.cmd;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.zldz.data.Message;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
/**
 * ç²®æƒ…信息命令
 *
 * @author Andy
 */
public class CommandBuilder8815 extends CommandBuilder {
    private final static CommandBuilder8815 instance = new CommandBuilder8815();
    private CommandBuilder8815() {
    }
    public static CommandBuilder8815 getInstance() {
        return instance;
    }
    public void buildHeader(Message message, BaseRequest request) {
        String hexCompanyId = BytesUtil.getTargetId(request.getCompanyId(), true);
        hexCompanyId = BytesUtil.tran_LH(hexCompanyId);
        message.setSourceId(hexCompanyId);
        message.setSendId(hexCompanyId);
        message.setCompanyId(hexCompanyId);
        message.setTargetId(BytesUtil.tran_LH(BytesUtil.getTargetId(request.getSerId(), true)));
        message.setMessageType(BytesUtil.tran_LH(ZldzServerUtil.MSG_TYPE_8815));
    }
}
src/main/java/com/fzzy/protocol/zldz/cmd/CommandBuilder8817.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,54 @@
package com.fzzy.protocol.zldz.cmd;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.zldz.data.Message;
import com.fzzy.protocol.zldz.data.MessageBody;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
/**
 * ç²®æƒ…信息命令
 *
 * @author Andy
 */
public class CommandBuilder8817 extends CommandBuilder {
    private final static CommandBuilder8817 instance = new CommandBuilder8817();
    private CommandBuilder8817() {
    }
    public static CommandBuilder8817 getInstance() {
        return instance;
    }
    public void buildHeader(Message message, BaseRequest request) {
        //request.setCompanyId("1");
        String hexCompanyId = BytesUtil.getTargetId(request.getCompanyId(),true);
        hexCompanyId = BytesUtil.tran_LH(hexCompanyId);
        message.setSourceId(hexCompanyId);
        message.setSendId(hexCompanyId);
        message.setCompanyId(hexCompanyId);
        message.setTargetId(BytesUtil.tran_LH(BytesUtil.getTargetId(request.getSerId(), true)));
        message.setMessageType(BytesUtil.tran_LH(ZldzServerUtil.MSG_TYPE_8817));
    }
    public void buildBody(Message message, BaseRequest request) {
        MessageBody body = new MessageBody();
        body.setContent(request.getBizType());
        body.setLength(1);
        message.setBody(body);
    }
}
src/main/java/com/fzzy/protocol/zldz/cmd/ReMessageBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,131 @@
package com.fzzy.protocol.zldz.cmd;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.ContextUtil;
import com.fzzy.protocol.zldz.data.ReMessage;
import com.fzzy.protocol.zldz.data.ReMessageBody;
import java.util.Date;
/**
 * æ ¹æ®æŽ¥æ”¶åˆ°çš„信息进行封装
 *
 * @author Andy
 */
public class ReMessageBuilder {
    private final static ReMessageBuilder instance = new ReMessageBuilder();
    private ReMessageBuilder() {
    }
    public static ReMessageBuilder getInstance() {
        return instance;
    }
    /**
     * ä½¿ç”¨ä¸­å‘现CRC16可能以EE结尾,NETTY误以为是结尾导致截取少了一个EE,当前方法必须从头向后截取,保证CRC16的位置准确
     *
     * @param bytes
     * @param device
     * @param strMsg
     * @return
     */
    public ReMessage buildMessage(byte[] bytes, ApiCommonDevice device, String strMsg) {
        ReMessage message = new ReMessage();
        message.setIp(device.getIp());
        message.setPort(device.getPort());
        message.setStrMsg(strMsg);
        message.setByteMsg(bytes);
        // æºID,分机唯一ID
        int start = 2, len = 2;
        String temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setSourceId(BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) + "");
        //分机所属组织编码
        String companyId = device.getOrgId();
        // ç›®æ ‡ID
        start = 4;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setTargetId(BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) + "");
        // å‘送ID
        start = 6;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setSendId(BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) + "");
        // è·¯ç”±ä¿¡æ¯ï¼Œä¸è§£æž
        // æ¶ˆæ¯ç±»åž‹
        start = 12;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setMessageType(BytesUtil.tran_LH(temp));
        // å¤„理结果
        start = 14;
        len = 1;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setResult(BytesUtil.hexToInt(temp));
        // ç»„织编码
        start = 15;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        if (null == companyId) {
            message.setCompanyId(BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) + "");
        } else {
            message.setCompanyId(companyId);
        }
        //包头校验
        start = 17;
        len = 1;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setHexCrc8(temp);
        // å‘½ä»¤ä½“-长度
        message.setBody(buildBody());
        start = 18;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        int bodyLen = BytesUtil.hexToInt(BytesUtil.tran_LH(temp));
        message.getBody().setLength(bodyLen);
        //命令体-内容
        start = 20;
        len = bodyLen;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.getBody().setContent(temp);
        // crc16验证
        start = 20 + bodyLen;
        len = 2;
        temp = strMsg.substring(start * 2, start * 2 + len * 2);
        message.setHexCrc16(temp);
        message.setReceiveDate(new Date());
        message.setBatchId(ContextUtil.getDefaultBatchId());
        return message;
    }
    /**
     * åˆ›å»ºBODY对象
     *
     * @param
     * @return
     */
    public ReMessageBody buildBody() {
        ReMessageBody body = new ReMessageBody();
        body.setLength(0);
        body.setContent("");
        return body;
    }
}
src/main/java/com/fzzy/protocol/zldz/data/Message.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.fzzy.protocol.zldz.data;
import lombok.Data;
/**
 * å­—符串值均采用十六进制,方便校验和开发
 */
@Data
public class Message {
    private String begin;
    private String sourceId;// æº ID
    private String targetId="FFFF";// ç›®æ ‡ID
    private String sendId;//发送者ID
    private String gateway1 = "0100";//路由1
    private String gateway2 = "0000";//路由2
    private String messageType;// æ¶ˆæ¯ç±»åž‹
    private String result ="00";// å¤„理结果
    private String companyId;// ç»„织编码
    private String hexCrc8;//crc8包头校验
    private MessageBody body;
    private String hexCrc16;//crc16校验
    private String end;
    private byte[] byteMsg;// å½“前命令的字节信息
    private String strMsg;// å½“前命令转换为字符串的信息
    @Override
    public String toString() {
        return "Message [sourceId=" + sourceId
                + ", targetId=" + targetId
                + ", messageType=" + messageType
                + ", result=" + result + ", companyId=" + companyId
                + ", hexCrc8=" + hexCrc8 + ", body=" + body + ", hexCrc16="
                + hexCrc16 + ", strMsg=" + strMsg + "]";
    }
}
src/main/java/com/fzzy/protocol/zldz/data/MessageBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.fzzy.protocol.zldz.data;
import lombok.Data;
@Data
public class MessageBody {
    //默认10进制长度
    private int length = 0;
    //消息体内容
    private String content = "";
}
src/main/java/com/fzzy/protocol/zldz/data/Metadata.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.fzzy.protocol.zldz.data;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface Metadata {
    String label() default "";
    int bytes() default 0;
    int startIndex() default 0;
}
src/main/java/com/fzzy/protocol/zldz/data/ReMessage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.fzzy.protocol.zldz.data;
import lombok.Data;
import java.util.Date;
/**
 * æ¶ˆæ¯å¤´å¯¹è±¡
 *
 * @author Andy
 *
 */
@Data
public class ReMessage {
    private String ip;
    private int port;
    private String begin;
    private String sourceId;// æº ID
    private String targetId;// ç›®æ ‡ID
    private String sendId;//发送者ID
    private String gateway1;//路由1
    private String gateway2;//路由2
    private String messageType;// æ¶ˆæ¯ç±»åž‹
    private int result;// å¤„理结果
    private String companyId;// ç»„织编码
    private String hexCrc8;//crc8包头校验
    private ReMessageBody body;
    private String hexCrc16;//crc16校验
    private String end;
    private byte[] byteMsg;// å½“前命令的字节信息
    private String strMsg;// å½“前命令转换为字符串的信息
    private String batchId;
    private Date receiveDate;
    // å¼‚常信息
    private String error;
    @Override
    public String toString() {
        return "ReMessage{" +
                "ip='" + ip + '\'' +
                ", port=" + port +
                ", sourceId='" + sourceId + '\'' +
                ", targetId='" + targetId + '\'' +
                ", sendId='" + sendId + '\'' +
                ", messageType='" + messageType + '\'' +
                ", result=" + result +
                ", companyId='" + companyId + '\'' +
                ", hexCrc8='" + hexCrc8 + '\'' +
                ", hexCrc16='" + hexCrc16 + '\'' +
                ", strMsg='" + strMsg + '\'' +
                '}';
    }
}
src/main/java/com/fzzy/protocol/zldz/data/ReMessageBody.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,18 @@
package com.fzzy.protocol.zldz.data;
import lombok.Data;
/**
 * æ¶ˆæ¯-消息体
 *
 * @author Andy
 *
 */
@Data
public class ReMessageBody {
    private int length;
    private String content;
}
src/main/java/com/fzzy/protocol/zldz/package-info.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
/**
 * æ­£æ¥ç”µå­-粮情协议解析
 */
package com.fzzy.protocol.zldz;
src/main/java/com/fzzy/protocol/zldz/server/HeartbeatProviderImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,25 @@
package com.fzzy.protocol.zldz.server;
import com.ld.io.api.HeartbeatProvider;
import com.ld.io.api.IoSession;
import lombok.extern.slf4j.Slf4j;
/**
 * å¿ƒè·³ç»´æŒï¼ŒéªŒè¯å½“前连接中的IP在服务器上配置的有没有,如果有则表示正常连接,如果没有则踢除连接。
 * <p>
 * å¦‚果有正常心跳,则发送正常心跳命令,如果没有则发送设备状态查询,
 */
@Slf4j
public class HeartbeatProviderImpl implements HeartbeatProvider {
    @Override
    public byte[] provide(IoSession session) {
        log.debug("========系统开始执行心跳=========={}---{}", session.getCompanyId(), session.getBusinessKey());
        return null;
    }
}
src/main/java/com/fzzy/protocol/zldz/server/MsgConsumer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,44 @@
package com.fzzy.protocol.zldz.server;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.protocol.bhzn.cmd.ReMessageBuilder;
import com.fzzy.protocol.bhzn.data.IoMessage;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerUtils;
import com.fzzy.protocol.zldz.analysis.AnalysisService;
import com.ld.io.api.IoMsgConsumer;
import com.ld.io.api.IoSession;
import lombok.extern.slf4j.Slf4j;
/**
 * æŽ¥æ”¶ç»ˆç«¯è¿”回回来的信息。
 *
 * @author Andy
 */
@Slf4j
public class MsgConsumer implements IoMsgConsumer {
    private AnalysisService analysis;
    @Override
    public void consume(IoSession session, byte[] bytes) {
        try {
            String hexStr = BytesUtil.bytesToString(bytes);
            log.debug("【" + session.getAddress() + "】主机------->>平台:报文:" + hexStr);
           // hexStr = hexStr.substring(ZldzServerUtil.MSG_START.length());
            if (null == analysis) {
                analysis = (AnalysisService) SpringUtil.getBean(AnalysisService.BEAN_ID);
            }
            analysis.analysis(session.getAddress(),session.getPort(), hexStr);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
src/main/java/com/fzzy/protocol/zldz/server/SessionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,59 @@
package com.fzzy.protocol.zldz.server;
import com.fzzy.api.Constant;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.gateway.service.GatewayDeviceService;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerUtils;
import com.ld.io.api.IoSession;
import com.ld.io.api.IoSessionListener;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class SessionListener implements IoSessionListener {
    private GatewayDeviceService gatewayDeviceService;
    /**
     * è®¾å¤‡åˆ›å»ºåœ¨çº¿ï¼Œéœ€è¦æ³¨æ„å½“前使用主机模式,主机上线默认所有相同SN配置的分机全部上线
     *
     * @param session
     */
    @Override
    public void onCreate(IoSession session) {
        log.info("++++新建连接++++-IP={},PORT={}", session.getAddress(), session.getPort());
        // æ·»åŠ è‡ªå®šä¹‰ä¸šåŠ¡ID
        session.setBusinessKey(BhznGrainV2ServerUtils.getServerKey(session.getAddress(), session.getPort()));
        //执行分机上线
        ApiCommonDevice commonDevice = Constant.updateCacheOnline(session.getAddress(), session.getPort());
        if (null == commonDevice.getSn()) {
            log.error("------设备上线,系统中未发现当前配置-------");
        }
    }
    /**
     * æ³¨æ„ï¼Œå½“前采用主机模式,主机离线所有相同SN配置的分机全部离线
     *
     * @param session
     */
    @Override
    public void onDestroy(IoSession session) {
        log.info("----连接断开-----IP={},PORT={}", session.getAddress(), session.getPort());
        //设置分机掉线
        ApiCommonDevice commonDevice = Constant.updateCacheOffline(session.getAddress(), session.getPort());
        if (null == commonDevice) return;
        if (null == gatewayDeviceService) {
            gatewayDeviceService = SpringUtil.getBean(GatewayDeviceService.class);
            gatewayDeviceService.OfflineByCommonDevice(commonDevice);
        }
    }
}
src/main/java/com/fzzy/protocol/zldz/server/ZldzServerEngine.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,85 @@
package com.fzzy.protocol.zldz.server;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.protocol.fzzy.server.ServerUtils;
import com.ld.io.api.*;
import com.ld.io.netty.NettyServer;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
 * é…ç½®ä¸»æœåŠ¡ä¿¡æ¯
 *
 */
@Slf4j
public class ZldzServerEngine {
    public static final int PORT = 19302;
    public static NettyServer ioServer = null;
    // é…ç½®æ¶ˆæ¯æŽ¥æ”¶ç±»
    private static MsgConsumer messageConsume = new MsgConsumer();
    // ç›‘听会话的创建与销毁
    private static SessionListener ioSessionListener = new SessionListener();
    // å¿ƒè·³æä¾› ï¼Œè¯¥æœåŠ¡ä¸éœ€è¦å¿ƒè·³ç»´æŒ
    private static HeartbeatProvider heartbeatProvider = new HeartbeatProviderImpl();
    public static void start() {
        start(PORT);
    }
    public static void start(int port) {
        // é…ç½®Server的配置
        IoServerOption ioServerOption = new IoServerOption(port);
        ioServerOption.setSplitDecoderType(SplitByteDecoderType.DELIMITER_SYMBOL);
        ioServerOption.setDelimiter(BytesUtil.hexStrToBytes(ZldzServerUtil.MSG_END));
        // é…ç½®å¿ƒè·³æ‰§è¡Œæ—¶é—´
        ioServerOption.setReaderIdleTime(60 * 60);
        ioServer = new NettyServer(ioServerOption, messageConsume, ioSessionListener, heartbeatProvider);
        ioServer.startup();
        log.info("* ========================");
        log.info("* ");
        log.info("* FZZY-ZLDZ纯粮情协议,端口号={}", port);
        log.info("* ");
        log.info("* ========================");
        System.out.println("* ========================");
        System.out.println("* ");
        System.out.println("* FZZY-ZLDZ纯粮情协议,端口号=" + port);
        System.out.println("* ");
        System.out.println("* ========================");
    }
    /**
     * å‘送信息
     *
     * @param ip
     * @param port
     * @param msg
     * @return
     */
    public static InvokeResult push(String ip, int port, byte[] msg) {
        IoSessionQuery sessionFactory = ioServer.getSessionQuery();
        List<IoSession> sessions = sessionFactory.getAllSession();
        IoSession session = null;
        for (IoSession ioSession : sessions) {
            if (ServerUtils.getServerKey(ip, port).equals(ioSession.getBusinessKey())) {
                session = ioSession;
                break;
            }
        }
        if (null == session) {
            return InvokeResult.CHANNEL_CLOSED;
        }
        return session.invoke(msg);
    }
}
src/main/java/com/fzzy/protocol/zldz/server/ZldzServerUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.fzzy.protocol.zldz.server;
public class ZldzServerUtil {
    public static final String MSG_START = "AAAA";
    public static final String MSG_END = "EEEE";
    //默认组织编号
    public static final String DEFAULT_COMPANY = "0000";
    public static final String MSG_TYPE_1115 = "1115";// åŽå°èŽ·å–ç²®æƒ…æ•°æ®è¯·æ±‚
    public static final String MSG_TYPE_8815 = "8815";// ç»ˆç«¯åº”答粮情数据请求
    public static final String MSG_TYPE_1116 = "1116";// é…ç½®è¯»å–分机参数
    public static final String MSG_TYPE_8816 = "8816";// é…ç½®è¯»å–分机参数应答
    public static final String MSG_TYPE_1117 = "1117";// ç»ˆç«¯å‘送粮情数据给后台
    public static final String MSG_TYPE_8817 = "8817";// åŽå°æ”¶åˆ°ç²®æƒ…数据应答
    public static final String MSG_TYPE_1122 = "1122";// åˆå§‹åŒ–电缆电缆
    public static final String MSG_TYPE_1123 = "1123";// ç”µç¼†æ±‡æ€»
    public static final String MSG_TYPE_1125 = "1125";// è¯»å–通道电缆
    public static final String MSG_TYPE_8825 = "8825";//读取通道电缆应答
    public static final String MSG_TYPE_1126 = "1126";// ä¿®æ”¹é€šé“电缆
    public static final String MSG_TYPE_8826 = "8826";// ä¿®æ”¹é€šé“电缆应答
    public static final String MSG_TYPE_1128 = "1128";// è¯»å–有线温湿度
    public static final String MSG_TYPE_8822 = "8822";// åº”答初始化电缆电缆
    public static final String MSG_TYPE_8823 = "8823";// åº”答电缆汇总结果
    public static final String MSG_TYPE_8828 = "8828";// è¯»å–有线温湿度应答
    public static final String MSG_TYPE_1129 = "1129";// ç»ˆç«¯å‘送通道电缆数据给后台
    public static final String MSG_TYPE_8829 = "8829";// åŽå°æ”¶åˆ°ç”µç¼†æ•°æ®åº”ç­”
    public static final String MSG_TYPE_112B = "112B";// é‡å¯åˆ†æœº
    public static final String MSG_TYPE_882B = "882B";// é‡å¯åˆ†æœºåº”ç­”
    public static String getServerKey(String ip, int port) {
        return ip + ":" + port;
    }
}
src/main/java/com/fzzy/protocol/zldz/service/ZldzGatewayGrainService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,147 @@
package com.fzzy.protocol.zldz.service;
import com.fzzy.api.Constant;
import com.fzzy.api.data.ApiCommonDevice;
import com.fzzy.api.data.GatewayDeviceProtocol;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.api.GatewaySyncGranService;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.io.request.BaseRequest;
import com.fzzy.protocol.ProtocolUtils;
import com.fzzy.protocol.bhzn.cmd.CommandBuild;
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerEngine;
import com.fzzy.protocol.zldz.cmd.CommandBuilder1115;
import com.fzzy.protocol.zldz.cmd.CommandBuilder8815;
import com.fzzy.protocol.zldz.cmd.CommandBuilder8817;
import com.fzzy.protocol.zldz.data.Message;
import com.fzzy.protocol.zldz.server.ZldzServerEngine;
import com.fzzy.protocol.zldz.server.ZldzServerUtil;
import com.ld.io.api.InvokeResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * æ­£æ¥ç”µå­ç²®æƒ…协议实现
 */
@Slf4j
@Component
public class ZldzGatewayGrainService implements GatewaySyncGranService {
    @Override
    public String getGrainProtocol() {
        return GatewayDeviceProtocol.GRAIN_FZZY_ZLDZ_WEB.getCode();
    }
    @Override
    public BaseResp syncGrain(BaseReqData reqData) {
        BaseResp resp = new BaseResp();
        GatewayDevice device = reqData.getDevice();
        //获取连接中的设备信息
        ApiCommonDevice apiCommonDevice = Constant.getCommonDeviceCache(device.getDeviceSn());
        if (null == apiCommonDevice) {
            resp.setCode(500);
            resp.setMsg("系统未获取到下行连接设备信息,无法执行");
            log.error("----------------系统未获取到下行连接设备信息,无法执行---------");
            return resp;
        }
        if (Constant.YN_N.equals(apiCommonDevice.getStatus())) {
            resp.setCode(500);
            resp.setMsg("下行设备不在线---无法执行----" + device.getDeviceName());
            log.error("下行设备不在线---无法执行----" + device.getDeviceName());
            return resp;
        }
        device.setIp(apiCommonDevice.getIp());
        device.setPort(apiCommonDevice.getPort());
        reqData.setDevice(device);
        try {
            //Step è¯·æ±‚信息放入内存
            ProtocolUtils.addSyncReq2Map(device.getDepotIdSys(), reqData);
            // ç”Ÿæˆç²®æƒ…信息
            Message message = CommandBuilder1115.getInstance().buildMessage(reqData, apiCommonDevice);
            // å‘送命令
            InvokeResult result = ZldzServerEngine.push(apiCommonDevice.getIp(), apiCommonDevice.getPort(), message.getByteMsg());
            log.error("平台------>>>>控制柜:发送粮情检测命令-{}", message);
            // å°è£…返回信息
            if (!InvokeResult.SUCCESS.getCode().equals(result.getCode())) {
                log.error("平台------>>>>控制柜:发送粮情检测命令-失败{}", result.getMessage());
                resp.setCode(500);
                resp.setMsg("平台------>>>>控制柜:发送粮情检测命令-失败:" + result.getMessage());
            }
        } catch (Exception e) {
            log.error("粮情检测异常:{}", e);
            resp.setCode(500);
            resp.setMsg("平台------>>>>控制柜:发送粮情检测命令:" + e.getMessage());
            return resp;
        }
        return resp;
    }
    /**
     * æœåŠ¡å™¨å›žå¤ç»ˆç«¯çš„æ”¶åˆ°è¯·æ±‚
     *
     * @param request
     */
    public BaseResp reply8815(BaseRequest request) {
        BaseResp resp = new BaseResp();
        // Step1 ç”Ÿæˆç²®æƒ…信息
        Message message = CommandBuilder8815.getInstance().buildMessage(
                request);
        log.debug("平台------>>>分机:" +request.getSerName() + "-粮情服务端回复命令=" + message.toString());
        // å‘送命令
        InvokeResult result = ZldzServerEngine.push(request.getIp(), request.getPort(), message.getByteMsg());
        // å°è£…返回信息
        if (!InvokeResult.SUCCESS.getCode().equals(result.getCode())) {
            log.error("平台------>>>>控制柜:发送粮情检测命令-失败{}", result.getMessage());
            resp.setCode(500);
            resp.setMsg("平台------>>>>控制柜:发送粮情检测命令-失败:" + result.getMessage());
        }
        return resp;
    }
    /**
     * å›žå¤å‘½ä»¤
     *
     * @param request
     * @param hexCurPacket å½“前包的hex
     */
    public BaseResp reply8817(BaseRequest request, String hexCurPacket) {
        BaseResp resp = new BaseResp();
        // Step1 ç”Ÿæˆç²®æƒ…信息,把信息放在request
        request.setBizType(hexCurPacket);
        Message message = CommandBuilder8817.getInstance().buildMessage(request);
        log.debug("平台------>>>分机:" +request.getSerName() + "-粮情服务端回复收到粮情包命令=" + message.toString());
        // å‘送命令
        InvokeResult result = ZldzServerEngine.push(request.getIp(), request.getPort(),
                message.getByteMsg());
        // å°è£…返回信息
        if (!InvokeResult.SUCCESS.getCode().equals(result.getCode())) {
            log.error("平台------>>>>控制柜:发送粮情检测命令-失败{}", result.getMessage());
            resp.setCode(500);
            resp.setMsg("平台------>>>>控制柜:发送粮情检测命令-失败:" + result.getMessage());
        }
        return resp;
    }
}
src/main/java/com/fzzy/protocol/zldz/util/CRC16.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,129 @@
package com.fzzy.protocol.zldz.util;
/***
 *
 * @author Andy
 *
 */
public class CRC16 {
    static byte[] crc16_tab_h = { (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1, (byte) 0x81, (byte) 0x40, (byte) 0x01, (byte) 0xC0,
            (byte) 0x80, (byte) 0x41, (byte) 0x01, (byte) 0xC0, (byte) 0x80, (byte) 0x41, (byte) 0x00, (byte) 0xC1,
            (byte) 0x81, (byte) 0x40 };
    static byte[] crc16_tab_l = { (byte) 0x00, (byte) 0xC0, (byte) 0xC1, (byte) 0x01, (byte) 0xC3, (byte) 0x03,
            (byte) 0x02, (byte) 0xC2, (byte) 0xC6, (byte) 0x06, (byte) 0x07, (byte) 0xC7, (byte) 0x05, (byte) 0xC5,
            (byte) 0xC4, (byte) 0x04, (byte) 0xCC, (byte) 0x0C, (byte) 0x0D, (byte) 0xCD, (byte) 0x0F, (byte) 0xCF,
            (byte) 0xCE, (byte) 0x0E, (byte) 0x0A, (byte) 0xCA, (byte) 0xCB, (byte) 0x0B, (byte) 0xC9, (byte) 0x09,
            (byte) 0x08, (byte) 0xC8, (byte) 0xD8, (byte) 0x18, (byte) 0x19, (byte) 0xD9, (byte) 0x1B, (byte) 0xDB,
            (byte) 0xDA, (byte) 0x1A, (byte) 0x1E, (byte) 0xDE, (byte) 0xDF, (byte) 0x1F, (byte) 0xDD, (byte) 0x1D,
            (byte) 0x1C, (byte) 0xDC, (byte) 0x14, (byte) 0xD4, (byte) 0xD5, (byte) 0x15, (byte) 0xD7, (byte) 0x17,
            (byte) 0x16, (byte) 0xD6, (byte) 0xD2, (byte) 0x12, (byte) 0x13, (byte) 0xD3, (byte) 0x11, (byte) 0xD1,
            (byte) 0xD0, (byte) 0x10, (byte) 0xF0, (byte) 0x30, (byte) 0x31, (byte) 0xF1, (byte) 0x33, (byte) 0xF3,
            (byte) 0xF2, (byte) 0x32, (byte) 0x36, (byte) 0xF6, (byte) 0xF7, (byte) 0x37, (byte) 0xF5, (byte) 0x35,
            (byte) 0x34, (byte) 0xF4, (byte) 0x3C, (byte) 0xFC, (byte) 0xFD, (byte) 0x3D, (byte) 0xFF, (byte) 0x3F,
            (byte) 0x3E, (byte) 0xFE, (byte) 0xFA, (byte) 0x3A, (byte) 0x3B, (byte) 0xFB, (byte) 0x39, (byte) 0xF9,
            (byte) 0xF8, (byte) 0x38, (byte) 0x28, (byte) 0xE8, (byte) 0xE9, (byte) 0x29, (byte) 0xEB, (byte) 0x2B,
            (byte) 0x2A, (byte) 0xEA, (byte) 0xEE, (byte) 0x2E, (byte) 0x2F, (byte) 0xEF, (byte) 0x2D, (byte) 0xED,
            (byte) 0xEC, (byte) 0x2C, (byte) 0xE4, (byte) 0x24, (byte) 0x25, (byte) 0xE5, (byte) 0x27, (byte) 0xE7,
            (byte) 0xE6, (byte) 0x26, (byte) 0x22, (byte) 0xE2, (byte) 0xE3, (byte) 0x23, (byte) 0xE1, (byte) 0x21,
            (byte) 0x20, (byte) 0xE0, (byte) 0xA0, (byte) 0x60, (byte) 0x61, (byte) 0xA1, (byte) 0x63, (byte) 0xA3,
            (byte) 0xA2, (byte) 0x62, (byte) 0x66, (byte) 0xA6, (byte) 0xA7, (byte) 0x67, (byte) 0xA5, (byte) 0x65,
            (byte) 0x64, (byte) 0xA4, (byte) 0x6C, (byte) 0xAC, (byte) 0xAD, (byte) 0x6D, (byte) 0xAF, (byte) 0x6F,
            (byte) 0x6E, (byte) 0xAE, (byte) 0xAA, (byte) 0x6A, (byte) 0x6B, (byte) 0xAB, (byte) 0x69, (byte) 0xA9,
            (byte) 0xA8, (byte) 0x68, (byte) 0x78, (byte) 0xB8, (byte) 0xB9, (byte) 0x79, (byte) 0xBB, (byte) 0x7B,
            (byte) 0x7A, (byte) 0xBA, (byte) 0xBE, (byte) 0x7E, (byte) 0x7F, (byte) 0xBF, (byte) 0x7D, (byte) 0xBD,
            (byte) 0xBC, (byte) 0x7C, (byte) 0xB4, (byte) 0x74, (byte) 0x75, (byte) 0xB5, (byte) 0x77, (byte) 0xB7,
            (byte) 0xB6, (byte) 0x76, (byte) 0x72, (byte) 0xB2, (byte) 0xB3, (byte) 0x73, (byte) 0xB1, (byte) 0x71,
            (byte) 0x70, (byte) 0xB0, (byte) 0x50, (byte) 0x90, (byte) 0x91, (byte) 0x51, (byte) 0x93, (byte) 0x53,
            (byte) 0x52, (byte) 0x92, (byte) 0x96, (byte) 0x56, (byte) 0x57, (byte) 0x97, (byte) 0x55, (byte) 0x95,
            (byte) 0x94, (byte) 0x54, (byte) 0x9C, (byte) 0x5C, (byte) 0x5D, (byte) 0x9D, (byte) 0x5F, (byte) 0x9F,
            (byte) 0x9E, (byte) 0x5E, (byte) 0x5A, (byte) 0x9A, (byte) 0x9B, (byte) 0x5B, (byte) 0x99, (byte) 0x59,
            (byte) 0x58, (byte) 0x98, (byte) 0x88, (byte) 0x48, (byte) 0x49, (byte) 0x89, (byte) 0x4B, (byte) 0x8B,
            (byte) 0x8A, (byte) 0x4A, (byte) 0x4E, (byte) 0x8E, (byte) 0x8F, (byte) 0x4F, (byte) 0x8D, (byte) 0x4D,
            (byte) 0x4C, (byte) 0x8C, (byte) 0x44, (byte) 0x84, (byte) 0x85, (byte) 0x45, (byte) 0x87, (byte) 0x47,
            (byte) 0x46, (byte) 0x86, (byte) 0x82, (byte) 0x42, (byte) 0x43, (byte) 0x83, (byte) 0x41, (byte) 0x81,
            (byte) 0x80, (byte) 0x40 };
    /**
     * è®¡ç®—CRC16校验
     *
     * @param data
     *            éœ€è¦è®¡ç®—的数组
     * @return CRC16校验值
     */
    public static int calcCrc16(byte[] data) {
        return calcCrc16(data, 0, data.length);
    }
    /**
     * è®¡ç®—CRC16校验
     *
     * @param data
     *            éœ€è¦è®¡ç®—的数组
     * @param offset
     *            èµ·å§‹ä½ç½®
     * @param len
     *            é•¿åº¦
     * @return CRC16校验值
     */
    public static int calcCrc16(byte[] data, int offset, int len) {
        return calcCrc16(data, offset, len, 0xffff);
    }
    /**
     * è®¡ç®—CRC16校验
     *
     * @param data
     *            éœ€è¦è®¡ç®—的数组
     * @param offset
     *            èµ·å§‹ä½ç½®
     * @param len
     *            é•¿åº¦
     * @param preval
     *            ä¹‹å‰çš„æ ¡éªŒå€¼
     * @return CRC16校验值
     */
    public static int calcCrc16(byte[] data, int offset, int len, int preval) {
        int ucCRCHi = (preval & 0xff00) >> 8;
        int ucCRCLo = preval & 0x00ff;
        int iIndex;
        for (int i = 0; i < len; ++i) {
            iIndex = (ucCRCLo ^ data[offset + i]) & 0x00ff;
            ucCRCLo = ucCRCHi ^ crc16_tab_h[iIndex];
            ucCRCHi = crc16_tab_l[iIndex];
        }
        return ((ucCRCHi & 0x00ff) << 8) | (ucCRCLo & 0x00ff) & 0xffff;
    }
}
src/main/java/com/fzzy/protocol/zldz/util/CRC8.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
package com.fzzy.protocol.zldz.util;
/**
 *计算CRC8校验值
 */
public class CRC8 {
    static short[] gCrc16Table = { (short) 0x0000, (short) 0x1021, (short) 0x2042, (short) 0x3063, (short) 0x4084,
            (short) 0x50a5, (short) 0x60c6, (short) 0x70e7, (short) 0xd94c, (short) 0xc96d, (short) 0xf90e,
            (short) 0xe92f, (short) 0x99c8, (short) 0x89e9, (short) 0xb98a, (short) 0xa9ab, (short) 0x5844,
            (short) 0x4865, (short) 0x7806, (short) 0x6827, (short) 0x18c0, (short) 0x08e1, (short) 0x3882,
            (short) 0x28a3, (short) 0xcb7d, (short) 0xdb5c, (short) 0xeb3f, (short) 0xfb1e, (short) 0x8bf9,
            (short) 0x9bd8, (short) 0xabbb, (short) 0xbb9a, (short) 0x4a75, (short) 0x5a54, (short) 0x6a37,
            (short) 0x7a16, (short) 0x0af1, (short) 0x1ad0, (short) 0x2ab3, (short) 0x3a92, (short) 0xfd2e,
            (short) 0xed0f, (short) 0xdd6c, (short) 0xcd4d, (short) 0xbdaa, (short) 0xad8b, (short) 0x9de8,
            (short) 0x8dc9, (short) 0xc9cc, (short) 0xd9ed, (short) 0xe98e, (short) 0xf9af, (short) 0x8948,
            (short) 0x9969, (short) 0xa90a, (short) 0xb92b, (short) 0x5af5, (short) 0x4ad4, (short) 0x7ab7,
            (short) 0x6a96, (short) 0x1a71, (short) 0x0a50, (short) 0x3a33, (short) 0x2a12, (short) 0xdbfd,
            (short) 0xcbdc, (short) 0xfbbf, (short) 0xeb9e, (short) 0x9b79, (short) 0x8b58, (short) 0xbb3b,
            (short) 0xab1a, (short) 0x6ca6, (short) 0x7c87, (short) 0x4ce4, (short) 0x5cc5, (short) 0x2c22,
            (short) 0x3c03, (short) 0x0c60, (short) 0x1c41, (short) 0x8108, (short) 0x9129, (short) 0xa14a,
            (short) 0xb16b, (short) 0xc18c, (short) 0xd1ad, (short) 0xe1ce, (short) 0xf1ef, (short) 0x1231,
            (short) 0x0210, (short) 0x3273, (short) 0x2252, (short) 0x52b5, (short) 0x4294, (short) 0x72f7,
            (short) 0x62d6, (short) 0x9339, (short) 0x8318, (short) 0xb37b, (short) 0xa35a, (short) 0xd3bd,
            (short) 0xc39c, (short) 0xf3ff, (short) 0xe3de, (short) 0x2462, (short) 0x3443, (short) 0x0420,
            (short) 0x1401, (short) 0x64e6, (short) 0x74c7, (short) 0x44a4, (short) 0x5485, (short) 0xa56a,
            (short) 0xb54b, (short) 0x8528, (short) 0x9509, (short) 0xe5ee, (short) 0xf5cf, (short) 0xc5ac,
            (short) 0xd58d, (short) 0x3653, (short) 0x2672, (short) 0x1611, (short) 0x0630, (short) 0x76d7,
            (short) 0x66f6, (short) 0x5695, (short) 0x46b4, (short) 0xb75b, (short) 0xa77a, (short) 0x9719,
            (short) 0x8738, (short) 0xf7df, (short) 0xe7fe, (short) 0xd79d, (short) 0xc7bc, (short) 0x48c4,
            (short) 0x58e5, (short) 0x6886, (short) 0x78a7, (short) 0x0840, (short) 0x1861, (short) 0x2802,
            (short) 0x3823, (short) 0x83b9, (short) 0x9398, (short) 0xa3fb, (short) 0xb3da, (short) 0xc33d,
            (short) 0xd31c, (short) 0xe37f, (short) 0xf35e, (short) 0x02b1, (short) 0x1290, (short) 0x22f3,
            (short) 0x32d2, (short) 0x4235, (short) 0x5214, (short) 0x6277, (short) 0x7256, (short) 0xb5ea,
            (short) 0xa5cb, (short) 0x95a8, (short) 0x8589, (short) 0xf56e, (short) 0xe54f, (short) 0xd52c,
            (short) 0xc50d, (short) 0x34e2, (short) 0x24c3, (short) 0x14a0, (short) 0x0481, (short) 0x7466,
            (short) 0x6447, (short) 0x5424, (short) 0x4405, (short) 0xa7db, (short) 0xb7fa, (short) 0x8799,
            (short) 0x97b8, (short) 0xe75f, (short) 0xf77e, (short) 0xc71d, (short) 0xd73c, (short) 0x26d3,
            (short) 0x36f2, (short) 0x0691, (short) 0x16b0, (short) 0x6657, (short) 0x7676, (short) 0x4615,
            (short) 0x5634, (short) 0xedae, (short) 0xfd8f, (short) 0xcdec, (short) 0xddcd, (short) 0xad2a,
            (short) 0xbd0b, (short) 0x8d68, (short) 0x9d49, (short) 0x7e97, (short) 0x6eb6, (short) 0x5ed5,
            (short) 0x4ef4, (short) 0x3e13, (short) 0x2e32, (short) 0x1e51, (short) 0x0e70, (short) 0xff9f,
            (short) 0xefbe, (short) 0xdfdd, (short) 0xcffc, (short) 0xbf1b, (short) 0xaf3a, (short) 0x9f59,
            (short) 0x8f78, (short) 0x9188, (short) 0x81a9, (short) 0xb1ca, (short) 0xa1eb, (short) 0xd10c,
            (short) 0xc12d, (short) 0xf14e, (short) 0xe16f, (short) 0x1080, (short) 0x00a1, (short) 0x30c2,
            (short) 0x20e3, (short) 0x5004, (short) 0x4025, (short) 0x7046, (short) 0x6067, (short) 0x7c26,
            (short) 0x6c07, (short) 0x5c64, (short) 0x4c45, (short) 0x3ca2, (short) 0x2c83, (short) 0x1ce0,
            (short) 0x0cc1, (short) 0xef1f, (short) 0xff3e, (short) 0xcf5d, (short) 0xdf7c, (short) 0xaf9b,
            (short) 0xbfba, (short) 0x8fd9, (short) 0x9ff8, (short) 0x6e17, (short) 0x7e36, (short) 0x4e55,
            (short) 0x5e74, (short) 0x2e93, (short) 0x3eb2, (short) 0x0ed1, (short) 0x1ef0 };
    static short[] crc8_tab = { (short) 0x00, (short) 0x07, (short) 0x0E, (short) 0x09, (short) 0x1C, (short) 0x1B,
            (short) 0x12, (short) 0x15, (short) 0x38, (short) 0x3F, (short) 0x36, (short) 0x31, (short) 0x24,
            (short) 0x23, (short) 0x2A, (short) 0x2D, (short) 0x70, (short) 0x77, (short) 0x7E, (short) 0x79,
            (short) 0x6C, (short) 0x6B, (short) 0x62, (short) 0x65, (short) 0x48, (short) 0x4F, (short) 0x46,
            (short) 0x41, (short) 0x54, (short) 0x53, (short) 0x5A, (short) 0x5D, (short) 0xE0, (short) 0xE7,
            (short) 0xEE, (short) 0xE9, (short) 0xFC, (short) 0xFB, (short) 0xF2, (short) 0xF5, (short) 0xD8,
            (short) 0xDF, (short) 0xD6, (short) 0xD1, (short) 0xC4, (short) 0xC3, (short) 0xCA, (short) 0xCD,
            (short) 0x90, (short) 0x97, (short) 0x9E, (short) 0x99, (short) 0x8C, (short) 0x8B, (short) 0x82,
            (short) 0x85, (short) 0xA8, (short) 0xAF, (short) 0xA6, (short) 0xA1, (short) 0xB4, (short) 0xB3,
            (short) 0xBA, (short) 0xBD, (short) 0xC7, (short) 0xC0, (short) 0xC9, (short) 0xCE, (short) 0xDB,
            (short) 0xDC, (short) 0xD5, (short) 0xD2, (short) 0xFF, (short) 0xF8, (short) 0xF1, (short) 0xF6,
            (short) 0xE3, (short) 0xE4, (short) 0xED, (short) 0xEA, (short) 0xB7, (short) 0xB0, (short) 0xB9,
            (short) 0xBE, (short) 0xAB, (short) 0xAC, (short) 0xA5, (short) 0xA2, (short) 0x8F, (short) 0x88,
            (short) 0x81, (short) 0x86, (short) 0x93, (short) 0x94, (short) 0x9D, (short) 0x9A, (short) 0x27,
            (short) 0x20, (short) 0x29, (short) 0x2E, (short) 0x3B, (short) 0x3C, (short) 0x35, (short) 0x32,
            (short) 0x1F, (short) 0x18, (short) 0x11, (short) 0x16, (short) 0x03, (short) 0x04, (short) 0x0D,
            (short) 0x0A, (short) 0x57, (short) 0x50, (short) 0x59, (short) 0x5E, (short) 0x4B, (short) 0x4C,
            (short) 0x45, (short) 0x42, (short) 0x6F, (short) 0x68, (short) 0x61, (short) 0x66, (short) 0x73,
            (short) 0x74, (short) 0x7D, (short) 0x7A, (short) 0x89, (short) 0x8E, (short) 0x87, (short) 0x80,
            (short) 0x95, (short) 0x92, (short) 0x9B, (short) 0x9C, (short) 0xB1, (short) 0xB6, (short) 0xBF,
            (short) 0xB8, (short) 0xAD, (short) 0xAA, (short) 0xA3, (short) 0xA4, (short) 0xF9, (short) 0xFE,
            (short) 0xF7, (short) 0xF0, (short) 0xE5, (short) 0xE2, (short) 0xEB, (short) 0xEC, (short) 0xC1,
            (short) 0xC6, (short) 0xCF, (short) 0xC8, (short) 0xDD, (short) 0xDA, (short) 0xD3, (short) 0xD4,
            (short) 0x69, (short) 0x6E, (short) 0x67, (short) 0x60, (short) 0x75, (short) 0x72, (short) 0x7B,
            (short) 0x7C, (short) 0x51, (short) 0x56, (short) 0x5F, (short) 0x58, (short) 0x4D, (short) 0x4A,
            (short) 0x43, (short) 0x44, (short) 0x19, (short) 0x1E, (short) 0x17, (short) 0x10, (short) 0x05,
            (short) 0x02, (short) 0x0B, (short) 0x0C, (short) 0x21, (short) 0x26, (short) 0x2F, (short) 0x28,
            (short) 0x3D, (short) 0x3A, (short) 0x33, (short) 0x34, (short) 0x4E, (short) 0x49, (short) 0x40,
            (short) 0x47, (short) 0x52, (short) 0x55, (short) 0x5C, (short) 0x5B, (short) 0x76, (short) 0x71,
            (short) 0x78, (short) 0x7F, (short) 0x6A, (short) 0x6D, (short) 0x64, (short) 0x63, (short) 0x3E,
            (short) 0x39, (short) 0x30, (short) 0x37, (short) 0x22, (short) 0x25, (short) 0x2C, (short) 0x2B,
            (short) 0x06, (short) 0x01, (short) 0x08, (short) 0x0F, (short) 0x1A, (short) 0x1D, (short) 0x14,
            (short) 0x13, (short) 0xAE, (short) 0xA9, (short) 0xA0, (short) 0xA7, (short) 0xB2, (short) 0xB5,
            (short) 0xBC, (short) 0xBB, (short) 0x96, (short) 0x91, (short) 0x98, (short) 0x9F, (short) 0x8A,
            (short) 0x8D, (short) 0x84, (short) 0x83, (short) 0xDE, (short) 0xD9, (short) 0xD0, (short) 0xD7,
            (short) 0xC2, (short) 0xC5, (short) 0xCC, (short) 0xCB, (short) 0xE6, (short) 0xE1, (short) 0xE8,
            (short) 0xEF, (short) 0xFA, (short) 0xFD, (short) 0xF4, (short) 0xF3 };
    static byte[] crc8_tab2 = { (byte) 0x00, (byte) 0x07, (byte) 0x0E, (byte) 0x09, (byte) 0x1C, (byte) 0x1B,
            (byte) 0x12, (byte) 0x15, (byte) 0x38, (byte) 0x3F, (byte) 0x36, (byte) 0x31, (byte) 0x24, (byte) 0x23,
            (byte) 0x2A, (byte) 0x2D, (byte) 0x70, (byte) 0x77, (byte) 0x7E, (byte) 0x79, (byte) 0x6C, (byte) 0x6B,
            (byte) 0x62, (byte) 0x65, (byte) 0x48, (byte) 0x4F, (byte) 0x46, (byte) 0x41, (byte) 0x54, (byte) 0x53,
            (byte) 0x5A, (byte) 0x5D, (byte) 0xE0, (byte) 0xE7, (byte) 0xEE, (byte) 0xE9, (byte) 0xFC, (byte) 0xFB,
            (byte) 0xF2, (byte) 0xF5, (byte) 0xD8, (byte) 0xDF, (byte) 0xD6, (byte) 0xD1, (byte) 0xC4, (byte) 0xC3,
            (byte) 0xCA, (byte) 0xCD, (byte) 0x90, (byte) 0x97, (byte) 0x9E, (byte) 0x99, (byte) 0x8C, (byte) 0x8B,
            (byte) 0x82, (byte) 0x85, (byte) 0xA8, (byte) 0xAF, (byte) 0xA6, (byte) 0xA1, (byte) 0xB4, (byte) 0xB3,
            (byte) 0xBA, (byte) 0xBD, (byte) 0xC7, (byte) 0xC0, (byte) 0xC9, (byte) 0xCE, (byte) 0xDB, (byte) 0xDC,
            (byte) 0xD5, (byte) 0xD2, (byte) 0xFF, (byte) 0xF8, (byte) 0xF1, (byte) 0xF6, (byte) 0xE3, (byte) 0xE4,
            (byte) 0xED, (byte) 0xEA, (byte) 0xB7, (byte) 0xB0, (byte) 0xB9, (byte) 0xBE, (byte) 0xAB, (byte) 0xAC,
            (byte) 0xA5, (byte) 0xA2, (byte) 0x8F, (byte) 0x88, (byte) 0x81, (byte) 0x86, (byte) 0x93, (byte) 0x94,
            (byte) 0x9D, (byte) 0x9A, (byte) 0x27, (byte) 0x20, (byte) 0x29, (byte) 0x2E, (byte) 0x3B, (byte) 0x3C,
            (byte) 0x35, (byte) 0x32, (byte) 0x1F, (byte) 0x18, (byte) 0x11, (byte) 0x16, (byte) 0x03, (byte) 0x04,
            (byte) 0x0D, (byte) 0x0A, (byte) 0x57, (byte) 0x50, (byte) 0x59, (byte) 0x5E, (byte) 0x4B, (byte) 0x4C,
            (byte) 0x45, (byte) 0x42, (byte) 0x6F, (byte) 0x68, (byte) 0x61, (byte) 0x66, (byte) 0x73, (byte) 0x74,
            (byte) 0x7D, (byte) 0x7A, (byte) 0x89, (byte) 0x8E, (byte) 0x87, (byte) 0x80, (byte) 0x95, (byte) 0x92,
            (byte) 0x9B, (byte) 0x9C, (byte) 0xB1, (byte) 0xB6, (byte) 0xBF, (byte) 0xB8, (byte) 0xAD, (byte) 0xAA,
            (byte) 0xA3, (byte) 0xA4, (byte) 0xF9, (byte) 0xFE, (byte) 0xF7, (byte) 0xF0, (byte) 0xE5, (byte) 0xE2,
            (byte) 0xEB, (byte) 0xEC, (byte) 0xC1, (byte) 0xC6, (byte) 0xCF, (byte) 0xC8, (byte) 0xDD, (byte) 0xDA,
            (byte) 0xD3, (byte) 0xD4, (byte) 0x69, (byte) 0x6E, (byte) 0x67, (byte) 0x60, (byte) 0x75, (byte) 0x72,
            (byte) 0x7B, (byte) 0x7C, (byte) 0x51, (byte) 0x56, (byte) 0x5F, (byte) 0x58, (byte) 0x4D, (byte) 0x4A,
            (byte) 0x43, (byte) 0x44, (byte) 0x19, (byte) 0x1E, (byte) 0x17, (byte) 0x10, (byte) 0x05, (byte) 0x02,
            (byte) 0x0B, (byte) 0x0C, (byte) 0x21, (byte) 0x26, (byte) 0x2F, (byte) 0x28, (byte) 0x3D, (byte) 0x3A,
            (byte) 0x33, (byte) 0x34, (byte) 0x4E, (byte) 0x49, (byte) 0x40, (byte) 0x47, (byte) 0x52, (byte) 0x55,
            (byte) 0x5C, (byte) 0x5B, (byte) 0x76, (byte) 0x71, (byte) 0x78, (byte) 0x7F, (byte) 0x6A, (byte) 0x6D,
            (byte) 0x64, (byte) 0x63, (byte) 0x3E, (byte) 0x39, (byte) 0x30, (byte) 0x37, (byte) 0x22, (byte) 0x25,
            (byte) 0x2C, (byte) 0x2B, (byte) 0x06, (byte) 0x01, (byte) 0x08, (byte) 0x0F, (byte) 0x1A, (byte) 0x1D,
            (byte) 0x14, (byte) 0x13, (byte) 0xAE, (byte) 0xA9, (byte) 0xA0, (byte) 0xA7, (byte) 0xB2, (byte) 0xB5,
            (byte) 0xBC, (byte) 0xBB, (byte) 0x96, (byte) 0x91, (byte) 0x98, (byte) 0x9F, (byte) 0x8A, (byte) 0x8D,
            (byte) 0x84, (byte) 0x83, (byte) 0xDE, (byte) 0xD9, (byte) 0xD0, (byte) 0xD7, (byte) 0xC2, (byte) 0xC5,
            (byte) 0xCC, (byte) 0xCB, (byte) 0xE6, (byte) 0xE1, (byte) 0xE8, (byte) 0xEF, (byte) 0xFA, (byte) 0xFD,
            (byte) 0xF4, (byte) 0xF3 };
    /**
     * è®¡ç®—数组的CRC8校验值
     *
     * @param data
     *            éœ€è¦è®¡ç®—的数组
     * @return CRC8校验值
     */
    public static byte calcCrc8(byte[] data) {
        return calcCrc8(data, (short) 2, (short) (data.length - 2), (byte) 0);
    }
    /**
     * è®¡ç®—CRC8校验值
     *
     * @param data
     *            æ•°æ®
     * @param offset
     *            èµ·å§‹ä½ç½®
     * @param len
     *            é•¿åº¦
     * @return æ ¡éªŒå€¼
     */
    public static byte calcCrc8(byte[] data, short offset, short len) {
        return calcCrc8(data, offset, len, (byte) 0);
    }
    public static byte calcCrc8(byte[] ucPtr, short offset, short ucLen, byte preval) {
        short ucIndex; // CRC8校验表格索引
        short ucCRC8 = 0; // CRC8字节初始化
        short i = 0;
        // è¿›è¡ŒCRC8位校验
        while ((ucLen--) > 0) {
            short indexI = (short) (i + offset);
            short data = ucPtr[indexI];
            if (data < 0) {
                int sd = Byte.toUnsignedInt(ucPtr[indexI]);
                data = (short) sd;
            }
            ucIndex = (short) (ucCRC8 ^ data);
            ucCRC8 = crc8_tab[(short) ucIndex];
            i++;
        }
        // è¿”回CRC8校验数据
        return (byte) (~ucCRC8);
    }
    public static short crc16Byte(short crc, byte data) {
        return (short) ((crc << 8) ^ gCrc16Table[((crc >> 8) ^ data) & 0xff]);
    }
    public static short calculateCrc16(byte[] buf, short offset, short length) {
        short crc = 0;
        short i = 0;
        while ((length--) > 0) {
            crc = crc16Byte(crc, buf[offset + (i++)]);
        }
        return crc;
    }
}