告警逻辑优化

This commit is contained in:
weitang 2025-05-08 16:51:43 +08:00
parent bc0b52f893
commit f7aca83257
17 changed files with 551 additions and 950 deletions

View File

@ -8,10 +8,10 @@ import com.yfd.platform.component.iec104.server.handler.ChannelHandler;
import com.yfd.platform.component.iec104.server.handler.DataHandler;
import com.yfd.platform.component.iec104.server.master.BootNettyClientChannel;
import com.yfd.platform.component.iec104.server.master.BootNettyClientChannelCache;
import com.yfd.platform.modules.auxcontrol.service.IDeviceAlarmRecordService;
import com.yfd.platform.modules.auxcontrol.service.IDeviceSignalService;
import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService;
import com.yfd.platform.modules.auxcontrol.service.IGatewayDeviceService;
import com.yfd.platform.modules.patroltask.service.IAlarmLogService;
import com.yfd.platform.utils.SpringContextHolder;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
@ -29,7 +29,7 @@ public class MasterSysDataHandler implements DataHandler {
IDeviceSignalService signalService = SpringContextHolder.getBean(IDeviceSignalService.class);
IDeviceWorkDataService workDataService = SpringContextHolder.getBean(IDeviceWorkDataService.class);
IGatewayDeviceService gatewayDeviceService = SpringContextHolder.getBean(IGatewayDeviceService.class);
IDeviceAlarmRecordService alarmRecordService = SpringContextHolder.getBean(IDeviceAlarmRecordService.class);
IAlarmLogService alarmLogService = SpringContextHolder.getBean(IAlarmLogService.class);
@Override
public void handlerAdded(ChannelHandler ctx) throws Exception {
@ -63,7 +63,7 @@ public class MasterSysDataHandler implements DataHandler {
String dateTime = messageInfo.getTimeScale();
signalService.updateDeviceSignalValue(slaveIp, address, "yx", status, dateTime);
//生成设备自身报警记录status=1
alarmRecordService.doAlaramRecord("IEC104", "yx", slaveIp, address, status);
alarmLogService.doAlaramRecord("IEC104", "yx", slaveIp, address, status);
}
}
if (type == 9 || type == 11 || type == 13 || type == 34 || type == 35 || type == 36) {
@ -78,7 +78,7 @@ public class MasterSysDataHandler implements DataHandler {
workDataService.insertData("IEC104", slaveIp, address, value, dateTime);
signalService.updateDeviceSignalValue(slaveIp, address, "yc", value, dateTime);
//生成阈值越限报警记录
alarmRecordService.doAlaramRecord("IEC104", "yc", slaveIp, address, value);
alarmLogService.doAlaramRecord("IEC104", "yc", slaveIp, address, value);
}
}

View File

@ -2,8 +2,8 @@ package com.yfd.platform.component.iec61850.client;
import com.beanit.iec61850bean.*;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.service.IDeviceAlarmRecordService;
import com.yfd.platform.modules.auxcontrol.service.IDeviceWorkDataService;
import com.yfd.platform.modules.patroltask.service.IAlarmLogService;
import com.yfd.platform.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
@ -22,7 +22,7 @@ public class IEC61850ClientListener extends Thread implements ClientEventListene
private static final Logger log = LoggerFactory.getLogger(StringUtils.class);
private final DeviceSignalMapper deviceSignalMapper;
private final IDeviceAlarmRecordService deviceAlarmRecordService;
private final IAlarmLogService alarmLogService;
private final IDeviceWorkDataService deviceWorkDataService;
@Override
@ -41,7 +41,7 @@ public class IEC61850ClientListener extends Thread implements ClientEventListene
//插入历史数据
deviceWorkDataService.insertData("IEC61850", null, node_name, node_value, datestr);
//执行报警处理
deviceAlarmRecordService.doAlaramRecord("IEC61850", "yc", null, node_name, node_value);
alarmLogService.doAlaramRecord("IEC61850", "yc", null, node_name, node_value);
} else if ("ST".equals(value.getFc().name())) {
//遥信 状态值
@ -54,7 +54,7 @@ public class IEC61850ClientListener extends Thread implements ClientEventListene
//更新信号状态
deviceSignalMapper.updateDeviceSignalValue_yx(node_name, node_value, datestr);
//执行报警处理生成设备自身报警记录status=1
deviceAlarmRecordService.doAlaramRecord("IEC61850", "yx", null, node_name, node_value);
alarmLogService.doAlaramRecord("IEC61850", "yx", null, node_name, node_value);
}
}
}

View File

