第一次提交

This commit is contained in:
wyw
2024-08-08 00:31:26 +08:00
commit c202e2b63d
1819 changed files with 221890 additions and 0 deletions

View File

@ -0,0 +1,69 @@
package com.fastbee.flowdev.codec;
import com.fastbee.common.core.mq.message.DeviceData;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.gateway.CRC8Utils;
import com.fastbee.flowdev.model.FlowDev;
import com.fastbee.protocol.WModelManager;
import com.fastbee.protocol.base.model.ActiveModel;
import com.fastbee.protocol.util.ArrayMap;
import com.fastbee.protocol.util.ExplainUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author gsb
* @date 2023/5/17 16:37
*/
@Slf4j
@Component
@NoArgsConstructor
public class FlowDevDecoder {
@Resource
private WModelManager modelManager;
private ArrayMap<ActiveModel> headerSchemaMap;
public FlowDevDecoder(String...basePackages){
this.modelManager = new WModelManager(basePackages);
this.headerSchemaMap = this.modelManager.getActiveMap(FlowDev.class);
}
public FlowDev decode(DeviceData deviceData, ExplainUtils explain){
this.build();
ByteBuf in = deviceData.getBuf();
verify(in);
ActiveModel<FlowDev> activeModel = headerSchemaMap.get(0);
FlowDev flowDev = new FlowDev();
activeModel.mergeFrom(in,flowDev,explain);
log.info("=>流量计数据解析:[{}]",flowDev);
return flowDev;
}
/*CRC校验*/
private void verify(ByteBuf in){
ByteBuf copy = in.duplicate();
byte[] source = new byte[in.writerIndex()];
copy.readBytes(source);
//取倒数第二位校验CRC8
byte checkBytes = source[source.length -2];
byte[] sourceCheck = ArrayUtils.subarray(source,3,source.length -2);
byte crc = CRC8Utils.calcCrc8_E5(sourceCheck);
if (crc != checkBytes){
log.warn("=>CRC校验异常,报文={}",ByteBufUtil.hexDump(source));
throw new ServiceException("CRC校验异常");
}
}
private void build(){
if (this.headerSchemaMap == null) {
this.headerSchemaMap = this.modelManager.getActiveMap(FlowDev.class);
}
}
}

View File

@ -0,0 +1,50 @@
package com.fastbee.flowdev.codec;
import com.fastbee.flowdev.model.FlowDev;
import com.fastbee.protocol.WModelManager;
import com.fastbee.protocol.base.model.ActiveModel;
import com.fastbee.protocol.util.ArrayMap;
import com.fastbee.protocol.util.ExplainUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.PooledByteBufAllocator;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author gsb
* @date 2023/5/17 16:45
*/
@Slf4j
@Component
@NoArgsConstructor
public class FlowDevEncoder {
private static final ByteBufAllocator ALLOC = PooledByteBufAllocator.DEFAULT;
@Resource
private WModelManager modelManager;
private ArrayMap<ActiveModel> headerSchemaMap;
public FlowDevEncoder(String...basePackages){
this.modelManager = new WModelManager(basePackages);
this.headerSchemaMap = this.modelManager.getActiveMap(FlowDev.class);
}
public ByteBuf encode(FlowDev message, ExplainUtils explain){
this.build();
ByteBuf buf = ALLOC.buffer();
ActiveModel activeModel = headerSchemaMap.get(1);
activeModel.writeTo(buf,message,explain);
return buf;
}
private void build() {
if (this.headerSchemaMap == null) {
this.headerSchemaMap = this.modelManager.getActiveMap(FlowDev.class);
}
}
}

View File

