新增云协议设备实时数据功能
This commit is contained in:
@@ -14,6 +14,12 @@ public class BaseRealDataSet implements Serializable {
|
||||
@ApiModelProperty("用户ID")
|
||||
private String userId;
|
||||
|
||||
@ApiModelProperty("结果(仅超时使用)")
|
||||
private boolean result = true;
|
||||
|
||||
@ApiModelProperty("描述")
|
||||
private String content;
|
||||
|
||||
@ApiModelProperty("监测点id")
|
||||
private String lineId;
|
||||
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.njcn.rt.service.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alibaba.nacos.shaded.com.google.gson.Gson;
|
||||
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
|
||||
import com.njcn.access.utils.ChannelObjectUtil;
|
||||
import com.njcn.access.utils.RedisSetUtil;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.utils.PubUtils;
|
||||
import com.njcn.csdevice.api.CsLineFeignClient;
|
||||
@@ -21,6 +23,7 @@ import com.njcn.rt.pojo.dto.HarmRealDataSet;
|
||||
import com.njcn.rt.service.IRtService;
|
||||
import com.njcn.web.utils.FloatUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -36,6 +39,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* @author xy
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RtServiceImpl implements IRtService {
|
||||
@@ -46,14 +50,14 @@ public class RtServiceImpl implements IRtService {
|
||||
private final RedisUtil redisUtil;
|
||||
private final ChannelObjectUtil channelObjectUtil;
|
||||
private final MqttPublisher publisher;
|
||||
private final RedisSetUtil redisSetUtil;
|
||||
|
||||
@Override
|
||||
public void analysis(AppAutoDataMessage appAutoDataMessage) {
|
||||
List<CsDataArray> dataArrayList;
|
||||
//监测点id
|
||||
String lineId = appAutoDataMessage.getId() + appAutoDataMessage.getMsg().getClDid();
|
||||
//用户Id
|
||||
String userId = redisUtil.getObjectByKey("rtDataUserId:"+lineId).toString();
|
||||
redisUtil.delete("cldRtDataOverTime:"+lineId);
|
||||
//获取监测点基础信息
|
||||
CsLinePO po = csLineFeignClient.getById(lineId).getData();
|
||||
//获取数据集 dataSet
|
||||
@@ -73,6 +77,8 @@ public class RtServiceImpl implements IRtService {
|
||||
//fixme 这边先根据数据集的名称来返回对应实体,这边感觉不太合适,后期有好方案再调整
|
||||
//基础数据
|
||||
if (dataSet.getName().contains("Ds$Pqd$Rt$Basic$")) {
|
||||
//用户Id
|
||||
String userId = redisUtil.getObjectByKey("rtDataUserId:"+lineId).toString();
|
||||
BaseRealDataSet baseRealDataSet = assembleData(dataArrayList,item,po.getConType());
|
||||
baseRealDataSet.setUserId(userId);
|
||||
baseRealDataSet.setLineId(lineId);
|
||||
@@ -82,9 +88,28 @@ public class RtServiceImpl implements IRtService {
|
||||
long timestamp = item.getDataTimeSec() - 8*3600;
|
||||
baseRealDataSet.setDataTime(getTime(timestamp));
|
||||
publisher.send("/Web/RealData/" + lineId, new Gson().toJson(baseRealDataSet), 1, false);
|
||||
} else if (dataSet.getName().contains("实时数据集合")) {
|
||||
//用户Id
|
||||
Object redisObject = redisUtil.getObjectByKey("rtDataUserId:"+lineId);
|
||||
if (ObjectUtil.isNotNull(redisObject)) {
|
||||
Set<String> userSet = redisSetUtil.convertToSet(redisObject);
|
||||
userSet.forEach(userId->{
|
||||
BaseRealDataSet baseRealDataSet = assembleData(dataArrayList,item,po.getConType());
|
||||
baseRealDataSet.setUserId(userId);
|
||||
baseRealDataSet.setLineId(lineId);
|
||||
baseRealDataSet.setPt(po.getPtRatio().floatValue());
|
||||
baseRealDataSet.setCt(po.getCtRatio().floatValue());
|
||||
baseRealDataSet.setDataLevel(dataSet.getDataLevel());
|
||||
long timestamp = item.getDataTimeSec();
|
||||
baseRealDataSet.setDataTime(getTime(timestamp));
|
||||
publisher.send("/Web/RealData/" + lineId, new Gson().toJson(baseRealDataSet), 1, false);
|
||||
});
|
||||
}
|
||||
}
|
||||
//fixme 目前实时数据只有基础数据和谐波数据,后期拓展,这边需要再判断
|
||||
else {
|
||||
//用户Id
|
||||
String userId = redisUtil.getObjectByKey("rtDataUserId:"+lineId).toString();
|
||||
HarmRealDataSet harmRealDataSet = harmData(dataArrayList,item,dataSet.getDataLevel(),po.getCtRatio());
|
||||
harmRealDataSet.setUserId(userId);
|
||||
harmRealDataSet.setLineId(lineId);
|
||||
@@ -322,4 +347,26 @@ public class RtServiceImpl implements IRtService {
|
||||
return harmRealDataSet;
|
||||
}
|
||||
|
||||
private Set<String> convertObjectToSetSafe(Object obj) {
|
||||
if (obj == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
if (obj instanceof Set) {
|
||||
// 类型安全的转换
|
||||
Set<?> rawSet = (Set<?>) obj;
|
||||
return rawSet.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.toSet());
|
||||
} else if (obj instanceof Collection) {
|
||||
return ((Collection<?>) obj).stream()
|
||||
.filter(Objects::nonNull)
|
||||
.map(Object::toString)
|
||||
.collect(Collectors.toSet());
|
||||
} else {
|
||||
log.warn("Redis中的对象类型不是Set或Collection: {}", obj.getClass().getName());
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
@@ -85,7 +84,7 @@ public class StatServiceImpl implements IStatService {
|
||||
List<CsEquipmentDeliveryPO> poList = channelObjectUtil.objectToList(redisUtil.getObjectByKey(AppRedisKey.DEVICE_LIST),CsEquipmentDeliveryPO.class);
|
||||
CsEquipmentDeliveryPO po = poList.stream().filter(item->Objects.equals(item.getNdid(),appAutoDataMessage.getId())).findFirst().orElse(null);
|
||||
List<SysDicTreePO> dictTreeList = channelObjectUtil.objectToList(redisUtil.getObjectByKey(AppRedisKey.DICT_TREE),SysDicTreePO.class);
|
||||
String code = dictTreeList.stream().filter(item->Objects.equals(item.getId(),po.getDevType())).findFirst().orElse(null).getCode();
|
||||
String code = Objects.requireNonNull(dictTreeList.stream().filter(item -> Objects.equals(item.getId(), po.getDevType())).findFirst().orElse(null)).getCode();
|
||||
|
||||
//便携式设备
|
||||
if (Objects.equals(DicDataEnum.PORTABLE.getCode(),code)) {
|
||||
@@ -93,13 +92,19 @@ public class StatServiceImpl implements IStatService {
|
||||
}
|
||||
//直连设备
|
||||
else if (Objects.equals(DicDataEnum.CONNECT_DEV.getCode(),code)) {
|
||||
if (Objects.equals(appAutoDataMessage.getDid(),1)){lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get("0").toString();
|
||||
} else if (Objects.equals(appAutoDataMessage.getDid(),2)){
|
||||
if (Objects.equals(appAutoDataMessage.getDid(),1)) {
|
||||
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get("0").toString();
|
||||
} else if (Objects.equals(appAutoDataMessage.getDid(),2)) {
|
||||
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get(appAutoDataMessage.getMsg().getClDid().toString()).toString();
|
||||
}
|
||||
}
|
||||
//云前置设备
|
||||
else if (Objects.equals(DicDataEnum.DEV_CLD.getCode(),code)) {
|
||||
lineId = appAutoDataMessage.getId() + appAutoDataMessage.getMsg().getClDid();
|
||||
}
|
||||
|
||||
//获取当前设备信息
|
||||
if (CollectionUtil.isNotEmpty(list)){
|
||||
if (CollectionUtil.isNotEmpty(list)) {
|
||||
List<String> recordList = new ArrayList<>();
|
||||
for (AppAutoDataMessage.DataArray item : list) {
|
||||
switch (item.getDataAttr()) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.njcn.zlevent.service.impl;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import com.alibaba.nacos.shaded.com.google.gson.Gson;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.csdevice.api.CsLineFeignClient;
|
||||
import com.njcn.csdevice.api.EquipmentFeignClient;
|
||||
@@ -92,7 +93,6 @@ public class EventServiceImpl implements IEventService {
|
||||
//获取设备类型 true:治理设备 false:其他类型的设备
|
||||
boolean devModel = equipmentFeignClient.judgeDevModel(appEventMessage.getId()).getData();
|
||||
try {
|
||||
// lineId = appEventMessage.getId() + appEventMessage.getMsg().getClDid();
|
||||
if (devModel) {
|
||||
if (Objects.equals(appEventMessage.getDid(),1)){
|
||||
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appEventMessage.getId())), Map.class).get("0").toString();
|
||||
@@ -103,74 +103,81 @@ public class EventServiceImpl implements IEventService {
|
||||
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appEventMessage.getId())), Map.class).get(appEventMessage.getMsg().getClDid().toString()).toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//处理事件数据
|
||||
List<AppEventMessage.DataArray> dataArray = appEventMessage.getMsg().getDataArray();
|
||||
for (AppEventMessage.DataArray item : dataArray) {
|
||||
eventTime = timeFormat(item.getDataTimeSec(),item.getDataTimeUSec());
|
||||
id = IdUtil.fastSimpleUUID();
|
||||
//事件入库
|
||||
CsEventPO csEvent = new CsEventPO();
|
||||
csEvent.setId(id);
|
||||
csEvent.setDeviceId(po.getId());
|
||||
csEvent.setProcess(po.getProcess());
|
||||
csEvent.setCode(item.getCode());
|
||||
eventTime = timeFormat(item.getDataTimeSec(),item.getDataTimeUSec());
|
||||
csEvent.setStartTime(eventTime);
|
||||
tag = item.getName();
|
||||
csEvent.setTag(tag);
|
||||
if (Objects.equals(item.getType(),"2")){
|
||||
csEvent.setType(0);
|
||||
} else if (Objects.equals(item.getType(),"3")){
|
||||
csEvent.setType(1);
|
||||
} else if (Objects.equals(item.getType(),"1")){
|
||||
csEvent.setType(2);
|
||||
}
|
||||
csEvent.setLevel(Integer.parseInt(item.getType()));
|
||||
csEvent.setClDid(appEventMessage.getMsg().getClDid());
|
||||
csEvent.setLineId(lineId);
|
||||
//参数入库
|
||||
Map<String,String> map = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD)), Map.class);
|
||||
//判断是否有参数
|
||||
List<AppEventMessage.Param> params = item.getParam();
|
||||
if (CollectionUtil.isNotEmpty(params)) {
|
||||
String tableName = map.get(item.getName());
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(InfluxDBTableConstant.UUID,id);
|
||||
Map<String,Object> fields = new HashMap<>();
|
||||
for (AppEventMessage.Param param : params) {
|
||||
if (Objects.equals(param.getName(),ZlConstant.EVT_PARAM_TM)){
|
||||
csEvent.setPersistTime(Double.parseDouble(param.getData().toString()));
|
||||
}
|
||||
fields.put(param.getName(),param.getData());
|
||||
//判断事件是否存在,如果存在则不处理
|
||||
LambdaQueryWrapper<CsEventPO> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(CsEventPO::getDeviceId,po.getId())
|
||||
.eq(CsEventPO::getTag,tag)
|
||||
.eq(CsEventPO::getStartTime,eventTime)
|
||||
.eq(CsEventPO::getLineId,lineId);
|
||||
List<CsEventPO> eventList = csEventService.list(queryWrapper);
|
||||
if (CollectionUtil.isEmpty(eventList)) {
|
||||
id = IdUtil.fastSimpleUUID();
|
||||
//事件入库
|
||||
CsEventPO csEvent = new CsEventPO();
|
||||
csEvent.setId(id);
|
||||
csEvent.setDeviceId(po.getId());
|
||||
csEvent.setProcess(po.getProcess());
|
||||
csEvent.setCode(item.getCode());
|
||||
eventTime = timeFormat(item.getDataTimeSec(),item.getDataTimeUSec());
|
||||
csEvent.setStartTime(eventTime);
|
||||
tag = item.getName();
|
||||
csEvent.setTag(tag);
|
||||
if (Objects.equals(item.getType(),"2")){
|
||||
csEvent.setType(0);
|
||||
} else if (Objects.equals(item.getType(),"3")){
|
||||
csEvent.setType(1);
|
||||
} else if (Objects.equals(item.getType(),"1")){
|
||||
csEvent.setType(2);
|
||||
}
|
||||
//只有治理型号的设备有监测位置
|
||||
if (devModel) {
|
||||
if (appEventMessage.getMsg().getClDid() == 1) {
|
||||
fields.put("Evt_Param_Position","电网侧");
|
||||
csEvent.setLocation("grid");
|
||||
} else if (appEventMessage.getMsg().getClDid() == 2) {
|
||||
fields.put("Evt_Param_Position","负载侧");
|
||||
csEvent.setLocation("load");
|
||||
csEvent.setLevel(Integer.parseInt(item.getType()));
|
||||
csEvent.setClDid(appEventMessage.getMsg().getClDid());
|
||||
csEvent.setLineId(lineId);
|
||||
//参数入库
|
||||
Map<String,String> map = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD)), Map.class);
|
||||
//判断是否有参数
|
||||
List<AppEventMessage.Param> params = item.getParam();
|
||||
if (CollectionUtil.isNotEmpty(params)) {
|
||||
String tableName = map.get(item.getName());
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
tags.put(InfluxDBTableConstant.UUID,id);
|
||||
Map<String,Object> fields = new HashMap<>();
|
||||
for (AppEventMessage.Param param : params) {
|
||||
if (Objects.equals(param.getName(),ZlConstant.EVT_PARAM_TM)){
|
||||
csEvent.setPersistTime(Double.parseDouble(param.getData().toString()));
|
||||
}
|
||||
fields.put(param.getName(),param.getData());
|
||||
}
|
||||
//只有治理型号的设备有监测位置
|
||||
if (devModel) {
|
||||
if (appEventMessage.getMsg().getClDid() == 1) {
|
||||
fields.put("Evt_Param_Position","电网侧");
|
||||
csEvent.setLocation("grid");
|
||||
} else if (appEventMessage.getMsg().getClDid() == 2) {
|
||||
fields.put("Evt_Param_Position","负载侧");
|
||||
csEvent.setLocation("load");
|
||||
}
|
||||
}
|
||||
//fixme 这边前置传递的应该是UTC时间,但是前置说是传递的北京时间,讨论了一下没太理解。这边暂时先这样处理,influx入库处理成北京时间,减去8小时。
|
||||
Point point = influxDbUtils.pointBuilder(tableName, item.getDataTimeSec()-8*3600, TimeUnit.SECONDS, tags, fields);
|
||||
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
|
||||
batchPoints.point(point);
|
||||
records.add(batchPoints.lineProtocol());
|
||||
}
|
||||
//fixme 这边前置传递的应该是UTC时间,但是前置说是传递的北京时间,讨论了一下没太理解。这边暂时先这样处理,influx入库处理成北京时间,减去8小时。
|
||||
Point point = influxDbUtils.pointBuilder(tableName, item.getDataTimeSec()-8*3600, TimeUnit.SECONDS, tags, fields);
|
||||
BatchPoints batchPoints = BatchPoints.database(influxDbUtils.getDbName()).retentionPolicy("").consistency(InfluxDB.ConsistencyLevel.ALL).build();
|
||||
batchPoints.point(point);
|
||||
records.add(batchPoints.lineProtocol());
|
||||
list1.add(csEvent);
|
||||
//事件处理日志库
|
||||
CsEventLogs csEventLogs = new CsEventLogs();
|
||||
csEventLogs.setLineId(lineId);
|
||||
csEventLogs.setDeviceId(po.getId());
|
||||
csEventLogs.setStartTime(timeFormat(item.getDataTimeSec(),item.getDataTimeUSec()));
|
||||
csEventLogs.setTag(item.getName());
|
||||
csEventLogs.setStatus(1);
|
||||
csEventLogs.setTime(LocalDateTime.now());
|
||||
csEventLogsService.save(csEventLogs);
|
||||
}
|
||||
list1.add(csEvent);
|
||||
//事件处理日志库
|
||||
CsEventLogs csEventLogs = new CsEventLogs();
|
||||
csEventLogs.setLineId(lineId);
|
||||
csEventLogs.setDeviceId(po.getId());
|
||||
csEventLogs.setStartTime(timeFormat(item.getDataTimeSec(),item.getDataTimeUSec()));
|
||||
csEventLogs.setTag(item.getName());
|
||||
csEventLogs.setStatus(1);
|
||||
csEventLogs.setTime(LocalDateTime.now());
|
||||
csEventLogsService.save(csEventLogs);
|
||||
}
|
||||
//cs_event入库
|
||||
if (CollectionUtil.isNotEmpty(list1)){
|
||||
|
||||
Reference in New Issue
Block a user