29 Commits

Author SHA1 Message Date
xy
9c95d740d2 消息推送过滤null值 2024-09-03 20:19:58 +08:00
xy
63c293d813 微调 2024-09-03 17:57:31 +08:00
xy
81286c33cb 消息推送调整 2024-09-03 13:41:41 +08:00
xy
c9e6f43729 微调 2024-08-30 09:51:18 +08:00
xy
f035eab005 微调 2024-08-21 16:50:41 +08:00
xy
19cc757255 微调 2024-08-21 16:38:13 +08:00
xy
ed21efeda1 微调 2024-08-20 16:52:10 +08:00
xy
e1db9ffb1a 微调 2024-08-20 16:47:17 +08:00
xy
a0e5394f11 优化装置掉线重连机制 2024-08-20 16:30:50 +08:00
xy
21ee13e71f 微调 2024-08-16 18:18:58 +08:00
xy
90dc22021f 装置接入流程调整 2024-08-16 13:00:22 +08:00
xy
ab9215f13e 手动发起接入 2024-08-15 08:36:12 +08:00
xy
adbb9a16f4 文件校验 2024-08-14 21:07:27 +08:00
xy
a0142917c7 微调 2024-08-14 14:05:32 +08:00
xy
04e59d2282 MQTT上传文件至装置 2024-08-13 10:51:19 +08:00
xy
c6213d06e5 日志记录 2024-08-12 09:28:02 +08:00
xy
7657269b33 bug调整 2024-08-09 14:29:35 +08:00
xy
6a0e15ef84 新增一次值、二次值标识 2024-08-09 08:30:43 +08:00
xy
329143772b 微调 2024-08-08 18:41:34 +08:00
xy
0233c3e04f 微调 2024-08-08 15:47:12 +08:00
xy
14e81fd795 装置注册逻辑判断添加 2024-08-06 20:36:48 +08:00
xy
9b7ec5725b 微调 2024-08-06 10:04:37 +08:00
xy
32a6b5c52e 微调 2024-08-02 15:57:05 +08:00
xy
08c8e4374d 添加装置信息 2024-07-31 15:35:35 +08:00
guofeihu
b67e55a4ac 补充controller里面缺失的methodDescribe 2024-06-27 09:29:07 +08:00
guofeihu
25b3da033a 设备注册后校验模板参数修改及注册后插入检测点cs_line重复校验 2024-06-14 10:02:31 +08:00
guofeihu
563163a5af 设备接入出现异常时 返回具体错误提示 2024-06-13 11:12:03 +08:00
guofeihu
4ce70bc5ff 设备接入出现异常直接抛出 2024-06-13 09:23:44 +08:00
xy
6800eea117 便携式设备接入代码兼容 2024-04-09 09:42:26 +08:00
24 changed files with 1044 additions and 378 deletions

View File