@ -1,57 +0,0 @@
package com.yfd.platform.modules.auxcontrol.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.yfd.platform.modules.auxcontrol.service.IDeviceAlarmRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* <p>
* 变电站-辅控设备-告警记录 前端控制器
* </p>
*
* @author zhengsl
* @since 2025-04-23
*/
@RestController
@RequestMapping("/auxcontrol/device-alarm-record")
@Api(value = "DeviceAlarmRecordController", tags = "变电站辅控设备告警记录")
public class DeviceAlarmRecordController {
@Resource
private IDeviceAlarmRecordService deviceAlarmRecordService;
/**********************************
* 用途说明: 分页查询变电站辅控设备告警记录
* 参数说明
* systemcode 所属系统
* deviceName 告警设备名称
* signalName 告警信号名称
* startDate (开始日期)
* endDate 结束日期
* alarmLevel 告警等级
* status 告警状态
* page 分页对象
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/
@GetMapping("/page")
@ApiOperation("分页查询变电站辅控设备告警记录")
public ResponseResult getDeviceAlarmRecordPage(String systemcode, String deviceName, String signalName, String startDate, String endDate, String alarmLevel, String status, Page<DeviceAlarmRecord> page) {
//参数校验 所属系统不能为空
if (systemcode == null) {
return ResponseResult.error("参数为空");
}
//分页查询
Page<DeviceAlarmRecord> deviceAlarmRecordPage = deviceAlarmRecordService.getDeviceAlarmRecordPage(systemcode, deviceName, signalName, startDate,endDate,alarmLevel,status,page);
return ResponseResult.successData(deviceAlarmRecordPage);
}
}

View File

@ -1,9 +1,7 @@
package com.yfd.platform.modules.auxcontrol.controller;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.yfd.platform.modules.auxcontrol.domain.DeviceSignal;
import com.yfd.platform.modules.auxcontrol.domain.DeviceWorkData;
import com.yfd.platform.modules.auxcontrol.service.IDeviceSignalService;
@ -20,8 +18,6 @@ import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.LongStream;
/**
* <p>

View File

@ -7,17 +7,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yfd.platform.component.iec104.client.IIEC104Service;
import com.yfd.platform.component.iec61850.client.IEC61850Service;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.yfd.platform.modules.auxcontrol.domain.DeviceSignal;
import com.yfd.platform.modules.auxcontrol.domain.GatewayDevice;
import com.yfd.platform.modules.auxcontrol.domain.MeterDevice;
import com.yfd.platform.modules.auxcontrol.service.IDeviceAlarmRecordService;
import com.yfd.platform.modules.auxcontrol.service.IDeviceSignalService;
import com.yfd.platform.modules.auxcontrol.service.IGatewayDeviceService;
import com.yfd.platform.modules.auxcontrol.service.IMeterDeviceService;
import com.yfd.platform.modules.basedata.service.ISubstationAreaService;
import com.yfd.platform.modules.basedata.service.ISubstationComponentService;
import com.yfd.platform.modules.basedata.service.ISubstationMaindeviceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
@ -25,7 +20,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* <p>
@ -51,9 +45,6 @@ public class IECController {
@Resource
private IMeterDeviceService meterDeviceService;
//变电站报警记录
@Resource
private IDeviceAlarmRecordService deviceAlarmRecordService;
@Resource
private IIEC104Service iec104Service;
@ -62,16 +53,6 @@ public class IECController {
private IEC61850Service iec61850Service;
@GetMapping("/confirmclosealarm")
@ApiOperation("确认告警信息,关闭告警弹窗")
public ResponseResult confirmCloseAlarmRecord(String record_id) {
DeviceAlarmRecord alarmRecord = new DeviceAlarmRecord();
alarmRecord.setRecordId(record_id);
alarmRecord.setStatus("03");
alarmRecord.setFixTime(DateUtil.toLocalDateTime(DateUtil.date()));
deviceAlarmRecordService.updateById(alarmRecord);
return ResponseResult.success();
}
/**********************************
* 用途说明: 发送遥控遥调命令

View File

@ -1,238 +0,0 @@
package com.yfd.platform.modules.auxcontrol.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 变电站-辅控设备-告警记录
* </p>
*
* @author zhengsl
* @since 2025-04-23
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("fk_device_alarm_record")
public class DeviceAlarmRecord implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 记录ID
*/
@TableId(type = IdType.ASSIGN_UUID)
private String recordId;
/**
* 变电站ID
*/
private String stationId;
/**
* 所属系统01-在线监测 02-消防系统 03-安防系统 04-动环系统 05-锁控系统 06-辅控系统 07-照明系统
*/
private String systemcode;
/**
* 告警时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime alarmTime;
/**
* 告警设备ID
*/
private String deviceId;
/**
* 告警设备名称
*/
private String deviceName;
/**
* 告警信号ID
*/
private String signalId;
/**
* 告警信号名称
*/
private String signalName;
/**
* 告警类型
*/
private String alarmType;
/**
* 告警等级一般严重危急
*/
private String alarmLevel;
/**
* 告警值
*/
private String alarmValue;
/**
* 值单位
*/
private String signalUnit;
/**
* 正常范围
*/
private String normalRange;
/**
* 告警信息
*/
private String alarmMessage;
/**
* 01-组件变色 02-系统弹窗 03-邮件通知 04-触发联动 可多选01,02
*/
private String noticeAction;
/**
* 邮件通知[{name:"张三",email:"1122@163.com"}]
*/
private String noticeEmails;
/**
* 触发联动[{name:"XX联动",id:"12345678"}]
*/
private String noticeLinkages;
/**
* 状态01-初始生成 02-已执行动作 03-手动关闭 09-故障消除
*/
private String status;
/**
* 备用1
*/
private String custom1;
/**
* 备用2
*/
private String custom2;
/**
* 备用3
*/
private String custom3;
/**
* 告警分类1-越限告警 2-设备报警
*/
private String alarmClass;
/**
* 故障消除时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime fixTime;
/**
* 区域标识
*/
private String region;
/**
* 是否关闭告警0为关闭 1关闭
*/
private String confirmClosure;
/**
* 操作人
*/
private String operator;
/**
* 操作时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime operationTime;
/**
* 告警分类1-越限告警 2-设备报警 TODO 增加用于前端展示
*/
@TableField(exist = false)
private String alarmClassName;
/**
* 告警类型名称温度过高压力异常电流过载 TODO 增加用于前端展示
*/
@TableField(exist = false)
private String alarmTypeName;
/**
* 告警等级名称一般严重危急 TODO 增加用于前端展示
*/
@TableField(exist = false)
private String alarmLevelName;
/**
* 次数TODO 增加用于前端展示
*/
@TableField(exist = false)
private String frequency;
/**
* 开始时间TODO 增加用于前端展示
*/
@TableField(exist = false)
private String startDate;
/**
* 结束时间TODO 增加用于前端展示
*/
@TableField(exist = false)
private String endDate;
/**
* 区域名称TODO 增加用于前端展示
*/
@TableField(exist = false)
private String regionName;
/**
* 告警状态名称TODO 增加用于前端展示
*/
@TableField(exist = false)
private String statusName;
/**
* 告警通知方式名称01-系统弹窗 02-邮件通知 03-触发联动 可多选01,02
*/
@TableField(exist = false)
private String noticeTypeName;
/**
* 0:未核查1:已审核2.已修正
*/
private String checkFlag;
/**
* 核查反馈意见
*/
private String checkComment;
/**
* 是否属实
*/
private String checkResult;
}

View File

@ -1,22 +0,0 @@
package com.yfd.platform.modules.auxcontrol.mapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import java.util.Map;
/**
* <p>
* 变电站-辅控设备-告警记录 Mapper 接口
* </p>
*
* @author zhengsl
* @since 2025-04-23
*/
public interface DeviceAlarmRecordMapper extends BaseMapper<DeviceAlarmRecord> {
Page<DeviceAlarmRecord> getDeviceAlarmRecordPage(Page<DeviceAlarmRecord> page, String systemcode, String deviceName, String signalName, String startDate, String endDate, String alarmLevel, String status);
Map<String, Object> getAlarmLogById(String id);
}

View File