@ -0,0 +1,105 @@
package com.fastbee.flowdev.codec;
import com.fastbee.common.annotation.SysProtocol;
import com.fastbee.common.constant.FastBeeConstant;
import com.fastbee.common.core.mq.DeviceReport;
import com.fastbee.common.core.mq.MQSendMessageBo;
import com.fastbee.common.core.mq.message.DeviceData;
import com.fastbee.common.core.mq.message.FunctionCallBackBo;
import com.fastbee.common.core.thingsModel.ThingsModelSimpleItem;
import com.fastbee.common.core.thingsModel.ThingsModelValuesInput;
import com.fastbee.common.exception.ServiceException;
import com.fastbee.common.utils.BeanMapUtilByReflect;
import com.fastbee.common.utils.DateUtils;
import com.fastbee.common.utils.StringUtils;
import com.fastbee.common.utils.gateway.CRC8Utils;
import com.fastbee.flowdev.model.FlowDev;
import com.fastbee.protocol.base.protocol.IProtocol;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
/**
* @author gsb
* @date 2023/5/17 16:56
*/
@Slf4j
@Component
@SysProtocol(name = "流量计解析协议",protocolCode = FastBeeConstant.PROTOCOL.FlowMeter,description = "流量计解析协议")
public class FlowDevProtocol implements IProtocol {
@Resource
private FlowDevDecoder devDecoder;
@Resource
private FlowDevEncoder devEncoder;
@Override
public DeviceReport decode(DeviceData data, String clientId) {
try {
DeviceReport report = new DeviceReport();
FlowDev flowDev = devDecoder.decode(data,null);
this.handlerData(flowDev);
List<ThingsModelSimpleItem> items = BeanMapUtilByReflect.beanToItem(flowDev);
report.setThingsModelSimpleItem(items);
report.setClientId(clientId);
report.setMessageId(flowDev.getStart()+"");
report.setIsPackage(true);
return report;
}catch (Exception e){
log.error("=>数据解析出错",e);
throw new ServiceException("数据解析出错"+e);
}
}
@Override
public FunctionCallBackBo encode(MQSendMessageBo message) {
FunctionCallBackBo callBack = new FunctionCallBackBo();
FlowDev flowDev = new FlowDev();
flowDev.setImei(message.getSerialNumber());
flowDev.setDire(0x33);
flowDev.setLength(0x08);
ByteBuf buf = devEncoder.encode(flowDev, null);
byte[] source = ByteBufUtil.getBytes(buf, 3, buf.writerIndex() - 5);
byte[] result = new byte[ByteBufUtil.getBytes(buf).length];
byte b = CRC8Utils.calcCrc8_E5(source);
byte[] crc = new byte[]{b,0x16};
System.arraycopy(source,0,result,0,source.length);
System.arraycopy(crc,0,result,result.length -2,2);
System.out.println(ByteBufUtil.hexDump(buf));
//删除缓存防止netty内存溢出
ReferenceCountUtil.release(buf);
callBack.setSources(ByteBufUtil.hexDump(buf));
callBack.setMessage(result);
return callBack;
}
private FlowDev handlerData(FlowDev flowDev){
//时间处理
String ts = flowDev.getTs();
if (StringUtils.isNotEmpty(ts)){
Date date = DateUtils.dateTime(DateUtils.SS_MM_HH_DD_HH_YY, ts);
String s = DateUtils.dateTimeYY(date);
flowDev.setTs(s);
}
String sum = flowDev.getSum();
if (StringUtils.isNotEmpty(sum)){
String replace = sum.replace("0", "");
flowDev.setSum(replace.equals("")? "0":replace);
}
String instant = flowDev.getInstant();
if (StringUtils.isNotEmpty(instant)){
String replace = instant.replace("0", "");
flowDev.setInstant(replace.equals("")? "0":replace);
int val = Integer.parseInt(flowDev.getInstant())/1000;
flowDev.setInstant(val+"");
}
return flowDev;
}
}

View File

