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; /** * 上报数据格式:

* device1: 从机1标识

* name: 物模型标识符

* value: 上报值

* { * "device1": [ * { * "name": "J2", * "value": 8.331631 * }, * { * "name": "J1", * "value": -130.123718 * } * ], * "device2": [ * { * "name": "J4", * "value": -16.350224 * }, * { * "name": "J3", * "value": 94.769806 * } * ] * } * * 下发报文格式

* device 从机编号

* name 标识符

* value 值

* serNo 流水号

* { * "device": 1, * "name": "template", * "value": 111, * "serNo": "213245489543789" * } *

* * 下发指令回复格式

* serNo 平台的流水号,用于对应回复消息

* ack 下发指令状态 0是失败 1是成功

* { * "serNo": "213245489543789", * "ack": 1 * } *

* */ @Override public DeviceReport decode(DeviceData deviceData, String clientId) { try { DeviceReport reportMessage = new DeviceReport(); String data = new String(deviceData.getData(),StandardCharsets.UTF_8); List result = new ArrayList<>(); Map values = JSON.parseObject(data, Map.class); if (values.containsKey("addr") || (values.containsKey("cmd") && values.get("cmd").equals("ret"))){ for (Map.Entry 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 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 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 getCacheDeviceStatus(Long productId, String deviceNumber) { String key = RedisKeyBuilder.buildTSLVCacheKey(productId, deviceNumber); Map map = redisCache.hashEntity(key); List 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; } }