@ -1,44 +0,0 @@
package com.yfd.platform.modules.auxcontrol.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 变电站-辅控设备-告警记录 服务类
* </p>
*
* @author zhengsl
* @since 2025-04-23
*/
public interface IDeviceAlarmRecordService extends IService<DeviceAlarmRecord> {
/**********************************
* 用途说明: 生成报警记录
* 参数说明
* from 'IEC104','IEC61850'
* type 'yx','yc'
* slave_ip 服务器IP
* address 地址
* value
* 返回值说明: 无返回值
***********************************/
void doAlaramRecord(String from,String type,String slaveIp,String address,String value);
/**********************************
* 用途说明: 分页查询变电站辅控设备告警记录
* 参数说明
* systemcode 所属系统
* deviceName 告警设备名称
* signalName 告警信号名称
* startDate (开始日期)
* endDate 结束日期
* alarmLevel 告警等级
* status 告警状态
* page 分页对象
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/
Page<DeviceAlarmRecord> getDeviceAlarmRecordPage(String systemcode, String deviceName, String signalName, String startDate, String endDate, String alarmLevel, String status, Page<DeviceAlarmRecord> page);
}

View File

@ -1,428 +0,0 @@
package com.yfd.platform.modules.auxcontrol.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmParameter;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord;
import com.yfd.platform.modules.auxcontrol.domain.MeterDevice;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceAlarmParameterMapper;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceAlarmRecordMapper;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.mapper.MeterDeviceMapper;
import com.yfd.platform.modules.auxcontrol.service.IDeviceAlarmRecordService;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.mapper.SysDictionaryItemsMapper;
import com.yfd.platform.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* <p>
* 变电站-辅控设备-告警记录 服务实现类
* </p>
*
* @author zhengsl
* @since 2025-04-23
*/
@Service
@Slf4j
public class DeviceAlarmRecordServiceImpl extends ServiceImpl<DeviceAlarmRecordMapper, DeviceAlarmRecord> implements IDeviceAlarmRecordService {
@Resource
private DeviceSignalMapper deviceSignalMapper;
@Resource
private MeterDeviceMapper meterDeviceMapper;
@Resource
private DeviceAlarmParameterMapper deviceAlarmParameterMapper;
@Resource
private DeviceAlarmRecordMapper deviceAlarmRecordMapper;
@Resource
private SysDictionaryItemsMapper sysDictionaryItemsMapper;
/**********************************
* 用途说明: 分页查询变电站辅控设备告警记录
* 参数说明
* systemcode 所属系统
* deviceName 告警设备名称
* signalName 告警信号名称
* startDate (开始日期)
* endDate 结束日期
* alarmLevel 告警等级
* status 告警状态
* page 分页对象
* 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
***********************************/
@Override
public Page<DeviceAlarmRecord> getDeviceAlarmRecordPage(String systemcode, String deviceName, String signalName,
String startDate, String endDate, String alarmLevel,
String status, Page<DeviceAlarmRecord> page) {
return deviceAlarmRecordMapper.getDeviceAlarmRecordPage(page, systemcode, deviceName, signalName, startDate, endDate, alarmLevel, status);
}
/**********************************
* 用途说明: 生成报警记录IEC104
* 参数说明
* from 'IEC104','IEC61850'
* type 'yx','yc'
* slave_ip IP
* address 遥信要测地址
* value
* 返回值说明: 无返回值
***********************************/
@Override
@Transactional
public void doAlaramRecord(String from, String type, String slaveIp, String address, String value) {
String sinnalType = type;
if ("IEC104".equals(from)) {
sinnalType = "yc";
} else if ("IEC61850".equals(from)) {
slaveIp = null;
}
Map<String, Object> map = deviceSignalMapper.selectDeviceSignalMap(slaveIp, sinnalType, address);
if (map == null || ObjUtil.isEmpty(map)) {
return;
}
//如果是yx 遥信 设备自身报警记录
if ("yx".equals(type)) {
//如果信号类型是1 设备告警
if ("1".equals(map.get("signalType").toString())) {
//紧接者判断 value 1是告警 0是正常 status
if ("1".equals(value)) {
//填充告警记录信息接口
DeviceAlarmRecord deviceAlarmRecord = FillingDeviceAlarmRecord(type, null, map, value);
//首先判断 在不在时间范围之内 判断时间在不在时间范围之内接口
Map<String, Object> timeInterval = getTimeInterval(7);
//查询表中是否存在该报警记录
List<DeviceAlarmRecord> alarmRecords = queryDeviceAlarmRecord(deviceAlarmRecord, timeInterval);
//如果没有有报警记录 新增记录
if (alarmRecords.size() == 0) {
doAlarmAction(deviceAlarmRecord);
} else if (alarmRecords.size() > 1) {
this.removeById(alarmRecords.get(0).getRecordId());
}
} else {
//判断 value 1是告警 0是正常 status 同一信号监测到报警状态消除对当前信号所有未处理历史报警打上已处理标签并记录消除时间
LambdaQueryWrapper<DeviceAlarmRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceAlarmRecord::getSignalId, map.get("signalId").toString());
queryWrapper.eq(DeviceAlarmRecord::getAlarmClass, "2");
queryWrapper.in(DeviceAlarmRecord::getStatus, "01", "02");
DeviceAlarmRecord deviceAlarmRecord = new DeviceAlarmRecord();
deviceAlarmRecord.setStatus("09");
//状态 故障消除
deviceAlarmRecord.setFixTime(DateUtil.toLocalDateTime(DateUtil.date()));
//故障消除时间
this.update(deviceAlarmRecord, queryWrapper);
}
}
} else if ("yc".equals(type)) {
//1.通过设备id 和信号id 查询告警参数设置表告警规则
LambdaQueryWrapper<DeviceAlarmParameter> querywrapperdap = new LambdaQueryWrapper<>();
if (StrUtil.isNotEmpty(map.get("meterDeviceId").toString())) {
querywrapperdap.eq(DeviceAlarmParameter::getDeviceId, map.get("meterDeviceId").toString());
}
if (StrUtil.isNotEmpty(map.get("signalId").toString())) {
querywrapperdap.eq(DeviceAlarmParameter::getSignalId, map.get("signalId").toString());
}
List<DeviceAlarmParameter> deviceAlarmParameters = deviceAlarmParameterMapper.selectList(querywrapperdap);
if (deviceAlarmParameters != null && deviceAlarmParameters.size() > 0) {
for (DeviceAlarmParameter deviceAlarmParameter : deviceAlarmParameters) {
//如果告警触发条件 不为空 1<=value<=100
if (deviceAlarmParameter.getAlarmCondition() != null) {
//根据告警规则 判断是否触发告警
boolean alarmTrigger = TriggerAlarm(deviceAlarmParameter, value);
//2.通过告警触发条件 value比较 满足条件 触发告警
if (alarmTrigger) {
DeviceAlarmRecord deviceAlarmRecord = FillingDeviceAlarmRecord(type, deviceAlarmParameter
, map, value);
//首先判断 在不在时间范围之内 判断时间在不在时间范围之内接口
Map<String, Object> timeInterval = getTimeInterval(7);
//如果在时间范围内
//查询表中是否存在该报警记录
List<DeviceAlarmRecord> alarmRecords = queryDeviceAlarmRecord(deviceAlarmRecord,
timeInterval);
//如果没有有报警记录 新增记录
if (alarmRecords.size() == 0) {
// 新增
deviceAlarmRecordMapper.insert(deviceAlarmRecord);
//TODO 邮件推送暂时删除了
}
} else {
//不满足条件 同一信号监测到报警状态消除对当前信号所有未处理历史报警打上已处理标签并记录消除时间
LambdaUpdateWrapper<DeviceAlarmRecord> queryWrapper = new LambdaUpdateWrapper<>();
queryWrapper.eq(DeviceAlarmRecord::getSignalId, map.get("signalId").toString());
queryWrapper.eq(DeviceAlarmRecord::getAlarmClass, "1");
queryWrapper.eq(DeviceAlarmRecord::getAlarmLevel, deviceAlarmParameter.getAlarmLevel());
queryWrapper.in(DeviceAlarmRecord::getStatus, "01", "02")
.set(DeviceAlarmRecord::getStatus, "09")
.set(DeviceAlarmRecord::getFixTime, LocalDateTime.now());
//故障消除时间
this.update(null, queryWrapper);
}
}
}
}
}
}
/**
* 填充告警记录表
*
* @return 返回告警记录信息
*/
public DeviceAlarmRecord FillingDeviceAlarmRecord(String type, DeviceAlarmParameter deviceAlarmParameter,
Map<String, Object> singalData, String value) {
DeviceAlarmRecord deviceAlarmRecord = new DeviceAlarmRecord();
MeterDevice device = meterDeviceMapper.selectById(singalData.get("meterDeviceId").toString());
deviceAlarmRecord.setCheckFlag("0");
// 创建 SimpleDateFormat 对象指定日期格式
if ("yx".equals(type)) {
deviceAlarmRecord.setRecordId(IdUtil.fastSimpleUUID());
deviceAlarmRecord.setStationId(singalData.get("stationId").toString());
//变电站id
deviceAlarmRecord.setSystemcode(singalData.get("systemcode").toString());
//所属系统
deviceAlarmRecord.setAlarmTime(DateUtil.toLocalDateTime(DateUtil.date()));
//告警时间
deviceAlarmRecord.setDeviceId(singalData.get("meterDeviceId").toString());
//告警设备ID
deviceAlarmRecord.setDeviceName(singalData.get("deviceName").toString());
//告警设名称
deviceAlarmRecord.setSignalId(singalData.get("signalId").toString());
//告警信号id
deviceAlarmRecord.setSignalName(singalData.get("signalName").toString());
//告警信号名称
deviceAlarmRecord.setAlarmValue(value);
//告警值
deviceAlarmRecord.setSignalUnit("");
//值单位
String alarmMessage = String.format("[%s]发生了%s", singalData.get("deviceName").toString(),
singalData.get("signalName").toString());
deviceAlarmRecord.setAlarmMessage(alarmMessage);
//告警信息
deviceAlarmRecord.setStatus("01");
//状态
deviceAlarmRecord.setAlarmLevel("03");
deviceAlarmRecord.setAlarmClass("2");
//2-设备报警
deviceAlarmRecord.setRegion(device.getRegion());
//区域标识
}
if ("yc".equals(type)) {
deviceAlarmRecord.setRecordId(IdUtil.fastSimpleUUID());
//变电站id
deviceAlarmRecord.setStationId(singalData.get("stationId").toString());
//所属系统
deviceAlarmRecord.setSystemcode(singalData.get("systemcode").toString());
//告警时间
deviceAlarmRecord.setAlarmTime(DateUtil.toLocalDateTime(DateUtil.date()));
//告警设备ID
deviceAlarmRecord.setDeviceId(singalData.get("meterDeviceId").toString());
//告警设备名称
deviceAlarmRecord.setDeviceName(singalData.get("deviceName").toString());
//告警信号id
deviceAlarmRecord.setSignalId(singalData.get("signalId").toString());
//告警信号名称
deviceAlarmRecord.setSignalName(singalData.get("signalName").toString());
//告警类型
deviceAlarmRecord.setAlarmType(deviceAlarmParameter.getAlarmType());
//告警等级
deviceAlarmRecord.setAlarmLevel(deviceAlarmParameter.getAlarmLevel());
//告警值
deviceAlarmRecord.setAlarmValue(value);
String sinalUnit = ObjUtil.isNotEmpty(singalData.get("signalUnit")) ?
singalData.get("signalUnit").toString() : "";
//值单位
deviceAlarmRecord.setSignalUnit(sinalUnit);
//正常范围
deviceAlarmRecord.setNormalRange(deviceAlarmParameter.getAlarmCondition());
String alarmLevelname = getDictName(deviceAlarmParameter.getAlarmLevel(), "alarmLevel");
String alarmMessage = String.format("信号[%s]监测值为[%s]%s,达到了设置的报警阈值范围[%s],发生告警,告警级别为[%s]",
singalData.get("signal_name").toString(), value, sinalUnit,
deviceAlarmParameter.getAlarmCondition(), alarmLevelname
);
//告警信息
deviceAlarmRecord.setAlarmMessage(alarmMessage);
//告警方式
deviceAlarmRecord.setNoticeAction(deviceAlarmParameter.getNoticeType());
//邮件通知
deviceAlarmRecord.setNoticeEmails(deviceAlarmParameter.getNoticeEmails());
//触发联动
deviceAlarmRecord.setNoticeLinkages(deviceAlarmParameter.getNoticeLinkages());
//状态
deviceAlarmRecord.setStatus("01");
//1-越限报警
deviceAlarmRecord.setAlarmClass("1");
//区域标识
deviceAlarmRecord.setRegion(device.getRegion());
}
return deviceAlarmRecord;
}
//获取字典名称 根据项目编码和父项编码
public String getDictName(String itemcode, String parentcode) {
QueryWrapper<SysDictionaryItems> queryWrapperSysDictionaryItems = new QueryWrapper<>();
String dictname = "";
queryWrapperSysDictionaryItems.eq("itemcode", itemcode);
queryWrapperSysDictionaryItems.eq("parentcode", parentcode);
SysDictionaryItems sysDictionaryItems = sysDictionaryItemsMapper.selectOne(queryWrapperSysDictionaryItems);
if (sysDictionaryItems != null) {
dictname = sysDictionaryItems.getDictName();
}
return dictname;
}
/**
* 根据告警规则 判断是否触发告警
*
* @return true 触发恭敬规则
* false 没有触发告警规则
*/
public boolean TriggerAlarm(DeviceAlarmParameter deviceAlarmParameter, String value) {
// //获取告警触发条件
String str = deviceAlarmParameter.getAlarmCondition();
// 定义正则表达式
String regex = "(\\d+)\\s*((?:==?|!=|<=?|>=?))\\s*value\\s*((?:==?|!=|<=?|>=?))\\s*(\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
// 查找并输出比较符号和数值
if (matcher.find()) {
try {
// 第一个数字
String number1 = matcher.group(1);
// 第一个比较符
String operator1 = matcher.group(2);
// 第二个比较符
String operator2 = matcher.group(3);
// 第二个数字
String number2 = matcher.group(4);
Double aDouble = Double.valueOf(value);
boolean result = compare(Double.valueOf(number1), operator1, aDouble);
boolean resultTwo = compare(aDouble, operator2, Double.valueOf(number2));
return result && resultTwo;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
return false;
}
private static boolean compare(Double value1, String operator, Double value2) {
switch (operator) {
case "<":
return value1.compareTo(value2) < 0;
case "<=":
return value1.compareTo(value2) < 0 || value1.compareTo(value2) == 0;
case ">":
return value1.compareTo(value2) > 0;
case ">=":
return value1.compareTo(value2) > 0 || value1.compareTo(value2) == 0;
case "==":
case "=":
return value1.compareTo(value2) == 0;
case "!=":
return value1.compareTo(value2) != 0;
default:
throw new IllegalArgumentException("错误的告警规则: " + operator);
}
}
//执行告警相关动作 插入数据库
private void doAlarmAction(DeviceAlarmRecord alarmRecord) {
//1.通过设备id 和信号id 查询告警参数设置表告警规则
LambdaQueryWrapper<DeviceAlarmParameter> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceAlarmParameter::getDeviceId, alarmRecord.getDeviceId());
queryWrapper.eq(DeviceAlarmParameter::getSignalId, alarmRecord.getSignalId());
List<DeviceAlarmParameter> alarmParameters = deviceAlarmParameterMapper.selectList(queryWrapper);
for (DeviceAlarmParameter alarmParameter : alarmParameters) {
alarmRecord.setAlarmType(alarmParameter.getAlarmType());
alarmRecord.setNoticeAction(alarmParameter.getNoticeType());
alarmRecord.setNoticeLinkages(alarmParameter.getNoticeLinkages());
//todo 发送邮件
// pushEmail(alarmRecord,alarmParameter);
}
this.saveOrUpdate(alarmRecord);
}
/**
* 判断当前时间在不在区间范围之内
*
* @return true 在区间范围之内
* false 不在时间范围之内
*/
public Map<String, Object> getTimeInterval(int clockHour) {
int beforeclock = 0;
Map<String, Object> map = new HashMap<>(10);
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 获取昨天的 7
LocalDateTime yesterdayClockAM = LocalDateTime.of(now.minusDays(1).toLocalDate(), LocalTime.of(clockHour, 0));
map.put("starttime", yesterdayClockAM);
// 获取今天的 7
LocalDateTime todayClockAM = LocalDateTime.of(now.toLocalDate(), LocalTime.of(clockHour, 0));
LocalDateTime nextdayClockAM = LocalDateTime.of(now.plusDays(1).toLocalDate(), LocalTime.of(clockHour, 0));
map.put("endtime", todayClockAM);
// 判断时间是否在范围内
if (now.isAfter(yesterdayClockAM) && now.isBefore(todayClockAM)) {
beforeclock = 1;
} else {
map.put("starttime", todayClockAM);
map.put("endtime", nextdayClockAM);
}
map.put("beforeclock", beforeclock);
return map;
}
/**
* 根据条件查询告警记录表 判断是否存在告警记录
*
* @return true 存在告警记录
* false 不存在告警记录
*/
public List<DeviceAlarmRecord> queryDeviceAlarmRecord(DeviceAlarmRecord deviceAlarmRecord,
Map<String, Object> timeInterval) {
LambdaQueryWrapper<DeviceAlarmRecord> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceAlarmRecord::getSignalId, deviceAlarmRecord.getSignalId());
queryWrapper.eq(DeviceAlarmRecord::getAlarmLevel, deviceAlarmRecord.getAlarmLevel());
LocalDateTime starttime = (LocalDateTime) timeInterval.get("starttime");
LocalDateTime endtime = (LocalDateTime) timeInterval.get("endtime");
queryWrapper.between(DeviceAlarmRecord::getAlarmTime, starttime, endtime);
queryWrapper.in(DeviceAlarmRecord::getStatus, "01", "02");
return this.list(queryWrapper);
}
}