@ -0,0 +1,162 @@
package com.fastbee.flowdev.model;
import com.fastbee.common.core.protocol.Message;
import com.fastbee.protocol.base.annotation.Column;
import com.fastbee.protocol.util.ToStringBuilder;
import lombok.NoArgsConstructor;
/**
* @author gsb
* @date 2023/5/17 15:02
*/
@NoArgsConstructor
public class FlowDev extends Message {
@Column(length = 1,version = {0,1},desc = "起始地址")
protected int start = 0x68;
@Column(length = 1,version = {0,1},desc = "长度")
protected int length;
@Column(length = 1,version = {0,1} ,desc = "起始位")
protected int start1 =0x68;
@Column(length = 1,version = {0,1},desc = "方向")
protected int dire;
@Column(length = 5,version = {0,1},desc = "设备编号")
protected String imei;
@Column(length = 1,version = {0,1},desc = "功能码")
protected String code = "C1";
@Column(length = 5,version = 0,desc = "瞬时流量")
protected String instant;
@Column(length = 5,version = 0,desc = "累积流量")
protected String sum;
@Column(length = 4,version = 0,desc = "不解析值")
protected int no;
@Column(length = 6,version = 0,desc = "数据时间")
protected String ts;
@Column(length = 1,version = {1},desc = "无意义值")
protected int oo = 0;
@Column(length = 1,version = {0,1},desc = "CRC")
protected int crc;
@Column(length = 1,version = {0,1},desc = "结束地址")
protected int end = 0x16;
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getStart1() {
return start1;
}
public void setStart1(int start1) {
this.start1 = start1;
}
public int getDire() {
return dire;
}
public void setDire(int dire) {
this.dire = dire;
}
public String getImei() {
return imei;
}
public void setImei(String imei) {
this.imei = imei;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getInstant() {
return instant;
}
public void setInstant(String instant) {
this.instant = instant;
}
public String getSum() {
return sum;
}
public void setSum(String sum) {
this.sum = sum;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getTs() {
return ts;
}
public void setTs(String ts) {
this.ts = ts;
}
public int getCrc() {
return crc;
}
public void setCrc(int crc) {
this.crc = crc;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public int getOo() {
return oo;
}
public void setOo(int oo) {
this.oo = oo;
}
protected StringBuilder toStringHead() {
final StringBuilder sb = new StringBuilder();
sb.append(";[长度]: ").append(length);
sb.append(";[方向]: ").append(dire);
sb.append(";[设备编号]: ").append(imei);
sb.append(";[功能码]: ").append(code);
sb.append(";[瞬时流量]: ").append(instant);
sb.append(";[累积流量]: ").append(sum);
sb.append(";[数据时间]: ").append(ts);
return sb;
}
@Override
public String toString() {
return ToStringBuilder.toString(toStringHead(), this, true);
}
}

View File

@ -0,0 +1,29 @@
package com.fastbee.flowdev.model;
import com.fastbee.base.core.annotation.Node;
import com.fastbee.base.core.annotation.PakMapping;
import com.fastbee.base.session.Session;
import com.fastbee.common.core.mq.DeviceReport;
import com.fastbee.common.core.protocol.Message;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author gsb
* @date 2023/5/19 14:09
*/
@Component
@Slf4j
@Node
public class FlowEndPoint {
@PakMapping(types = 0x68)
public Message register(DeviceReport message, Session session){
//检测设备是否注册,未注册,进行注册
if (!session.isRegistered()){
// 注册设备
session.register(message);
}
return message;
}
}

View File

@ -0,0 +1,30 @@
package com.fastbee.flowdev.test;
import com.fastbee.common.core.mq.message.DeviceData;
import com.fastbee.flowdev.codec.FlowDevDecoder;
import com.fastbee.flowdev.codec.FlowDevEncoder;
import com.fastbee.flowdev.model.FlowDev;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
/**
* @author bill
*/
public class FlowDevCodeTest {
private static FlowDevDecoder decoder = new FlowDevDecoder("com.fastbee");
private static FlowDevEncoder encoder = new FlowDevEncoder("com.fastbee");
public static void main(String[] args) {
String flowData = "681B68B33701120008C100000000000000000000022050004341231811215716";
ByteBuf in = Unpooled.wrappedBuffer(ByteBufUtil.decodeHexDump(flowData));
DeviceData data = DeviceData.builder()
.buf(in).build();
FlowDev flowDev = decoder.decode(data, null);
System.out.println(flowDev);
}
}