@@ -14,11 +14,13 @@ public enum AccessResponseEnum {
* A0301 ~ A0399 用于用户模块的枚举 * A0301 ~ A0399 用于用户模块的枚举
* <p> * <p>
*/ */
NDID_NO_FIND("A0301", "此设备未录入或已注册!"), NDID_NO_FIND("A0301", "此设备未录入!"),
NDID_SAME_STEP("A0301", "此设备已注册!"),
MISSING_CLIENT("A0302","设备客户端不在线!"), MISSING_CLIENT("A0302","设备客户端不在线!"),
MODEL_REPEAT("A0302", "模板存在,请勿重复录入!"), MODEL_REPEAT("A0302", "模板存在,请勿重复录入!"),
MODEL_NO_FIND("A0302", "模板不存在,请先录入模板数据!"), MODEL_NO_FIND("A0302", "模板不存在,请先录入模板数据!"),
MODEL_ERROR("A0302", "模板未找到,生成监测点失败!"),
DICT_ANALYSIS_ERROR("A0303","字典解析错误!"), DICT_ANALYSIS_ERROR("A0303","字典解析错误!"),
MODEL_ANALYSIS_ERROR("A0303","模板解析错误!"), MODEL_ANALYSIS_ERROR("A0303","模板解析错误!"),
@@ -28,6 +30,7 @@ public enum AccessResponseEnum {
DEV_MODEL_NOT_FIND("A0303","装置型号未找到!"), DEV_MODEL_NOT_FIND("A0303","装置型号未找到!"),
DEV_IS_NOT_ZL("A0303","注册装置不是直连装置!"), DEV_IS_NOT_ZL("A0303","注册装置不是直连装置!"),
DEV_IS_NOT_WG("A0303","注册装置不是网关!"), DEV_IS_NOT_WG("A0303","注册装置不是网关!"),
DEV_IS_NOT_PORTABLE("A0303","注册装置不是便携式设备!"),
REGISTER_RESPONSE_ERROR("A0304","装置注册,装置侧应答失败!"), REGISTER_RESPONSE_ERROR("A0304","装置注册,装置侧应答失败!"),
ACCESS_RESPONSE_ERROR("A0304","装置注册,装置侧应答失败!"), ACCESS_RESPONSE_ERROR("A0304","装置注册,装置侧应答失败!"),
@@ -55,6 +58,8 @@ public enum AccessResponseEnum {
MODEL_MISS("A0308","模板信息缺失!"), MODEL_MISS("A0308","模板信息缺失!"),
MODEL_VERSION_ERROR("A0308","询问装置模板信息错误"), MODEL_VERSION_ERROR("A0308","询问装置模板信息错误"),
UPLOAD_ERROR("A0308","平台上送文件异常"),
RELOAD_UPLOAD_ERROR("A0308","平台重新上送文件异常"),
CLDID_IS_NULL("A0309","逻辑子设备标识为空"), CLDID_IS_NULL("A0309","逻辑子设备标识为空"),
MODULE_NUMBER_IS_NULL("A0309","设备子模块个数为空"), MODULE_NUMBER_IS_NULL("A0309","设备子模块个数为空"),
@@ -65,6 +70,7 @@ public enum AccessResponseEnum {
PROCESS_SAME_ERROR("A0311","当前调试已完成,请勿重复调试"), PROCESS_SAME_ERROR("A0311","当前调试已完成,请勿重复调试"),
PROCESS_MISSING_ERROR("A0311","调试流程缺失,请核查功能调试、出厂调试"), PROCESS_MISSING_ERROR("A0311","调试流程缺失,请核查功能调试、出厂调试"),
PROCESS_ERROR("A0311","调试流程异常,请先进行功能调试、出厂调试!"),
; ;
private final String code; private final String code;

View File

@@ -0,0 +1,37 @@
package com.njcn.access.pojo.dto;
import com.alibaba.nacos.shaded.com.google.gson.annotations.SerializedName;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author xy
*/
@Data
public class UploadFileDto {
@SerializedName("Name")
@ApiModelProperty("文件名称,全路径")
private String name;
@SerializedName("FileSize")
@ApiModelProperty("文件总大小(单位字节)")
private Integer fileSize;
@SerializedName("Offset")
@ApiModelProperty("当前上送数据包在文件中偏移位置")
private Integer offset;
@SerializedName("Len")
@ApiModelProperty("当前上送数据包长度")
private Integer len;
@SerializedName("Data")
@ApiModelProperty("文件包数据")
private String data;
@SerializedName("FileCheck")
@ApiModelProperty("文件校验码")
private String fileCheck;
}

View File

@@ -36,6 +36,11 @@ public class DataSetDto implements Serializable {
@ApiModelProperty("0-不存储;1-存储") @ApiModelProperty("0-不存储;1-存储")
private Integer storeFlag; private Integer storeFlag;
@SerializedName("DataLevel")
@NotNull(message = "数据标识(一次值、二次值),不可为空")
@ApiModelProperty("Primary-一次值;Secondary-二次值")
private String dataLevel;
@SerializedName("DataArray") @SerializedName("DataArray")
@NotEmpty(message = "数据集合描述,不可为空") @NotEmpty(message = "数据集合描述,不可为空")
private List<DataArrayDto> dataArrayDtoList; private List<DataArrayDto> dataArrayDtoList;

View File

@@ -0,0 +1,22 @@
package com.njcn.access.pojo.dto.file;
import lombok.Data;
/**
* @author xy
*/
@Data
public class FileRedisDto {
private String name;
private Integer allStep;
private Integer nowStep;
private Integer retry = 0;
private Integer code;
}

View File

@@ -13,10 +13,7 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
/** /**
@@ -48,5 +45,14 @@ public class CsDevModelController extends BaseController {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/uploadDevFile")
@ApiOperation("上传文件至装置")
@Transactional(rollbackFor = {Exception.class})
public HttpResult<String> uploadDevFile(@RequestPart("file") @Validated MultipartFile file, @RequestParam("id") @Validated String id, @RequestParam("filePath") @Validated String path){
String methodDescribe = getMethodDescribe("uploadDevFile");
csDevModelService.uploadDevFile(file,id,path);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
}
} }

View File

@@ -44,8 +44,9 @@ public class CsDeviceController extends BaseController {
}) })
@ReturnMsg @ReturnMsg
public HttpResult<String> devRegister(@RequestParam String nDid,@RequestParam Integer type){ public HttpResult<String> devRegister(@RequestParam String nDid,@RequestParam Integer type){
String methodDescribe = getMethodDescribe("devRegister");
csDeviceService.devRegister(nDid,type); csDeviceService.devRegister(nDid,type);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, "设备MQTT通讯状态!"); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON) @OperateInfo(info = LogEnum.BUSINESS_COMMON)
@@ -78,4 +79,45 @@ public class CsDeviceController extends BaseController {
csDeviceService.resetFactory(nDid); csDeviceService.resetFactory(nDid);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe); return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
} }
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/manualAccess")
@ApiOperation("手动发起接入")
@ApiImplicitParam(name = "nDid", value = "设备id", required = true)
public HttpResult<String> manualAccess(@RequestParam String nDid){
String methodDescribe = getMethodDescribe("manualAccess");
boolean result = csDeviceService.manualAccess(nDid);
if (result) {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "成功", methodDescribe);
} else {
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, "失败", methodDescribe);
}
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/wlRegister")
@ApiOperation("便携式设备注册")
@ApiImplicitParams({
@ApiImplicitParam(name = "nDid", value = "设备识别码", required = true)
})
@ReturnMsg
public HttpResult<String> wlRegister(@RequestParam String nDid){
String methodDescribe = getMethodDescribe("wlRegister");
String result = csDeviceService.wlDevRegister(nDid);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
}
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
@PostMapping("/wlAccess")
@ApiOperation("便携式设备接入")
@ApiImplicitParams({
@ApiImplicitParam(name = "nDid", value = "设备识别码", required = true)
})
@ReturnMsg
public HttpResult<String> wlAccess(@RequestParam String nDid){
String methodDescribe = getMethodDescribe("wlAccess");
csDeviceService.wlAccess(nDid);
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, "success", methodDescribe);
}
} }

View File

@@ -17,6 +17,7 @@ import com.njcn.access.enums.TypeEnum;
import com.njcn.access.pojo.RspDataDto; import com.njcn.access.pojo.RspDataDto;
import com.njcn.access.pojo.dto.*; import com.njcn.access.pojo.dto.*;
import com.njcn.access.pojo.dto.file.FileDto; import com.njcn.access.pojo.dto.file.FileDto;
import com.njcn.access.pojo.dto.file.FileRedisDto;
import com.njcn.access.pojo.param.ReqAndResParam; import com.njcn.access.pojo.param.ReqAndResParam;
import com.njcn.access.pojo.po.CsDeviceOnlineLogs; import com.njcn.access.pojo.po.CsDeviceOnlineLogs;
import com.njcn.access.pojo.po.CsLineModel; import com.njcn.access.pojo.po.CsLineModel;
@@ -56,7 +57,6 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -225,6 +225,7 @@ public class MqttMessageHandler {
@MqttSubscribe(value = "/Pfm/DevRsp/{version}/{edgeId}",qos = 1) @MqttSubscribe(value = "/Pfm/DevRsp/{version}/{edgeId}",qos = 1)
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void devModelOperation(String topic, MqttMessage message, @NamedValue("version") String version, @NamedValue("edgeId") String nDid, @Payload String payload){ public void devModelOperation(String topic, MqttMessage message, @NamedValue("version") String version, @NamedValue("edgeId") String nDid, @Payload String payload){
log.info("收到当前设备所用模板响应--->" + nDid);
DeviceLogDTO logDto = new DeviceLogDTO(); DeviceLogDTO logDto = new DeviceLogDTO();
try{ try{
logDto.setUserName(RequestUtil.getUsername()); logDto.setUserName(RequestUtil.getUsername());
@@ -246,6 +247,8 @@ public class MqttMessageHandler {
logDto.setResult(0); logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.MODEL_VERSION_ERROR.getMessage()); logDto.setFailReason(AccessResponseEnum.MODEL_VERSION_ERROR.getMessage());
csLogsFeignClient.addUserLog(logDto); csLogsFeignClient.addUserLog(logDto);
//有异常删除缓存的模板信息
redisUtil.delete(AppRedisKey.MODEL + nDid);
throw new BusinessException(AccessResponseEnum.MODEL_VERSION_ERROR); throw new BusinessException(AccessResponseEnum.MODEL_VERSION_ERROR);
} }
//校验前置传递的装置模板库中是否存在 //校验前置传递的装置模板库中是否存在
@@ -264,6 +267,8 @@ public class MqttMessageHandler {
logDto.setResult(0); logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.MODEL_NO_FIND.getMessage()); logDto.setFailReason(AccessResponseEnum.MODEL_NO_FIND.getMessage());
csLogsFeignClient.addUserLog(logDto); csLogsFeignClient.addUserLog(logDto);
//有异常删除缓存的模板信息
redisUtil.delete(AppRedisKey.MODEL + nDid);
throw new BusinessException(AccessResponseEnum.MODEL_NO_FIND); throw new BusinessException(AccessResponseEnum.MODEL_NO_FIND);
} }
if (Objects.equals(po.getType(),0)){ if (Objects.equals(po.getType(),0)){
@@ -272,6 +277,8 @@ public class MqttMessageHandler {
logDto.setResult(0); logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.MODULE_NUMBER_IS_NULL.getMessage()); logDto.setFailReason(AccessResponseEnum.MODULE_NUMBER_IS_NULL.getMessage());
csLogsFeignClient.addUserLog(logDto); csLogsFeignClient.addUserLog(logDto);
//有异常删除缓存的模板信息
redisUtil.delete(AppRedisKey.MODEL + nDid);
throw new BusinessException(AccessResponseEnum.MODULE_NUMBER_IS_NULL); throw new BusinessException(AccessResponseEnum.MODULE_NUMBER_IS_NULL);
} }
csModelDto.setModuleNumber(dataSetList.size()); csModelDto.setModuleNumber(dataSetList.size());
@@ -345,6 +352,10 @@ public class MqttMessageHandler {
} }
//询问设备软件信息 //询问设备软件信息
askDevData(nDid,version,1,mid); askDevData(nDid,version,1,mid);
//更新治理监测点信息和设备容量
askDevData(nDid,version,2,(res.getMid()+1));
//更新电网侧、负载侧监测点信息
askDevData(nDid,version,3,(res.getMid()+1));
} else { } else {
log.info(AccessResponseEnum.ACCESS_RESPONSE_ERROR.getMessage()); log.info(AccessResponseEnum.ACCESS_RESPONSE_ERROR.getMessage());
logDto.setResult(0); logDto.setResult(0);
@@ -358,7 +369,6 @@ public class MqttMessageHandler {
RspDataDto rspDataDto = JSON.parseObject(JSON.toJSONString(res.getMsg()), RspDataDto.class); RspDataDto rspDataDto = JSON.parseObject(JSON.toJSONString(res.getMsg()), RspDataDto.class);
switch (rspDataDto.getDataType()){ switch (rspDataDto.getDataType()){
case 1: case 1:
log.info("{} 更新设备软件信息",nDid);
logDto.setOperate(nDid + "更新设备软件信息"); logDto.setOperate(nDid + "更新设备软件信息");
RspDataDto.SoftInfo softInfo = JSON.parseObject(JSON.toJSONString(rspDataDto.getDataArray()), RspDataDto.SoftInfo.class); RspDataDto.SoftInfo softInfo = JSON.parseObject(JSON.toJSONString(rspDataDto.getDataArray()), RspDataDto.SoftInfo.class);
//记录设备软件信息 //记录设备软件信息
@@ -377,7 +387,7 @@ public class MqttMessageHandler {
} }
equipmentFeignClient.updateSoftInfo(nDid,csSoftInfoPo.getId()); equipmentFeignClient.updateSoftInfo(nDid,csSoftInfoPo.getId());
//询问设备容量信息 //询问设备容量信息
askDevData(nDid,version,2,(res.getMid()+1)); //askDevData(nDid,version,2,(res.getMid()+1));
} catch (ParseException e) { } catch (ParseException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -386,7 +396,6 @@ public class MqttMessageHandler {
List<RspDataDto.LdevInfo> devInfo = JSON.parseArray(JSON.toJSONString(rspDataDto.getDataArray()), RspDataDto.LdevInfo.class); List<RspDataDto.LdevInfo> devInfo = JSON.parseArray(JSON.toJSONString(rspDataDto.getDataArray()), RspDataDto.LdevInfo.class);
if (CollectionUtil.isNotEmpty(devInfo)){ if (CollectionUtil.isNotEmpty(devInfo)){
if (Objects.equals(res.getDid(),1)){ if (Objects.equals(res.getDid(),1)){
log.info("{} 更新治理监测点信息和设备容量",nDid);
logDto.setOperate(nDid + "更新治理监测点信息和设备容量"); logDto.setOperate(nDid + "更新治理监测点信息和设备容量");
List<CsDevCapacityPO> list = new ArrayList<>(); List<CsDevCapacityPO> list = new ArrayList<>();
devInfo.forEach(item->{ devInfo.forEach(item->{
@@ -411,9 +420,8 @@ public class MqttMessageHandler {
//3.更新设备模块个数 //3.更新设备模块个数
equipmentFeignClient.updateModuleNumber(nDid,(devInfo.size()-1)); equipmentFeignClient.updateModuleNumber(nDid,(devInfo.size()-1));
//4.询问监测点pt/ct信息 //4.询问监测点pt/ct信息
askDevData(nDid,version,3,(res.getMid()+1)); //askDevData(nDid,version,3,(res.getMid()+1));
} else if (Objects.equals(res.getDid(),2)) { } else if (Objects.equals(res.getDid(),2)) {
log.info("{} 更新电网侧、负载侧监测点信息",nDid);
logDto.setOperate(nDid + "更新电网侧、负载侧监测点信息"); logDto.setOperate(nDid + "更新电网侧、负载侧监测点信息");
//1.更新电网侧、负载侧监测点相关信息 //1.更新电网侧、负载侧监测点相关信息
devInfo.forEach(item->{ devInfo.forEach(item->{
@@ -460,8 +468,8 @@ public class MqttMessageHandler {
case 4865: case 4865:
//设置心跳时间,超时改为掉线 //设置心跳时间,超时改为掉线
redisUtil.saveByKeyWithExpire("MQTT:" + nDid, Instant.now().toEpochMilli(),180L); redisUtil.saveByKeyWithExpire("MQTT:" + nDid, Instant.now().toEpochMilli(),180L);
//装置改成在线 //有心跳,则将装置改成在线
csEquipmentDeliveryService.updateRunStatusBynDid(nDid,AccessEnum.ONLINE.getCode()); //csEquipmentDeliveryService.updateRunStatusBynDid(nDid,AccessEnum.ONLINE.getCode());
//处理心跳 //处理心跳
ReqAndResDto.Res reqAndResParam = new ReqAndResDto.Res(); ReqAndResDto.Res reqAndResParam = new ReqAndResDto.Res();
reqAndResParam.setMid(res.getMid()); reqAndResParam.setMid(res.getMid());
@@ -504,8 +512,7 @@ public class MqttMessageHandler {
switch (dataDto.getMsg().getDataAttr()) { switch (dataDto.getMsg().getDataAttr()) {
//暂态事件、录波处理 //暂态事件、录波处理
case 0: case 0:
log.info("处理事件"); log.info(nDid + "事件报文为:" + new String(message.getPayload(), StandardCharsets.UTF_8));
log.info("事件报文为:" + new String(message.getPayload(), StandardCharsets.UTF_8));
EventDto eventDto = gson.fromJson(new String(message.getPayload(), StandardCharsets.UTF_8), EventDto.class); EventDto eventDto = gson.fromJson(new String(message.getPayload(), StandardCharsets.UTF_8), EventDto.class);
JSONObject jsonObject0 = JSONObject.parseObject(JSON.toJSONString(eventDto)); JSONObject jsonObject0 = JSONObject.parseObject(JSON.toJSONString(eventDto));
AppEventMessage appEventMessage = JSONObject.toJavaObject(jsonObject0, AppEventMessage.class); AppEventMessage appEventMessage = JSONObject.toJavaObject(jsonObject0, AppEventMessage.class);
@@ -514,14 +521,16 @@ public class MqttMessageHandler {
break; break;
//实时数据 //实时数据
case 1: case 1:
log.info("处理实时数据"); log.info(nDid + "处理实时数据");
break; break;
//处理主动上送的统计数据 //处理主动上送的统计数据
case 2: case 2:
log.info("处理统计数据");
JSONObject jsonObject2 = JSONObject.parseObject(JSON.toJSONString(dataDto)); JSONObject jsonObject2 = JSONObject.parseObject(JSON.toJSONString(dataDto));
AppAutoDataMessage appAutoDataMessage = JSONObject.toJavaObject(jsonObject2, AppAutoDataMessage.class); AppAutoDataMessage appAutoDataMessage = JSONObject.toJavaObject(jsonObject2, AppAutoDataMessage.class);
appAutoDataMessage.setId(nDid); appAutoDataMessage.setId(nDid);
appAutoDataMessage.getMsg().getDataArray().forEach(item->{
log.info(nDid + "处理统计数据" + item.getDataAttr());
});
appAutoDataMessageTemplate.sendMember(appAutoDataMessage); appAutoDataMessageTemplate.sendMember(appAutoDataMessage);
break; break;
default: default:
@@ -567,6 +576,12 @@ public class MqttMessageHandler {
log.info("需要缓存请求的文件信息"); log.info("需要缓存请求的文件信息");
} }
break; break;
case 4659:
log.info("装置收到系统上传的文件");
FileRedisDto fileRedisDto = new FileRedisDto();
fileRedisDto.setCode(fileDto.getCode());
redisUtil.saveByKeyWithExpire("uploadFileStep",fileRedisDto,10L);
break;
default: default:
break; break;
} }
@@ -584,7 +599,7 @@ public class MqttMessageHandler {
reqAndResParam.setMid(mid); reqAndResParam.setMid(mid);
reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode()); reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode());
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_6.getCode())); reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_6.getCode()));
reqAndResParam.setExpire(1); reqAndResParam.setExpire(-1);
AskDataDto askDataDto = new AskDataDto(); AskDataDto askDataDto = new AskDataDto();
askDataDto.setDataAttr(0); askDataDto.setDataAttr(0);
askDataDto.setOperate(1); askDataDto.setOperate(1);
@@ -606,6 +621,12 @@ public class MqttMessageHandler {
askDataDto.setCldid(-1); askDataDto.setCldid(-1);
askDataDto.setDataType(2); askDataDto.setDataType(2);
break; break;
//询问工程信息
case 48:
reqAndResParam.setDid(1);
askDataDto.setCldid(1);
askDataDto.setDataType(48);
break;
default: default:
break; break;
} }

View File

@@ -1,16 +1,12 @@
package com.njcn.access.listener; package com.njcn.access.listener;
import com.njcn.access.enums.AccessEnum; import com.njcn.access.enums.AccessEnum;
import com.njcn.access.pojo.po.CsDeviceOnlineLogs;
import com.njcn.access.service.ICsDeviceOnlineLogsService; import com.njcn.access.service.ICsDeviceOnlineLogsService;
import com.njcn.access.service.ICsEquipmentDeliveryService; import com.njcn.access.service.ICsEquipmentDeliveryService;
import com.njcn.access.service.ICsTopicService; import com.njcn.access.service.ICsTopicService;
import com.njcn.access.service.impl.CsDeviceServiceImpl; import com.njcn.access.service.impl.CsDeviceServiceImpl;
import com.njcn.common.pojo.dto.DeviceLogDTO; import com.njcn.common.pojo.dto.DeviceLogDTO;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.api.CsLogsFeignClient; import com.njcn.csdevice.api.CsLogsFeignClient;
import com.njcn.web.utils.RequestUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.Message;
@@ -19,10 +15,10 @@ import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture; import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@@ -53,6 +49,11 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
super(listenerContainer); super(listenerContainer);
} }
// 最大尝试次数
private static final int MAX_ATTEMPTS = 4;
// 当前尝试次数
private static int attemptCount = 1;
/** /**
* 针对redis数据失效事件进行数据处理 * 针对redis数据失效事件进行数据处理
* 注意message.toString()可以获取失效的key * 注意message.toString()可以获取失效的key
@@ -62,58 +63,77 @@ public class RedisKeyExpirationListener extends KeyExpirationEventMessageListene
if (StringUtils.isBlank(message.toString())) { if (StringUtils.isBlank(message.toString())) {
return; return;
} }
//日志实体
DeviceLogDTO logDto = new DeviceLogDTO();
try{
logDto.setUserName(RequestUtil.getUsername());
logDto.setLoginName(RequestUtil.getLoginName());
} catch (Exception e) {
logDto.setUserName("redis失效存储");
logDto.setLoginName(null);
}
logDto.setResult(1);
//判断失效的key是否为MQTT消费端存入的 //判断失效的key是否为MQTT消费端存入的
String expiredKey = message.toString(); String expiredKey = message.toString();
if(expiredKey.startsWith("MQTT:")){ if(expiredKey.startsWith("MQTT:")){
String nDid = expiredKey.split(":")[1]; String nDid = expiredKey.split(":")[1];
String version = csTopicService.getVersion(nDid);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
executeMainTask(scheduler,nDid,version);
}
}
//主任务
private void executeMainTask(ScheduledExecutorService scheduler, String nDid, String version) {
System.out.println("正在执行主任务...");
DeviceLogDTO logDto = new DeviceLogDTO();
logDto.setUserName("装置失去心跳触发");
logDto.setOperate(nDid + "重连");
//装置下线 //装置下线
csEquipmentDeliveryService.updateRunStatusBynDid(nDid, AccessEnum.OFFLINE.getCode()); csEquipmentDeliveryService.updateRunStatusBynDid(nDid, AccessEnum.OFFLINE.getCode());
logDto.setOperate("装置掉线,装置为:" + nDid); //装置没有心跳,则立马发起接入请求
csLogsFeignClient.addUserLog(logDto); csDeviceService.devAccessAskTemplate(nDid,version,1);
//记录装置下线日志
CsDeviceOnlineLogs record = onlineLogsService.findLastData(nDid);
record.setOfflineTime(LocalDateTime.now());
onlineLogsService.updateById(record);
try {
//装置掉线等待10分钟,发起接入请求
String version = csTopicService.getVersion(nDid);
log.info("装置掉线10分钟发送接入请求接入失败则进入定时接入任务");
Thread.sleep(600000);
csDeviceService.devAccess(nDid,version);
//接入再次失败,则定时发起接入请求
Thread.sleep(1000);
Integer status = csEquipmentDeliveryService.queryEquipmentBynDid(nDid).getRunStatus(); Integer status = csEquipmentDeliveryService.queryEquipmentBynDid(nDid).getRunStatus();
if (!Objects.isNull(status) && Objects.equals(status,AccessEnum.OFFLINE.getCode())){ if (Objects.equals(status,AccessEnum.ONLINE.getCode())){
final int[] mid = {2}; logDto.setResult(1);
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2); scheduler.shutdown();
ScheduledFuture<?> runnableFuture = executor.scheduleAtFixedRate(() -> {
log.info("定时发送接入请求...");
csDeviceService.devAccessMid(nDid,version, mid[0]);
Integer status2 = csEquipmentDeliveryService.queryEquipmentBynDid(nDid).getRunStatus();
if (Objects.equals(status2,AccessEnum.ONLINE.getCode())){
throw new BusinessException(CommonResponseEnum.SUCCESS);
} else { } else {
mid[0] = mid[0] + 1; logDto.setResult(0);
startScheduledTask(scheduler,nDid,version);
} }
//记录日志
logDto.setOperate("装置掉线,定时发送接入请求,装置为:" + nDid + ",请求的时间戳为:" + System.currentTimeMillis());
csLogsFeignClient.addUserLog(logDto); csLogsFeignClient.addUserLog(logDto);
}, 1, 600, TimeUnit.SECONDS);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
//启动第一次定时任务
private void startScheduledTask(ScheduledExecutorService scheduler, String nDid, String version) {
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(() -> {
DeviceLogDTO logDto = new DeviceLogDTO();
logDto.setOperate(nDid + "第一阶段重连定时任务");
if (attemptCount < MAX_ATTEMPTS) {
System.out.println(nDid + "执行第一阶段重连定时任务,第 " + attemptCount + " 次尝试...");
attemptCount++;
csDeviceService.devAccessAskTemplate(nDid,version,attemptCount);
int status = csEquipmentDeliveryService.queryEquipmentBynDid(nDid).getRunStatus();
if (Objects.equals(status,AccessEnum.ONLINE.getCode())){
logDto.setResult(1);
scheduler.shutdown();
}
} else {
scheduler.shutdown();
attemptCount++;
logDto.setResult(0);
startSecondScheduledTask(nDid,version);
}
csLogsFeignClient.addUserLog(logDto);
}, 0, 1, TimeUnit.MINUTES);
}
//启动第二个定时任务
private void startSecondScheduledTask(String nDid, String version) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(() -> {
System.out.println(nDid + "执行第二阶段重连定时任务...");
DeviceLogDTO logDto = new DeviceLogDTO();
logDto.setOperate(nDid + "第二阶段重连定时任务");
csDeviceService.devAccessAskTemplate(nDid,version,attemptCount++);
int status = csEquipmentDeliveryService.queryEquipmentBynDid(nDid).getRunStatus();
if (Objects.equals(status,AccessEnum.ONLINE.getCode())) {
logDto.setResult(1);
scheduler.shutdown();
} else {
logDto.setResult(0);
}
csLogsFeignClient.addUserLog(logDto);
}, 0, 10, TimeUnit.MINUTES);
} }
} }

View File

@@ -1,47 +1,47 @@
package com.njcn.access.runner; //package com.njcn.access.runner;
//
import com.njcn.access.service.ICsEquipmentDeliveryService; //import com.njcn.access.service.ICsEquipmentDeliveryService;
import com.njcn.access.service.ICsTopicService; //import com.njcn.access.service.ICsTopicService;
import com.njcn.access.service.impl.CsDeviceServiceImpl; //import com.njcn.access.service.impl.CsDeviceServiceImpl;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO; //import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO;
import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments; //import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner; //import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; //import org.springframework.stereotype.Component;
//
import javax.annotation.Resource; //import javax.annotation.Resource;
import java.util.List; //import java.util.List;
import java.util.Objects; //import java.util.Objects;
//
/** ///**
* 类的介绍:用来重新发起设备的接入,存在程序意外停止了,缓存失效导致无法更新装置的状态,所以需要在程序启动时发起设备的接入 // * 类的介绍:用来重新发起设备的接入,存在程序意外停止了,缓存失效导致无法更新装置的状态,所以需要在程序启动时发起设备的接入
* // *
* @author xuyang // * @author xuyang
* @version 1.0.0 // * @version 1.0.0
* @createTime 2023/8/28 13:57 // * @createTime 2023/8/28 13:57
*/ // */
@Component //@Component
@Slf4j //@Slf4j
public class AccessApplicationRunner implements ApplicationRunner { //public class AccessApplicationRunner implements ApplicationRunner {
//
@Resource // @Resource
private CsDeviceServiceImpl csDeviceService; // private CsDeviceServiceImpl csDeviceService;
//
@Resource // @Resource
private ICsTopicService csTopicService; // private ICsTopicService csTopicService;
//
@Resource // @Resource
private ICsEquipmentDeliveryService csEquipmentDeliveryService; // private ICsEquipmentDeliveryService csEquipmentDeliveryService;
//
@Override // @Override
public void run(ApplicationArguments args){ // public void run(ApplicationArguments args){
List<CsEquipmentDeliveryPO> list = csEquipmentDeliveryService.getAll(); // List<CsEquipmentDeliveryPO> list = csEquipmentDeliveryService.getAll();
list.forEach(item->{ // list.forEach(item->{
String version = csTopicService.getVersion(item.getNdid()); // String version = csTopicService.getVersion(item.getNdid());
if (!Objects.isNull(version)){ // if (!Objects.isNull(version)){
csDeviceService.devAccess(item.getNdid(),version); // csDeviceService.devAccess(item.getNdid(),version,1);
} // }
}); // });
} // }
//
} //}

View File

@@ -1,50 +1,53 @@
package com.njcn.access.runner; //package com.njcn.access.runner;
//
import com.njcn.access.service.ICsEquipmentDeliveryService; //import cn.hutool.core.collection.CollUtil;
import com.njcn.access.service.ICsTopicService; //import cn.hutool.core.collection.CollectionUtil;
import com.njcn.access.service.impl.CsDeviceServiceImpl; //import com.njcn.access.service.ICsEquipmentDeliveryService;
import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO; //import com.njcn.access.service.ICsTopicService;
import lombok.extern.slf4j.Slf4j; //import com.njcn.access.service.impl.CsDeviceServiceImpl;
import org.springframework.scheduling.annotation.Scheduled; //import com.njcn.csdevice.pojo.po.CsEquipmentDeliveryPO;
import org.springframework.stereotype.Component; //import lombok.extern.slf4j.Slf4j;
//import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.Resource; //import org.springframework.stereotype.Component;
import java.util.List; //
import java.util.Objects; //import javax.annotation.Resource;
//import java.util.List;
/** //import java.util.Objects;
* 类的介绍:防止设备掉线 系统未能调整,做一个定时任务,每天凌晨将所有设备重新接入 //
* ///**
* @author xuyang // * 类的介绍:防止设备掉线 系统未能调整,做一个定时任务,每天凌晨将所有设备重新接入
* @version 1.0.0 // *
* @createTime 2023/8/28 14:21 // * @author xuyang
*/ // * @version 1.0.0
@Component // * @createTime 2023/8/28 14:21
@Slf4j // */
public class AccessScheduledTask { //@Component
//@Slf4j
@Resource //public class AccessScheduledTask {
private CsDeviceServiceImpl csDeviceService; //
// @Resource
@Resource // private CsDeviceServiceImpl csDeviceService;
private ICsTopicService csTopicService; //
// @Resource
@Resource // private ICsTopicService csTopicService;
private ICsEquipmentDeliveryService csEquipmentDeliveryService; //
// @Resource
/** // private ICsEquipmentDeliveryService csEquipmentDeliveryService;
* {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)} //
*/ // /**
@Scheduled(cron = "0 0 0 * * ?") // * {秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}
public void executeTask() { // */
log.info("每日凌晨定时任务执行"); // @Scheduled(cron = "0 0 0 * * ?")
List<CsEquipmentDeliveryPO> list = csEquipmentDeliveryService.getAll(); // public void executeTask() {
list.forEach(item->{ // log.info("每日凌晨定时任务执行");
String version = csTopicService.getVersion(item.getNdid()); // List<CsEquipmentDeliveryPO> list = csEquipmentDeliveryService.getAll();
if (!Objects.isNull(version)){ // if (CollUtil.isNotEmpty(list)) {
csDeviceService.devAccess(item.getNdid(),version); // for (int i = 0; i < list.size(); i++) {
} // String version = csTopicService.getVersion(list.get(i).getNdid());
}); // if (!Objects.isNull(version)){
} // csDeviceService.devAccess(list.get(i).getNdid(),version,i);
// }
} // }
// }
// }
//}

View File

@@ -26,4 +26,10 @@ public interface ICsDataSetService extends IService<CsDataSet> {
*/ */
void addList(List<CsDataSet> list); void addList(List<CsDataSet> list);
/**
* 根据模板id获取模板的数据集
* @param modelId 模板ID
*/
List<CsDataSet> getDataSetData(String modelId);
} }

View File

@@ -27,5 +27,12 @@ public interface ICsDevModelRelationService extends IService<CsDevModelRelationP
*/ */
CsDevModelRelationPO addDevModelRelation(CsDevModelRelationAddParm addParm); CsDevModelRelationPO addDevModelRelation(CsDevModelRelationAddParm addParm);
/**
* 根据装置id删除模板信息
*/
void deleteByDeviceId(String deviceId);
void addRelation(CsDevModelRelationPO po);
} }

View File

@@ -26,4 +26,11 @@ public interface ICsDevModelService {
*/ */
void addDict(MultipartFile file); void addDict(MultipartFile file);
/**
* 上传文件至装置
* 更新程序、更新模板
*/
void uploadDevFile(MultipartFile file, String id, String path);
} }

View File

@@ -36,4 +36,22 @@ public interface ICsDeviceService {
* @param nDid * @param nDid
*/ */
void resetFactory(String nDid); void resetFactory(String nDid);
/**
* 手动发起接入
* @param nDid
*/
boolean manualAccess(String nDid);
/**
* 直连设备注册
* @param nDid 设备识别码
*/
String wlDevRegister(String nDid);
/**
* 直连设备接入
* @param nDid 设备识别码
*/
void wlAccess(String nDid);
} }

