vince
2024-05-20 75bdadc0c4e468217b93142d965cd92ee52838ec
粮情协议优化
已修改12个文件
已添加16个文件
1657 ■■■■■ 文件已修改
src/main/java/com/fzzy/api/data/GatewayDeviceProtocol.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/gateway/GatewayTimerScheduled.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/ProtocolRunner.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/analysis/AnalysisService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v0/analysis/AnalysisService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v0/server/BhznGrainV0ServerEngine.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v0/server/BhznGrainV0ServerUtils.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v0/不带开头结尾的版本 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/analysis/AnalysisService.java 577 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/cmd/CommandBuild.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/cmd/ReMessageBuilder.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/data/Content.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/data/IoMessage.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/package-info.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01HeartbeatImpl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01MessageConsumer.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01ServerEngine.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01ServerUtils.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01SessionListener.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/service/Bhzn01GatewayGrainService.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/bhzn/v01/带开头结尾的版本 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/sjLpr/GatewayLprApi.java 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/sjLpr/熵基车牌识别接口 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/wujia/analysis/AnalysisService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/xsyg/analysis/AnalysisService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/youxian0/analysis/AnalysisService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/youxian0/service/Youxian0GatewayGrainService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisGrain.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/fzzy/api/data/GatewayDeviceProtocol.java
@@ -14,7 +14,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", "粮情-FZZY-BHZN网口协议"),
    GRAIN_BHZN_V0_WEB("GRAIN_BHZN_V0_WEB", "粮情-BHZN-V0网口协议"),
    GRAIN_BHZN_V0_WEB("GRAIN_BHZN_V0_WEB", "粮情-BHZN-V0无线协议"),
    GRAIN_BHZN_V01_WEB("GRAIN_BHZN_V01_WEB", "粮情-BHZN-V01无线协议带开头结尾符号"),
    GRAIN_FZZY_ZLDZ_WEB("GRAIN_FZZY_ZLDZ_WEB", "粮情-FZZY-ZLDZ网口协议"),
    GRAIN_YOUXIAN0_2023("GRAIN_YOUXIAN0_2023", "粮情-游仙主库协议"),
    GRAIN_YOUXIAN1_2023("GRAIN_YOUXIAN1_2023", "粮情-游仙分库协议"),
@@ -36,6 +37,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_BHZN_V0_WEB.getCode(), GRAIN_BHZN_V0_WEB.getName()));
        list.add(new ApiTrigger(GRAIN_BHZN_V01_WEB.getCode(), GRAIN_BHZN_V01_WEB.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(GRAIN_YOUXIAN0_2023.getCode(), GRAIN_YOUXIAN0_2023.getName()));
src/main/java/com/fzzy/gateway/GatewayTimerScheduled.java
@@ -105,8 +105,10 @@
    /**
     * <p>
     * ç²®æƒ…每天8点采集粮情
     *
     */
    @Scheduled(cron = "0 32 7 ? * *")
//    @Scheduled(cron = "0 32 11 ? * *")
    @Scheduled(cron = "0 32 11 ? * 2,5 *")
    public void scheduledGrain2() {
        //获取设备配置,只针对粮情设备进行执行
        log.info("定时粮情采集kafka推送");
@@ -132,6 +134,7 @@
                GatewaySyncGranService syncGrainService = gatewayRemoteManager.getSyncGrainService(device.getSyncProtocol());
                 resp = syncGrainService.syncGrain(reqData);
                log.info("命令发送结果:"+resp.toString());
                Thread.sleep(30000);
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }
src/main/java/com/fzzy/protocol/ProtocolRunner.java
@@ -2,6 +2,7 @@
import com.fzzy.protocol.bhzn.server.BhznGrainV2ServerEngine;
import com.fzzy.protocol.bhzn.v0.server.BhznGrainV0ServerEngine;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerEngine;
import com.fzzy.protocol.fzzy.server.FzzyServerEngine;
import com.fzzy.protocol.weightyh.YhScaleServerEngine;
import com.fzzy.protocol.zldz.server.ZldzServerEngine;
@@ -36,7 +37,9 @@
        //邦海智能纯网口设备协议
        BhznGrainV2ServerEngine.start(null);
        //邦海智能无线主机设备协议
        BhznGrainV0ServerEngine.start(null);
        //BhznGrainV0ServerEngine.start(null);
        //邦海智能无线主机设备协议
        BhznGrainV01ServerEngine.start(null);
    }
}
src/main/java/com/fzzy/protocol/bhzn/analysis/AnalysisService.java
@@ -346,7 +346,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        JSONObject properties = new JSONObject();
src/main/java/com/fzzy/protocol/bhzn/v0/analysis/AnalysisService.java
@@ -465,7 +465,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        List<GrainTH> ths = new ArrayList<>();
        ths.add(new GrainTH(thDto.getTempIn() != null ? thDto.getTempIn() + "" : "", thDto.getHumidityIn() != null ? thDto.getHumidityIn() + "" : "", "1"));
src/main/java/com/fzzy/protocol/bhzn/v0/server/BhznGrainV0ServerEngine.java
@@ -44,10 +44,10 @@
        //确认结尾标志
        //ioServerOption.setDelimiter(BhznGrainV2ServerUtils.MSG_END.getBytes());
//        ioServerOption.setSplitDecoderType(SplitByteDecoderType.NO_LIMIT);
        ioServerOption.setSplitDecoderType(SplitByteDecoderType.NO_LIMIT);
        ioServerOption.setDelimiter(BhznGrainV2ServerUtils.MSG_END.getBytes());
        ioServerOption.setSplitDecoderType(SplitByteDecoderType.DELIMITER_SYMBOL);
//        ioServerOption.setDelimiter(BhznGrainV2ServerUtils.MSG_END.getBytes());
//        ioServerOption.setSplitDecoderType(SplitByteDecoderType.DELIMITER_SYMBOL);
        // é…ç½®ç³»ç»Ÿå¿ƒè·³é—´éš”
        ioServerOption.setReaderIdleTime(5 * 60);
src/main/java/com/fzzy/protocol/bhzn/v0/server/BhznGrainV0ServerUtils.java
@@ -26,10 +26,10 @@
    public static int HEART_BEAT_TIME = 30;//心跳间隔时间
    public static String MSG_START = "3C42485A4E3E";//<BHZN>
    public static String MSG_START = "";//<BHZN> 3C42485A4E3E
    public static String MSG_START2 = "AA";
    public static String MSG_END = "<END>";//<END>
    public static String MSG_END_16 = "3C454E443E";//<END>3C454E443E
    public static String MSG_END_16 = "";//<END>3C454E443E
    public static final String CHARSET = "UTF-8";
src/main/java/com/fzzy/protocol/bhzn/v0/²»´ø¿ªÍ·½áβµÄ°æ±¾
src/main/java/com/fzzy/protocol/bhzn/v01/analysis/AnalysisService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,577 @@
package com.fzzy.protocol.bhzn.v01.analysis;
import com.alibaba.fastjson.JSONObject;
import com.fzzy.api.data.DepotType;
import com.fzzy.api.data.GatewayDeviceType;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.NumberUtil;
import com.fzzy.api.utils.RedisConst;
import com.fzzy.api.utils.RedisUtil;
import com.fzzy.data.ConfigData;
import com.fzzy.gateway.GatewayUtils;
import com.fzzy.gateway.api.GatewayDeviceReportService;
import com.fzzy.gateway.api.GatewayRemoteManager;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.data.GrainCableData;
import com.fzzy.gateway.data.WeatherWebDto;
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.bhzn.v01.cmd.CommandBuild;
import com.fzzy.protocol.bhzn.v01.cmd.ReMessageBuilder;
import com.fzzy.protocol.bhzn.v01.data.IoMessage;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerEngine;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerUtils;
import com.fzzy.protocol.data.THDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * åè®®è§£æž
 */