View File

@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@ -77,11 +78,12 @@ public class AlarmLogController {
if (StrUtil.isBlank(stationId)) {
return ResponseResult.successData(null);
}
String[] split = stationId.split(",");
LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AlarmLog::getDatastatus, "1").in(AlarmLog::getStationId, Arrays.asList(split)).eq(AlarmLog::getCheckFlag
, 0).orderByDesc(AlarmLog::getAlarmDate);
List<AlarmLog> list = alarmLogService.list(queryWrapper);
List<AlarmLog> list =alarmLogService.getNotCheckAlarmCount(stationId);
// String[] split = stationId.split(",");
// LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
// queryWrapper.eq(AlarmLog::getDatastatus, "1").in(AlarmLog::getStationId, Arrays.asList(split)).eq(AlarmLog::getCheckFlag
// , 0).orderByDesc(AlarmLog::getAlarmDate);
// List<AlarmLog> list = alarmLogService.list(queryWrapper);
Map<String, Object> map = new HashMap<>();
map.put("count", list.size());
map.put("notCheck", list);
@ -287,8 +289,8 @@ public class AlarmLogController {
@GetMapping("/getAlarmLogById")
@ApiOperation("根据告警信息ID查询详情")
public ResponseResult getAlarmLogById(String id,String systemType) {
Map<String, Object> alarmLog = alarmLogService.getAlarmLogById(id,systemType);
public ResponseResult getAlarmLogById(String id) {
Map<String, Object> alarmLog = alarmLogService.getAlarmLogById(id);
return ResponseResult.successData(alarmLog);
}
@ -299,4 +301,14 @@ public class AlarmLogController {
Map<String, Object> alarmLog = alarmLogService.getConfirmationRate(stationId);
return ResponseResult.successData(alarmLog);
}
@GetMapping("/sendAlarmById")
@ApiOperation("发送报警")
public ResponseResult sendAlarmById(String stationId,String id) {
AlarmLog alarmLog = alarmLogService.getById(id);
WebSocketServer.sendInfo(stationId, JSONUtil.parseObj(alarmLog).toString());
return ResponseResult.success();
}
}

View File

@ -93,6 +93,11 @@ public class AlarmLog implements Serializable {
*/
private String deviceId;
/**
* 巡视设备id(告警设备ID巡视设备ID)
*/
private String patroldeviceId;
/**
* 巡视设备编码
*/
@ -262,5 +267,50 @@ public class AlarmLog implements Serializable {
*/
private String custom3;
/**
* 所属系统01-在线监测 02-消防系统 03-安防系统 04-动环系统 05-锁控系统 06-辅控系统 07-照明系统辅控
*/
private String systemcode;
/**
* 辅控告警类型辅控
*/
private String fkAlarmType;
/**
* 正常范围辅控
*/
private String normalRange;
/**
* 01-组件变色 02-系统弹窗 03-邮件通知 04-触发联动 可多选01,02辅控
*/
private String noticeAction;
/**
* 邮件通知[{name:"张三",email:"1122@163.com"}]辅控
*/
private String noticeEmails;
/**
* 触发联动[{name:"XX联动",id:"12345678"}]辅控
*/
private String noticeLinkages;
/**
* 告警分类1-越限告警 2-设备报警辅控
*/
private String alarmClass;
/**
* 区域标识辅控
*/
private String region;
/**
* 报警来源类型1:智巡2辅控
*/
private String alarmSourceType;
}

View File

@ -56,4 +56,7 @@ public interface AlarmLogMapper extends BaseMapper<AlarmLog> {
List<Map<String, Object>> getAlarmLogList(String stationId);
Map<String, Object> getAlarmLogById(String id);
List<AlarmLog> getNotCheckAlarmCount(String stationId);
}

View File

@ -59,7 +59,7 @@ public interface IAlarmLogService extends IService<AlarmLog> {
* 参数说明 id 告警id
* 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
***********************************/
Map<String, Object> getAlarmLogById(String id,String systemType);
Map<String, Object> getAlarmLogById(String id);
boolean updateDeviceResult(JSONObject jsonObject) throws Exception;
@ -77,4 +77,19 @@ public interface IAlarmLogService extends IService<AlarmLog> {
***********************************/
List<Map<String, Object>> getAlarmLogList(String stationId);
List<AlarmLog> getNotCheckAlarmCount(String stationId);
/**********************************
* 用途说明: 生成报警记录
* 参数说明
* from 'IEC104','IEC61850'
* type 'yx','yc'
* slave_ip 服务器IP
* address 地址
* value
* 返回值说明: 无返回值
***********************************/
void doAlaramRecord(String from,String type,String slaveIp,String address,String value);
}

View File

@ -2,9 +2,7 @@ package com.yfd.platform.modules.patroltask.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.*;
@ -12,6 +10,7 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -22,8 +21,11 @@ import com.yfd.platform.component.nettyclient.*;
import com.yfd.platform.config.AlarmTemplateConfig;
import com.yfd.platform.config.HttpServerConfig;
import com.yfd.platform.config.ParentConfig;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceAlarmRecordMapper;
import com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmParameter;
import com.yfd.platform.modules.auxcontrol.domain.MeterDevice;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceAlarmParameterMapper;
import com.yfd.platform.modules.auxcontrol.mapper.DeviceSignalMapper;
import com.yfd.platform.modules.auxcontrol.mapper.MeterDeviceMapper;
import com.yfd.platform.modules.basedata.domain.LinkageSignal;
import com.yfd.platform.modules.basedata.domain.Substation;
import com.yfd.platform.modules.basedata.domain.SubstationDevice;
@ -42,6 +44,7 @@ import com.yfd.platform.modules.patroltask.service.IAlarmLogService;
import com.yfd.platform.modules.patroltask.service.ITaskTodoService;
import com.yfd.platform.modules.robotapi.service.IStationRobotService;
import com.yfd.platform.system.domain.Message;
import com.yfd.platform.system.domain.SysDictionaryItems;
import com.yfd.platform.system.domain.SysOrganization;
import com.yfd.platform.system.mapper.SysOrganizationMapper;
import com.yfd.platform.system.service.IMessageService;
@ -50,15 +53,11 @@ import com.yfd.platform.utils.FileUtil;
import com.yfd.platform.utils.SecurityUtils;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
@ -66,10 +65,12 @@ import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* <p>
@ -120,11 +121,19 @@ public class AlarmLogServiceImpl extends ServiceImpl<AlarmLogMapper, AlarmLog> i
@Resource
private ISysDictionaryItemsService sysDictionaryItemsService;
@Resource
private DeviceAlarmRecordMapper deviceAlarmRecordMapper;
@Resource
private MqttGateway mqttGateway;
@Resource
private DeviceSignalMapper deviceSignalMapper;
@Resource
private MeterDeviceMapper meterDeviceMapper;
@Resource
private DeviceAlarmParameterMapper deviceAlarmParameterMapper;
@Override
public synchronized boolean updateTaskResult(JSONObject jsonObject) throws Exception {
JSONArray resultList = jsonObject.getJSONArray("resultList");
@ -415,6 +424,11 @@ public class AlarmLogServiceImpl extends ServiceImpl<AlarmLogMapper, AlarmLog> i
return alarmLogMapper.getAlarmLogList(stationId);
}
@Override
public List<AlarmLog> getNotCheckAlarmCount(String stationId) {
return alarmLogMapper.getNotCheckAlarmCount(stationId);
}
/**********************************
* 用途说明: 设置任务结果数据
* 参数说明 taskResult
@ -1179,16 +1193,8 @@ public class AlarmLogServiceImpl extends ServiceImpl<AlarmLogMapper, AlarmLog> i
* 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
***********************************/
@Override
public Map<String, Object> getAlarmLogById(String id, String systemType) {
if ("01".equals(systemType)) {
Map<String, Object> map = deviceAlarmRecordMapper.getAlarmLogById(id);
}
if ("02".equals(systemType)) {
Map<String, Object> map = alarmLogMapper.getAlarmLogById(id);
return ResponseResult.successData(map);
}
return ResponseResult.successData(null);
public Map<String, Object> getAlarmLogById(String id) {
return alarmLogMapper.getAlarmLogById(id);
}
private String getSlienceType(String type) {
@ -1949,4 +1955,338 @@ public class AlarmLogServiceImpl extends ServiceImpl<AlarmLogMapper, AlarmLog> i
}
}
/**********************************
* 用途说明: 生成报警记录IEC104
* 参数说明
* from 'IEC104','IEC61850'
* type 'yx','yc'
* slave_ip IP
* address 遥信要测地址
* value
* 返回值说明: 无返回值
***********************************/
@Override
@Transactional
public void doAlaramRecord(String from, String type, String slaveIp, String address, String value) {
String sinnalType = type;
if ("IEC104".equals(from)) {
sinnalType = "yc";
} else if ("IEC61850".equals(from)) {
slaveIp = null;
}
Map<String, Object> map = deviceSignalMapper.selectDeviceSignalMap(slaveIp, sinnalType, address);
if (map == null || ObjUtil.isEmpty(map)) {
return;
}
//如果是yx 遥信 设备自身报警记录
if ("yx".equals(type)) {
//如果信号类型是1 设备告警
if ("1".equals(map.get("signalType").toString())) {
//紧接者判断 value 1是告警 0是正常 status
if ("1".equals(value)) {
//填充告警记录信息接口
AlarmLog alarmLog = FillingDeviceAlarmRecord(type, null, map, value);
//首先判断 在不在时间范围之内 判断时间在不在时间范围之内接口
Map<String, Object> timeInterval = getTimeInterval(7);
//查询表中是否存在该报警记录
List<AlarmLog> alarmRecords = queryDeviceAlarmRecord(alarmLog, timeInterval);
//如果没有有报警记录 新增记录
if (alarmRecords.size() == 0) {
doAlarmAction(alarmLog);
} else if (alarmRecords.size() > 1) {
this.removeById(alarmRecords.get(0).getId());
}
}
}
} else if ("yc".equals(type)) {
//1.通过设备id 和信号id 查询告警参数设置表告警规则
LambdaQueryWrapper<DeviceAlarmParameter> querywrapperdap = new LambdaQueryWrapper<>();
if (StrUtil.isNotEmpty(map.get("meterDeviceId").toString())) {
querywrapperdap.eq(DeviceAlarmParameter::getDeviceId, map.get("meterDeviceId").toString());
}
if (StrUtil.isNotEmpty(map.get("signalId").toString())) {
querywrapperdap.eq(DeviceAlarmParameter::getSignalId, map.get("signalId").toString());
}
List<DeviceAlarmParameter> deviceAlarmParameters = deviceAlarmParameterMapper.selectList(querywrapperdap);
if (deviceAlarmParameters != null && deviceAlarmParameters.size() > 0) {
for (DeviceAlarmParameter deviceAlarmParameter : deviceAlarmParameters) {
//如果告警触发条件 不为空 1<=value<=100
if (deviceAlarmParameter.getAlarmCondition() != null) {
//根据告警规则 判断是否触发告警
boolean alarmTrigger = TriggerAlarm(deviceAlarmParameter, value);
//2.通过告警触发条件 value比较 满足条件 触发告警
if (alarmTrigger) {
AlarmLog alarmLog = FillingDeviceAlarmRecord(type, deviceAlarmParameter
, map, value);
//首先判断 在不在时间范围之内 判断时间在不在时间范围之内接口
Map<String, Object> timeInterval = getTimeInterval(7);
//如果在时间范围内
//查询表中是否存在该报警记录
List<AlarmLog> alarmRecords = queryDeviceAlarmRecord(alarmLog,
timeInterval);
//如果没有有报警记录 新增记录
if (alarmRecords.size() == 0) {
// 新增
alarmLogMapper.insert(alarmLog);
//TODO 邮件推送暂时删除了
}
}
}
}
}
}
}
/**
* 填充告警记录表
*
* @return 返回告警记录信息
*/
public AlarmLog FillingDeviceAlarmRecord(String type, DeviceAlarmParameter deviceAlarmParameter,
Map<String, Object> signalDate, String value) {
AlarmLog alarmLog = new AlarmLog();
MeterDevice meterDevice = meterDeviceMapper.selectById(signalDate.get("meterDeviceId").toString());
alarmLog.setCheckFlag("0");
alarmLog.setAlarmSourceType("2");
// 创建 SimpleDateFormat 对象指定日期格式
if ("yx".equals(type)) {
alarmLog.setId(IdUtil.fastSimpleUUID());
alarmLog.setStationId(signalDate.get("stationId").toString());
alarmLog.setStationName(signalDate.get("stationName").toString());
alarmLog.setStationCode(signalDate.get("stationCode").toString());
alarmLog.setAreaId(signalDate.get("areaId").toString());
alarmLog.setAreaName(signalDate.get("areaName").toString());
alarmLog.setBayId(signalDate.get("bayId").toString());
alarmLog.setBayName(signalDate.get("bayName").toString());
alarmLog.setMainDeviceName(signalDate.get("mainDeviceName").toString());
alarmLog.setComponentName(signalDate.get("componentName").toString());
//所属系统
alarmLog.setSystemcode(signalDate.get("systemcode").toString());
//告警时间
alarmLog.setAlarmDate(DateUtil.now());
//告警设备ID
alarmLog.setPatroldeviceId(meterDevice.getDeviceId());
alarmLog.setPatroldeviceName(meterDevice.getDeviceName());
//告警设名称
alarmLog.setDeviceId(signalDate.get("signalId").toString());
//告警信号id
alarmLog.setDeviceName(signalDate.get("signalName").toString());
//告警信号名称
alarmLog.setValue(value);
//告警值
alarmLog.setUnit("");
//值单位
String alarmMessage = String.format("[%s]发生了%s", signalDate.get("deviceName").toString(),
signalDate.get("signalName").toString());
alarmLog.setContent(alarmMessage);
//状态
alarmLog.setAlarmLevel("4");
alarmLog.setAlarmClass("2");
//2-设备报警
alarmLog.setRegion(meterDevice.getRegion());
//区域标识
}
if ("yc".equals(type)) {
alarmLog.setId(IdUtil.fastSimpleUUID());
//变电站id
alarmLog.setStationId(signalDate.get("stationId").toString());
alarmLog.setStationName(signalDate.get("stationName").toString());
alarmLog.setStationCode(signalDate.get("stationCode").toString());
alarmLog.setAreaId(signalDate.get("areaId").toString());
alarmLog.setAreaName(signalDate.get("areaName").toString());
alarmLog.setBayId(signalDate.get("bayId").toString());
alarmLog.setBayName(signalDate.get("bayName").toString());
alarmLog.setMainDeviceName(signalDate.get("mainDeviceName").toString());
alarmLog.setComponentName(signalDate.get("componentName").toString());
//所属系统
alarmLog.setSystemcode(signalDate.get("systemcode").toString());
//告警时间
alarmLog.setAlarmDate(DateUtil.now());
//告警设备ID
alarmLog.setPatroldeviceId(meterDevice.getDeviceId());
//告警设备名称
alarmLog.setPatroldeviceName(meterDevice.getDeviceName());
//告警信号id
alarmLog.setDeviceId(signalDate.get("signalId").toString());
//告警信号名称
alarmLog.setDeviceName(signalDate.get("signalName").toString());
//告警类型
alarmLog.setAlarmType(deviceAlarmParameter.getAlarmType());
//告警等级
alarmLog.setAlarmLevel(deviceAlarmParameter.getAlarmLevel());
//告警值
alarmLog.setValue(value);
String sinalUnit = ObjUtil.isNotEmpty(signalDate.get("signalUnit")) ?
signalDate.get("signalUnit").toString() : "";
//值单位
alarmLog.setUnit(sinalUnit);
//正常范围
alarmLog.setNormalRange(deviceAlarmParameter.getAlarmCondition());
String alarmLevelname = getDictName(deviceAlarmParameter.getAlarmLevel(), "alarmLevel");
String alarmMessage = String.format("信号[%s]监测值为[%s]%s,达到了设置的报警阈值范围[%s],发生告警,告警级别为[%s]",
signalDate.get("signal_name").toString(), value, sinalUnit,
deviceAlarmParameter.getAlarmCondition(), alarmLevelname
);
//告警信息
alarmLog.setContent(alarmMessage);
//告警方式
alarmLog.setNoticeAction(deviceAlarmParameter.getNoticeType());
//邮件通知
alarmLog.setNoticeEmails(deviceAlarmParameter.getNoticeEmails());
//触发联动
alarmLog.setNoticeLinkages(deviceAlarmParameter.getNoticeLinkages());
//1-越限报警
alarmLog.setAlarmClass("1");
//区域标识
alarmLog.setRegion(meterDevice.getRegion());
}
return alarmLog;
}
//获取字典名称 根据项目编码和父项编码
public String getDictName(String itemcode, String parentcode) {
QueryWrapper<SysDictionaryItems> queryWrapperSysDictionaryItems = new QueryWrapper<>();
String dictname = "";
queryWrapperSysDictionaryItems.eq("itemcode", itemcode);
queryWrapperSysDictionaryItems.eq("parentcode", parentcode);
SysDictionaryItems sysDictionaryItems = sysDictionaryItemsService.getOne(queryWrapperSysDictionaryItems);
if (sysDictionaryItems != null) {
dictname = sysDictionaryItems.getDictName();
}
return dictname;
}
/**
* 根据告警规则 判断是否触发告警
*
* @return true 触发恭敬规则
* false 没有触发告警规则
*/
public boolean TriggerAlarm(DeviceAlarmParameter deviceAlarmParameter, String value) {
// //获取告警触发条件
String str = deviceAlarmParameter.getAlarmCondition();
// 定义正则表达式
String regex = "(\\d+)\\s*((?:==?|!=|<=?|>=?))\\s*value\\s*((?:==?|!=|<=?|>=?))\\s*(\\d+)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
// 查找并输出比较符号和数值
if (matcher.find()) {
try {
// 第一个数字
String number1 = matcher.group(1);
// 第一个比较符
String operator1 = matcher.group(2);
// 第二个比较符
String operator2 = matcher.group(3);
// 第二个数字
String number2 = matcher.group(4);
Double aDouble = Double.valueOf(value);
boolean result = compare(Double.valueOf(number1), operator1, aDouble);
boolean resultTwo = compare(aDouble, operator2, Double.valueOf(number2));
return result && resultTwo;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
return false;
}
private static boolean compare(Double value1, String operator, Double value2) {
switch (operator) {
case "<":
return value1.compareTo(value2) < 0;
case "<=":
return value1.compareTo(value2) < 0 || value1.compareTo(value2) == 0;
case ">":
return value1.compareTo(value2) > 0;
case ">=":
return value1.compareTo(value2) > 0 || value1.compareTo(value2) == 0;
case "==":
case "=":
return value1.compareTo(value2) == 0;
case "!=":
return value1.compareTo(value2) != 0;
default:
throw new IllegalArgumentException("错误的告警规则: " + operator);
}
}
//执行告警相关动作 插入数据库
private void doAlarmAction(AlarmLog alarmLog) {
//1.通过设备id 和信号id 查询告警参数设置表告警规则
LambdaQueryWrapper<DeviceAlarmParameter> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DeviceAlarmParameter::getDeviceId, alarmLog.getPatroldeviceId());
queryWrapper.eq(DeviceAlarmParameter::getSignalId, alarmLog.getDeviceId());
List<DeviceAlarmParameter> alarmParameters = deviceAlarmParameterMapper.selectList(queryWrapper);
for (DeviceAlarmParameter alarmParameter : alarmParameters) {
alarmLog.setFkAlarmType(alarmParameter.getAlarmType());
alarmLog.setNoticeAction(alarmParameter.getNoticeType());
alarmLog.setNoticeLinkages(alarmParameter.getNoticeLinkages());
//todo 发送邮件
// pushEmail(alarmRecord,alarmParameter);
}
this.saveOrUpdate(alarmLog);
}
/**
* 判断当前时间在不在区间范围之内
*
* @return true 在区间范围之内
* false 不在时间范围之内
*/
public Map<String, Object> getTimeInterval(int clockHour) {
int beforeclock = 0;
Map<String, Object> map = new HashMap<>(10);
// 获取当前时间
LocalDateTime now = LocalDateTime.now();
// 获取昨天的 7
LocalDateTime yesterdayClockAM = LocalDateTime.of(now.minusDays(1).toLocalDate(), LocalTime.of(clockHour, 0));
map.put("starttime", yesterdayClockAM);
// 获取今天的 7
LocalDateTime todayClockAM = LocalDateTime.of(now.toLocalDate(), LocalTime.of(clockHour, 0));
LocalDateTime nextdayClockAM = LocalDateTime.of(now.plusDays(1).toLocalDate(), LocalTime.of(clockHour, 0));
map.put("endtime", todayClockAM);
// 判断时间是否在范围内
if (now.isAfter(yesterdayClockAM) && now.isBefore(todayClockAM)) {
beforeclock = 1;
} else {
map.put("starttime", todayClockAM);
map.put("endtime", nextdayClockAM);
}
map.put("beforeclock", beforeclock);
return map;
}
/**
* 根据条件查询告警记录表 判断是否存在告警记录
*
* @return true 存在告警记录
* false 不存在告警记录
*/
public List<AlarmLog> queryDeviceAlarmRecord(AlarmLog alarmLog,
Map<String, Object> timeInterval) {
LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AlarmLog::getDeviceId, alarmLog.getDeviceId());
queryWrapper.eq(AlarmLog::getAlarmLevel, alarmLog.getAlarmLevel());
LocalDateTime starttime = (LocalDateTime) timeInterval.get("starttime");
LocalDateTime endtime = (LocalDateTime) timeInterval.get("endtime");
queryWrapper.between(AlarmLog::getAlarmDate, starttime, endtime);
return this.list(queryWrapper);
}
}

View File

@ -1,74 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yfd.platform.modules.auxcontrol.mapper.DeviceAlarmRecordMapper">
<select id="getDeviceAlarmRecordPage"
resultType="com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord">
SELECT
dar.*,
sdi1.dictname AS alarmTypeName,
sdi2.dictname AS alarmLevelName,
sdi3.dictname AS alarmStatusName,
COALESCE (
(
SELECT
GROUP_CONCAT( dictname ORDER BY itemcode SEPARATOR ',' )
FROM
sys_dictionary_items
WHERE
dictid = 'd3a5c69ef214012abcdb31495ef4e772'
AND FIND_IN_SET( itemcode, dar.notice_action ) > 0
),
''
) AS noticeTypeName
FROM
fk_device_alarm_record dar
LEFT JOIN sys_dictionary_items sdi1 ON sdi1.dictid = 'aad92e9fd54d05e090b074f3e0666c8c'
AND sdi1.itemcode = dar.alarm_type
LEFT JOIN sys_dictionary_items sdi2 ON sdi2.dictid = '138d15a0ce89e5abd516389a1176db6e'
AND sdi2.itemcode = dar.alarm_level
LEFT JOIN sys_dictionary_items sdi3 ON sdi3.dictid = '1f0eb135658ed4c825021e2d5189efc0'
AND sdi3.itemcode = dar.`status`
where 1=1
<if test="systemcode != null and systemcode != ''">
and dar.systemcode= #{systemcode}
</if>
<if test="deviceName != null and deviceName != ''">
and dar.device_name like concat('%',#{deviceName},'%')
</if>
<if test="signalName != null and signalName != ''">
and dar.signal_name like concat('%',#{signalName},'%')
</if>
<if test="alarmLevel != null and alarmLevel != ''">
and dar.alarm_level = #{alarmLevel}
</if>
<if test="status != null and status != ''">
and dar.status = #{status}
</if>
<if test="startDate != null and startDate != ''">
and dar.alarm_time &gt;= #{startDate}
</if>
<if test="endDate != null and endDate != ''">
and dar.alarm_time &lt;= #{endDate}
</if>
</select>
<select id="getAlarmLogById" resultType="java.util.Map">
SELECT
dar.*,
'01' systemType,
ism.main_device_name,
ism.main_device_id,
isc.component_id,
isc.component_name
FROM
fk_device_alarm_record dar
INNER JOIN fk_device_signal ds ON dar.signal_id = ds.signal_id
INNER JOIN iis_substation_maindevice ism ON ism.main_device_id = ds.main_device_id
INNER JOIN iis_substation_component isc ON isc.component_id = ds.main_component_id
WHERE
dar.record_id = #{id}
LIMIT 1
</select>
</mapper>

View File

@ -5,14 +5,24 @@
<!-- 查询辅控设备信号表-->
<select id="selectDeviceSignalMap" resultType="java.util.Map">
SELECT
sc.station_code,
sc.station_name,
sc.area_id,
sc.area_name,
sc.bay_id,
sc.bay_name,
sc.component_id,
sc.component_name,
sc.main_device_name,
a.station_id,
a.systemcode,
a.device_name,
b.*
FROM
fk_meter_device a
JOIN fk_device_signal b ON ( a.device_id = b.meter_device_id )
JOIN fk_gateway_device c ON ( a.netdevice_ip = c.ip_addr )
INNER JOIN fk_device_signal b ON ( a.device_id = b.meter_device_id )
INNER JOIN fk_gateway_device c ON ( a.netdevice_ip = c.ip_addr )
INNER JOIN iis_substation_component sc ON ( sc.component_id = b.main_component_id )
WHERE
1 =1
<if test="slaveIp != null and slaveIp != ''">

View File

@ -76,29 +76,14 @@
</select>
<select id="getAlarmLogList" resultType="java.util.Map">
SELECT
*
id,
station_id,
alarm_source_type,
content,
alarm_level alarm_level,
alarm_date
FROM
(
(
SELECT
record_id AS id,
station_id,
'01' system_type,
alarm_message AS content,
CASE
WHEN alarm_level = 1 THEN
2
WHEN alarm_level = 2 THEN
3
WHEN alarm_level = 3 THEN
4 ELSE alarm_level
END AS alarm_level,
alarm_time AS alarm_date
FROM
`fk_device_alarm_record`
) UNION ALL
( SELECT id, station_id,'02' system_type, content, alarm_level alarm_level, alarm_date FROM iis_alarm_log )
) AS combined_data
iis_alarm_log
WHERE
station_id = #{stationId}
ORDER BY
@ -106,15 +91,87 @@
</select>
<select id="getAlarmLogById" resultType="java.util.Map">
SELECT
'02' systemType,
al.*,
tr.patroldevice_code deviceId,
tr.patroldevice_channelcode channelId,
tr.patroldevice_pos patroldevicePos
FROM
iis_alarm_log al
INNER JOIN iis_task_result tr ON al.task_result_id = tr.result_id
LEFT JOIN iis_task_result tr ON al.task_result_id = tr.result_id
WHERE
al.id = #{id}
</select>
<select id="getNotCheckAlarmCount" resultType="com.yfd.platform.modules.patroltask.domain.AlarmLog">
SELECT
record_id AS id,
ds.main_device_id,
ds.main_component_id,
'01' system_type
FROM
`fk_device_alarm_record` dar
INNER JOIN fk_device_signal ds ON dar.signal_id = ds.signal_id
WHERE
dar.station_id = #{stationId} UNION ALL
SELECT
id,
main_device_id,
component_id,
'02' system_type
FROM
iis_alarm_log
WHERE
station_id = #{stationId}
</select>
<!-- <select id="getDeviceAlarmRecordPage"-->
<!-- resultType="com.yfd.platform.modules.auxcontrol.domain.DeviceAlarmRecord">-->
<!-- SELECT-->
<!-- dar.*,-->
<!-- sdi1.dictname AS alarmTypeName,-->
<!-- sdi2.dictname AS alarmLevelName,-->
<!-- sdi3.dictname AS alarmStatusName,-->
<!-- COALESCE (-->
<!-- (-->
<!-- SELECT-->
<!-- GROUP_CONCAT( dictname ORDER BY itemcode SEPARATOR ',' )-->
<!-- FROM-->
<!-- sys_dictionary_items-->
<!-- WHERE-->
<!-- dictid = 'd3a5c69ef214012abcdb31495ef4e772'-->
<!-- AND FIND_IN_SET( itemcode, dar.notice_action ) > 0-->
<!-- ),-->
<!-- ''-->
<!-- ) AS noticeTypeName-->
<!-- FROM-->
<!-- fk_device_alarm_record dar-->
<!-- LEFT JOIN sys_dictionary_items sdi1 ON sdi1.dictid = 'aad92e9fd54d05e090b074f3e0666c8c'-->
<!-- AND sdi1.itemcode = dar.alarm_type-->
<!-- LEFT JOIN sys_dictionary_items sdi2 ON sdi2.dictid = '138d15a0ce89e5abd516389a1176db6e'-->
<!-- AND sdi2.itemcode = dar.alarm_level-->
<!-- LEFT JOIN sys_dictionary_items sdi3 ON sdi3.dictid = '1f0eb135658ed4c825021e2d5189efc0'-->
<!-- AND sdi3.itemcode = dar.`status`-->
<!-- where 1=1-->
<!-- <if test="systemcode != null and systemcode != ''">-->
<!-- and dar.systemcode= #{systemcode}-->
<!-- </if>-->
<!-- <if test="deviceName != null and deviceName != ''">-->
<!-- and dar.device_name like concat('%',#{deviceName},'%')-->
<!-- </if>-->
<!-- <if test="signalName != null and signalName != ''">-->
<!-- and dar.signal_name like concat('%',#{signalName},'%')-->
<!-- </if>-->
<!-- <if test="alarmLevel != null and alarmLevel != ''">-->
<!-- and dar.alarm_level = #{alarmLevel}-->
<!-- </if>-->
<!-- <if test="status != null and status != ''">-->
<!-- and dar.status = #{status}-->
<!-- </if>-->
<!-- <if test="startDate != null and startDate != ''">-->
<!-- and dar.alarm_time &gt;= #{startDate}-->
<!-- </if>-->
<!-- <if test="endDate != null and endDate != ''">-->
<!-- and dar.alarm_time &lt;= #{endDate}-->
<!-- </if>-->
<!-- </select>-->
</mapper>