View File

@@ -28,4 +28,9 @@ public class CsDataSetServiceImpl extends ServiceImpl<CsDataSetMapper, CsDataSet
public void addList(List<CsDataSet> list) { public void addList(List<CsDataSet> list) {
this.saveBatch(list,1000); this.saveBatch(list,1000);
} }
@Override
public List<CsDataSet> getDataSetData(String modelId) {
return this.lambdaQuery().eq(CsDataSet::getPid, modelId).list();
}
} }

View File

@@ -1,6 +1,9 @@
package com.njcn.access.service.impl; package com.njcn.access.service.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.access.mapper.CsDevModelRelationMapper; import com.njcn.access.mapper.CsDevModelRelationMapper;
import com.njcn.access.service.ICsDevModelRelationService; import com.njcn.access.service.ICsDevModelRelationService;
@@ -12,10 +15,13 @@ import com.njcn.csdevice.pojo.po.CsDevModelRelationPO;
import com.njcn.csdevice.pojo.vo.CsDevModelRelationVO; import com.njcn.csdevice.pojo.vo.CsDevModelRelationVO;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -38,7 +44,7 @@ public class CsDevModelRelationServiceImpl extends ServiceImpl<CsDevModelRelatio
queryParm.setModelId (addParm.getModelId ()); queryParm.setModelId (addParm.getModelId ());
queryParm.setStatus ("1"); queryParm.setStatus ("1");
List<CsDevModelRelationVO> csDevModelRelationVOS = this.queryDevModelRelation (queryParm); List<CsDevModelRelationVO> csDevModelRelationVOS = this.queryDevModelRelation (queryParm);
if(csDevModelRelationVOS.size ()>0){ if(!csDevModelRelationVOS.isEmpty()){
throw new BusinessException (AlgorithmResponseEnum.DATA_ERROR); throw new BusinessException (AlgorithmResponseEnum.DATA_ERROR);
} }
CsDevModelRelationPO csDevModelRelationPO = new CsDevModelRelationPO(); CsDevModelRelationPO csDevModelRelationPO = new CsDevModelRelationPO();
@@ -48,6 +54,25 @@ public class CsDevModelRelationServiceImpl extends ServiceImpl<CsDevModelRelatio
return csDevModelRelationPO; return csDevModelRelationPO;
} }
@Override
public void deleteByDeviceId(String deviceId) {
LambdaQueryWrapper<CsDevModelRelationPO> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CsDevModelRelationPO::getDevId, deviceId)
.eq (CsDevModelRelationPO::getStatus, 1);
this.baseMapper.delete(wrapper);
}
@Override
public void addRelation(CsDevModelRelationPO po) {
LambdaUpdateWrapper<CsDevModelRelationPO> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(CsDevModelRelationPO::getDevId, po.getDevId())
.eq(CsDevModelRelationPO::getDid, po.getDid())
.eq(CsDevModelRelationPO::getStatus, 1)
.set(CsDevModelRelationPO::getModelId,po.getModelId())
.set(CsDevModelRelationPO::getUpdateTime,po.getUpdateTime());
this.update(wrapper);
}
public List<CsDevModelRelationVO> queryDevModelRelation(CsDevModelRelationQueryParm queryParm) { public List<CsDevModelRelationVO> queryDevModelRelation(CsDevModelRelationQueryParm queryParm) {
QueryWrapper<CsDevModelRelationPO> queryWrapper = new QueryWrapper<> (); QueryWrapper<CsDevModelRelationPO> queryWrapper = new QueryWrapper<> ();
queryWrapper.eq (StringUtils.isNotBlank (queryParm.getId ()),"id",queryParm.getId ()). queryWrapper.eq (StringUtils.isNotBlank (queryParm.getId ()),"id",queryParm.getId ()).

View File

@@ -3,38 +3,47 @@ package com.njcn.access.service.impl;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.nacos.shaded.com.google.gson.Gson; import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.github.tocrhz.mqtt.publisher.MqttPublisher;
import com.njcn.access.enums.AccessEnum;
import com.njcn.access.enums.AccessResponseEnum; import com.njcn.access.enums.AccessResponseEnum;
import com.njcn.access.enums.DataModel; import com.njcn.access.enums.DataModel;
import com.njcn.access.enums.TypeEnum; import com.njcn.access.enums.TypeEnum;
import com.njcn.access.handler.MqttMessageHandler;
import com.njcn.access.mapper.CsDevModelMapper; import com.njcn.access.mapper.CsDevModelMapper;
import com.njcn.access.pojo.dto.ReqAndResDto;
import com.njcn.access.pojo.dto.UploadFileDto;
import com.njcn.access.pojo.dto.data.*; import com.njcn.access.pojo.dto.data.*;
import com.njcn.access.pojo.dto.devModel.*; import com.njcn.access.pojo.dto.devModel.*;
import com.njcn.access.pojo.dto.file.FileRedisDto;
import com.njcn.access.pojo.po.CsLineModel; import com.njcn.access.pojo.po.CsLineModel;
import com.njcn.access.service.*; import com.njcn.access.service.*;
import com.njcn.access.utils.CRC32Utils;
import com.njcn.access.utils.JsonUtil; import com.njcn.access.utils.JsonUtil;
import com.njcn.common.pojo.dto.DeviceLogDTO; import com.njcn.common.pojo.dto.DeviceLogDTO;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.csdevice.api.CsLogsFeignClient; import com.njcn.csdevice.api.CsLogsFeignClient;
import com.njcn.csdevice.api.DevModelFeignClient; import com.njcn.csdevice.api.DevModelFeignClient;
import com.njcn.csdevice.pojo.po.*; import com.njcn.csdevice.pojo.po.*;
import com.njcn.csdevice.pojo.vo.CsEquipmentDeliveryVO;
import com.njcn.oss.constant.OssPath; import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil; import com.njcn.oss.utils.FileStorageUtil;
import com.njcn.system.api.DicDataFeignClient; import com.njcn.redis.utils.RedisUtil;
import com.njcn.system.api.EleEvtFeignClient; import com.njcn.system.api.*;
import com.njcn.system.api.EleWaveFeignClient;
import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.enums.DicDataEnum; import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.param.CsWaveParam; import com.njcn.system.pojo.param.CsWaveParam;
import com.njcn.system.pojo.param.EleEpdPqdParam; import com.njcn.system.pojo.param.EleEpdPqdParam;
import com.njcn.system.pojo.param.EleEvtParam; import com.njcn.system.pojo.param.EleEvtParam;
import com.njcn.system.pojo.po.EleEpdPqd; import com.njcn.system.pojo.po.EleEpdPqd;
import com.njcn.system.pojo.vo.DictTreeVO;
import com.njcn.web.utils.RequestUtil; import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.util.encoders.Hex;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.sql.Date; import java.sql.Date;
import java.util.*; import java.util.*;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
@@ -78,6 +87,18 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
private final EleWaveFeignClient waveFeignClient; private final EleWaveFeignClient waveFeignClient;
private final DictTreeFeignClient dictTreeFeignClient;
private final MqttPublisher publisher;
private final ICsTopicService csTopicService;
private final ICsEquipmentDeliveryService csEquipmentDeliveryService;
private final RedisUtil redisUtil;
private final MqttMessageHandler mqttMessageHandler;
@Override @Override
@Transactional(rollbackFor = {Exception.class}) @Transactional(rollbackFor = {Exception.class})
public void addModel(MultipartFile file) { public void addModel(MultipartFile file) {
@@ -96,7 +117,7 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
String filePath = fileStorageUtil.uploadMultipart(file, OssPath.DEV_MODEL + templateDto.getDevType() + "_"); String filePath = fileStorageUtil.uploadMultipart(file, OssPath.DEV_MODEL + templateDto.getDevType() + "_");
//1.录入cs_dev_model表记录装置型号和模板记录 //1.录入cs_dev_model表记录装置型号和模板记录
CsDevModelPO csDevModelPo = addCsDevModel(templateDto,filePath); CsDevModelPO csDevModelPo = addCsDevModel(templateDto,filePath);
//2.录入数据集、详细数据(主设备、模块、监测设备) //2.录入数据集、详细数据(主设备、模块、监测设备、便携式设备...)
analysisDataSet(templateDto,csDevModelPo.getId()); analysisDataSet(templateDto,csDevModelPo.getId());
//3.录入监测点模板表(记录当前模板有几个监测点治理类型的模板目前规定1个监测点电能质量模板根据逻辑子设备来) //3.录入监测点模板表(记录当前模板有几个监测点治理类型的模板目前规定1个监测点电能质量模板根据逻辑子设备来)
addCsLineModel(templateDto,csDevModelPo.getId()); addCsLineModel(templateDto,csDevModelPo.getId());
@@ -133,6 +154,138 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
} }
} }
public static void main(String[] args) {
}
@Override
public void uploadDevFile(MultipartFile file,String id,String path) {
DeviceLogDTO logDto = null;
try {
byte[] bytes = file.getBytes();
int length = bytes.length;
//生成文件校验码
int crc = CRC32Utils.calculateCRC32(bytes,length,0xffffffff);
String hexString = String.format("%08X", crc);
//判断nDid是否存在
CsEquipmentDeliveryVO csEquipmentDeliveryVO = csEquipmentDeliveryService.queryEquipmentBynDid(id);
logDto = new DeviceLogDTO();
logDto.setUserName(RequestUtil.getUserNickname());
logDto.setLoginName(RequestUtil.getUsername());
if (Objects.isNull(csEquipmentDeliveryVO.getNdid())) {
logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.NDID_NO_FIND.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(AccessResponseEnum.NDID_NO_FIND);
}
//存储文件至文件服务器
fileStorageUtil.uploadMultipart(file, OssPath.SYSTEM_TO_DEV + file.getOriginalFilename() + "_");
//获取版本
String version = csTopicService.getVersion(id);
int cap = 50 * 1024;
//需要分片处理 一帧按50k大小传递
if (length > cap){
//需要循环的次数
int times = bytes.length / cap + 1;
for (int i = 1; i <= times; i++) {
byte[] lsBytes;
if (length > 50*1024) {
lsBytes = Arrays.copyOfRange(bytes, (i - 1) * cap, i * cap);
ReqAndResDto.Req req = getPojo(i,path,file,bytes.length,lsBytes,(i-1)*cap,hexString);
publisher.send("/Pfm/DevFileCmd/" + version + "/" + id, new Gson().toJson(req), 1, false);
logDto.setOperate(id + "设备上送文件,这是第" + i + "");
logDto.setResult(1);
length = length - cap;
//判断是否重发
sendNextStep(logDto,path,file,bytes.length,lsBytes,(i-1)*cap,version,id,i,hexString);
FileRedisDto fileRedisDto = (FileRedisDto) redisUtil.getObjectByKey("uploadFileStep");
//重发之后判断继续循环还是跳出循环
if (!Objects.equals(fileRedisDto.getCode(),200)) {
break;
}
} else {
lsBytes = Arrays.copyOfRange(bytes, (i - 1) * cap, bytes.length);
ReqAndResDto.Req req = getPojo(i,path,file,bytes.length,lsBytes,(i-1)*cap,hexString);
publisher.send("/Pfm/DevFileCmd/" + version + "/" + id, new Gson().toJson(req), 1, false);
logDto.setOperate(id + "设备上送文件,这是最后一帧,为第" + i + "");
logDto.setResult(1);
//判断是否重发
sendNextStep(logDto,path,file,bytes.length,lsBytes,(i-1)*cap,version,id,i,hexString);
}
csLogsFeignClient.addUserLog(logDto);
}
} else {
ReqAndResDto.Req req = getPojo(1,path,file,length,bytes,0,hexString);
publisher.send("/Pfm/DevFileCmd/" + version + "/" + id, new Gson().toJson(req), 1, false);
logDto.setOperate(id + "系统上送文件,当前文件只有1帧");
logDto.setResult(1);
csLogsFeignClient.addUserLog(logDto);
//判断是否重发
sendNextStep(logDto,path,file,length,bytes,0,version,id,1,hexString);
}
} catch (Exception e) {
assert logDto != null;
logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.UPLOAD_ERROR.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(AccessResponseEnum.UPLOAD_ERROR);
}
}
/**
* 上送文件至装置
*/
public ReqAndResDto.Req getPojo(Integer mid, String path, MultipartFile file, Integer allLength, byte[] bytes, Integer offset, String fileCheck) {
//组装报文
ReqAndResDto.Req reqAndResParam = new ReqAndResDto.Req();
reqAndResParam.setMid(mid);
reqAndResParam.setDid(0);
reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode());
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_10.getCode()));
reqAndResParam.setExpire(-1);
UploadFileDto uploadFileDto = new UploadFileDto();
uploadFileDto.setName(path + "/" + file.getOriginalFilename());
uploadFileDto.setFileSize(allLength);
uploadFileDto.setOffset(offset);
uploadFileDto.setLen(bytes.length);
uploadFileDto.setData(Base64.getEncoder().encodeToString(bytes));
uploadFileDto.setFileCheck(fileCheck);
reqAndResParam.setMsg(uploadFileDto);
return reqAndResParam;
}
/**
* 根据装置响应来判断发送的内容
*/
public void sendNextStep(DeviceLogDTO logDto, String path, MultipartFile file, int length, byte[] bytes, Integer offset, String version, String id, int mid, String fileCheck) {
try {
for (int i = 0; i < 3; i++) {
Thread.sleep(300);
FileRedisDto fileRedisDto = (FileRedisDto) redisUtil.getObjectByKey("uploadFileStep");
FileRedisDto fileRedis = new FileRedisDto();
if (Objects.nonNull(fileRedisDto.getCode()) && fileRedisDto.getCode().equals(200)) {
fileRedis.setCode(200);
break;
} else {
ReqAndResDto.Req req = getPojo(mid,path,file,length,bytes,offset,fileCheck);
publisher.send("/Pfm/DevFileCmd/" + version + "/" + id, new Gson().toJson(req), 1, false);
logDto.setOperate(id + "系统上送文件,装置响应失败,重新发送,这是第" + (i+1) + "");
logDto.setResult(1);
csLogsFeignClient.addUserLog(logDto);
fileRedis.setCode(fileRedisDto.getCode());
}
redisUtil.saveByKeyWithExpire("uploadFileStep",fileRedis,10L);
}
} catch (InterruptedException e) {
assert logDto != null;
logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.RELOAD_UPLOAD_ERROR.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new RuntimeException(e);
}
}
/** /**
* 新增cs_dev_model数据 * 新增cs_dev_model数据
*/ */
@@ -267,7 +420,7 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
eleEvtParam.setPid(dictId); eleEvtParam.setPid(dictId);
eleEvtParam.setData(param.getData()); eleEvtParam.setData(param.getData());
eleEvtParam.setName(param.getName()); eleEvtParam.setName(param.getName());
String showName = dataSetName(param.getName()); String showName = dataSetName(param.getName(),null);
if (Objects.isNull(showName)){ if (Objects.isNull(showName)){
eleEvtParam.setShowName(param.getName()); eleEvtParam.setShowName(param.getName());
} else { } else {
@@ -647,7 +800,7 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
CsWaveParam csWaveParam = new CsWaveParam(); CsWaveParam csWaveParam = new CsWaveParam();
csWaveParam.setPid(dictId); csWaveParam.setPid(dictId);
csWaveParam.setName(param.getName()); csWaveParam.setName(param.getName());
String showName = dataSetName(param.getName()); String showName = dataSetName(param.getName(),null);
if (Objects.isNull(showName)){ if (Objects.isNull(showName)){
csWaveParam.setShowName(param.getName()); csWaveParam.setShowName(param.getName());
} else { } else {
@@ -678,22 +831,29 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
List<CsDataSet> setList = new ArrayList<>(); List<CsDataSet> setList = new ArrayList<>();
List<CsDataArray> arrayList = new ArrayList<>(); List<CsDataArray> arrayList = new ArrayList<>();
List<DataSetDto> dataSetList = templateDto.getDataSet(); List<DataSetDto> dataSetList = templateDto.getDataSet();
String devType = templateDto.getDevType();
DictTreeVO dictTreeVO = dictTreeFeignClient.queryByCode(devType).getData();
if (Objects.isNull(dictTreeVO)){
throw new BusinessException(AccessResponseEnum.DEV_TYPE_NOT_FIND);
}
String code = dictTreeFeignClient.queryById(dictTreeVO.getPid()).getData().getCode();
//逻辑设备录入 //逻辑设备录入
if (CollectionUtil.isNotEmpty(dataSetList)){ if (CollectionUtil.isNotEmpty(dataSetList)){
dataSetList.forEach(item1->{ dataSetList.forEach(item1->{
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
CsDataSet CsDataSet = new CsDataSet(); CsDataSet csDataSet = new CsDataSet();
CsDataSet.setId(id); csDataSet.setId(id);
CsDataSet.setPid(pId); csDataSet.setPid(pId);
CsDataSet.setName(item1.getName()); csDataSet.setName(item1.getName());
CsDataSet.setAnotherName(dataSetName(item1.getName())); csDataSet.setAnotherName(dataSetName(item1.getName(),code));
CsDataSet.setIdx(item1.getIdx()); csDataSet.setIdx(item1.getIdx());
CsDataSet.setPeriod(item1.getPeriod()); csDataSet.setPeriod(item1.getPeriod());
CsDataSet.setStoreFlag(item1.getStoreFlag()); csDataSet.setStoreFlag(item1.getStoreFlag());
CsDataSet.setDataList(String.join(",",templateDto.getDataList())); csDataSet.setDataList(String.join(",",templateDto.getDataList()));
CsDataSet.setType(0); csDataSet.setType(0);
CsDataSet.setClDev(0); csDataSet.setClDev(0);
setList.add(CsDataSet); csDataSet.setDataLevel(item1.getDataLevel());
setList.add(csDataSet);
List<DataArrayDto> list = item1.getDataArrayDtoList(); List<DataArrayDto> list = item1.getDataArrayDtoList();
if(CollectionUtil.isNotEmpty(list)) { if(CollectionUtil.isNotEmpty(list)) {
int i = 0; int i = 0;
@@ -717,23 +877,24 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
if (CollectionUtil.isNotEmpty(clDataSetList)){ if (CollectionUtil.isNotEmpty(clDataSetList)){
clDataSetList.forEach(item4->{ clDataSetList.forEach(item4->{
String id = IdUtil.fastSimpleUUID(); String id = IdUtil.fastSimpleUUID();
CsDataSet CsDataSet = new CsDataSet(); CsDataSet csDataSet = new CsDataSet();
CsDataSet.setId(id); csDataSet.setId(id);
CsDataSet.setPid(pId); csDataSet.setPid(pId);
CsDataSet.setName(item4.getName()); csDataSet.setName(item4.getName());
CsDataSet.setAnotherName(dataSetName(item4.getName())); csDataSet.setAnotherName(dataSetName(item4.getName(),code));
CsDataSet.setIdx(item4.getIdx()); csDataSet.setIdx(item4.getIdx());
CsDataSet.setPeriod(item4.getPeriod()); csDataSet.setPeriod(item4.getPeriod());
CsDataSet.setStoreFlag(item4.getStoreFlag()); csDataSet.setStoreFlag(item4.getStoreFlag());
CsDataSet.setDataList(String.join(",",item3.getDataList())); csDataSet.setDataList(String.join(",",item3.getDataList()));
csDataSet.setDataLevel(item4.getDataLevel());
//fixme 先用数据类型来区分模板的类型 //fixme 先用数据类型来区分模板的类型
if (item3.getDataList().contains("Apf") || item3.getDataList().contains("Dvr")){ if (item3.getDataList().contains("Apf") || item3.getDataList().contains("Dvr")){
CsDataSet.setType(1); csDataSet.setType(1);
} else { } else {
CsDataSet.setType(2); csDataSet.setType(2);
} }
CsDataSet.setClDev(item3.getClDid()); csDataSet.setClDev(item3.getClDid());
setList.add(CsDataSet); setList.add(csDataSet);
List<DataArrayDto> list = item4.getDataArrayDtoList(); List<DataArrayDto> list = item4.getDataArrayDtoList();
if(CollectionUtil.isNotEmpty(list)) { if(CollectionUtil.isNotEmpty(list)) {
@@ -1024,7 +1185,7 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
/** /**
* 数据集名称调整 * 数据集名称调整
*/ */
public String dataSetName(String name){ public String dataSetName(String name,String code){
String showName = null; String showName = null;
switch (name) { switch (name) {
//数据集 //数据集
@@ -1056,10 +1217,18 @@ public class CsDevModelServiceImpl implements ICsDevModelService {
showName = "APF模块8数据"; showName = "APF模块8数据";
break; break;
case "Ds$Pqd$Stat$01": case "Ds$Pqd$Stat$01":
if (Objects.equals(code, DicDataEnum.CONNECT_DEV.getCode()) || Objects.isNull(code)){
showName = "电网侧数据"; showName = "电网侧数据";
} else if (Objects.equals(code, DicDataEnum.PORTABLE.getCode())){
showName = "监测1路数据";
}
break; break;
case "Ds$Pqd$Stat$02": case "Ds$Pqd$Stat$02":
if (Objects.equals(code, DicDataEnum.CONNECT_DEV.getCode()) || Objects.isNull(code)){
showName = "负载侧数据"; showName = "负载侧数据";
} else if (Objects.equals(code, DicDataEnum.PORTABLE.getCode())){
showName = "监测2路数据";
}
break; break;
//波形参数名称 //波形参数名称
case "Wave_Param_Position": case "Wave_Param_Position":

View File

@@ -1,8 +1,8 @@
package com.njcn.access.service.impl; package com.njcn.access.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.CollectionUtils; import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.alibaba.nacos.shaded.com.google.gson.Gson; import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -13,11 +13,9 @@ import com.njcn.access.enums.TypeEnum;
import com.njcn.access.param.DevAccessParam; import com.njcn.access.param.DevAccessParam;
import com.njcn.access.pojo.RspDataDto; import com.njcn.access.pojo.RspDataDto;
import com.njcn.access.pojo.dto.AccessDto; import com.njcn.access.pojo.dto.AccessDto;
import com.njcn.access.pojo.dto.AskDataDto;
import com.njcn.access.pojo.dto.CsModelDto; import com.njcn.access.pojo.dto.CsModelDto;
import com.njcn.access.pojo.dto.ReqAndResDto; import com.njcn.access.pojo.dto.ReqAndResDto;
import com.njcn.access.pojo.param.DeviceStatusParam; import com.njcn.access.pojo.param.DeviceStatusParam;
import com.njcn.access.pojo.po.CsSoftInfoPO;
import com.njcn.access.service.*; import com.njcn.access.service.*;
import com.njcn.access.utils.MqttUtil; import com.njcn.access.utils.MqttUtil;
import com.njcn.common.pojo.dto.DeviceLogDTO; import com.njcn.common.pojo.dto.DeviceLogDTO;
@@ -38,20 +36,14 @@ import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.po.SysDicTreePO; import com.njcn.system.pojo.po.SysDicTreePO;
import com.njcn.web.utils.RequestUtil; import com.njcn.web.utils.RequestUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import net.sf.cglib.core.Local;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.test.annotation.Rollback;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -101,6 +93,8 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
private final CsDeviceUserPOService csDeviceUserPOService; private final CsDeviceUserPOService csDeviceUserPOService;
private final ICsDataSetService csDataSetService;
@Override @Override
@Transactional(rollbackFor = {Exception.class}) @Transactional(rollbackFor = {Exception.class})
public void devRegister(String nDid,Integer type) { public void devRegister(String nDid,Integer type) {
@@ -118,6 +112,13 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
csLogsFeignClient.addUserLog(logDto); csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(AccessResponseEnum.NDID_NO_FIND); throw new BusinessException(AccessResponseEnum.NDID_NO_FIND);
} }
//判断是否已经注册过
if (!Objects.isNull(csEquipmentDeliveryVO.getNdid()) && Objects.equals(type,csEquipmentDeliveryVO.getProcess()) && Objects.equals(AccessEnum.ACCESS.getCode(),csEquipmentDeliveryVO.getStatus())){
logDto.setResult(0);
logDto.setFailReason(AccessResponseEnum.NDID_SAME_STEP.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(AccessResponseEnum.NDID_SAME_STEP);
}
//2.判断设备是否是直连设备 //2.判断设备是否是直连设备
SysDicTreePO sysDicTreePo = dictTreeFeignClient.queryById(csEquipmentDeliveryVO.getDevType()).getData(); SysDicTreePO sysDicTreePo = dictTreeFeignClient.queryById(csEquipmentDeliveryVO.getDevType()).getData();
if (Objects.isNull(sysDicTreePo)){ if (Objects.isNull(sysDicTreePo)){
@@ -179,7 +180,7 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
logDto.setResult(1); logDto.setResult(1);
Object model = null; Object model = null;
try { try {
Thread.sleep(1500); Thread.sleep(3000);
String key = AppRedisKey.LINE + nDid; String key = AppRedisKey.LINE + nDid;
model = redisUtil.getObjectByKey(key); model = redisUtil.getObjectByKey(key);
if (Objects.isNull(model)){ if (Objects.isNull(model)){
@@ -234,6 +235,7 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
CsLedgerParam param = new CsLedgerParam(); CsLedgerParam param = new CsLedgerParam();
AppLineTopologyDiagramPO appLineTopologyDiagramPo = new AppLineTopologyDiagramPO(); AppLineTopologyDiagramPO appLineTopologyDiagramPo = new AppLineTopologyDiagramPO();
po.setName(item.getName()); po.setName(item.getName());
po.setDeviceId(vo.getId());
po.setPosition(item.getPosition()); po.setPosition(item.getPosition());
po.setClDid(0); po.setClDid(0);
if (Objects.equals(DicDataEnum.GRID_SIDE.getCode(),location)){ if (Objects.equals(DicDataEnum.GRID_SIDE.getCode(),location)){
@@ -285,7 +287,7 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
//6.修改装置状态 //6.修改装置状态
csEquipmentDeliveryService.updateStatusBynDid(devAccessParam.getNDid(), AccessEnum.REGISTERED.getCode()); csEquipmentDeliveryService.updateStatusBynDid(devAccessParam.getNDid(), AccessEnum.REGISTERED.getCode());
//7.发起自动接入请求 //7.发起自动接入请求
devAccess(devAccessParam.getNDid(),version); devAccessAskTemplate(devAccessParam.getNDid(),version,1);
//8.删除redis监测点模板信息 //8.删除redis监测点模板信息
redisUtil.delete(AppRedisKey.MODEL + devAccessParam.getNDid()); redisUtil.delete(AppRedisKey.MODEL + devAccessParam.getNDid());
@@ -356,26 +358,200 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
} }
} }
public void devAccess(String nDid,String version) { @Override
ReqAndResDto.Req reqAndResParam = new ReqAndResDto.Req(); @Transactional(rollbackFor = Exception.class)
reqAndResParam.setMid(1); public boolean manualAccess(String nDid) {
reqAndResParam.setDid(0); String version = csTopicService.getVersion(nDid);
reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode()); return devAccessAskTemplate(nDid,version,new Random().nextInt(10000));
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_5.getCode()));
reqAndResParam.setExpire(-1);
logger.info("设备接入报文为:" + new Gson().toJson(reqAndResParam));
publisher.send("/Pfm/DevCmd/"+version+"/"+nDid, new Gson().toJson(reqAndResParam),1,false);
} }
public void devAccessMid(String nDid,String version,Integer mid) {
@Override
@Transactional(rollbackFor = {Exception.class})
public String wlDevRegister(String nDid) {
try {
// 设备状态判断
checkDeviceStatus(nDid);
// 询问设备支持的主题信息,并将支持的主题入库
askAndStoreTopics(nDid);
// MQTT询问装置用的模板并判断库中是否存在模板
checkDeviceModel(nDid);
// 根据模板接入设备
DeviceLogDTO logDto = new DeviceLogDTO();
logDto.setUserName(RequestUtil.getUserNickname());
logDto.setLoginName(RequestUtil.getUsername());
logDto.setOperate("设备"+nDid+"注册");
logDto.setResult(1);
try {
Thread.sleep(1000);
//获取版本
String version = csTopicService.getVersion(nDid);
CsEquipmentDeliveryVO vo = equipmentFeignClient.queryEquipmentByndid(nDid).getData();
List<CsLinePO> csLinePoList = new ArrayList<>();
//1.根据模板获取监测点个数,插入监测点表
Thread.sleep(1000);
List<CsModelDto> modelList = objectToList(redisUtil.getObjectByKey(AppRedisKey.MODEL + nDid));
if (CollUtil.isEmpty(modelList)){
try {
throwExceptionAndLog(AccessResponseEnum.MODEL_ERROR, logDto);
} catch (Exception e) {
throw new BusinessException(e.getMessage());
}
}
List<CsDataSet> list = csDataSetService.getDataSetData(modelList.get(0).getModelId());
list.forEach(item->{
CsLinePO po = new CsLinePO();
po.setLineId(nDid + item.getClDev().toString());
po.setName(item.getClDev().toString() + "号监测点");
po.setStatus(1);
po.setClDid(item.getClDev());
po.setDeviceId(vo.getId());
//防止主键重复
QueryWrapper<CsLinePO> qw = new QueryWrapper();
qw.eq("line_id",po.getLineId());
if(csLineService.getBaseMapper().selectList(qw).isEmpty()){
csLinePoList.add(po);
}
});
csLineService.saveBatch(csLinePoList);
//2.生成装置和模板的关系表
CsDevModelRelationAddParm csDevModelRelationAddParm = new CsDevModelRelationAddParm();
csDevModelRelationAddParm.setDevId(vo.getId());
csDevModelRelationAddParm.setModelId(modelList.get(0).getModelId());
csDevModelRelationAddParm.setDid(modelList.get(0).getDid());
csDevModelRelationService.addDevModelRelation(csDevModelRelationAddParm);
//3.修改装置状态为注册状态
csEquipmentDeliveryService.updateStatusBynDid(nDid, AccessEnum.REGISTERED.getCode());
//4.发起自动接入请求
devAccessAskTemplate(nDid,version,1);
//5.存储日志
csLogsFeignClient.addUserLog(logDto);
//6.存储设备调试日志表
CsEquipmentProcessPO csEquipmentProcess = new CsEquipmentProcessPO();
csEquipmentProcess.setDevId(nDid);
csEquipmentProcess.setOperator(RequestUtil.getUserIndex());
csEquipmentProcess.setStartTime(LocalDateTime.now());
csEquipmentProcess.setEndTime(LocalDateTime.now());
csEquipmentProcess.setProcess(4);
csEquipmentProcess.setStatus(1);
processFeignClient.add(csEquipmentProcess);
//7.删除redis监测点模板信息
redisUtil.delete(AppRedisKey.MODEL + nDid);
redisUtil.delete(AppRedisKey.LINE + nDid);
} catch (Exception e) {
logDto.setResult(0);
logDto.setFailReason(e.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(CommonResponseEnum.FAIL);
}
return "success";
} catch (BusinessException e) {
throw new BusinessException(e.getMessage());
}
}
@Override
public void wlAccess(String nDid) {
//设备状态判断
checkDeviceStatus(nDid);
//获取版本
String version = csTopicService.getVersion(nDid);
//发起接入请求
this.devAccessAskTemplate(nDid,version,1);
}
private void checkDeviceStatus(String nDid) {
DeviceLogDTO logDto = createLogDto("当前设备"+nDid+"状态判断");
CsEquipmentDeliveryVO csEquipmentDeliveryVO = csEquipmentDeliveryService.queryEquipmentBynDid(nDid);
if (Objects.isNull(csEquipmentDeliveryVO.getNdid())) {
throwExceptionAndLog(AccessResponseEnum.NDID_NO_FIND, logDto);
}
SysDicTreePO sysDicTreePo = dictTreeFeignClient.queryById(csEquipmentDeliveryVO.getDevType()).getData();
if (Objects.isNull(sysDicTreePo)) {
throwExceptionAndLog(AccessResponseEnum.DEV_NOT_FIND, logDto);
}
String code = sysDicTreePo.getCode();
if (!Objects.equals(code, DicDataEnum.PORTABLE.getCode())) {
throwExceptionAndLog(AccessResponseEnum.DEV_IS_NOT_PORTABLE, logDto);
}
if (!mqttUtil.judgeClientOnline("NJCN-" + nDid.substring(nDid.length() - 6))) {
throwExceptionAndLog(AccessResponseEnum.MISSING_CLIENT, logDto);
}
}
private void askAndStoreTopics(String nDid) {
// 询问设备支持的主题信息
this.askTopic(nDid);
}
private void checkDeviceModel(String nDid) {
DeviceLogDTO logDto = createLogDto("MQTT询问装置用的模板并判断库中是否存在模板");
CsEquipmentDeliveryVO csEquipmentDeliveryVO = csEquipmentDeliveryService.queryEquipmentBynDid(nDid);
SysDicTreePO dictData = dictTreeFeignClient.queryById(csEquipmentDeliveryVO.getDevModel()).getData();
if (Objects.isNull(dictData)) {
throwExceptionAndLog(AccessResponseEnum.DEV_MODEL_NOT_FIND, logDto);
}
String devModel = dictData.getCode();
zhiLianRegister(nDid,devModel);
}
private DeviceLogDTO createLogDto(String operate) {
DeviceLogDTO logDto = new DeviceLogDTO();
logDto.setUserName(RequestUtil.getUserNickname());
logDto.setLoginName(RequestUtil.getUsername());
logDto.setOperate(operate);
logDto.setResult(1);
return logDto;
}
private void throwExceptionAndLog(AccessResponseEnum responseEnum, DeviceLogDTO logDto) {
logDto.setResult(0);
logDto.setFailReason(responseEnum.getMessage());
csLogsFeignClient.addUserLog(logDto);
throw new BusinessException(responseEnum);
}
/**
* 装置重新接入系统,需要校验所用的模板
* @param nDid
* @param version
*/
@Transactional(rollbackFor = Exception.class)
public boolean devAccessAskTemplate(String nDid,String version,Integer mid) {
boolean result = false;
try {
redisUtil.delete(AppRedisKey.MODEL + nDid);
//询问装置当前所用模板
ReqAndResDto.Req reqAndResParam = new ReqAndResDto.Req(); ReqAndResDto.Req reqAndResParam = new ReqAndResDto.Req();
reqAndResParam.setMid(mid); reqAndResParam.setMid(mid);
reqAndResParam.setDid(0); reqAndResParam.setDid(0);
reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode()); reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode());
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_5.getCode())); reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_3.getCode()));
reqAndResParam.setExpire(-1); reqAndResParam.setExpire(-1);
logger.info("设备接入报文为:" + new Gson().toJson(reqAndResParam));
publisher.send("/Pfm/DevCmd/"+version+"/"+nDid,new Gson().toJson(reqAndResParam),1,false); publisher.send("/Pfm/DevCmd/"+version+"/"+nDid,new Gson().toJson(reqAndResParam),1,false);
//接收到模板,判断模板是否存在,替换模板,发起接入
Thread.sleep(2000);
List<CsModelDto> modelId = objectToList(redisUtil.getObjectByKey(AppRedisKey.MODEL + nDid));
if (CollUtil.isNotEmpty(modelId)) {
CsEquipmentDeliveryVO vo = equipmentFeignClient.queryEquipmentByndid(nDid).getData();
//重新录入装置和模板关系信息
for (CsModelDto item : modelId) {
CsDevModelRelationPO po = new CsDevModelRelationPO();
po.setDevId(vo.getId());
po.setModelId(item.getModelId());
po.setDid(item.getDid());
po.setUpdateTime(LocalDateTime.now());
csDevModelRelationService.addRelation(po);
}
//发起接入
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_5.getCode()));
publisher.send("/Pfm/DevCmd/"+version+"/"+nDid, new Gson().toJson(reqAndResParam),1,false);
result = true;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return result;
} }
/** /**
@@ -388,7 +564,7 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode()); reqAndResParam.setPri(AccessEnum.FIRST_CHANNEL.getCode());
reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_1.getCode())); reqAndResParam.setType(Integer.parseInt(TypeEnum.TYPE_1.getCode()));
reqAndResParam.setExpire(-1); reqAndResParam.setExpire(-1);
logger.info("询问主题报文为:" + new Gson().toJson(reqAndResParam)); logger.info("询问主题报文为:{}", new Gson().toJson(reqAndResParam));
publisher.send("/Pfm/DevTopic/"+nDid, new Gson().toJson(reqAndResParam),1,false); publisher.send("/Pfm/DevTopic/"+nDid, new Gson().toJson(reqAndResParam),1,false);
} }
@@ -408,7 +584,7 @@ public class CsDeviceServiceImpl implements ICsDeviceService {
accessDto.setNdid(nDid); accessDto.setNdid(nDid);
accessDto.setDevType(devType); accessDto.setDevType(devType);
reqAndResParam.setMsg(accessDto); reqAndResParam.setMsg(accessDto);
logger.info("注册报文为:" + new Gson().toJson(reqAndResParam)); logger.info("注册报文为:{}", new Gson().toJson(reqAndResParam));
publisher.send("/Pfm/DevReg/"+nDid, new Gson().toJson(reqAndResParam),1,false); publisher.send("/Pfm/DevReg/"+nDid, new Gson().toJson(reqAndResParam),1,false);
} }

View File

@@ -0,0 +1,52 @@
package com.njcn.access.utils;
/**
* @author xy
*/
public class CRC32Utils {
// CRC-32/MPEG-2 多项式, x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
private static final int POLYNOMIAL = 0x04C11DB7;
public static int calculateCRC32(byte[] buf, int len, int seed) {
if (buf == null || len <= 0) {
return seed;
}
int crc = seed;
int count = 0;
// 对长度进行填充以适应32位整数
int rem = len % Integer.BYTES;
if (rem > 0) {
int n = Integer.BYTES - rem;
byte[] newBuf = new byte[len + n];
System.arraycopy(buf, 0, newBuf, 0, len);
// 填充字节用0xFF
for (int i = len; i < len + n; i++) {
newBuf[i] = (byte) 0xFF;
}
buf = newBuf;
len += n;
}
int uiCount = len / Integer.BYTES;
for (int k = 0; k < uiCount; k++) {
int uiTemp = 0;
for (int i = 0; i < Integer.BYTES; i++) {
uiTemp |= (buf[k * Integer.BYTES + i] & 0xFF) << (8 * (3 - i));
}
for (int j = 0; j < 32; j++) {
// 检查最高位是否为1
if ((crc ^ uiTemp) < 0) {
crc = 0x04C11DB7 ^ (crc << 1);
count ++;
} else {
crc <<= 1;
}
uiTemp <<= 1;
}
}
return crc;
}
}

View File

@@ -35,6 +35,10 @@ spring:
refresh: true refresh: true
main: main:
allow-bean-definition-overriding: true allow-bean-definition-overriding: true
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
#项目日志的配置 #项目日志的配置
logging: logging:

View File

@@ -14,6 +14,7 @@ import com.njcn.access.pojo.dto.ReqAndResDto;
import com.njcn.access.pojo.dto.mqtt.MqttClientDto; import com.njcn.access.pojo.dto.mqtt.MqttClientDto;
import com.njcn.access.service.ICsEquipmentDeliveryService; import com.njcn.access.service.ICsEquipmentDeliveryService;
import com.njcn.access.service.impl.CsDeviceServiceImpl; import com.njcn.access.service.impl.CsDeviceServiceImpl;
import com.njcn.access.utils.MqttUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum; import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException; import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils; import com.njcn.common.utils.PubUtils;
@@ -74,23 +75,25 @@ public class AppTest
@Resource @Resource
private CsDeviceServiceImpl csDeviceService; private CsDeviceServiceImpl csDeviceService;
@Resource
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Resource
private MqttUtil mqttUtil;
@Test @Test
public void lossTest() { public void lossTest() {
String nDid = "0008C0A801C8"; final int[] mid = {2};
Integer status = csEquipmentDeliveryService.queryEquipmentByndid(nDid).getRunStatus(); for (int i = 0; i < 2; i++) {
if (!Objects.isNull(status) && Objects.equals(status,AccessEnum.ONLINE.getCode())){ mid[0] = mid[0] + 1;
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
ScheduledFuture<?> runnableFuture = executor.scheduleAtFixedRate(() -> {
log.info("定时发送接入请求...");
Integer status2 = csEquipmentDeliveryService.queryEquipmentByndid(nDid).getRunStatus();
if (Objects.equals(status2,AccessEnum.OFFLINE.getCode())){
throw new BusinessException(CommonResponseEnum.SUCCESS);
} }
}, 1, 5, TimeUnit.SECONDS); System.out.println("mid==:" + mid[0]);
} }
@Test
public void test1() {
String clientName = "NJCN-A801C8";
boolean mqttClient = mqttUtil.judgeClientOnline(clientName);
System.out.println("mqttClient==:" + mqttClient);
} }

View File

@@ -21,6 +21,7 @@ import com.njcn.redis.utils.RedisUtil;
import com.njcn.stat.enums.StatResponseEnum; import com.njcn.stat.enums.StatResponseEnum;
import com.njcn.stat.service.IStatService; import com.njcn.stat.service.IStatService;
import com.njcn.system.api.DicDataFeignClient; import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
import com.njcn.system.api.EpdFeignClient; import com.njcn.system.api.EpdFeignClient;
import com.njcn.system.enums.DicDataEnum; import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.pojo.dto.EpdDTO; import com.njcn.system.pojo.dto.EpdDTO;
@@ -62,6 +63,8 @@ public class StatServiceImpl implements IStatService {
private final EquipmentFeignClient equipmentFeignClient; private final EquipmentFeignClient equipmentFeignClient;
private final DictTreeFeignClient dictTreeFeignClient;
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void analysis(AppAutoDataMessage appAutoDataMessage) { public void analysis(AppAutoDataMessage appAutoDataMessage) {
@@ -82,36 +85,44 @@ public class StatServiceImpl implements IStatService {
if (Objects.isNull(object1)){ if (Objects.isNull(object1)){
lineInfo(appAutoDataMessage.getId()); lineInfo(appAutoDataMessage.getId());
} }
if (Objects.equals(appAutoDataMessage.getDid(),1)){ //获取当前设备信息判断装置型号,来筛选监测点
lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get("0").toString(); CsEquipmentDeliveryPO po = equipmentFeignClient.findDevByNDid(appAutoDataMessage.getId()).getData();
String code = dictTreeFeignClient.queryById(po.getDevType()).getData().getCode();
//便携式设备
if (Objects.equals(DicDataEnum.PORTABLE.getCode(),code)) {
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.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)){ } 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(); lineId = new Gson().fromJson(String.valueOf(redisUtil.getObjectByKey(AppRedisKey.LINE_POSITION+appAutoDataMessage.getId())), Map.class).get(appAutoDataMessage.getMsg().getClDid().toString()).toString();
} }
}
//缓存指标和influxDB表关系 //缓存指标和influxDB表关系
Object object2 = redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD); Object object2 = redisUtil.getObjectByKey(AppRedisKey.ELE_EPD_PQD);
if(Objects.isNull(object2)) { if(Objects.isNull(object2)) {
saveData(); saveData();
} }
//获取当前设备信息 //获取当前设备信息
CsEquipmentDeliveryPO po = equipmentFeignClient.findDevByNDid(appAutoDataMessage.getId()).getData();
if (CollectionUtil.isNotEmpty(list)){ if (CollectionUtil.isNotEmpty(list)){
List<String> recordList = new ArrayList<>(); List<String> recordList = new ArrayList<>();
for (AppAutoDataMessage.DataArray item : list) { for (AppAutoDataMessage.DataArray item : list) {
switch (item.getDataAttr()) { switch (item.getDataAttr()) {
case 1: case 1:
log.info("处理最大值"); log.info("{}-->处理最大值", po.getNdid());
dataArrayParam.setStatMethod("max"); dataArrayParam.setStatMethod("max");
break; break;
case 2: case 2:
log.info("处理最小值"); log.info("{}-->处理最小值", po.getNdid());
dataArrayParam.setStatMethod("min"); dataArrayParam.setStatMethod("min");
break; break;
case 3: case 3:
log.info("处理avg"); log.info("{}-->处理avg", po.getNdid());
dataArrayParam.setStatMethod("avg"); dataArrayParam.setStatMethod("avg");
break; break;
case 4: case 4:
log.info("处理cp95"); log.info("{}-->处理cp95", po.getNdid());
dataArrayParam.setStatMethod("cp95"); dataArrayParam.setStatMethod("cp95");
break; break;
default: default:
@@ -144,10 +155,10 @@ public class StatServiceImpl implements IStatService {
throw new BusinessException(StatResponseEnum.LINE_NULL); throw new BusinessException(StatResponseEnum.LINE_NULL);
} }
for (CsLinePO item : lineList) { for (CsLinePO item : lineList) {
if (Objects.isNull(item.getPosition())){
map.put(item.getClDid(),item.getLineId());
} else {
DictData dictData = dicDataFeignClient.getDicDataById(item.getPosition()).getData(); DictData dictData = dicDataFeignClient.getDicDataById(item.getPosition()).getData();
if (Objects.isNull(dictData)){
throw new BusinessException(StatResponseEnum.DICT_NULL);
}
if (Objects.equals(dictData.getCode(), DicDataEnum.OUTPUT_SIDE.getCode())){ if (Objects.equals(dictData.getCode(), DicDataEnum.OUTPUT_SIDE.getCode())){
map.put(0,item.getLineId()); map.put(0,item.getLineId());
} else if (Objects.equals(dictData.getCode(), DicDataEnum.GRID_SIDE.getCode())){ } else if (Objects.equals(dictData.getCode(), DicDataEnum.GRID_SIDE.getCode())){
@@ -156,6 +167,7 @@ public class StatServiceImpl implements IStatService {
map.put(2,item.getLineId()); map.put(2,item.getLineId());
} }
} }
}
redisUtil.saveByKeyWithExpire(AppRedisKey.LINE_POSITION+id,map,600L); redisUtil.saveByKeyWithExpire(AppRedisKey.LINE_POSITION+id,map,600L);
} }

View File

@@ -2,8 +2,6 @@ package com.njcn.zlevent.utils;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.nacos.shaded.com.google.gson.Gson; import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.njcn.csdevice.api.CsDeviceUserFeignClient; import com.njcn.csdevice.api.CsDeviceUserFeignClient;
import com.njcn.csdevice.api.CsLedgerFeignClient; import com.njcn.csdevice.api.CsLedgerFeignClient;
@@ -22,7 +20,6 @@ import com.njcn.zlevent.service.ICsEventUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.BufferedReader; import java.io.BufferedReader;
@@ -87,7 +84,7 @@ public class SendEventUtils {
public void sendUser(Integer eventType,String type,String devId, String eventName, LocalDateTime eventTime, String id) { public void sendUser(Integer eventType,String type,String devId, String eventName, LocalDateTime eventTime, String id) {
int code; int code;
List<User> users = new ArrayList<>(); List<User> users = new ArrayList<>();
List<String> eventUser;
List<String> devCodeList; List<String> devCodeList;
List<CsEventSendMsg> csEventSendMsgList = new ArrayList<>(); List<CsEventSendMsg> csEventSendMsgList = new ArrayList<>();
NoticeUserDto noticeUserDto = new NoticeUserDto(); NoticeUserDto noticeUserDto = new NoticeUserDto();
@@ -101,51 +98,64 @@ public class SendEventUtils {
case "1": case "1":
code = 2; code = 2;
//设备自身事件 不推送给用户,推送给业务管理 //设备自身事件 不推送给用户,推送给业务管理
users = getAdminUser(); eventUser = getEventUser(devId,false);
if (CollectionUtil.isNotEmpty(users)){ if (CollectionUtil.isNotEmpty(eventUser)) {
noticeUserDto.setPushClientId(Collections.singletonList(users.get(0).getDevCode())); eventUser.forEach(item->{
noticeUserDto.setTitle("设备事件");
//记录需要通知的用户和事件关系
CsEventUserPO csEventUser = new CsEventUserPO(); CsEventUserPO csEventUser = new CsEventUserPO();
csEventUser.setUserId(users.get(0).getId()); csEventUser.setUserId(item);
csEventUser.setStatus(0); csEventUser.setStatus(0);
csEventUser.setEventId(id); csEventUser.setEventId(id);
result.add(csEventUser); result.add(csEventUser);
});
users = getSendUser(eventUser,2);
if (CollectionUtil.isNotEmpty(users)){
for (User user : users){
noticeUserDto.setPushClientId(Collections.singletonList(user.getDevCode()));
noticeUserDto.setTitle("设备事件");
}
}
} }
break; break;
case "2": case "2":
code = 0; code = 0;
//暂态事件 //暂态事件
users = getEventUser(devId,0); eventUser = getEventUser(devId,true);
if (CollectionUtil.isNotEmpty(eventUser)) {
eventUser.forEach(item->{
CsEventUserPO csEventUser = new CsEventUserPO();
csEventUser.setUserId(item);
csEventUser.setStatus(0);
csEventUser.setEventId(id);
result.add(csEventUser);
});
users = getSendUser(eventUser,0);
if (CollectionUtil.isNotEmpty(users)){
devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList()); devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList());
noticeUserDto.setPushClientId(devCodeList); noticeUserDto.setPushClientId(devCodeList);
noticeUserDto.setTitle("暂态事件"); noticeUserDto.setTitle("暂态事件");
//记录需要通知的用户和事件关系 }
List<String> list2 = users.stream().map(User::getId).collect(Collectors.toList()); }
list2.forEach(item->{
CsEventUserPO csEventUser2 = new CsEventUserPO();
csEventUser2.setUserId(item);
csEventUser2.setStatus(0);
csEventUser2.setEventId(id);
result.add(csEventUser2);
});
break; break;
case "3": case "3":
code = 1; code = 1;
//稳态事件 //稳态事件
users = getEventUser(devId,1); eventUser = getEventUser(devId,true);
if (CollectionUtil.isNotEmpty(eventUser)) {
eventUser.forEach(item->{
CsEventUserPO csEventUser = new CsEventUserPO();
csEventUser.setUserId(item);
csEventUser.setStatus(0);
csEventUser.setEventId(id);
result.add(csEventUser);
});
users = getSendUser(eventUser,1);
if (CollectionUtil.isNotEmpty(users)){
devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList()); devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList());
noticeUserDto.setPushClientId(devCodeList); noticeUserDto.setPushClientId(devCodeList);
noticeUserDto.setTitle("稳态事件"); noticeUserDto.setTitle("稳态事件");
//记录需要通知的用户和事件关系 }
List<String> list3 = users.stream().map(User::getId).collect(Collectors.toList()); }
list3.forEach(item->{
CsEventUserPO csEventUser3 = new CsEventUserPO();
csEventUser3.setUserId(item);
csEventUser3.setStatus(0);
csEventUser3.setEventId(id);
result.add(csEventUser3);
});
break; break;
default: default:
code = 0; code = 0;
@@ -164,36 +174,42 @@ public class SendEventUtils {
switch (type) { switch (type) {
case "1": case "1":
//Ⅰ级告警 不推送给用户,推送给业务管理 //Ⅰ级告警 不推送给用户,推送给业务管理
users = getAdminUser(); eventUser = getEventUser(devId,false);
if (CollectionUtil.isNotEmpty(users)){ if (CollectionUtil.isNotEmpty(eventUser)) {
eventName = epdFeignClient.findByName(eventName).getData().getShowName(); eventUser.forEach(item->{
noticeUserDto.setPushClientId(Collections.singletonList(users.get(0).getDevCode()));
//记录需要通知的用户和事件关系
users.forEach(item->{
CsEventUserPO csEventUser = new CsEventUserPO(); CsEventUserPO csEventUser = new CsEventUserPO();
csEventUser.setUserId(item.getId()); csEventUser.setUserId(item);
csEventUser.setStatus(0); csEventUser.setStatus(0);
csEventUser.setEventId(id); csEventUser.setEventId(id);
result.add(csEventUser); result.add(csEventUser);
}); });
users = getSendUser(eventUser,3);
if (CollectionUtil.isNotEmpty(users)){
eventName = epdFeignClient.findByName(eventName).getData().getShowName();
devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList());
noticeUserDto.setPushClientId(devCodeList);
}
} }
break; break;
case "2": case "2":
eventName = epdFeignClient.findByName(eventName).getData().getShowName(); eventName = epdFeignClient.findByName(eventName).getData().getShowName();
case "3": case "3":
//Ⅱ、Ⅲ级告警推送相关用户及业务管理员 //Ⅱ、Ⅲ级告警推送相关用户及业务管理员
users = getEventUser(devId,3); eventUser = getEventUser(devId,true);
if (CollectionUtil.isNotEmpty(eventUser)) {
eventUser.forEach(item->{
CsEventUserPO csEventUser = new CsEventUserPO();
csEventUser.setUserId(item);
csEventUser.setStatus(0);
csEventUser.setEventId(id);
result.add(csEventUser);
});
users = getSendUser(eventUser,3);
if (CollectionUtil.isNotEmpty(users)){
devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList()); devCodeList = users.stream().map(User::getDevCode).distinct().collect(Collectors.toList());
noticeUserDto.setPushClientId(devCodeList); noticeUserDto.setPushClientId(devCodeList);
//记录需要通知的用户和事件关系 }
List<String> list4 = users.stream().map(User::getId).collect(Collectors.toList()); }
list4.forEach(item->{
CsEventUserPO csEventUser4 = new CsEventUserPO();
csEventUser4.setUserId(item);
csEventUser4.setStatus(0);
csEventUser4.setEventId(id);
result.add(csEventUser4);
});
break; break;
default: default:
break; break;
@@ -206,7 +222,14 @@ public class SendEventUtils {
payload.setPath("/pages/message/message?type="+payload.getType()); payload.setPath("/pages/message/message?type="+payload.getType());
noticeUserDto.setPayload(payload); noticeUserDto.setPayload(payload);
} }
if (CollectionUtil.isNotEmpty(noticeUserDto.getPushClientId())) {
List<String> filteredList = noticeUserDto.getPushClientId().stream()
//过滤掉null
.filter(Objects::nonNull)
.collect(Collectors.toList());
noticeUserDto.setPushClientId(filteredList);
sendEventToUser(noticeUserDto); sendEventToUser(noticeUserDto);
}
//记录推送日志 //记录推送日志
for (User item : users) { for (User item : users) {
CsEventSendMsg csEventSendMsg = new CsEventSendMsg(); CsEventSendMsg csEventSendMsg = new CsEventSendMsg();
@@ -235,7 +258,8 @@ public class SendEventUtils {
public void sendEventToUser(NoticeUserDto noticeUserDto) { public void sendEventToUser(NoticeUserDto noticeUserDto) {
try { try {
// 创建一个URL对象指定目标HTTPS接口地址 // 创建一个URL对象指定目标HTTPS接口地址
URL url = new URL("https://fc-mp-b46c4dff-7244-4f7c-ae8b-7c1194d8cce8.next.bspapp.com/push"); //URL url = new URL("https://fc-mp-b46c4dff-7244-4f7c-ae8b-7c1194d8cce8.next.bspapp.com/push");
URL url = new URL("https://fc-mp-ff7b310f-94c9-4468-8260-109111c0a6b2.next.bspapp.com/push");
// 打开HTTPS连接 // 打开HTTPS连接
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// 设置请求方法为POST // 设置请求方法为POST
@@ -270,20 +294,29 @@ public class SendEventUtils {
} }
} }
/** /**
* 获取需要通知事件的用户 * 获取所有需要推送的用户id
*/ */
public List<User> getEventUser(String devId,Integer type) { public List<String> getEventUser(String devId,boolean isAdmin) {
List<User> users = new ArrayList<>();
List<String> result = new ArrayList<>();
//获取设备下主用户和子用户集合
List<String> list = csDeviceUserFeignClient.findUserById(devId).getData(); List<String> list = csDeviceUserFeignClient.findUserById(devId).getData();
if (isAdmin) {
List<User> adminUser = appUserFeignClient.getAdminInfo().getData(); List<User> adminUser = appUserFeignClient.getAdminInfo().getData();
List<String> adminList = adminUser.stream().map(User::getId).collect(Collectors.toList()); List<String> adminList = adminUser.stream().map(User::getId).collect(Collectors.toList());
list.addAll(adminList); list.addAll(adminList);
//查询哪些用户打开了事件提示 }
if (CollectionUtil.isNotEmpty(list)){ return list;
List<AppInfoSet> appInfoSet = appInfoSetFeignClient.getListById(list).getData(); }
/**
* 获取所有打开推送的用户信息
*/
public List<User> getSendUser(List<String> userList,Integer type) {
List<User> users = new ArrayList<>();
List<String> result = new ArrayList<>();
List<AppInfoSet> appInfoSet = appInfoSetFeignClient.getListById(userList).getData();
switch (type) { switch (type) {
case 0: case 0:
result = appInfoSet.stream() result = appInfoSet.stream()
@@ -295,6 +328,11 @@ public class SendEventUtils {
.filter(person -> person.getHarmonicInfo() == 1) .filter(person -> person.getHarmonicInfo() == 1)
.map(AppInfoSet::getUserId).collect(Collectors.toList()); .map(AppInfoSet::getUserId).collect(Collectors.toList());
break; break;
case 2:
result = appInfoSet.stream()
.filter(person -> person.getRunInfo() == 1)
.map(AppInfoSet::getUserId).collect(Collectors.toList());
break;
case 3: case 3:
result = appInfoSet.stream() result = appInfoSet.stream()
.filter(person -> person.getAlarmInfo() == 1) .filter(person -> person.getAlarmInfo() == 1)
@@ -303,25 +341,8 @@ public class SendEventUtils {
default: default:
break; break;
} }
}
if (CollectionUtil.isNotEmpty(result)){ if (CollectionUtil.isNotEmpty(result)){
users = userFeignClient.getUserByIdList(result).getData(); users = userFeignClient.appuserByIdList(result).getData();
}
return users;
}
public List<User> getAdminUser() {
List<User> users = appUserFeignClient.getAdminInfo().getData();
List<String> result = new ArrayList<>();
List<String> adminList = users.stream().map(User::getId).collect(Collectors.toList());
if (CollectionUtil.isNotEmpty(adminList)){
List<AppInfoSet> appInfoSet = appInfoSetFeignClient.getListById(adminList).getData();
result = appInfoSet.stream()
.filter(person -> person.getRunInfo() == 1)
.map(AppInfoSet::getUserId).collect(Collectors.toList());
}
if (CollectionUtil.isNotEmpty(result)){
users = userFeignClient.getUserByIdList(result).getData();
} }
return users; return users;
} }

View File

@@ -6,12 +6,12 @@
<repository> <repository>
<id>nexus-releases</id> <id>nexus-releases</id>
<name>Nexus Release Repository</name> <name>Nexus Release Repository</name>
<url>http://192.168.1.13:8001/nexus/content/repositories/releases/</url> <url>http://192.168.1.22:8001/nexus/content/repositories/releases/</url>
</repository> </repository>
<snapshotRepository> <snapshotRepository>
<id>nexus-snapshots</id> <id>nexus-snapshots</id>
<name>Nexus Snapshot Repository</name> <name>Nexus Snapshot Repository</name>
<url>http://192.168.1.13:8001/nexus/content/repositories/snapshots/</url> <url>http://192.168.1.22:8001/nexus/content/repositories/snapshots/</url>
</snapshotRepository> </snapshotRepository>
</distributionManagement> </distributionManagement>
@@ -32,16 +32,15 @@
<properties> <properties>
<!--中间件目标地址--> <!--中间件目标地址-->
<middle.server.url>192.168.1.13</middle.server.url> <middle.server.url>192.168.1.22</middle.server.url>
<!--微服务模块发布地址--> <!--微服务模块发布地址-->
<service.server.url>127.0.0.1</service.server.url> <service.server.url>127.0.0.1</service.server.url>
<!--docker仓库地址--> <!--docker仓库地址-->
<docker.server.url>192.168.1.13</docker.server.url> <docker.server.url>192.168.1.22</docker.server.url>
<!--nacos的ip:port--> <!--nacos的ip:port-->
<nacos.url>${middle.server.url}:18848</nacos.url> <nacos.url>${middle.server.url}:18848</nacos.url>
<!--服务器发布内容为空--> <!--服务器发布内容为空-->
<nacos.namespace>415a1c87-33aa-47bd-8e25-13cc456c87ed</nacos.namespace> <nacos.namespace>415a1c87-33aa-47bd-8e25-13cc456c87ed</nacos.namespace>
<!-- <nacos.namespace>3eaa4bd1-bfb6-497b-aba2-47edda305427</nacos.namespace>-->
<!--sentinel:port--> <!--sentinel:port-->
<sentinel.url>${middle.server.url}:8080</sentinel.url> <sentinel.url>${middle.server.url}:8080</sentinel.url>
<!--网关地址主要用于配置swagger中认证token--> <!--网关地址主要用于配置swagger中认证token-->