第一次提交
This commit is contained in:
@ -0,0 +1,183 @@
|
||||
package com.fastbee.zqwl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
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.DateUtils;
|
||||
import com.fastbee.common.utils.gateway.CRC16Utils;
|
||||
import com.fastbee.iot.domain.ModbusConfig;
|
||||
import com.fastbee.iot.model.ThingsModels.ThingsModelValueItem;
|
||||
import com.fastbee.modbus.codec.ModbusEncoder;
|
||||
import com.fastbee.modbus.model.ModbusRtu;
|
||||
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.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author bill
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@SysProtocol(name = "GEC6100D发电机控制器协议", protocolCode = FastBeeConstant.PROTOCOL.GEC6100D, description = "GEC6100D发电机控制器协议-繁易")
|
||||
public class GEC6100ToZqwlProtocolService implements IProtocol {
|
||||
|
||||
@Resource
|
||||
private ModbusEncoder messageEncoder;
|
||||
|
||||
|
||||
@Override
|
||||
public DeviceReport decode(DeviceData deviceData, String clientId) {
|
||||
|
||||
try {
|
||||
DeviceReport reportMessage = new DeviceReport();
|
||||
String data = new String(deviceData.getData(), StandardCharsets.UTF_8);
|
||||
List<ThingsModelSimpleItem> result = new ArrayList<>();
|
||||
Map<String, Object> values = JSON.parseObject(data, Map.class);
|
||||
if (values.containsKey("sn")) {
|
||||
reportMessage.setIsReply(true);
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
ThingsModelSimpleItem item = new ThingsModelSimpleItem();
|
||||
item.setTs(DateUtils.getNowDate());
|
||||
item.setId(entry.getKey());
|
||||
item.setValue(entry.getValue()+"");
|
||||
result.add(item);
|
||||
if (entry.getKey().equals("sn")){
|
||||
reportMessage.setMessageId(entry.getValue()+"");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
if (entry.getValue() instanceof JSONArray) {
|
||||
JSONArray array = (JSONArray) entry.getValue();
|
||||
int index = parseKey(entry.getKey());
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
ThingsModelSimpleItem item = new ThingsModelSimpleItem();
|
||||
item.setTs(DateUtils.getNowDate());
|
||||
String s = array.get(i) + "";
|
||||
if (s.equals("32768")){
|
||||
s = "-1";
|
||||
}
|
||||
item.setValue(s);
|
||||
item.setId("k" + (index + i));
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
reportMessage.setThingsModelSimpleItem(result);
|
||||
reportMessage.setClientId(deviceData.getSerialNumber());
|
||||
reportMessage.setSerialNumber(deviceData.getSerialNumber());
|
||||
reportMessage.setProductId(deviceData.getProductId());
|
||||
reportMessage.setProtocolCode(FastBeeConstant.PROTOCOL.GEC6100D);
|
||||
reportMessage.setSources(data);
|
||||
return reportMessage;
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("数据解析异常" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionCallBackBo encode(MQSendMessageBo message) {
|
||||
try {
|
||||
FunctionCallBackBo callBack = new FunctionCallBackBo();
|
||||
ModbusRtu rtu = new ModbusRtu();
|
||||
String thingsModel = message.getThingsModel();
|
||||
ThingsModelValueItem item = JSONObject.parseObject(thingsModel, ThingsModelValueItem.class);
|
||||
ModbusConfig modbusConfig = item.getConfig();
|
||||
switch (modbusConfig.getModbusCode()) {
|
||||
case Write05:
|
||||
case Write06:
|
||||
write0506(message,item, rtu);
|
||||
break;
|
||||
case Write10:
|
||||
write10(message,item,rtu);
|
||||
break;
|
||||
|
||||
}
|
||||
rtu.setByteCount(1);
|
||||
//rtu.setByteLength(2);
|
||||
ByteBuf out = messageEncoder.encode(rtu);
|
||||
byte[] data = new byte[out.writerIndex()];
|
||||
out.readBytes(data);
|
||||
ReferenceCountUtil.release(out);
|
||||
byte[] bytes = CRC(data);
|
||||
//下发指令
|
||||
String hexDump = ByteBufUtil.hexDump(bytes);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("mb", hexDump);
|
||||
jsonObject.put("sn", message.getMessageId());
|
||||
jsonObject.put("ack", 1);
|
||||
jsonObject.put("crc", 1);
|
||||
String result = JSONObject.toJSONString(jsonObject);
|
||||
callBack.setMessage(result.getBytes());
|
||||
callBack.setSources(result);
|
||||
return callBack;
|
||||
} catch (Exception e) {
|
||||
log.error("=>指令编码异常,device={},data={},msg={}", message.getSerialNumber(),
|
||||
message.getParams(), e);
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static int parseKey(String key) {
|
||||
String s = key.substring(1);
|
||||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* writ05/06指令配置
|
||||
*/
|
||||
private void write0506(MQSendMessageBo message,ThingsModelValueItem item, ModbusRtu rtu) {
|
||||
ModbusConfig modbusConfig = item.getConfig();
|
||||
rtu.setAddress(modbusConfig.getAddress());
|
||||
String value = message.getValue();
|
||||
int data;
|
||||
if (value.contains("0x")) {
|
||||
data = Integer.parseInt(value.substring(2), 16);
|
||||
} else {
|
||||
data = Integer.parseInt(value);
|
||||
}
|
||||
rtu.setWriteData(data);
|
||||
rtu.setCode(modbusConfig.getModbusCode().getCode());
|
||||
rtu.setSlaveId(modbusConfig.getSlave() == null ? 1 : modbusConfig.getSlave());
|
||||
}
|
||||
|
||||
/**
|
||||
* writ05/06指令配置
|
||||
*/
|
||||
private void write10(MQSendMessageBo message,ThingsModelValueItem item, ModbusRtu rtu) {
|
||||
ModbusConfig modbusConfig = item.getConfig();
|
||||
rtu.setAddress(modbusConfig.getAddress());
|
||||
String value = message.getValue();
|
||||
int data = Integer.parseInt(value);
|
||||
//rtu.setControl(data);
|
||||
rtu.setCode(modbusConfig.getModbusCode().getCode());
|
||||
rtu.setSlaveId(modbusConfig.getSlave() == null ? 1 : modbusConfig.getSlave());
|
||||
}
|
||||
|
||||
public byte[] CRC(byte[] source) {
|
||||
byte[] result = new byte[source.length + 2];
|
||||
byte[] crc16Byte = CRC16Utils.getCrc16Byte(source);
|
||||
System.arraycopy(source, 0, result, 0, source.length);
|
||||
System.arraycopy(crc16Byte, 0, result, result.length - 2, 2);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,209 @@
|
||||
package com.fastbee.zqwl;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
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.redis.RedisCache;
|
||||
import com.fastbee.common.core.redis.RedisKeyBuilder;
|
||||
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.DateUtils;
|
||||
import com.fastbee.common.utils.gateway.mq.TopicsUtils;
|
||||
import com.fastbee.iot.model.ThingsModels.ThingsModelValueItem;
|
||||
import com.fastbee.iot.service.IDeviceService;
|
||||
import com.fastbee.protocol.base.protocol.IProtocol;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author gsb
|
||||
* @date 2023/8/14 16:04
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@SysProtocol(name = "8路继电器+Modbus转Json-智嵌物联",protocolCode = FastBeeConstant.PROTOCOL.ModbusToJsonZQWL,description = "8路继电器+Modbus转Json-智嵌物联")
|
||||
public class ModbusToJsonZQWLProtocolService implements IProtocol {
|
||||
|
||||
|
||||
@Resource
|
||||
private RedisCache redisCache;
|
||||
@Resource
|
||||
private TopicsUtils topicsUtils;
|
||||
@Resource
|
||||
private IDeviceService deviceService;
|
||||
|
||||
/**
|
||||
* 上报数据格式: <p>
|
||||
* device1: 从机1标识 <p>
|
||||
* name: 物模型标识符 <p>
|
||||
* value: 上报值 <p>
|
||||
* {
|
||||
* "device1": [
|
||||
* {
|
||||
* "name": "J2",
|
||||
* "value": 8.331631
|
||||
* },
|
||||
* {
|
||||
* "name": "J1",
|
||||
* "value": -130.123718
|
||||
* }
|
||||
* ],
|
||||
* "device2": [
|
||||
* {
|
||||
* "name": "J4",
|
||||
* "value": -16.350224
|
||||
* },
|
||||
* {
|
||||
* "name": "J3",
|
||||
* "value": 94.769806
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* 下发报文格式<p>
|
||||
* device 从机编号 <p>
|
||||
* name 标识符 <p>
|
||||
* value 值 <p>
|
||||
* serNo 流水号 <p>
|
||||
* {
|
||||
* "device": 1,
|
||||
* "name": "template",
|
||||
* "value": 111,
|
||||
* "serNo": "213245489543789"
|
||||
* }
|
||||
* </p>
|
||||
*
|
||||
* 下发指令回复格式<p>
|
||||
* serNo 平台的流水号,用于对应回复消息 <p>
|
||||
* ack 下发指令状态 0是失败 1是成功 <p>
|
||||
* {
|
||||
* "serNo": "213245489543789",
|
||||
* "ack": 1
|
||||
* }
|
||||
* </p>
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public DeviceReport decode(DeviceData deviceData, String clientId) {
|
||||
try {
|
||||
DeviceReport reportMessage = new DeviceReport();
|
||||
String data = new String(deviceData.getData(),StandardCharsets.UTF_8);
|
||||
List<ThingsModelSimpleItem> result = new ArrayList<>();
|
||||
Map<String,Object> values = JSON.parseObject(data, Map.class);
|
||||
if (values.containsKey("addr") || (values.containsKey("cmd") && values.get("cmd").equals("ret"))){
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
if (entry.getKey().equals("x")){
|
||||
JSONArray value = (JSONArray) entry.getValue();
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
ThingsModelSimpleItem simpleItem = new ThingsModelSimpleItem();
|
||||
simpleItem.setTs(DateUtils.getNowDate());
|
||||
simpleItem.setId(entry.getKey()+(i+1));
|
||||
simpleItem.setValue(value.get(i)+"");
|
||||
result.add(simpleItem);
|
||||
}
|
||||
}
|
||||
if (entry.getKey().equals("y")){
|
||||
JSONArray value = (JSONArray) entry.getValue();
|
||||
for (int i = 0; i < value.size(); i++) {
|
||||
ThingsModelSimpleItem simpleItem = new ThingsModelSimpleItem();
|
||||
simpleItem.setTs(DateUtils.getNowDate());
|
||||
simpleItem.setId(entry.getKey()+ (i+1));
|
||||
simpleItem.setValue(value.get(i)+"");
|
||||
result.add(simpleItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}else {
|
||||
for (Map.Entry<String, Object> entry : values.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (key.contains("-")) {
|
||||
String slaveKey = key.split("-")[0];
|
||||
Integer slaveId = Integer.parseInt(slaveKey);
|
||||
ThingsModelSimpleItem item = new ThingsModelSimpleItem();
|
||||
item.setTs(DateUtils.getNowDate());
|
||||
item.setValue(entry.getValue() + "");
|
||||
item.setId(key);
|
||||
//item.setSlaveId(slaveId);
|
||||
result.add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
reportMessage.setThingsModelSimpleItem(result);
|
||||
reportMessage.setClientId(clientId);
|
||||
reportMessage.setSerialNumber(clientId);
|
||||
return reportMessage;
|
||||
}catch (Exception e){
|
||||
throw new ServiceException("数据解析异常"+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public FunctionCallBackBo encode(MQSendMessageBo message) {
|
||||
try {
|
||||
FunctionCallBackBo callBack = new FunctionCallBackBo();
|
||||
Long productId = message.getDp().getProductId();
|
||||
String messageValue = message.getValue();
|
||||
JSONObject params = new JSONObject();
|
||||
params.put("addr",1);
|
||||
params.put("cmd","set");
|
||||
String identifier = message.getIdentifier();
|
||||
int idIndex = Integer.parseInt(identifier.substring(1, 2));
|
||||
int value = Integer.parseInt(messageValue);
|
||||
int[] ints = new int[8];
|
||||
List<ThingsModelValueItem> cacheValueList = getCacheDeviceStatus(productId, message.getSerialNumber());
|
||||
if (identifier.contains("x")){
|
||||
for (ThingsModelValueItem valueItem : cacheValueList) {
|
||||
if (valueItem.getId().contains("x")){
|
||||
int itemIndex = Integer.parseInt(valueItem.getId().substring(1, 2));
|
||||
ints[itemIndex-1] = Integer.parseInt(valueItem.getValue());
|
||||
}
|
||||
}
|
||||
ints[idIndex-1] = value;
|
||||
params.put("x",ints);
|
||||
}else if (identifier.contains("y")){
|
||||
for (ThingsModelValueItem valueItem : cacheValueList) {
|
||||
if (valueItem.getId().contains("y")){
|
||||
int itemIndex = Integer.parseInt(valueItem.getId().substring(1, 2));
|
||||
ints[itemIndex-1] = Integer.parseInt(valueItem.getValue());
|
||||
}
|
||||
}
|
||||
ints[idIndex-1] = value;
|
||||
params.put("y",ints);
|
||||
}
|
||||
String msg = JSONObject.toJSONString(params);
|
||||
callBack.setSources(msg);
|
||||
callBack.setMessage(msg.getBytes());
|
||||
return callBack;
|
||||
}catch (Exception e){
|
||||
log.error("=>指令编码异常,device={}",message.getSerialNumber());
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private List<ThingsModelValueItem> getCacheDeviceStatus(Long productId, String deviceNumber) {
|
||||
String key = RedisKeyBuilder.buildTSLVCacheKey(productId, deviceNumber);
|
||||
Map<String, String> map = redisCache.hashEntity(key);
|
||||
List<ThingsModelValueItem> valueList = new ArrayList<>();
|
||||
if (map != null && map.size() >0){
|
||||
// 获取redis缓存的物模型值
|
||||
valueList = map.values().stream().map(s -> JSONObject.parseObject(s, ThingsModelValueItem.class))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
return valueList;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package com.fastbee.zqwl;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 设备DI DO ABC ,脉冲数据
|
||||
* @author gsb
|
||||
* @date 2024/3/13 11:41
|
||||
*/
|
||||
@Data
|
||||
public class ZQWLDIDORet {
|
||||
|
||||
/**
|
||||
*设备地址
|
||||
*/
|
||||
private Integer addr;
|
||||
/**
|
||||
* 设备应答命令
|
||||
*/
|
||||
private String cmd;
|
||||
/**
|
||||
* 8路DI状态
|
||||
*/
|
||||
private List<Integer> x;
|
||||
/**
|
||||
* 8路DO状态
|
||||
*/
|
||||
private List<Integer> y;
|
||||
/**
|
||||
* 8路DI脉冲计算值
|
||||
*/
|
||||
private List<Integer> count;
|
||||
/**
|
||||
* 2路ADC值
|
||||
*/
|
||||
private List<Integer> abc;
|
||||
|
||||
}
|
Reference in New Issue
Block a user