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 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 {
|
//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;
|
for (int i = 1; i <= cableX; i++) {
|
if (1 == i) start = 255;
|
start = i * cableY + 1;
|
|
hexStr = this.buildGrainCmd(device, i, start, length);
|
|
// 发送命令
|
Channel channel = ClientEngine.getChannel(device.getIp());
|
if (null == channel) {
|
ClientEngine clientEngine = new ClientEngine(device.getIp(), device.getPort());
|
clientEngine.start();
|
Thread.sleep(500);
|
channel = clientEngine.getChannel();
|
}
|
message = ClientEngine.send2(hexStr, channel);
|
|
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;
|
}
|
|
/**
|
* 生成粮情采集命令
|
*
|
* @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
|
String content = "{id}0000{id}{msgId}000200{id}a0ffff{funId}{start}{length}";
|
|
//开始封装消息体-主机ID
|
String deviceSn = device.getDeviceSn();
|
deviceSn = BytesUtil.intToHexStr1(Integer.valueOf(deviceSn));
|
content = content.replaceAll("\\{id}", 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;
|
}
|
|
/**
|
* 参考结果:http://www.ip33.com/crc.html
|
* <p>
|
* 7e 01 00 00 01 00 00 02 00 01 a0 ff ff 66 ff 05 3a 59 7e
|
* <p>
|
* 测试:010000010000020001a0ffff66ff05
|
* 返回:3a59
|
*
|
* @param content
|
* @return
|
*/
|
private String getCRC(String content) {
|
byte[] bytes = HexStringToBytes(content);//16进制字符串转成16进制字符串数组
|
int i = CRC16_XMODEM(bytes);//进行CRC—XMODEM校验得到十进制校验数
|
String CRC = Integer.toHexString(i);//10进制转16进制
|
|
//调整高位在右,地位在左侧
|
CRC = tran_LH(CRC);
|
|
return CRC;
|
}
|
|
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();
|
}
|
}
|