DeviceStatusJob.java 17.9 KB
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";
    }
}