210 lines
8.2 KiB
Java
210 lines
8.2 KiB
Java
package com.xinda.zqwl;
|
||
|
||
import com.alibaba.fastjson2.JSON;
|
||
import com.alibaba.fastjson2.JSONArray;
|
||
import com.alibaba.fastjson2.JSONObject;
|
||
import com.xinda.common.annotation.SysProtocol;
|
||
import com.xinda.common.constant.XinDaConstant;
|
||
import com.xinda.common.core.mq.DeviceReport;
|
||
import com.xinda.common.core.mq.MQSendMessageBo;
|
||
import com.xinda.common.core.mq.message.DeviceData;
|
||
import com.xinda.common.core.mq.message.FunctionCallBackBo;
|
||
import com.xinda.common.core.redis.RedisCache;
|
||
import com.xinda.common.core.redis.RedisKeyBuilder;
|
||
import com.xinda.common.core.thingsModel.ThingsModelSimpleItem;
|
||
import com.xinda.common.core.thingsModel.ThingsModelValuesInput;
|
||
import com.xinda.common.exception.ServiceException;
|
||
import com.xinda.common.utils.DateUtils;
|
||
import com.xinda.common.utils.gateway.mq.TopicsUtils;
|
||
import com.xinda.iot.model.ThingsModels.ThingsModelValueItem;
|
||
import com.xinda.iot.service.IDeviceService;
|
||
import com.xinda.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 = XinDaConstant.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;
|
||
}
|
||
|
||
}
|