@Slf4j
@Component(AnalysisService.BEAN_ID)
public class AnalysisService {
    public static final String BEAN_ID = "bhzn01.analysisService";
    @Resource
    private GatewayRemoteManager gatewayRemoteManager;
    @Resource
    private ConfigData configData;
    @Resource
    private RedisUtil redisUtil;
    /**
     * é’ˆå¯¹åˆ†åŒ…粮情报文进行封装
     */
    public static Map<String, String> contextMapGrain = new HashMap<>();
    /**
     * ç”¨äºŽå­˜æ”¾è¿”回的仓温仓湿信息
     */
    public static Map<String, THDto> contextMapTH = new HashMap<>();
    /**
     * @param sessionKey ip:port
     */
    public void analysis(String sessionKey, IoMessage message) throws Exception {
        //注册
        if (BhznGrainV01ServerUtils.FUNCTION_ID_F1.equals(message.getFunctionId())) {
            log.info("主机------->>平台:注册信息报文={}", message);
            //DO NOTHING
            return;
        }
        //心跳
        if (BhznGrainV01ServerUtils.FUNCTION_ID_F2.equals(message.getFunctionId())) {
            //DO NOTHING
            return;
        }
        // 93 è§£æžä»“温仓湿,并返回收到报文
        if (BhznGrainV01ServerUtils.FUNCTION_ID_93.equals(message.getFunctionId())) {
            log.info("主机------->>平台:温湿度信息报文={}", message);
            analysisTh(message);
            return;
        }
        // 92 è§£æžç²®æ¸©ï¼Œå¹¶è¿”回收到报文
        if (BhznGrainV01ServerUtils.FUNCTION_ID_92.equals(message.getFunctionId())) {
            log.info("主机------->>平台:粮情信息报文={}", message);
            analysisGrain(message);
        }
    }
    /**
     * æš‚时不支持义分机多仓模式,--平房仓
     *
     * @param message
     */
    private void analysisGrain(IoMessage message) {
        try {
            //根据分机SN获取设备配置信息
            GatewayDevice gatewayDevice = BhznGrainV01ServerUtils.contextOrder;
            if (null == gatewayDevice) {
                replayGrain(message);
                log.error("主机-------->>平台,解析粮情失败,未获取到系统设备配置信息:" + message.getAddr());
                return;
            }
            //根据分机地址获取分机信息
//            ApiCommonDevice commonDevice = Constant.getCommonDeviceCache(message.getIp());
//            if (commonDevice == null) {
//                replayGrain(message);
//                log.error("主机-------->>平台,解析粮情失败,未获取到系统粮情主机配置:" + message.getAddr());
//                return;
//            }
            //获取请求信息
            BaseReqData reqData = ProtocolUtils.getSyncReq(gatewayDevice.getDepotIdSys());
            if (null == reqData) {
                replayGrain(message);
                log.error("主机-------->>平台,解析粮情失败,未获取到粮情请求信息:" + message.getAddr());
                return;
            }
            // åˆ¤æ–­æ•°æ®æœ‰æ²¡æœ‰æ”¶å–完整
            GrainCableData cableData = GatewayUtils.getCableData(gatewayDevice);
            //获取当前粮情温度报文
            String grainHex = message.getContent().substring(16);
            //当前报文温度点数
            int curPoint = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(4, 8)));
            //如果当前包的数据个数大于等于当前仓库的配置点位则表示单包返回
            if (curPoint >= cableData.getSumNum()) {
                log.info("分机------>>>平台:粮情数据单包=" + grainHex);
                //返回粮情接收信息
                replayGrain(message);
                analysisGrain2(message, reqData, grainHex, cableData);
                return;
            }
            //表示分包传递
            String key = "GRAIN_" + message.getAddr();
            String oldGrainHex = contextMapGrain.get(key) == null ? "" : contextMapGrain.get(key);
            //获取当前包起始点的层行列
            int hang = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(8, 10)));
            int lie = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(10, 12)));
            int ceng = BytesUtil.hexToInt(BytesUtil.tran_LH(message.getContent().substring(12, 14)));
            if (hang > 0 || lie > 0 || ceng > 0) {
                //说明非第一包数据
                grainHex = oldGrainHex + grainHex;
            }
            if (grainHex.length() >= cableData.getSumNum() * 4) {
                //返回粮情接收信息
                replayGrain(message);
                log.info("分机------>>>平台:粮情数据多包,完整数据=" + grainHex);
                analysisGrain2(message, reqData, grainHex, cableData);
                return;
            } else {
                log.info("分机------>>>平台:将第一包数据存入内存=" + grainHex);
                contextMapGrain.put(key, grainHex);
                replayGrain(message);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
    /**
     * è¿”回粮情收到报文信息,需要注意:如果存在分包情况下,需要等所有包收到后返回
     *
     * @param message
     */
    private void replayGrain(IoMessage message) throws InterruptedException {
        Thread.sleep(50);
        String hexStr = CommandBuild.getMsgGrainReply(message.getAddr());
        log.info("平台--------->>>主机,返回粮情报文收到信息,报文={}", hexStr);
        BhznGrainV01ServerEngine.pushByMin(hexStr);
    }
    /**
     * èŽ·å–åˆ°æ‰€æœ‰çš„ç²®æƒ…æ•°æ®ï¼Œå¼€å§‹è§£æž
     *
     * @param message
     * @param reqData
     * @param grainStr
     */
    private void analysisGrain2(IoMessage message, BaseReqData reqData, String grainStr, GrainCableData cableData) {
        GatewayDevice device = reqData.getDevice();
        // æ ¹æ®å±‚行列获取指定长度
        int start = 0;
        int len = 4 * cableData.getSumNum();
        log.info("分机------>>>平台:返回粮情完整信息,分机={}", device.getDeviceName());
        String strPoints = grainStr.substring(start, start + len);
        // å°†ç²®æƒ…解析成数组
        List<Double> temps = new ArrayList<>();
        double tempValue;
        String temp;
        for (int i = 0; i < strPoints.length() / 4; i++) {
            temp = strPoints.substring(i * 4, i * 4 + 4);
            if (temp == null) {
                temp = "0000";
            }
            if (ReMessageBuilder.ERROR_TAG.equals(temp)) {
                tempValue = ProtocolUtils.ERROR_TEMP;
            } else {
                tempValue = BytesUtil.hexToInt(BytesUtil.tran_LH(temp)) / 10.0;
            }
            // æ•…障值处理
            if (tempValue >= ReMessageBuilder.FAULT_CHECK_TAG) {
                tempValue = ProtocolUtils.FAULT_TEMP;
            }
            temps.add(tempValue);
        }
        THDto thDto = this.getTH(message);
        if (null != thDto) {
            log.info("-------THDto--={}", thDto);
        }
        //清空
        String key = "GRAIN_" + message.getAddr();
        contextMapGrain.put(key, null);
        if(DepotType.TYPE_03.getCode().equals(device.getDepotType())){
            //筒仓
            analysisAndPush3(temps, reqData, thDto, cableData);
        }else if(DepotType.TYPE_02.getCode().equals(device.getDepotType())){
            analysisAndPush2(temps, reqData, thDto, cableData);
        }else if(DepotType.TYPE_04.getCode().equals(device.getDepotType())){
            analysisAndPush2(temps, reqData, thDto, cableData);
        }else {
            //平房仓
            analysisAndPush1(temps, reqData, thDto, cableData);
        }
    }
    /**
     * ç­’仓,解析第二步,解析到坐标数据
     * @param temps
     * @param reqData
     * @param thDto
     * @param cableData
     */
    private void analysisAndPush2(List<Double> temps, BaseReqData reqData, THDto thDto, GrainCableData cableData) {
        //TODO
        log.info("-------------------------暂未实现----------------");
    }
    /**
     * æ²¹ç½ä»“,解析第二步,解析到坐标数据
     *
     * @param temps
     * @throws Exception
     */
    private void analysisAndPush3(List<Double> temps, BaseReqData reqData, THDto thDto, GrainCableData cableData) {
        GatewayDevice device = reqData.getDevice();
        int cableZ = cableData.getCableZ();
        int cableY = cableData.getCableY();
        int cableX = cableData.getCableX();
        int sumNum = temps.size();
        //数据封装
        GrainData grain = new GrainData();
        grain.setMessageId(ScConstant.getMessageId());
        grain.setDeviceId(device.getDeviceId());
        grain.setTimestamp(System.currentTimeMillis() + "");
        ClientHeaders headers = new ClientHeaders();
        headers.setDeviceName(device.getDeviceName());
        headers.setProductId(device.getProductId());
        headers.setOrgId(device.getOrgId());
        headers.setMsgId(reqData.getMessageId());
        grain.setHeaders(headers);
        GrainOutPut outPut = new GrainOutPut();
        double max = ReMessageBuilder.MAX_TEMP, min = ReMessageBuilder.MIN_TEMP, sumT = 0.0;
        List<GrainTemp> temperature = new ArrayList<>();
        //根号
        int cableNum = 1, position = 0;
        double curTemp;
        int x = 0, y = 0, z = 0;
        for (int i = 0; i < sumNum; i++) {
            curTemp = temps.get(i);
            position = i;
            z = i % cableZ + 1;
            x = i / (cableZ * cableY);
            y = x * (cableZ * cableY);
            y = (i - y) / cableZ;
            //根号
            cableNum = (i / cableZ) + 1;
            temperature.add(new GrainTemp(cableNum + "", z + "", curTemp + "", position + ""));
            //求最大最小值
            if (curTemp < -900) {
                sumNum--;
            } else {
                sumT += curTemp;
                if (curTemp > max) {
                    max = curTemp;
                }
                if (curTemp < min) {
                    min = curTemp;
                }
            }
        }
        if (sumNum == 0) {
            sumNum = 1;
            log.warn("---当前粮情采集异常--");
        }
        //过滤比较用的最大最小值
        if (max == ReMessageBuilder.MAX_TEMP) {
            max = 0.0;
        }
        if (min == ReMessageBuilder.MIN_TEMP) {
            min = 0.0;
        }
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        JSONObject properties = new JSONObject();
        properties.put("data", outPut);
        properties.put("timestamp", grain.getTimestamp());
        String height = this.getCacheHeight(device);
        if (StringUtils.isEmpty(height)) height = "0.0";
        properties.put("liquidHeight", height);
        grain.setProperties(properties);
        //封装好的数据
        log.info("---浅圆仓封装完成----开始执行推送");
        reqData.setData(JSONObject.toJSONString(grain));
        doPushGrain(reqData,grain);
    }
    /**
     * ä»ŽREDIS中获取液位高度信息
     *
     * @param device
     * @return
     */
    private String getCacheHeight(GatewayDevice device) {
        //给其他软使用
        String key = RedisConst.KEY_DEPOT_HEIGHT + ":" + configData.getCompanyId() + "_" + device.getDepotIdSys();
        return (String) redisUtil.get(key);
    }
    /**
     * å¹³æˆ¿ä»“,解析第二步,解析到坐标数据
     *
     * @param temps
     * @throws Exception
     */
    private void analysisAndPush1(List<Double> temps, BaseReqData reqData, THDto thDto, GrainCableData cableData) {
        GatewayDevice device = reqData.getDevice();
        int cableZ = cableData.getCableZ();
        int cableY = cableData.getCableY();
        int cableX = cableData.getCableX();
        //数据封装
        GrainData grain = new GrainData();
        grain.setMessageId(ScConstant.getMessageId());
        grain.setDeviceId(device.getDeviceId());
        grain.setTimestamp(System.currentTimeMillis() + "");
        ClientHeaders headers = new ClientHeaders();
        headers.setDeviceName(device.getDeviceName());
        headers.setProductId(device.getProductId());
        headers.setOrgId(device.getOrgId());
        headers.setMsgId(reqData.getMessageId());
        grain.setHeaders(headers);
        GrainOutPut outPut = new GrainOutPut();
        double max = ReMessageBuilder.MAX_TEMP, min = ReMessageBuilder.MIN_TEMP, sumT = 0.0, sumNum = cableData.getSumNum();
        List<GrainTemp> temperature = new ArrayList<>();
        //根号
        int cableNum = 1, position = 0;
        double curTemp;
        int x = 0, y = 0, z = 0;
        for (int i = 0; i < temps.size(); i++) {
            curTemp = temps.get(i);
            position = i;
            z = i % cableZ + 1;
            x = i / (cableZ * cableY);
            y = x * (cableZ * cableY);
            y = (i - y) / cableZ;
            //根号
            cableNum = (i / cableZ) + 1;
            temperature.add(new GrainTemp(cableNum + "", z + "", curTemp + "", position + ""));
            //求最大最小值
            if (curTemp < -900) {
                sumNum--;
            } else {
                sumT += curTemp;
                if (curTemp > max) {
                    max = curTemp;
                }
                if (curTemp < min) {
                    min = curTemp;
                }
            }
        }
        if (sumNum == 0) {
            sumNum = 1;
            log.warn("---当前粮情采集异常--");
        }
        //过滤比较用的最大最小值
        if (max == ReMessageBuilder.MAX_TEMP) {
            max = 0.0;
        }
        if (min == ReMessageBuilder.MIN_TEMP) {
            min = 0.0;
        }
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        List<GrainTH> ths = new ArrayList<>();
        ths.add(new GrainTH(thDto.getTempIn() != null ? thDto.getTempIn() + "" : "", thDto.getHumidityIn() != null ? thDto.getHumidityIn() + "" : "", "1"));
        outPut.setTemperatureAndhumidity(ths);
        grain.setOutput(JSONObject.toJSONString(outPut));
        GatewayDevice gatewayDeviceWeather = GatewayUtils.getCacheByDeviceTypeOne(GatewayDeviceType.TYPE_09.getCode());
        //系统气象站信息
        WeatherWebDto weather = WeatherWebDto.contextMap.get("default");
        //气象信息
        GrainWeather weatherStation = new GrainWeather();
        weatherStation.setMessageId(ScConstant.getMessageId());
        weatherStation.setMessgeId(weatherStation.getMessageId());
        if (null != gatewayDeviceWeather) {
            weatherStation.setId(gatewayDeviceWeather.getDeviceId());
        } else {
            weatherStation.setId(device.getDeviceId());
        }
        weatherStation.setAirPressure(weather.getPressure());
        weatherStation.setHumidity(weather.getHumidity());
        weatherStation.setPm(weather.getAir_pm25());
        weatherStation.setRadiation("0");
        weatherStation.setRainfallAmount(weather.getWea());
        weatherStation.setTemperature(weather.getTem());
        weatherStation.setWindDirection(weather.getWin());
        weatherStation.setWindPower(weather.getWin_meter());
        weatherStation.setWindSpeed(weather.getWin_speed());
        grain.setWeatherStation(JSONObject.toJSONString(weatherStation));
        //封装好的数据
        log.info("---粮情机械封装完成----开始执行推送");
        reqData.setData(JSONObject.toJSONString(grain));
        doPushGrain(reqData,grain);
    }
    private void doPushGrain(BaseReqData reqData,GrainData grainData) {
        GatewayDeviceReportService reportService = gatewayRemoteManager.getDeviceReportService(reqData.getDevice().getPushProtocol());
        if (null == reportService) {
            log.error("------------粮情推送失败,系统不存在当前协议执行类----{}", reqData.getDevice().getDeviceName());
            return;
        }
        reportService.reportGrainData(reqData);
        reqData.setData(reportService.grainData2GatewayApiInfoKafka(grainData,reqData.getDevice()).getData());
        reportService.reportGrainDataByKafka(reqData);
    }
    private void analysisTh(IoMessage message) {
        try {
            THDto th = new THDto();
            String data = message.getContent();
            String houseNo = data.substring(0, 2);
            int depotId = BytesUtil.hexToInt(houseNo);
            String t = data.substring(4, 8);
            String h = data.substring(8, 12);
            double humy;
            String temp;
            int symbol = 0; //符号位
            double tempValue;
            if (ReMessageBuilder.ERROR_TAG.equals(t)) {
                temp = "0000";
            } else {
                temp = BytesUtil.tran_LH(t);
            }
            temp = BytesUtil.hexString2binaryString(temp, 16);
            //符号位
            symbol = Integer.valueOf(temp.substring(0, 1));
            //获取温度值
            tempValue = BytesUtil.biannary2Decimal(temp.substring(6)) / 10;
            //若为负,则补码:取反加1
            if (symbol == 1) {
                tempValue = 0.0 - BytesUtil.twoToString(temp) / 10;
            }
            th.setTempIn(tempValue);
            if (ReMessageBuilder.ERROR_TAG.equals(h)) {
                humy = 0.0;
            } else {
                humy = (double) BytesUtil.hexToBigInt(BytesUtil.tran_LH(h)) / 10;
            }
            th.setHumidityIn(humy);
            log.info("主机--------->>>平台,解析仓温仓湿信息,仓库={},结果={}", depotId, th.toString());
            String key = "TH_" + depotId;
            contextMapTH.put(key, th);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            String hexStr = CommandBuild.getMsgTHReply(message.getAddr());
            log.info("平台--------->>>主机,返回仓温仓湿收到信息,报文={}", hexStr);
            BhznGrainV01ServerEngine.pushByMin(hexStr);
        }
    }
    private THDto getTH(IoMessage message) {
        String data = message.getContent();
        String houseNo = data.substring(0, 2);
        Integer depotId = BytesUtil.hexToInt(houseNo);
        String key = "TH_" + depotId;
        return contextMapTH.get(key);
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/cmd/CommandBuild.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,179 @@
package com.fzzy.protocol.bhzn.v01.cmd;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerUtils;
/**
 * å‘½ä»¤ç”Ÿæˆ
 *
 * @author vince
 */
public class CommandBuild {
    private final static CommandBuild instance = new CommandBuild();
    private CommandBuild() {
    }
    public static CommandBuild getInstance() {
        return instance;
    }
    /**
     * PC回复 å¿ƒè·³å•Š æ”¶åˆ°ä¿¡æ¯
     *
     * @param grainAddr
     * @return
     */
    public static String getMsgHeartReply(String grainAddr) {
        StringBuffer sb = new StringBuffer();
        //开始符号
        sb.append(BhznGrainV01ServerUtils.MSG_START);
        sb.append(BhznGrainV01ServerUtils.MSG_START2);
        //分机地址
        int i = Integer.parseInt(grainAddr);
        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
        //发送方地址
        sb.append("0001");
        //命令ID
        sb.append(BhznGrainV01ServerUtils.FUNCTION_ID_F2);
        //数据长度-01
        sb.append("01");
        //数据区--任意值
        sb.append("01");
        //获取校验码
        sb.append(BhznGrainV01ServerUtils.getCheck(sb.toString()));
        //结尾符
        sb.append(BhznGrainV01ServerUtils.MSG_END_16);
        return sb.toString();
    }
    /**
     * ç²®æƒ…采集命令
     *
     * @param grainAddr ç²®æƒ…分机地址
     * @param deptId    ä»“库编号地址
     * @return
     */
    public static String getMsgCheck(String grainAddr, String deptId) {
        StringBuffer sb = new StringBuffer();
        //开始符号
        sb.append(BhznGrainV01ServerUtils.MSG_START);
        sb.append(BhznGrainV01ServerUtils.MSG_START2);
        //分机地址
        int i = Integer.parseInt(grainAddr);
        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
        //发送方地址
        sb.append("0001");
        //命令ID
        sb.append(BhznGrainV01ServerUtils.FUNCTION_ID_83);
        //数据长度-01
        sb.append("01");
        //数据区--主机里面配置的仓库编码
        i = Integer.parseInt(deptId);
        sb.append(BytesUtil.intToHexStr1(i));
        //获取校验码
        sb.append(BhznGrainV01ServerUtils.getCheck(sb.toString()));
        //结尾符
        sb.append(BhznGrainV01ServerUtils.MSG_END_16);
        return sb.toString();
    }
    /**
     * PC回复 ä»“温仓湿 æ”¶åˆ°ä¿¡æ¯
     *
     * @param grainAddr
     * @return
     */
    public static String getMsgTHReply(String grainAddr) {
        StringBuffer sb = new StringBuffer();
        //开始符号
       // sb.append(BhznGrainV0ServerUtils.MSG_START);
        sb.append(BhznGrainV01ServerUtils.MSG_START2);
        //分机地址
        int i = Integer.parseInt(grainAddr);
        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
        //发送方地址
        sb.append("0001");
        //命令ID
        sb.append(BhznGrainV01ServerUtils.FUNCTION_ID_93);
        //数据长度-01
        sb.append("01");
        //数据区--任意值
        sb.append("01");
        //获取校验码
        sb.append(BhznGrainV01ServerUtils.getCheck(sb.toString()));
        //结尾符
        sb.append(BhznGrainV01ServerUtils.MSG_END_16);
        return sb.toString();
    }
    /**
     * PC回复粮温收到信息
     *
     * @param grainAddr
     * @return
     */
    public static String getMsgGrainReply(String grainAddr) {
        StringBuffer sb = new StringBuffer();
        //开始符号
        sb.append(BhznGrainV01ServerUtils.MSG_START);
        sb.append(BhznGrainV01ServerUtils.MSG_START2);
        //分机地址
        int i = Integer.parseInt(grainAddr);
        sb.append(BytesUtil.tran_LH(BytesUtil.intToHexStr(i)));
        //发送方地址
        sb.append("0001");
        //命令ID
        sb.append(BhznGrainV01ServerUtils.FUNCTION_ID_92);
        //数据长度-01
        sb.append("01");
        //数据区--任意值
        sb.append("01");
        //获取校验码
        sb.append(BhznGrainV01ServerUtils.getCheck(sb.toString()));
        //结尾符
        sb.append(BhznGrainV01ServerUtils.MSG_END_16);
        return sb.toString();
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/cmd/ReMessageBuilder.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,52 @@
package com.fzzy.protocol.bhzn.v01.cmd;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.protocol.bhzn.v01.data.IoMessage;
/**
 * æ ¹æ®æŽ¥æ”¶åˆ°çš„信息进行封装
 *
 * @author vince
 */
public class ReMessageBuilder {
    public final static String ERROR_TAG = "3CF6";
    public static double FAULT_CHECK_TAG = 85.0;
    public static double MAX_TEMP = -50.0;
    public static double MIN_TEMP = 50.0;
    private final static ReMessageBuilder instance = new ReMessageBuilder();
    private ReMessageBuilder() {
    }
    public static ReMessageBuilder getInstance() {
        return instance;
    }
    /**
     * @param message
     * @return
     */
    public IoMessage buildMessage(String message) throws Exception {
        IoMessage ioMessage = new IoMessage();
        //转换为数字,高低位转换(4位)
        int i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(2, 6)));
        ioMessage.setPcAddr(i + "");
        i = BytesUtil.hexToBigInt(BytesUtil.tran_LH(message.substring(6, 10)));//高低位转换(4位)
        ioMessage.setAddr(i + "");
        ioMessage.setFunctionId(message.substring(10, 12));//功能码(2位),不用高低位转换
        i = BytesUtil.hexToBigInt(message.substring(12, 14));//长度(1位)
        ioMessage.setLength(i);
        //获取消息体
        ioMessage.setContent(message.substring(14, 14 + (i * 2)));
        ioMessage.setCheck(message.substring(message.length() - 2));
        return ioMessage;
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/data/Content.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,43 @@
package com.fzzy.protocol.bhzn.v01.data;
import lombok.Data;
/**
 * @author vince.xu
 * @Title: Content
 * @ProjectName igds-35
 * @Description: TODO
 * @date 2022-12-715:48
 */
@Data
public class Content {
    /**
     * çŠ¶æ€åå›ž
     */
    public  String result;
    /**
     * çº¯åº¦
     */
    public String purity;
    /**
     * æµé‡
     */
    public String flow;
    /**
     * åŽ‹åŠ›
     */
    public String pressure;
    /**
     * æ¸©åº¦
     */
    public String temperature;
    /**
     * æµé‡ç´¯è®¡
     */
    public String flowAll;
    /**
     * è¿è¡ŒçŠ¶æ€
     */
    public String isRun;
}
src/main/java/com/fzzy/protocol/bhzn/v01/data/IoMessage.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,20 @@
package com.fzzy.protocol.bhzn.v01.data;
import lombok.Data;
@Data
public class IoMessage {
    private String ip;
    private int port;
    private String pcAddr;
    private String addr;
    private String functionId;
    private int length;
    private String content;
    private String check;
}
src/main/java/com/fzzy/protocol/bhzn/v01/package-info.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,4 @@
/**
 * é‚¦æµ·æ™ºèƒ½-自有协议-纯粮情分机协议
 */
package com.fzzy.protocol.bhzn.v01;
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01HeartbeatImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
package com.fzzy.protocol.bhzn.v01.server;
import com.ld.io.api.HeartbeatProvider;
import com.ld.io.api.IoSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * æä¾›å¿ƒè·³ä¿¡æ¯
 *
 * @author Andy
 */
@Slf4j
@Service
public class BhznGrainV01HeartbeatImpl implements HeartbeatProvider {
    @Override
    public byte[] provide(IoSession session) {
        //直接根据主机SESSIOn判断
        IoSession session1 = BhznGrainV01ServerUtils.getSession();
        Long lastBeatTime = BhznGrainV01ServerUtils.getHearBeat(session1);
        if (null == lastBeatTime) {
            return null;
        }
        //如果最后一次终端心跳时间距离当前时间大于 ç»ˆç«¯å¿ƒè·³æ—¶é—´çš„3次,则判断为离线
        long deTime = System.currentTimeMillis() - lastBeatTime;
        if (deTime > (BhznGrainV01ServerUtils.HEART_BEAT_TIME * 3 * 1000)) {
            log.info("-----------超过{}秒未获取到心跳信息,判定终端离线,踢出连接------------{}-{}", deTime, session.getAddress(), session.getPort());
           // session.destroy();
        }
        return null;
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01MessageConsumer.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
package com.fzzy.protocol.bhzn.v01.server;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.api.utils.SpringUtil;
import com.fzzy.protocol.bhzn.v01.analysis.AnalysisService;
import com.fzzy.protocol.bhzn.v01.cmd.ReMessageBuilder;
import com.fzzy.protocol.bhzn.v01.data.IoMessage;
import com.ld.io.api.IoMsgConsumer;
import com.ld.io.api.IoSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 *
 */
@Slf4j
@Service
public class BhznGrainV01MessageConsumer implements IoMsgConsumer {
    @Autowired
    private AnalysisService analysisService;
    /**
     * å¤„理消息
     *
     * @param ioSession
     * @param bytes
     */
    @Override
    public void consume(IoSession ioSession, byte[] bytes) {
        if (null == bytes) {
            log.error("Reply bytes is null");
            return;
        }
        //添加信息心跳标记
        BhznGrainV01ServerUtils.addHeartBeat(ioSession);
        //默认设置主通讯服务
        BhznGrainV01ServerUtils.addSession(ioSession);
        try {
            String hexStr = BytesUtil.bytesToString(bytes);
            log.info("【"+ioSession.getAddress()+"】主机返回报文------->>平台:" + hexStr);
            hexStr = hexStr.substring(BhznGrainV01ServerUtils.MSG_START.length());
            IoMessage ioMessage = ReMessageBuilder.getInstance().buildMessage(hexStr);
            ioMessage.setIp(ioSession.getAddress());
            ioMessage.setPort(ioSession.getPort());
            analysisService = SpringUtil.getBean(AnalysisService.class);
            analysisService.analysis(ioSession.getBusinessKey(), ioMessage);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01ServerEngine.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
package com.fzzy.protocol.bhzn.v01.server;
import com.fzzy.api.utils.BytesUtil;
import com.ld.io.api.*;
import com.ld.io.netty.NettyServer;
import lombok.extern.slf4j.Slf4j;
/**
 * @Desc: é‚¦æµ·æ™ºèƒ½çº¯ç²®æƒ…协议
 * @author: Andy
 */
@Slf4j
public class BhznGrainV01ServerEngine {
    public static final Integer PORT = 19304;
    public static NettyServer ioServer = null;
    private static BhznGrainV01MessageConsumer defaultMessageConsumer = new BhznGrainV01MessageConsumer();
    private static BhznGrainV01SessionListener defaultSessionListener = new BhznGrainV01SessionListener();
    // å¿ƒè·³æä¾›
    private static HeartbeatProvider heartbeatProvider = new BhznGrainV01HeartbeatImpl();
    private IoSessionQuery sessionQuery;
    public static void start(Integer port) {
        IoServerOption ioServerOption = new IoServerOption();
        if (null != port) {
            ioServerOption.setPort(port);
        } else {
            port = PORT;
            ioServerOption.setPort(port);
        }
        //确认结尾标志-没有固定结束符号
        //确认结尾标志
        //ioServerOption.setDelimiter(BhznGrainV2ServerUtils.MSG_END.getBytes());
        //ioServerOption.setSplitDecoderType(SplitByteDecoderType.NO_LIMIT);
        ioServerOption.setDelimiter(BhznGrainV01ServerUtils.MSG_END.getBytes());
        ioServerOption.setSplitDecoderType(SplitByteDecoderType.DELIMITER_SYMBOL);
        // é…ç½®ç³»ç»Ÿå¿ƒè·³é—´éš”
        ioServerOption.setReaderIdleTime(5 * 60);
        NettyServer ioServer = new NettyServer(ioServerOption, defaultMessageConsumer, defaultSessionListener, heartbeatProvider);
        ioServer.startup();
        log.info("* ");
        log.info("* ========================");
        log.info("* ");
        log.info("* [GRAIN-SERVER:BHZN_GRAIN-V0,PORT={}]" + port);
        log.info("* ");
        log.info("* ========================");
        log.info("* ");
        System.out.println("* ========================");
        System.out.println("* ");
        System.out.println("* [GRAIN-SERVER:BHZN_GRAIN-V0,PORT={}]" + port);
        System.out.println("* ");
        System.out.println("* ========================");
    }
    /**
     * ç›´æŽ¥ä½¿ç”¨å†…存的Session执行
     */
    public static InvokeResult pushByMin(String hexStr) {
        IoSession session = BhznGrainV01ServerUtils.getSession();
        if (null == session) {
            return InvokeResult.CHANNEL_CLOSED;
        }
        byte[] msg = BytesUtil.hexStrToBytes(hexStr);
        return session.invoke(msg);
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01ServerUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,104 @@
package com.fzzy.protocol.bhzn.v01.server;
import com.fzzy.api.utils.BytesUtil;
import com.fzzy.gateway.entity.GatewayDevice;
import com.ld.io.api.IoSession;
import java.util.HashMap;
import java.util.Map;
/**
 * å·¥å…·ç±»
 *
 * @author vince
 */
public class BhznGrainV01ServerUtils {
    /**
     * è®°å½•每个连接的最后一次信息时间 key = è¿žæŽ¥çš„KYE,data =当前时间戳
     */
    public static Map<String, Long> contextMapHeart = new HashMap<>();
    public static Map<String, IoSession> contextIoSession = new HashMap<>();
    public static  GatewayDevice contextOrder = new GatewayDevice();
    public static int HEART_BEAT_TIME = 30;//心跳间隔时间
    public static String MSG_START = "3C42485A4E3E";//<BHZN> 3C42485A4E3E
    public static String MSG_START2 = "AA";
    public static String MSG_END = "<END>";//<END>
    public static String MSG_END_16 = "3C454E443E";//<END>3C454E443E
    public static final String CHARSET = "UTF-8";
    /**
     * é’ˆå¯¹æ— çº¿ç²®æƒ…主机的默认ID配置
     */
    public static String DEFAULT_MAC_ID = "53681";
    public static String FUNCTION_ID_00 = "00";
    public static String FUNCTION_ID_F1 = "F1";
    public static String FUNCTION_ID_F2 = "F2";
    public static String FUNCTION_ID_83 = "83";
    public static String FUNCTION_ID_93 = "93";
    public static String FUNCTION_ID_92 = "92";
    /**
     * ç”ŸæˆTCP连接的KEY
     *
     * @param ip
     * @param port
     * @return
     */
    public static String getServerKey(String ip, Integer port) {
        return ip + ":" + port;
    }
    /**
     * æ·»åŠ æœ€æ–°å¿ƒè·³æ—¶é—´æˆ³
     *
     * @param session
     */
    public static void addHeartBeat(IoSession session) {
        contextMapHeart.put(getServerKey(session.getAddress(), session.getPort()), System.currentTimeMillis());
    }
    public static Long getHearBeat(IoSession session) {
        return contextMapHeart.get(getServerKey(session.getAddress(), session.getPort()));
    }
    /**
     * è®¡ç®—校验
     *
     * @param content
     * @return
     */
    public static String getCheck(String content) {
        int start = BhznGrainV01ServerUtils.MSG_START.length() + BhznGrainV01ServerUtils.MSG_START2.length();
        content = content.substring(start);
        int sum = 0;
        String hex;
        for (int i = 0; i < content.length() / 2; i++) {
            hex = content.substring(i * 2, i * 2 + 2);
            sum += BytesUtil.hexToInt(hex);
        }
        String hexSum = BytesUtil.intToHexStr(sum);
        int check = BytesUtil.hexToInt(hexSum.substring(hexSum.length() - 2));
        return BytesUtil.intToHexStr(256 - check).substring(2);
    }
    public static void addSession(IoSession session) {
        contextIoSession.put(DEFAULT_MAC_ID, session);
    }
    public static IoSession getSession() {
        return contextIoSession.get(DEFAULT_MAC_ID);
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/server/BhznGrainV01SessionListener.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,76 @@
package com.fzzy.protocol.bhzn.v01.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.ld.io.api.IoSession;
import com.ld.io.api.IoSessionListener;
import lombok.extern.slf4j.Slf4j;
/**
 *
 */
@Slf4j
public class BhznGrainV01SessionListener implements IoSessionListener {
    private GatewayDeviceService gatewayDeviceService;
    /**
     * è®¾å¤‡åˆ›å»ºåœ¨çº¿ï¼Œéœ€è¦æ³¨æ„å½“前使用主机模式,主机上线默认所有相同SN配置的分机全部上线
     *
     * @param session
     */
    @Override
    public void onCreate(IoSession session) {
        //添加到内存
        BhznGrainV01ServerUtils.addSession(session);
        log.info("++++新建连接++++-IP={},PORT={}", session.getAddress(), session.getPort());
        // æ·»åŠ è‡ªå®šä¹‰ä¸šåŠ¡ID
        session.setBusinessKey(BhznGrainV01ServerUtils.getServerKey(session.getAddress(), session.getPort()));
//        GatewayDeviceService gatewayDeviceService = SpringUtil.getBean(GatewayDeviceService.class);
//        List<GatewayDevice> devices = gatewayDeviceService.listAll();
//        //执行分机上线
//        if(devices!= null && devices.size()>0){
//            ApiCommonDevice device =null;
//            for (GatewayDevice d:devices) {
//                device = new ApiCommonDevice();
//                device.setIp(d.getIp());
//                device.setPort(d.getPort());
//                device.setStatus(Constant.YN_N);
//                device.setSn(d.getDeviceSn());
//                device.setCode("ERROR");
//                device.setMsg("设备离线");
//            }
//
//
//            contextDeviceMap.put(device.getIp(), device);
//
//        }
        Constant.updateCacheOnline(session.getAddress(), session.getPort());
    }
    /**
     * æ³¨æ„ï¼Œå½“前采用主机模式,主机离线所有相同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/bhzn/v01/service/Bhzn01GatewayGrainService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,113 @@
package com.fzzy.protocol.bhzn.v01.service;
import com.fzzy.api.data.GatewayDeviceProtocol;
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.protocol.ProtocolUtils;
import com.fzzy.protocol.bhzn.v01.cmd.CommandBuild;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerEngine;
import com.fzzy.protocol.bhzn.v01.server.BhznGrainV01ServerUtils;
import com.ld.io.api.InvokeResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * é‚¦æµ·æ™ºèƒ½ç²®æƒ…协议-网口设备
 */
@Slf4j
@Component
public class Bhzn01GatewayGrainService implements GatewaySyncGranService {
    @Override
    public String getGrainProtocol() {
        return GatewayDeviceProtocol.GRAIN_BHZN_V01_WEB.getCode();
    }
    @Override
    public BaseResp syncGrain(BaseReqData reqData) {
        BaseResp resp = new BaseResp();
        GatewayDevice device = reqData.getDevice();
        BhznGrainV01ServerUtils.contextOrder = device;
        //获取连接中的设备信息
//        ApiCommonDevice apiCommonDevice = Constant.getCommonDeviceCacheBySn(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);
            // ç”Ÿæˆç²®æƒ…信息
            String hexStr = CommandBuild.getInstance().getMsgCheck(device.getDeviceSn(), device.getDepotIdSys());
            // å‘送命令
            InvokeResult message = BhznGrainV01ServerEngine.pushByMin(hexStr);
            log.error("平台------>>>>控制柜:发送粮情检测命令-{}", message);
            // å°è£…返回信息
            if (!InvokeResult.SUCCESS.getCode().equals(message.getCode())) {
                log.error("平台------>>>>控制柜:发送粮情检测命令-失败{}", message.getMessage());
                resp.setCode(500);
                resp.setMsg("平台------>>>>控制柜:发送粮情检测命令-失败:" + message.getMessage());
            }
        } catch (Exception e) {
            log.error("粮情检测异常:{}", e);
            resp.setCode(500);
            resp.setMsg("平台------>>>>控制柜:发送粮情检测命令:" + e.getMessage());
            return resp;
        }
        return resp;
    }
    @Override
    public BaseResp syncGrainTh(BaseReqData reqData) {
        return new BaseResp();
    }
    @Override
    public BaseResp syncConf(BaseReqData reqData) {
        return new BaseResp();
    }
    @Override
    public BaseResp writeConf(BaseReqData reqData) {
        return new BaseResp();
    }
    @Override
    public BaseResp initCable(BaseReqData reqData) {
        return new BaseResp();
    }
    @Override
    public BaseResp disconnect(BaseReqData reqData) {
        return new BaseResp();
    }
    @Override
    public BaseResp transparent(BaseReqData reqData) {
        return new BaseResp();
    }
}
src/main/java/com/fzzy/protocol/bhzn/v01/´ø¿ªÍ·½áβµÄ°æ±¾
src/main/java/com/fzzy/protocol/sjLpr/GatewayLprApi.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,256 @@
package com.fzzy.protocol.sjLpr;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fzzy.api.data.GatewayDeviceType;
import com.fzzy.gateway.api.GatewayRemoteManager;
import com.fzzy.gateway.data.BaseReqData;
import com.fzzy.gateway.data.BaseResp;
import com.fzzy.gateway.entity.GatewayDevice;
import com.fzzy.gateway.service.GatewayDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.stream.Collectors;
/**
 * ä¸Žç½‘关相关的接口数据对接,由第三方对接
 */
@Slf4j
@Controller
@RequestMapping("/gateway/api/v1/lpr/push")
public class GatewayLprApi {
    @Resource
    private GatewayRemoteManager gatewayRemoteManager;
    @Resource
    private GatewayDeviceService gatewayDeviceService;
    /**
     * ç†µåŸºè½¦ç‰Œè¯†åˆ«æŽ¨é€
     * @return
     * @throws Exception
     */
    @RequestMapping("/sj")
    public @ResponseBody
    String pushLpr(HttpServletRequest request, HttpServletResponse response,@RequestBody String str) {
        try {
           String carNumber =  doPost(request,response,str);
           pushLpr(carNumber);
        } catch (Exception e) {
            log.error("-----------推送车牌数据执行异常---{}", e.getMessage(),e);
//            resp.setCode(BaseResp.CODE_500);
//            resp.setMsg("执行异常:" + e.getMessage());
        }
        return "{\"Response_AlarmInfoPlate\":{\"info\":\"ok\",\"content\":\"...\",\"is_pay\":\"true\"}}";
    }
    /**
     * æŽ¨é€è½¦ç‰Œ
     *
     * @return
     */
    public String pushLpr(String carNumber) throws Exception {
        List<GatewayDevice> list = gatewayDeviceService.listAll();
        if (list == null || list.size() <= 0) {
            log.error("ERROR:没有配置设备信息,执行失败");
            return "ERROR:没有配置设备信息,执行失败";
        }
        List<GatewayDevice> weights = list.stream().filter(s -> (GatewayDeviceType.TYPE_02.getCode().equals(s.getType()))).collect(Collectors.toList());
        if (weights == null || weights.size() <= 0) {
            log.error("ERROR:没有配置设备信息,执行失败");
            return "ERROR:没有配置设备信息,执行失败";
        }
        BaseReqData reqData;
        BaseResp resp;
        for (GatewayDevice device : weights) {
            reqData = new BaseReqData();
            reqData.setDeviceId(device.getDeviceId());
            reqData.setProductId(device.getProductId());
            reqData.setDeviceName(device.getDeviceName());
            reqData.setDevice(device);
            reqData.setAutoReplay(true);
            reqData.setCarNumber(carNumber);
            resp = gatewayRemoteManager.getGatewayTestService(device.getPushProtocol()).testLpr(reqData);
            //自动推送
            if (BaseResp.CODE_200 == resp.getCode() && reqData.isAutoReplay()) {
                reqData.setData(resp.getData());
                gatewayRemoteManager.getDeviceReportService(device.getPushProtocol()).reportLprData(reqData);
            }
        }
        return "SUCCESS";
    }
    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected String doPost(HttpServletRequest request, HttpServletResponse response,String str) throws Exception {
        // TODO Auto-generated method stub
//        StringBuffer jb = new StringBuffer();
//        // JSONObject jsonObject;
//        String line = null;
//        char [] lineChars = new char[1024 * 1024];
//        char [] totalChars = new char[1024 * 1024];
//        int readLen = 0;
//        int totalLen = 0;
//        try {
//            BufferedReader reader = request.getReader();
//            while ((readLen = reader.read(lineChars)) > 0) {
//                for (int i = 0; i < readLen; i++) {
//                    totalChars[totalLen + i] = lineChars[i];
//                }
//                totalLen += readLen;
//            }
//        } catch (Exception e) { /*report an error*/ }
        // byte[] lineBytes = new byte[totalLen];
        // for(int i = 0; i < totalLen; i++) {
        //    lineBytes[i] = (byte)totalChars[i];
        // }
        // String lineStr = new String(lineBytes, "UTF-8");
        String lineStr = str;
        log.info(lineStr);
        // ï¿½Ñ½ï¿½ï¿½Õµï¿½ï¿½ï¿½ï¿½Æ½ï¿½ï¿½ï¿½ï¿½ï¿½æµ½txt���
        //WriteTxt("d:\\APP\\IGDS\\FILE\\plate_result.txt", lineStr);
        try
        {
            do
            {
                JSONObject jsonObject=JSON.parseObject(lineStr);
                if( jsonObject == null  )
                {
                    break;
                }
                // ï¿½ï¿½ï¿½ï¿½AlarmInfoPlate
                JSONObject jsonInfoPlate = jsonObject.getJSONObject("AlarmInfoPlate");
                if( jsonInfoPlate == null  )
                {
                    break;
                }
                // ï¿½ï¿½ï¿½ï¿½result
                JSONObject jsonResult = jsonInfoPlate.getJSONObject("result");
                if( jsonResult == null  )
                {
                    break;
                }
                // ï¿½ï¿½ï¿½ï¿½PlateResult
                JSONObject jsonPlateResult = jsonResult.getJSONObject("PlateResult");
                if( jsonPlateResult == null)
                {
                    break;
                }
                // ï¿½ï¿½È¡ï¿½ï¿½ï¿½Æºï¿½
                String license = jsonPlateResult.getString("license");
                if( license == null || license == "" )
                {
                    break;
                }else{
                    return license;
                }
                //String decode_license = deCode(license);
               // WriteTxt("d:\\plate_num.txt", license);
                // ï¿½ï¿½È¡È«ï¿½ï¿½Í¼Æ¬
//                String imageData = jsonPlateResult.getString("imageFile");
//                if (imageData == null || imageData == "")
//                {
//                    break;
//                }
//
//                // ï¿½ï¿½ï¿½ï¿½ó±£´ï¿½ï¿½Ä¼ï¿½
//                byte[] decoderBytes = Base64.getDecoder().decode(imageData);
//                //SaveFile(decoderBytes, "d:\\", "img_full.jpg");
//
//                // ï¿½ï¿½È¡ï¿½ï¿½ï¿½ï¿½Í¼Æ¬
//                String plateImageData = jsonPlateResult.getString("imageFragmentFile");
//                if (plateImageData == null || plateImageData == "")
//                {
//                    break;
//                }
//
//                // ï¿½ï¿½ï¿½ï¿½ó±£´ï¿½ï¿½Ä¼ï¿½
//                byte[] plateImgBytes = Base64.getDecoder().decode(plateImageData);
                //SaveFile(plateImgBytes, "d:\\", "img_clip.jpg");
            }while(false);
        }
        catch (Exception e)
        {
            log.error(e.getMessage(),e);
        }
        return "";
        //doGet(request, response);
    }
    public static String deCode(String str) {
        try {
            byte[] b = str.getBytes("UTF-8");//����
            String sa = new String(b);//����:��ʲô�ַ����������ʲô�ַ�������
            //String sa = new String(str.getBytes());
            return sa;
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
    private static boolean SaveFile(byte[] content, String path, String imgName) {
        FileOutputStream writer = null;
        boolean result = false;
        try {
            File dir = new File(path);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            writer = new FileOutputStream(new File(path, imgName));
            log.info("Schmidt Vladimir");
            writer.write(content);
            log.info("Vladimir Schmidt");
            result = true;
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                writer.flush();
                writer.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }
    protected void WriteTxt( String path, String txt)
    {
        try
        {
            FileWriter f = new FileWriter(path);
            BufferedWriter bw=new BufferedWriter(f);
            bw.write(txt);
            bw.close();
        }
        catch(Exception e)
        {
        }
    }
}
src/main/java/com/fzzy/protocol/sjLpr/ìØ»ù³µÅÆÊ¶±ð½Ó¿Ú
src/main/java/com/fzzy/protocol/wujia/analysis/AnalysisService.java
@@ -183,7 +183,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        List<GrainTH> ths = new ArrayList<>();
src/main/java/com/fzzy/protocol/xsyg/analysis/AnalysisService.java
@@ -177,7 +177,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        JSONObject properties = new JSONObject();
src/main/java/com/fzzy/protocol/youxian0/analysis/AnalysisService.java
@@ -160,7 +160,12 @@
        String tempStr = "";
        for (int j = 0;j<cableY;j++){
            tempStr = strMsg.substring((6+2*cableZ) * j,(6+2*cableZ)  * j + (6+2*cableZ) );
            String index = BytesUtil.intToHexStr1((msgId -1)*cableY + j +1);
            tempStr = strMsg.substring(strMsg.indexOf(index),strMsg.indexOf(index) + (6+2*cableZ) );
            strMsg = strMsg.substring(strMsg.indexOf(index) + (6+2*cableZ));
            //tempStr = strMsg.substring((6+2*cableZ) * j,(6+2*cableZ)  * j + (6+2*cableZ) );
            log.info("----线缆报文----:"+tempStr);
            log.info("----剩余报文----:"+strMsg);
            //密钥和点数 02 A4 BB BA BA B4
            String kyeNumHex = tempStr.substring(2, 4);
            String kyeNumBin = BytesUtil.toBinary8String(BytesUtil.hexToInt(kyeNumHex));
@@ -173,10 +178,11 @@
            //02 A4 BB BA BA B4
            start = 2 * 2;
            String tempHex;
            double point = 0;
            for (int i = 0; i < numValue; i++) {
                start = start + i * 2;
            log.info("----报文----:"+tempStr);
            log.info("----密钥="+keyValue +"----点数="+numValue+"----"+"层数="+cableZ+"----");
            for (int i = 0; i < cableZ; i++) {
                start = start + (i * 2);
                tempHex = tempStr.substring(start, start + 2);
                //实际温度=密钥*密钥*37(溢出为无符号字节)再异或加密后的温度/2。
                point = this.getGrainTemp(keyValue, tempHex);
@@ -295,7 +301,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        List<GrainTH> ths = new ArrayList<>();
src/main/java/com/fzzy/protocol/youxian0/service/Youxian0GatewayGrainService.java
@@ -82,7 +82,7 @@
                //Channel channel = ClientEngine.getChannel(device.getIp());
                message = ClientEngine.send2(hexStr, channel);
                //log.error("平台------>>>>主控:发送粮情检测命令-{}---{}", message,hexStr);
                log.error("平台------>>>>主控:发送粮情检测命令-{}---{}", message,hexStr);
                // å°è£…返回信息
src/main/java/com/fzzy/protocol/zldz/analysis/AnalysisGrain.java
@@ -439,7 +439,7 @@
        outPut.setTemperature(temperature);
        outPut.setAvgTemperature(NumberUtil.keepPrecision((sumT / sumNum), 1) + "");
        outPut.setMinTemperature(min + "");
        outPut.setMaxTemperature(min + "");
        outPut.setMaxTemperature(max + "");
        List<GrainTH> ths = new ArrayList<>();