package com.skua.modules.quartz; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.google.common.collect.Maps; import com.skua.core.util.DateUtils; import com.skua.modules.alarmtmp.entity.*; import com.skua.modules.alarmtmp.service.*; import com.skua.modules.alarmtmp.vo.SystemNoticeVO; import com.skua.modules.system.service.IPgService; import com.skua.modules.system.service.ISysDepartService; import com.skua.modules.system.service.ISysFactoryInfoService; import com.skua.modules.util.SystemNoticeUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; /** * @Description plc诊断定时任务和厂站在线离线任务 * @Date 2021-08-18 14:15 * @Param * @return **/ @Slf4j @Component public class DeviceStatusJob implements Job { @Autowired private SystemNoticeUtils systemNoticeUtils; @Autowired private IPgService pgService; @Autowired private ISysFactoryDeviceChildService sysFactoryDeviceChildService; @Autowired private ISysFactoryDeviceService sysFactoryDeviceService; @Autowired private IFactoryOffLineService factoryOffLineService; @Autowired private ISysFactoryInfoService sysFactoryInfoService; @Autowired private AlarmRecordHistoryService alarmRecordHistoryService; @Autowired private IAlarmRuleLevelConfigTemplateService alarmRuleLevelConfigTemplateService; @Autowired private ISysDepartService sysDepartService; private static String prefix = "【金控数矿】"; private static String templete = "${name}在${date}"; private static String suffix = "时断线,请处理!"; @Override public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { try { log.info(String.format(" 厂站在线离线状态定时任务! 时间:" + DateUtils.getTimestamp())); //更新网关子节点状态 //查询实时数据表里最新的状态 log.info("更新网关子节点状态开始"); QueryWrapper<SysFactoryDeviceChild> queryWrapper = new QueryWrapper<>(); queryWrapper.isNotNull("device_child_nm"); List<SysFactoryDeviceChild> list = sysFactoryDeviceChildService.list(queryWrapper); StringBuilder ids = new StringBuilder(); if (list != null && list.size() > 0) { list.forEach(v -> { ids.append(v.getDeviceChildNm() + ","); }); if (ids.length() > 0) { Map<String, Object> objectMap = pgService.queryMonitorByFeildsTime(ids.toString()); if (objectMap != null) { //更新plc状态 updateDeviceChild(list, objectMap); } } } log.info("更新网关子节点状态结束"); //更新网关状态 List<Map<String, Object>> status = pgService.queryFactoryStatus(); if (status != null && status.size() > 0) { updateDevice(status); } else { log.info(String.format("厂站在线离线状态定时任务未查询到PG盒子在线离线信息")); } //更新厂站在线离线状态 updateFactory(); log.info("厂站在线离线状态定时任务执行完成"); } catch (Exception e) { log.info("厂站在线离线状态定时任务异常" + e); } } /** * @return void * @Description 厂站诊断 * @Date 2021-08-18 19:08 * @Param [] **/ private void updateFactory() { String now = DateUtils.getDate("yyyy-MM-dd HH:mm:ss"); List<Map<String, Object>> facList = sysFactoryInfoService.queryAllFacListStatus(); facList.forEach(v -> { //查询plc状态和网关状态 String factoryId = (String) v.get("depart_id"); Integer lineStatusOld = (Integer) v.get("factory_status"); Integer lineStatusNew = -1; QueryWrapper<SysFactoryDeviceChild> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("depart_id", factoryId); List<SysFactoryDeviceChild> list = sysFactoryDeviceChildService.list(queryWrapper); if (list != null && list.size() > 0) { boolean flag = false; for (SysFactoryDeviceChild child : list) { if (1 == child.getDeviceChildStatus()) { flag = true; break; } } if (!flag) { //都是离线 厂站掉线 lineStatusNew = 0; } else { lineStatusNew = 1; } } if (lineStatusNew == -1) { //没有配置plc 通过网关判断是否在线 QueryWrapper<SysFactoryDevice> queryWrapper1 = new QueryWrapper<>(); queryWrapper1.eq("depart_id", factoryId); queryWrapper1.in("device_status", 1, 0); List<SysFactoryDevice> factoryDevices = sysFactoryDeviceService.list(queryWrapper1); if (factoryDevices != null && factoryDevices.size() > 0) { boolean flag = false; for (SysFactoryDevice sysFactoryDevice : factoryDevices) { if (1 == sysFactoryDevice.getDeviceStatus()) { flag = true; break; } } if (!flag) { //都是离线 厂站掉线 lineStatusNew = 0; } else { lineStatusNew = 1; } } else { //未接入 lineStatusNew = -1; } } //厂站状态 if (lineStatusNew == 0) { if (lineStatusOld == 1) { //断线 // todo 断线短信 factoryOffLineStatus(now, factoryId, "add", "fac", factoryId); //查询报警配置 报警 addAlarmRecord(factoryId, "", now, factoryId, "重要报警", "add", "6", "水厂断线报警配置"); //更新状态 更新最后在线时间 sysFactoryInfoService.updFacStatus(lineStatusNew, factoryId, now); } else { //不更新时间最后在线时间 sysFactoryInfoService.updFacStatus(lineStatusNew, factoryId, null); } } else if (lineStatusNew == 1) { if (lineStatusOld == 0) { // 上线 // todo 上线短信 factoryOffLineStatus(now, factoryId, "upd", "fac", factoryId); //查询报警配置 报警 addAlarmRecord(factoryId, "", now, factoryId, "重要报警", "upd", "6", "水厂断线报警配置"); //更新状态 更新最后在线时间 sysFactoryInfoService.updFacStatus(lineStatusNew, factoryId, now); } else { //更新状态 更新最后在线时间 sysFactoryInfoService.updFacStatus(lineStatusNew, factoryId, now); } } else { //更新状态 更新最后在线时间 sysFactoryInfoService.updFacStatus(lineStatusNew, factoryId, null); } }); log.info("更新厂站状态成功"); } /** * @return void * @Description 网关诊断 * @Date 2021-08-18 18:30 * @Param [status] **/ private void updateDevice(List<Map<String, Object>> status) { // 先查询原来的状态 List<SysFactoryDevice> list = sysFactoryDeviceService.list(); Map<String, String> tmp = Maps.newHashMap(); if (list != null && list.size() > 0) { list.forEach(v -> { tmp.put(v.getDeviceId(), v.getDeviceStatus() + "," + v.getDepartId()); }); } if (!tmp.isEmpty()) { status.forEach(v -> { String time = (String) v.get("time"); String newTime = DateUtils.format(DateUtils.getDate(Long.parseLong(time)), "yyyy-MM-dd HH:mm:ss"); String devicename = (String) v.get("devicename"); Integer devicestatusNew = (Integer) v.get("devicestatus"); String statusFac = tmp.get(devicename); if (StringUtils.isNotBlank(statusFac)) { String[] split = statusFac.split(","); Integer deviceStatusOld = Integer.parseInt(split[0]); String factoryId = split[1]; if (0 == devicestatusNew) { //现在断线 if (1 == deviceStatusOld) { //断线 // todo 断线短信 factoryOffLineStatus(newTime, factoryId, "add", "device", devicename); } } else { //现在在线 if (0 == deviceStatusOld) { // 上线 // todo 上线短信 factoryOffLineStatus(newTime, factoryId, "upd", "device", devicename); } } } }); //更新状态 sysFactoryDeviceChildService.updBatchByDeviceCode(status); } log.info("更新网关状态成功"); } /** * @return void * @Description plc诊断 * @Date 2021-08-18 17:29 * @Param [list, objectMap] **/ private void updateDeviceChild(List<SysFactoryDeviceChild> list, Map<String, Object> objectMap) { String now = DateUtils.getDate("yyyy-MM-dd HH:mm:ss"); list.forEach(v -> { //判断是否需要plc断线报警 Integer deviceChildStatusOld = v.getDeviceChildStatus(); String factoryId = v.getDepartId(); Integer deviceChildStatusNew = Integer.parseInt((String) objectMap.getOrDefault(v.getDeviceChildNm(), "0")); if (0 == deviceChildStatusNew) { //现在断线 if (1 == deviceChildStatusOld) { //断线 // todo 断线短信 factoryOffLineStatus(now, factoryId, "add", "deviceChild", v.getDeviceChildNm()); //查询报警配置 报警 addAlarmRecord(v.getDeviceChildNm(), v.getDeviceChildName(), now, factoryId, "重要报警", "add", "6", "PLC断线报警配置"); } else if (-1 == deviceChildStatusOld) { //未接入转离线 factoryOffLineStatus(now, factoryId, "add", "deviceChild", v.getDeviceChildNm()); addAlarmRecord(v.getDeviceChildNm(), v.getDeviceChildName(), now, factoryId, "重要报警", "add", "6", "PLC断线报警配置"); } } else { //现在在线 if (0 == deviceChildStatusOld) { // 上线 // todo 上线短信 factoryOffLineStatus(now, factoryId, "upd", "deviceChild", v.getDeviceChildNm()); addAlarmRecord(v.getDeviceChildNm(), v.getDeviceChildName(), now, factoryId, "重要报警", "upd", "6", "PLC断线报警配置"); } } //更新状态 v.setDeviceChildStatus(deviceChildStatusNew); }); sysFactoryDeviceChildService.updateBatchById(list); log.info("更新网关子节点状态成功"); } private void addAlarmRecord(String plc, String plcName, String time, String factoryId, String levelName, String status, String ruleType, String paramType) { Date now = null; try { now = DateUtils.parse(time, "yyyy-MM-dd HH:mm:ss"); } catch (ParseException e) { e.printStackTrace(); } //根据factoryId查询factoryName String factoryName = sysDepartService.queryDepartNameById(factoryId); if ("add".equals(status)) { AlarmRecordHistory alarmRecordHistory = new AlarmRecordHistory(); alarmRecordHistory.setAlarmParamCode(plc); alarmRecordHistory.setAlarmRuleType("6"); alarmRecordHistory.setAlarmParamType(paramType); alarmRecordHistory.setActualAvgValue("断线"); alarmRecordHistory.setDelFlag(1); String temp = ""; String nameMap = ""; if (StringUtils.isNotBlank(plcName)) { nameMap = factoryName + "的PLC设备" + plcName + "数据传输"; temp = templete.replace("${name}", nameMap).replace("${date}", time); alarmRecordHistory.setAlarmParamName(plcName); } else { nameMap = factoryName + "的数据传输"; temp = templete.replace("${name}", nameMap).replace("${date}", time); alarmRecordHistory.setAlarmParamName(factoryName); } String content = prefix + temp + suffix; alarmRecordHistory.setAlarmContent(content); alarmRecordHistory.setRecordTime(now); //未恢复状态 alarmRecordHistory.setHandleStatus(0); alarmRecordHistory.setDepartId(factoryId); alarmRecordHistory.setAlarmRuleLevelName(levelName); alarmRecordHistoryService.save(alarmRecordHistory); //短信 //todo 通知 //查询plc报警的短信配置 QueryWrapper<AlarmRuleLevelConfigTemplate> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("depart_id", factoryId); queryWrapper.eq("alarm_template_name", paramType); queryWrapper.eq("alarm_template_type", 2); AlarmRuleLevelConfigTemplate alarmRuleLevelConfigTemplate = alarmRuleLevelConfigTemplateService.getOne(queryWrapper); if (alarmRuleLevelConfigTemplate != null) { //判断是否需要发送系统通知 (内容跟报警记录信息相同) if ("1".equals(alarmRuleLevelConfigTemplate.getIsSendNotice())) { if (StringUtils.isNotBlank(alarmRuleLevelConfigTemplate.getAlarmNoticeRecipient())) { SystemNoticeVO systemNoticeVO = new SystemNoticeVO(alarmRuleLevelConfigTemplate.getAlarmNoticeRecipient(), alarmRuleLevelConfigTemplate.getAlarmTemplateLevelName(), temp + suffix, factoryId, "6"); systemNoticeUtils.dealNoticeMessage(systemNoticeVO); } } } } else if ("upd".equals(status)) { //查询记录 QueryWrapper<AlarmRecordHistory> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("depart_id", factoryId); queryWrapper.eq("alarm_param_code", plc); queryWrapper.eq("alarm_rule_type", ruleType); queryWrapper.eq("handle_status", 0); AlarmRecordHistory one = alarmRecordHistoryService.getOne(queryWrapper); if (one != null) { one.setHandleStatus(1); one.setHandleTime(now); alarmRecordHistoryService.updateById(one); } } } /** * @return void * @Description 增加离线记录 * @Date 2021-05-10 17:01 * @Param [newTime, factoryId] **/ private void factoryOffLineStatus(String newTime, String factoryId, String status, String type, String deviceId) { FactoryOffLine factoryOffLine = new FactoryOffLine(); factoryOffLine.setDepartId(factoryId); factoryOffLine.setType(type); if ("add".equals(status)) { factoryOffLine.setFactoryOffLineStartTime(newTime); factoryOffLine.setDelFlag(0); factoryOffLine.setFactoryOffLineEndTime(null); factoryOffLine.setOffLineLength(null); factoryOffLine.setDeviceId(deviceId); factoryOffLineService.save(factoryOffLine); } else if ("upd".equals(status)) { //查询记录 QueryWrapper<FactoryOffLine> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("depart_id", factoryId); queryWrapper.eq("type", type); queryWrapper.eq("device_id", deviceId); queryWrapper.eq("del_flag", 0); queryWrapper.orderByDesc("factory_off_line_start_time"); List<FactoryOffLine> lines = factoryOffLineService.list(queryWrapper); if (lines != null && lines.size() > 0) { FactoryOffLine one = lines.get(0); one.setDelFlag(1); one.setFactoryOffLineEndTime(newTime); one.setOffLineLength(getTimeLengthMin(one.getFactoryOffLineStartTime(), newTime)); factoryOffLineService.updateById(one); } } } /** * @return java.lang.String * @Description 计算两个日期之间的分钟数 * @Date 2021-05-10 17:24 * @Param [startTime, newTime] **/ private String getTimeLengthMin(String startTime, String newTime) { SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { long time1 = df.parse(startTime).getTime(); long time2 = df.parse(newTime).getTime(); return String.valueOf((time2 - time1) / 1000 / 60); } catch (ParseException e) { e.printStackTrace(); } return "0"; } }