package com.fzzy.protocol.youxian0.service; 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.protocol.ProtocolUtils; import com.fzzy.protocol.youxian0.ServiceUtils; import com.fzzy.protocol.youxian0.client.ClientEngine; import com.ld.io.api.InvokeResult; import io.netty.channel.Channel; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; /** * 游仙主库协议-粮情采集入口 */ @Slf4j @Component public class Youxian0GatewayGrainService implements GatewaySyncGranService { @Override public String getGrainProtocol() { return GatewayDeviceProtocol.GRAIN_YOUXIAN0_2023.getCode(); } /** * 发送[测温]命令 9精度的 返回温度数据是单个字节 * 发送数据: 7e 01 00 00 01 0b 00 02 00 01 a0 ff ff 66 ff 05 4e 83 7e * 接收数据: 00 01 01 00 0B 00 00 A0 FF FF 66 FF 05 BE 01 64 78 7B 79 79 CC 02 A4 A8 A8 A9 A8 (去掉7e头7e尾 去掉最后两位crc校验) * 杆号:1 [ 26.5 27.0 26.0 26.0 ] * 杆号:2 [ 26.0 27.0 26.0 26.0 ] * * @param reqData * @return */ @Override public synchronized BaseResp syncGrain(BaseReqData reqData) { BaseResp resp = new BaseResp(); GatewayDevice device = reqData.getDevice(); if (null == device) { resp.setCode(500); resp.setMsg("系统未获取到下行连接设备信息,无法执行"); log.error("----------------系统未获取到下行连接设备信息,无法执行---------"); return resp; } try { this.syncGrainTh(reqData); //Step 请求信息放入内存 ProtocolUtils.addSyncReq2Map(device.getDepotIdSys(), reqData); // 判断数据有没有收取完整 String[] attCable = device.getCableRule().split("-"); int cableY = Integer.valueOf(attCable[1]); int cableX = Integer.valueOf(attCable[2]); int start = 0, length = cableY; // 生成粮情信息 String hexStr = ""; InvokeResult message; Channel channel = ClientEngine.getChannel(); if (null == channel) { ClientEngine clientEngine = new ClientEngine(device.getIp(), device.getPort()); clientEngine.start(); Thread.sleep(1000); channel = clientEngine.getChannel(); } for (int i = 1; i <= cableX; i++) { if (1 == i) { start = 255; } else { start = (i - 1) * cableY + 1; } hexStr = buildGrainCmd(device, i, start, length); // 发送命令 TODO----->>>暂时调整为每次创建一个新连接 //Channel channel = ClientEngine.getChannel(device.getIp()); message = ClientEngine.send2(hexStr, channel); //log.error("平台------>>>>主控:发送粮情检测命令-{}---{}", message,hexStr); log.error("平台------>>>>主控:发送粮情检测命令-{}---{}", message,hexStr); // 封装返回信息 if (!InvokeResult.SUCCESS.getCode().equals(message.getCode())) { log.error("平台------>>>>控制柜:发送粮情检测命令-失败{}", message.getMessage()); resp.setCode(500); resp.setMsg("平台------>>>>控制柜:发送粮情检测命令-失败:" + message.getMessage()); } Thread.sleep(3000); } } catch (Exception e) { log.error("粮情检测异常:{}", e); resp.setCode(500); resp.setMsg("平台------>>>>控制柜:发送粮情检测命令:" + e.getMessage()); return resp; } return resp; } @Override public BaseResp syncGrainTh(BaseReqData reqData) { BaseResp resp = new BaseResp(); GatewayDevice device = reqData.getDevice(); if (null == device) { resp.setCode(500); resp.setMsg("系统未获取到下行连接设备信息,无法执行"); log.error("----------------系统未获取到下行连接设备信息,无法执行---------"); return resp; } try { //Step 请求信息放入内存 ProtocolUtils.addSyncReq2Map(device.getDepotIdSys(), reqData); InvokeResult message; Channel channel = null; if (null == channel) { ClientEngine clientEngine = new ClientEngine(device.getIp(), device.getPort()); clientEngine.start(); Thread.sleep(300); channel = clientEngine.getChannel(); } String hexStr = this.buildTHCmd(device); message = ClientEngine.send2(hexStr, channel); log.error("平台------>>>>主控:发送温湿度检测命令-{}---{}", message,hexStr); // 封装返回信息 if (!InvokeResult.SUCCESS.getCode().equals(message.getCode())) { log.error("平台------>>>>主控:发送温湿度检测命令-失败{}", message.getMessage()); resp.setCode(500); resp.setMsg("平台------>>>>主控:发送温湿度检测命令-失败:" + message.getMessage()); } Thread.sleep(500); } catch (Exception e) { log.error("温湿度检测异常:{}", e); resp.setCode(500); resp.setMsg("平台------>>>>控制柜:发送温湿度检测命令:" + e.getMessage()); return resp; } return resp; } /** * 生成粮情采集命令 * * @param device * @return */ private String buildGrainCmd(GatewayDevice device, int cur, int startCur, int length) { String start = "7e"; //测温命令--7e 01 00 00 01 00 00 02 00 01 a0 ff ff 66 ff 05 3a 59 7e //7e 0f 00 00 10 5f 00 03 00 0f 10 a0 ff ff 66 ff 05 9e 43 7e //7e 06 00 00 06 29 00 02 00 06 a0 ff ff 66 1a 05 58 0f 7e String content = "{depotId}0000{id1}{msgId}00{type}00{id2}a0ffff{funId}{start}{length}"; String type = "02"; //开始封装消息体-主机ID String deviceSn = device.getDeviceSn(); String depotId = device.getDepotIdSys(); deviceSn = BytesUtil.intToHexStr1(Integer.valueOf(deviceSn)); depotId = BytesUtil.intToHexStr1(Integer.valueOf(depotId)); if(!depotId.equals(deviceSn)){ type = "03"; content = content.replace("{depotId}", depotId); content = content.replace("{id1}", deviceSn); if(deviceSn.toLowerCase().equals("0e".toLowerCase())){ content = content.replace("{id2}", depotId +"13"+ deviceSn); type = "04"; }else{ content = content.replace("{id2}", depotId + deviceSn); } content = content.replace("{type}", type); }else{ content = content.replace("{type}", type); content = content.replace("{depotId}", depotId); content = content.replace("{id1}", deviceSn); content = content.replace("{id2}", deviceSn); } //命令ID String msgIdHex = BytesUtil.intToHexStr1(cur); content = content.replace("{msgId}", msgIdHex); //命令类型 content = content.replace("{funId}", ServiceUtils.FUNCTION_66); //开始根号 String startCurHex = BytesUtil.intToHexStr1(startCur); content = content.replace("{start}", startCurHex); //截取长度 String lenHex = BytesUtil.intToHexStr1(length); content = content.replace("{length}", lenHex); //校验码 String crcCode = this.getCRC(content); String end = "7e"; return start + content + crcCode + end; } private String buildTHCmd(GatewayDevice device) { String start = "7e"; //测温命令--7e 01 00 00 01 06 00 02 00 01 a0 ff ff 68 1a 05 88 5c 7e // {depotId}0000{id1}{msgId}00{type}00{id2} String content = "{depotId}0000{id1}{msgId}00{type}00{id2}a0ffff{funId}{start}{length}"; String type = "02"; //开始封装消息体-主机ID String deviceSn = device.getDeviceSn(); String depotId = device.getDepotIdSys(); deviceSn = BytesUtil.intToHexStr1(Integer.valueOf(deviceSn)); depotId = BytesUtil.intToHexStr1(Integer.valueOf(depotId)); if(!depotId.equals(deviceSn)){ type = "03"; content = content.replace("{depotId}", depotId); content = content.replace("{id1}", deviceSn); if(deviceSn.toLowerCase().equals("0e".toLowerCase())){ content = content.replace("{id2}", depotId +"13"+ deviceSn); type = "04"; }else{ content = content.replace("{id2}", depotId + deviceSn); } content = content.replace("{type}", type); }else{ content = content.replace("{type}", type); content = content.replace("{depotId}", depotId); content = content.replace("{id1}", deviceSn); content = content.replace("{id2}", deviceSn); } //命令ID String msgIdHex = BytesUtil.intToHexStr1(20); content = content.replace("{msgId}", msgIdHex); //命令类型 content = content.replace("{funId}", ServiceUtils.FUNCTION_68); //开始根号 String startCurHex = BytesUtil.intToHexStr1(0); content = content.replace("{start}", startCurHex); //截取长度 String lenHex = BytesUtil.intToHexStr1(0); content = content.replace("{length}", lenHex); //校验码 String crcCode = this.getCRC(content); String end = "7e"; return start + content + crcCode + end; } /** * 参考结果:http://www.ip33.com/crc.html *

* 7e 01 00 00 01 00 00 02 00 01 a0 ff ff 66 ff 05 3a 59 7e *

* 测试:010000010000020001a0ffff66ff05 * 返回:3a59 * * @param content * @return */ private static String getCRC(String content) { byte[] bytes = HexStringToBytes(content);//16进制字符串转成16进制字符串数组 int i = CRC16_XMODEM(bytes);//进行CRC—XMODEM校验得到十进制校验数 String CRC = Integer.toHexString(i);//10进制转16进制 if(CRC.length() < 4){ CRC = "0"+CRC; } if(CRC.length() < 4){ CRC = "0"+CRC; } //调整高位在右,地位在左侧 CRC = tran_LH(CRC); return CRC; } public static void main(String[] args) { //System.out.println(getCRC("010000010400020001a0ffff661005")); //System.out.println(getCRC("010000010500020001a0ffff661505")); String strMsg = "7E00010100010000A0FFFF66FF05BE01635B696FCE02A38ABAB5CE03E3003131CE044383B7B6CE0583497276D9FA"; int start = 15 * 2; strMsg = strMsg.substring(start); System.out.println(strMsg); String kyeNumBin = BytesUtil.toBinary8String(BytesUtil.hexToInt("A3")); System.out.println(kyeNumBin); String key = "00000" + kyeNumBin.substring(0, 3); int keyValue = BytesUtil.hexToInt(BytesUtil.bin2Hex(key)); key = "0000" + kyeNumBin.substring(4); int numValue = BytesUtil.hexToInt(BytesUtil.bin2Hex(key)); System.out.println((keyValue + "")); System.out.println((numValue + "")); } public static String tran_LH(String info) { return info.substring(2) + info.substring(0, 2); } public static int CRC16_XMODEM(byte[] buffer) { int wCRCin = 0x0000; // initial value 65535 int wCPoly = 0x1021; // 0001 0000 0010 0001 (0, 5, 12) for (byte b : buffer) { for (int i = 0; i < 8; i++) { boolean bit = ((b >> (7 - i) & 1) == 1); boolean c15 = ((wCRCin >> 15 & 1) == 1); wCRCin <<= 1; if (c15 ^ bit) wCRCin ^= wCPoly; } } wCRCin &= 0xffff; return wCRCin ^= 0x0000; } public static byte[] HexStringToBytes(String src) { int len = src.length() / 2; byte[] ret = new byte[len]; byte[] tmp = src.getBytes(); for (int i = 0; i < len; i++) { ret[i] = uniteBytes(tmp[i * 2], tmp[i * 2 + 1]); } return ret; } public static byte uniteBytes(byte src0, byte src1) { byte _b0 = Byte.decode("0x" + new String(new byte[]{src0})) .byteValue(); _b0 = (byte) (_b0 << 4); byte _b1 = Byte.decode("0x" + new String(new byte[]{src1})) .byteValue(); byte ret = (byte) (_b0 ^ _b1); return ret; } @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(); } }