package com.yfd.platform.modules.patroltask.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.*;
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.component.ServerSendEventServer;
import com.yfd.platform.component.WebSocketServer;
import com.yfd.platform.component.mqtt.MqttGateway;
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.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.*;
import com.yfd.platform.modules.basedata.mapper.LinkageSignalMapper;
import com.yfd.platform.modules.basedata.mapper.SubstationDeviceMapper;
import com.yfd.platform.modules.basedata.mapper.SubstationMapper;
import com.yfd.platform.modules.basedata.mapper.SubstationPatroldeviceMapper;
import com.yfd.platform.modules.basedata.service.IAlarmThresholdService;
import com.yfd.platform.modules.patroltask.domain.AlarmLog;
import com.yfd.platform.modules.patroltask.domain.TaskResult;
import com.yfd.platform.modules.patroltask.domain.TaskTodo;
import com.yfd.platform.modules.patroltask.mapper.AlarmLogMapper;
import com.yfd.platform.modules.patroltask.mapper.TaskResultMapper;
import com.yfd.platform.modules.patroltask.mapper.TaskTodoMapper;
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;
import com.yfd.platform.system.service.ISysDictionaryItemsService;
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.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.awt.*;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLDecoder;
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;

/**
 * <p>
 * 告警日志表 服务实现类
 * </p>
 *
 * @since 2023-05-03
 */
@Service
@Slf4j
public class AlarmLogServiceImpl extends ServiceImpl<AlarmLogMapper, AlarmLog> implements IAlarmLogService {

    @Resource
    private SubstationDeviceMapper deviceMapper;

    @Resource
    private SubstationPatroldeviceMapper patroldeviceMapper;

    @Resource
    private TaskTodoMapper taskTodoMapper;
    @Resource
    private TaskResultMapper taskResultMapper;
    @Resource
    private SubstationMapper stationMapper;
    @Resource
    private SubstationDeviceMapper substationDeviceMapper;
    @Resource
    private HttpServerConfig Config;
    @Resource
    private AlarmLogMapper alarmLogMapper;
    @Resource
    private ITaskTodoService taskTodoService;
    @Resource
    private AlarmTemplateConfig alarmTemplateConfig;
    @Resource
    private SysOrganizationMapper sysOrganizationMapper;
    @Resource
    IStationRobotService stationNodeService;
    @Resource
    private HttpServerConfig httpServerConfig;
    @Resource
    private ParentConfig parentConfig;
    @Resource
    private IMessageService messageService;

    @Resource
    private LinkageSignalMapper linkageSignalMapper;

    @Resource
    private ISysDictionaryItemsService sysDictionaryItemsService;

    @Resource
    private MqttGateway mqttGateway;

    @Resource
    private DeviceSignalMapper deviceSignalMapper;

    @Resource
    private MeterDeviceMapper meterDeviceMapper;

    @Resource
    private DeviceAlarmParameterMapper deviceAlarmParameterMapper;
    @Resource
    private IAlarmThresholdService alarmThresholdService;

    @Override
    public synchronized boolean updateTaskResult(JSONObject jsonObject) throws Exception {
        JSONArray resultList = jsonObject.getJSONArray("resultList");
        for (int i = 0; i < resultList.size(); i++) {
            JSONObject resultObject = resultList.getJSONObject(i);
            if (resultObject == null) {
                continue;
            }
            String resultId = resultObject.getStr("objectId");
            TaskResult taskResult = taskResultMapper.selectById(resultId);
            JSONArray results = resultObject.getJSONArray("results");
            //设置任务结果数据
            updateTaskResult(taskResult, results);

            taskResultMapper.updateById(taskResult);
            //更新当前任务状态及进度信息
            TaskTodo taskTodo = taskTodoMapper.selectById(taskResult.getTaskTodoId());
            int sumnum = taskTodo.getDeviceSumnum();
            // 赋值执行数量
            List<Map<String, Object>> list = taskTodoService.getTaskResultById(taskTodo.getTaskTodoId(), null, null, null);
            // 已送检点数
            long patrolCount = list.stream().filter(t -> !("0").equals(t.get("flag")) && !("1").equals(t.get("flag"))).count();
            // 失败的数量
            long failCount =
                    list.stream().filter(t -> ("4").equals(t.get("flag")) || ("6").equals(t.get("flag"))).count();
            // 异常数量
            long abnormalCount = list.stream().filter(t -> ("2").equals(t.get("valid1"))).count();
            taskTodo.setDeviceDeforeNum((int) patrolCount);
            taskTodo.setDeviceUnusualnum((int) abnormalCount);
            taskTodo.setDeviceFailureNum((int) failCount);
            int patrolnum = taskResultMapper.selectCount(
                    new LambdaQueryWrapper<TaskResult>().
                            eq(TaskResult::getTaskTodoId, taskResult.getTaskTodoId()).
                            ne(TaskResult::getFlag, "0")
            );
            int percent = 0;
            percent = patrolnum * 100 / sumnum;  //百分之多少
            if (!"100".equals(taskTodo.getTaskProgress())) {
                taskTodo.setTaskProgress(String.valueOf(percent));
            }
            boolean b = patrolnum == sumnum;
            if (b) {
                //全部完成
                taskTodo.setTaskState("1"); //已完成
                taskTodo.setEndTime(DateUtil.now());
            }
            taskTodo.setLastmodifydate(new Timestamp(DateUtil.current()));
            taskTodoMapper.updateById(taskTodo);
            // 向上级发送任务数据
            taskTodoService.sendTaskResult(taskTodo, taskResult);
            Map<String, Object> map = taskTodoService.getTaskTodoById(taskResult.getTaskTodoId(), null, null, null);
            String stationCode = taskResult.getStationCode();
//            if (StrUtil.isNotBlank(taskTodo.getControlNum())) {
//                if (b) {
//                    WebSocketServer.sendInfo("taskresult_" + stationCode, JSONUtil.toJsonStr(JSONUtil.parse(map)));
//                }
//            } else {
//                WebSocketServer.sendInfo("taskresult_" + stationCode, JSONUtil.toJsonStr(JSONUtil.parse(map)));
//            }
            WebSocketServer.sendInfo("taskresult_" + stationCode, JSONUtil.toJsonStr(JSONUtil.parse(map)));
            if (taskTodo.getTaskType().equals("4")) {
                String controlNum = taskTodo.getControlNum();
                List<LinkageSignal> linkageSignals =
                        linkageSignalMapper.selectList(new LambdaQueryWrapper<LinkageSignal>().eq(LinkageSignal::getControlNum, controlNum));
                if (linkageSignals.size() > 0) {
                    LinkageSignal linkageSignal = linkageSignals.get(0);
                    String linkageType = linkageSignal.getLinkageType();
                    if ("1".equals(linkageType)) {
                        //对于一键顺控任务调用顺控文件生成和处理方法
                        stationNodeService.createVideocfmresult(taskResult.getStationCode(), taskResult.getTaskCode(),
                                taskResult.getDesc());
                    }
                }

            }

        }
        return true;
    }

    @Override
    public boolean updateDeviceResult(JSONObject dataObject) throws Exception {
        JSONArray resultList = dataObject.getJSONArray("resultList");
        for (int i = 0; i < resultList.size(); i++) {
            JSONObject resultObject = resultList.getJSONObject(i);
            if (resultObject == null) {
                continue;
            }
            String objectId = resultObject.getStr("objectId");
            SubstationDevice substationDevice = substationDeviceMapper.selectById(objectId);
            JSONArray results = resultObject.getJSONArray("results");
            //设置点位结果数据

            Set<String> validList = new HashSet<>();
            List<String> valueList = new ArrayList<>();
            List<String> confList = new ArrayList<>();
            List<String> descList = new ArrayList<>();
            List<String> typeList = new ArrayList<>();
            String filename = "";
            JSONArray posArray = new JSONArray();
            JSONObject map = new JSONObject();
            String resImagePath = "";
            for (int a = 0; a < results.size(); a++) {
                JSONObject result = results.getJSONObject(a);
                String code = result.getStr("code");
                if ("2000".equals(code)) {
                    String type = result.getStr("type");
                    typeList.add(type);
                    String value = result.getStr("value");
                    String desc = result.getStr("desc");
                    String conf = result.getStr("conf");
                    if (ObjectUtil.isNotEmpty(conf)) {
                        confList.add(conf);
                    }
                    String valueType = result.getStr("type");
                    validList.add("1");
                    String posStr = "";
                    if (!"infrared".equals(result.getStr("type")) && !"sound".equals(result.getStr("type")) && !"yjsk"
                            .equals(result.getStr("type")) && !"isolator".equals(result.getStr("type"))) {
                        //图片 排除声音
                        //                    filename = StrUtil.subAfter(URLDecoder.decode(result.getStr
                        //                    ("resImagePath"), "utf-8"), "=",
                        //                            true);
                        filename = result.getStr("resImagePath");
                        String pos = result.getStr("pos");
                        // 将框坐标统一存储画框
                        if (StrUtil.isNotBlank(pos)) {
                            JSONArray jsonArray = JSONUtil.parseArray(pos);
                            // 写入内容到文件
                            if (jsonArray.size() > 0) {
                                JSONObject jsonObject = jsonArray.getJSONObject(0);
                                if (jsonObject.size() > 0) {
                                    posArray.addAll(jsonArray);
                                    JSONArray areas = jsonObject.getJSONArray("areas");
                                    JSONObject jsonObject1 = areas.getJSONObject(0);
                                    JSONObject jsonObject2 = areas.getJSONObject(1);
                                    posStr =
                                            " " + jsonObject1.getStr("x") + " " + jsonObject1.getStr("y") + " " + jsonObject2.getStr("x") + " " + jsonObject2.getStr("y");
                                }
                            }

                        }
                    } else {
                        resImagePath = result.getStr("resImagePath");
                    }
                    Map<String, Object> judgeresult = judgeAbnormal(result.getStr("type"), result.getStr("value"),
                            desc, substationDevice.getDeviceId(), "");
                    // || "yjsk".equals(result.getStr("type"))
                    log.info("=======================发送结果=======================" + result.getStr("type"));
                    if (!("meter".equals(type) || "infrared".equals(type) || "sound".equals(type) || StrUtil.isBlank(type) || "yjsk".equals(result.getStr("type")) || "isolator".equals(result.getStr("type")))) {
                        // 图像缺陷分析类型
                        List<Map<String, Object>> pictureDefectAnalysisTypeList =
                                sysDictionaryItemsService.getDeviceByType(
                                        "PictureDefectAnalysisType");
                        Set<String> customList =
                                pictureDefectAnalysisTypeList.stream().filter(c -> ObjectUtil.isNotEmpty(c.get(
                                        "custom1"))).map(c -> c.get("custom1").toString()).collect(Collectors.toSet());
                        for (String custom : customList) {
                            if (JSONUtil.isTypeJSONArray(custom)) {
                                JSONArray jsonArray = JSONUtil.parseArray(custom);
                                for (int j = 0; j < jsonArray.size(); j++) {
                                    JSONObject jsonObject = jsonArray.getJSONObject(j);
                                    // 检查当前对象的key字段是否与目标key匹配
                                    if (jsonObject.getStr("key").equals(valueType)) {
                                        valueList.add(jsonObject.getStr("value"));
                                        break; // 找到后跳出循环
                                    }
                                }
                            }

                        }
                    } else {
                        log.info("==============================进入===========================" + result.getStr("type"));
                        valueList.add(value);
                        descList.add(desc);
                        desc = "";
                    }
                    log.info("=========================================================" + judgeresult.get(
                            "isNormal").toString());
                    //判定为异常
                    String resultStr = "";
                    if ("0".equals(judgeresult.get("isNormal").toString())) {
                        //判定为异常
                        validList.add("2");
                        resultStr = result.getStr("type") + " " + result.getStr("conf") + posStr + "\n";
                    }
                    if (StrUtil.isNotBlank(desc) && ("0".equals(judgeresult.get("isNormal").toString()) || valueType.contains("fhz") || valueType.contains("isolator"))) {
                        descList.add(desc);
                    }
                } else {
                    // 非2000的判定为失败
                    validList.add("0");
                    descList.add("识别失败");
                }
            }
            log.info("========================validList.toString()=================================" + validList.toString());
            // 识别成功
            String value = StrUtil.join(",", valueList);
            String descJoin = StrUtil.join(",", descList);
            String confJoin = StrUtil.join(",", confList);
            String now = DateUtil.now();
            String typeStr = StrUtil.join(",", typeList);
            String fileName = URLEncoder.encode(filename, "utf-8");
            String defectFilePath = fileName;
            if (StrUtil.isNotBlank(filename) && posArray.size() > 0) {
                String originfilename = Config.getSnapFilePath() + filename;
                String markedfilename = Config.getSnapFilePath() + StrUtil.replace(filename, ".jpg", "_识别.jpg");
                FileUtil.MarkImageRectangle(originfilename, posArray.toString(), markedfilename);
                //水印字体
                Font font = new Font("微软雅黑", Font.PLAIN, 40);
                //水印图片色彩
                Color color1 = new Color(31, 183, 55);
                FileUtil.addWaterMark(markedfilename, markedfilename, substationDevice.getDeviceName(), 20, -40, color1,
                        font);
                Color color2 = new Color(226, 7, 24);
                String alertinfo = descJoin + "   " + "置信度:" + confJoin + "   " + now;
                FileUtil.addWaterMark(markedfilename, markedfilename, alertinfo, 600, -40, color2, font);
                defectFilePath = URLEncoder.encode(StrUtil.replace(filename, ".jpg", "_识别.jpg"), "utf-8");//转码存储
            }
            map.putOpt("filePath", fileName);
            if (StrUtil.isBlank(defectFilePath)) {
                map.putOpt("defectFilePath", resImagePath);
            } else {
                map.putOpt("defectFilePath", defectFilePath);
            }
            map.putOpt("value", value);
            map.putOpt("desc", descJoin);
            map.putOpt("valueType", typeStr);
            map.putOpt("conf", confJoin);
            map.putOpt("time", now);
            map.putOpt("patroldeviceDate", now);
            String flag = "2";
            String valid = "1";
            // 判定巡视结果
            if (validList.contains("2")) {
                // 只要存在异常就判定为异常
                flag = "2";
                valid = "2";
            }
            if (validList.size() == 1 && validList.contains("1")) {
                // 都为正常的判定为正常
                flag = "2";
                valid = "1";
            }
            if (validList.size() == 1 && validList.contains("0")) {
                // 都为巡视失败的判定为失败
                flag = "4";
                valid = "0";
            }
            map.putOpt("flag", flag);
            map.putOpt("deviceId", substationDevice.getDeviceId());
            map.putOpt("recognitionType", substationDevice.getRecognitionTypeList());
            map.putOpt("valid", valid);
            map.putOpt("meterType", substationDevice.getMeterType());
            String analysisResult = "";
            if ("4".equals(flag)) {
                analysisResult = "识别失败";
            } else if ("2".equals(valid)) {
                analysisResult = "异常";
            } else {
                analysisResult = "正常";
            }
            map.putOpt("analysisResult", analysisResult);
            log.info("--------------------------" + map.toString());
            // 发送数据到前端
            WebSocketServer.sendInfo("deviceresult_" + substationDevice.getStationCode(), map.toString());
        }
        return true;
    }

    /**********************************
     * 用途说明: 告警准确率统计
     * 参数说明 stationId 变电站Id
     * 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
     ***********************************/
    @Override
    public Map<String, Object> getConfirmationRate(String stationId) {
        return alarmLogMapper.getConfirmationRate(stationId);
    }

    /**********************************
     * 用途说明: 查询报警信息
     * 参数说明 stationId
     * 返回值说明: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     ***********************************/
    @Override
    public List<Map<String, Object>> getAlarmLogList(String stationId) {
        return alarmLogMapper.getAlarmLogList(stationId);
    }

    @Override
    public List<AlarmLog> getNotCheckAlarmCount(String stationId) {
        return alarmLogMapper.getNotCheckAlarmCount(stationId);
    }

    /**********************************
     * 用途说明: 设置任务结果数据
     * 参数说明 taskResult
     * 参数说明 result
     * 返回值说明: com.yfd.platform.modules.patroltask.domain.TaskResult
     ***********************************/
    private void updateTaskResult(TaskResult taskResult, JSONArray results) throws Exception {
        //正确 2000  图像数据错误 2001  算法分析失败 2002

        Set<String> validList = new HashSet<>();
        List<String> valueList = new ArrayList<>();
        List<String> confList = new ArrayList<>();
        List<String> descList = new ArrayList<>();
        List<String> typeList = new ArrayList<>();
        String filename = "";
        JSONArray posArray = new JSONArray();
        Map<String, Object> map = new HashMap<>();
        for (int a = 0; a < results.size(); a++) {
            JSONObject result = results.getJSONObject(a);
            String code = result.getStr("code");
            if ("2000".equals(code)) {
                String type = result.getStr("type");
                typeList.add(type);
                taskResult.setValueType(result.getStr("type"));
                String value = result.getStr("value");
                if ("infrared".equals(type) && StrUtil.isNotBlank(value)) {
                    value = StrUtil.split(value, ",").get(0);
                }
                String desc = result.getStr("desc");
                String conf = result.getStr("conf");
                if (ObjectUtil.isNotEmpty(conf)) {
                    confList.add(conf);
                }
                validList.add("1");
                if (!"infrared".equals(result.getStr("type")) && !"sound".equals(result.getStr("type")) && !"yjsk".equals(result.getStr("type")) && !"isolator".equals(result.getStr("type"))) {
                    filename = result.getStr("resImagePath");
                    String pos = result.getStr("pos");
                    // 将框坐标统一存储画框
                    if (StrUtil.isNotBlank(pos)) {
                        JSONArray jsonArray = JSONUtil.parseArray(pos);
                        // 写入内容到文件
                        if (jsonArray.size() > 0) {
                            JSONObject jsonObject = jsonArray.getJSONObject(0);
                            if (jsonObject.size() > 0) {
                                posArray.addAll(jsonArray);
                            }
                        }

                    }
                } else {
                    taskResult.setDefectFilePath(taskResult.getFilePath());
                }
                String valueType = taskResult.getValueType();
                Map<String, Object> judgeresult = judgeAbnormal(result.getStr("type"), value,
                        result.getStr("desc"), taskResult.getDeviceId(), taskResult.getResultId());
                log.info("=======================发送结果=======================" + result.getStr("type"));
                if (!("meter".equals(type) || "fhz".equals(result.getStr("type")) || "infrared".equals(type) ||
                        "sound".equals(type) || StrUtil.isBlank(type) || "yjsk".equals(result.getStr("type")) ||
                        "isolator".equals(result.getStr("type")))) {
                    // 图像缺陷分析类型
                    List<Map<String, Object>> pictureDefectAnalysisTypeList = sysDictionaryItemsService.getDeviceByType(
                            "PictureDefectAnalysisType");
                    Set<String> customList =
                            pictureDefectAnalysisTypeList.stream().filter(c -> ObjectUtil.isNotEmpty(c.get(
                                    "custom1"))).map(c -> c.get("custom1").toString()).collect(Collectors.toSet());
                    for (String custom : customList) {
                        if (JSONUtil.isTypeJSONArray(custom)) {
                            JSONArray jsonArray = JSONUtil.parseArray(custom);
                            for (int i = 0; i < jsonArray.size(); i++) {
                                JSONObject jsonObject = jsonArray.getJSONObject(i);
                                // 检查当前对象的key字段是否与目标key匹配
                                if (jsonObject.getStr("key").equals(valueType)) {
                                    valueList.add(jsonObject.getStr("value"));
                                    break; // 找到后跳出循环
                                }
                            }
                        }

                    }
                } else {
                    valueList.add(value);
                    descList.add(desc);
                    desc = "";
                }

                map.put("link_point", judgeresult.get("link_point"));
                map.put("alarmAnalysisType", judgeresult.get("alarmAnalysisType"));
                map.put("oldContent", judgeresult.get("oldContent"));
                map.put("isSame", judgeresult.get("isSame"));
                if (ObjectUtil.isNotEmpty(judgeresult.get("alarmlevel"))) {
                    map.put("alarmlevel", judgeresult.get("alarmlevel"));
                }
                if (ObjectUtil.isNotEmpty(judgeresult.get("alarmtype"))) {
                    map.put("alarmtype", judgeresult.get("alarmtype"));
                }
                //判定为异常
                if ("0".equals(judgeresult.get("isNormal").toString())) {
                    map.put("alarmlevel", judgeresult.get("alarmlevel"));
                    //判定为异常
                    validList.add("2");
                }

                if (StrUtil.isNotBlank(desc) && ("0".equals(judgeresult.get("isNormal").toString()) || valueType.contains("fhz") || valueType.contains("isolator"))) {
                    descList.add(desc);
                }
            } else {
                // 非2000的判定为失败
                validList.add("0");
                descList.add("识别失败");
            }
        }
        log.info("========================validList.toString()=================================" + validList.toString());
        // 识别成功
        taskResult.setValue(StrUtil.join(",", valueList));
        String descJoin = StrUtil.join(",", descList);
        String confJoin = StrUtil.join(",", confList);
        String now = DateUtil.now();
        if (StrUtil.isNotBlank(filename) && StrUtil.isNotBlank(taskResult.getFilePath()) && posArray.size() > 0) {
            String originfilename = Config.getSnapFilePath() + filename;
            String markedfilename = Config.getSnapFilePath() + StrUtil.replace(filename, ".jpg", "_识别.jpg");
            FileUtil.MarkImageRectangle(originfilename, posArray.toString(), markedfilename);
            //水印字体
            Font font = new Font("微软雅黑", Font.PLAIN, 40);
            //水印图片色彩
            Color color1 = new Color(31, 183, 55);
            FileUtil.addWaterMark(markedfilename, markedfilename, taskResult.getDeviceName(), 20, -40, color1, font);
            Color color2 = new Color(226, 7, 24);
            String alertinfo = descJoin + "   " + "置信度:" + confJoin + "   " + now;
            FileUtil.addWaterMark(markedfilename, markedfilename, alertinfo, 600, -40, color2, font);
            String defectFilePath =
                    URLEncoder.encode(StrUtil.replace(filename, ".jpg", "_识别.jpg"), "utf-8");//转码存储
            taskResult.setDefectFilePath(defectFilePath);
            taskResult.setRectangle(posArray.toString());
        }
        //识别结果描述  示例：表计表盘破损
        taskResult.setDesc(descJoin);
        //识别结果置信度  示例：0.99
        taskResult.setConf(confJoin);
        taskResult.setTime(now);
        taskResult.setLastmodifydate(new Timestamp(DateUtil.current()));
        taskResult.setValueType(StrUtil.join(",", typeList));
        // 判定巡视结果
        if (validList.contains("2")) {
            // 只要存在异常就判定为异常
            taskResult.setFlag("2");
            taskResult.setValid("2");
            SubstationDevice device = deviceMapper.selectById(taskResult.getDeviceId());
            // 根据巡视点位判断是否生成报警
            if ("1".equals(device.getIsAlarm())) {
                log.info("=========================生成报警记录====================");
                //生成报警记录
                createTaskAlarmLog(taskResult, map);
            }
        }
        if (validList.size() == 1 && validList.contains("1")) {
            // 都为正常的判定为正常
            taskResult.setFlag("2");
            taskResult.setValid("1");
        }
        if (validList.size() == 1 && validList.contains("0")) {
            // 都为巡视失败的判定为失败
            taskResult.setFlag("4");
            taskResult.setValid("0");
        }
        //TODO 新增加三相对比
//        sendNonCoherentMsg1(taskResult, 0);
    }

    /**********************************
     * 用途说明: 发送非同相告警
     * 参数说明 taskResult
     * 返回值说明: void
     ***********************************/
    @Override
    public void sendNonCoherentMsg1(TaskResult taskResult, double alertValue) throws Exception {
        log.info("=========================三相对比==============================" + taskResult.toString());
        SubstationDevice substationDevice1 = deviceMapper.selectById(taskResult.getDeviceId());
        if ("4".equals(substationDevice1.getRecognitionTypeList())) {
            substationDevice1.setMeterType("4");
        }
        String meterType = substationDevice1.getMeterType();
        if (!("4".equals(taskResult.getRecognitionType()) || "1".equals(taskResult.getRecognitionType()))) {
            return;
        }
        LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(TaskResult::getResultId, taskResult.getResultId()).eq(TaskResult::getTaskTodoId,
                taskResult.getTaskTodoId()).eq(TaskResult::getAreaId,
                taskResult.getAreaId()).eq(TaskResult::getBayId, taskResult.getBayId()).eq(TaskResult::getMainDeviceId, taskResult.getMainDeviceId()).eq(TaskResult::getComponentId, taskResult.getComponentId()).eq(TaskResult::getRecognitionType, taskResult.getRecognitionType()).eq(TaskResult::getFlag, "2");
        List<Map<String, Object>> mapList = taskResultMapper.selectMaps(queryWrapper);
        log.info("=========================三相对比数量==============================" + mapList.size());
        Map<String, Object> map1 = BeanUtil.beanToMap(taskResult);
        mapList.add(map1);
        if (mapList.size() < 3) {
            return;
        }
        log.info("=========================三相对比数量==============================" + mapList.size());
        mapList.forEach(r -> {
            String deviceId = r.get("deviceId").toString();
            SubstationDevice substationDevice = deviceMapper.selectById(deviceId);
            String meterType1 = substationDevice.getMeterType();
            if ("4".equals(substationDevice.getRecognitionTypeList())) {
                meterType1 = "4";
            }
            r.put("meterType", meterType1);
            r.put("phase", substationDevice.getPhase());
            //            if (taskResult.getResultId().equals(r.get("resultId").toString())) {
            //                r.put("value", taskResult.getValue());
            //            }
        });
        log.info("=========================三相对比数据==============================" + mapList.toString());
        Map<String, List<Map<String, Object>>> meterTypeMap =
                mapList.stream().collect(Collectors.groupingBy(m -> m.get("meterType").toString()));
        List<Map<String, Object>> mapList1 = meterTypeMap.get(meterType);
        int phaseSize = mapList1.stream().collect(Collectors.groupingBy(m -> m.get("phase").toString())).size();
        if (!(mapList1.size() == 3 && phaseSize == 3)) {
            return;
        }
        Map<String, String> map = new HashMap<>();
        // 三相对比
        if ("1".equals(taskResult.getRecognitionType())) {
            map.put("alarmtype", "9");
            map.put("alarmlevel", "4");
            alertValue = 1;
            // 仪表三相
            List<Double> values =
                    mapList1.stream().map(m -> NumberUtil.parseDouble(m.get("value").toString())).collect(Collectors.toList());
            List<Double> deviceNames =
                    mapList1.stream().map(m -> NumberUtil.parseDouble(m.get("deviceName").toString())).collect(Collectors.toList());
            Double max = CollectionUtil.max(values);
            Double min = CollectionUtil.min(values);
            String valueStr = StrUtil.join(",", values);
            String deviceNameStr = StrUtil.join(",", deviceNames);
            double difference = max - min;
            if (difference > alertValue) {
                String alarmInfo = String.format("仪表三相告警提示，点位【%s】，值【%s】，超过阈值%s告警！", deviceNameStr, valueStr,
                        alertValue);
                map.put("alarmInfo", alarmInfo);
                map.put("alertValue", alertValue + "");
                // 创建仪表三相告警
                createOtherAlarm(taskResult, map);
            }
        }

        if ("4".equals(taskResult.getRecognitionType())) {
            map.put("alarmtype", "3");
            map.put("alarmlevel", "4");
            alertValue = 10;
            // 仪表三相
            List<Double> values =
                    mapList1.stream().map(m -> NumberUtil.parseDouble(m.get("value").toString())).collect(Collectors.toList());
            List<String> deviceNames =
                    mapList1.stream().map(m -> m.get("deviceName").toString()).collect(Collectors.toList());
            Double max = CollectionUtil.max(values);
            Double min = CollectionUtil.min(values);
            String valueStr = StrUtil.join(",", values);
            String deviceNameStr = StrUtil.join(",", deviceNames);
            double difference = max - min;
            if (difference > alertValue) {
                String alarmInfo = String.format("三相温差报警告警提示，点位【%s】，值【%s】，超过阈值%s告警！", deviceNameStr, valueStr,
                        alertValue);
                map.put("alarmInfo", alarmInfo);
                map.put("alertValue", alertValue + "");
                // 创建三相温差告警
                createOtherAlarm(taskResult, map);
            }
        }
    }

    private boolean createOtherAlarm(TaskResult taskResult, Map<String, String> map) throws UnsupportedEncodingException {
        AlarmLog alarmLog = new AlarmLog();
        alarmLog.setId(IdUtil.fastSimpleUUID());
        String deviceid = taskResult.getDeviceId();
        SubstationDevice device = deviceMapper.selectById(deviceid);
        String alarmDate = DateUtil.now();
        Substation substation = stationMapper.selectOne(new LambdaQueryWrapper<Substation>().
                eq(Substation::getStationCode, device.getStationCode()));
        alarmLog.setStationCode(device.getStationCode());
        alarmLog.setStationId(substation.getStationId());
        alarmLog.setStationName(substation.getStationName());
        alarmLog.setAreaId(taskResult.getAreaId());
        alarmLog.setAreaName(taskResult.getAreaName());
        alarmLog.setBayId(taskResult.getBayId());
        alarmLog.setBayName(taskResult.getBayName());
        alarmLog.setAlarmSourceType("1");
        alarmLog.setMainDeviceId(taskResult.getMainDeviceId());
        alarmLog.setMainDeviceName(taskResult.getMainDeviceName());
        alarmLog.setComponentId(taskResult.getComponentId());
        alarmLog.setComponentName(taskResult.getComponentName());
        alarmLog.setDeviceId(taskResult.getDeviceId());
        alarmLog.setDeviceName(taskResult.getDeviceName());
        alarmLog.setPatroldeviceCode(taskResult.getPatroldeviceCode());
        alarmLog.setPatroldeviceName(taskResult.getPatroldeviceName());
        alarmLog.setMaterialId(taskResult.getMaterialId());
        TaskTodo taskTodo = taskTodoMapper.selectById(taskResult.getTaskTodoId());
        alarmLog.setTaskId(taskTodo.getTaskId());
        alarmLog.setTaskPatrolledId(taskResult.getTaskTodoId());
        alarmLog.setTaskResultId(taskResult.getResultId());
        alarmLog.setTaskCode(taskResult.getTaskCode());
        alarmLog.setTaskName(taskResult.getTaskName());
        alarmLog.setTaskAlarmType("1"); //'1:巡视任务告警；2:静默任务告警，3：巡视设备告警',
        //alarmLog.setMonitorType("");//非静默监视不填
        alarmLog.setAlarmType(ObjUtil.isNotEmpty(map.get("alarmtype")) ? map.get("alarmtype") : "");
        //'字典表<1>: = 超温报警<2>: = 温升报警<3>: = 三相温差报警<4>: = 三相对比报警<5>: = 声音异常<6>: = 外观异常<7>: = 仪表越限报警<8>: = 仪表超量程报警<9>: =
        // 仪表三相对比<10>: = 变位报警',
        alarmLog.setAlarmLevel(ObjUtil.isNotEmpty(map.get("alarmlevel")) ? map.get("alarmlevel") : "3");//
        // '1:预警；2:一般；3:严重；4;危急',  待判断细分
        alarmLog.setRecognitionType(taskResult.getRecognitionType());//'1:表计读取；2:位置状态识别；3:设备外观查看；4:红外测温；5:声音检测；6
        // :闪烁检测11:局放超声波检测12:局放地电压检测13:局放特高频检测101:环境温度检测102:环境湿度检测103:氧气浓度检测104SF6浓度检测',
        alarmLog.setFileType(taskResult.getFileType());//'1:红外图谱；2:可见光照片；3:音频4:视频5:识别图片，存在多个文件，文件类型用逗号分隔',
        //告警文件目录规范：地市名/区域名/变电站名/分类/年月
        String type = "缺陷";//缺陷、判别
        String alarmfilepath = String.format("%s/%s/%s/%s/%s/",
                substation.getCityName(),
                substation.getSectionName(),
                substation.getStationName(),
                type,
                DateUtil.format(DateUtil.date(), "yyyyMM")
        );
        log.info(
                "============================================拷贝原图到报警目录下============================================");
        //拷贝原图到报警目录下
        String fullfilename = URLDecoder.decode(taskResult.getFilePath(), "utf-8");
        String alarmfullfilename = alarmfilepath + StrUtil.subAfter(fullfilename, "/", true);
        FileUtil.copy(Config.getSnapFilePath() + fullfilename, Config.getAlarmFilePath() + alarmfullfilename, true);
        alarmLog.setFilePath(URLEncoder.encode(alarmfullfilename, "utf-8"));//原图文件名称（含路径）
        alarmLog.setDefectType(taskResult.getValueType());//'缺陷类别'
        log.info(
                "============================================拷贝识别图到报警目录下============================================");
        //拷贝识别图到报警目录下
        if (ObjUtil.isNotEmpty(taskResult.getDefectFilePath())) {
            String fulldefectfilename = URLDecoder.decode(taskResult.getDefectFilePath(), "utf-8");
            String alarmfilename = StrUtil.replace(StrUtil.subAfter(fulldefectfilename, "/", true), "识别", "缺陷告警");
            String fullalarmfile = alarmfilepath + alarmfilename;
            FileUtil.copy(Config.getSnapFilePath() + fulldefectfilename, Config.getAlarmFilePath() + fullalarmfile,
                    true);
            alarmLog.setDefectFilePath(URLEncoder.encode(fullalarmfile, "utf-8"));//标注了识别框和信息
        }
        log.info(
                "============================================图形识别结果（值）============================================");
        alarmLog.setValue(taskResult.getValue());//图形识别结果（值）
        alarmLog.setUnit(taskResult.getUnit());
        String alarminfo = map.get("alarmInfo");
        alarmLog.setContent(alarminfo);//告警描述信息
        alarmLog.setAlarmDate(alarmDate);//发送报警时间
        alarmLog.setCheckFlag("0");//'0:未核查；1:已审核；2.已修正'
        alarmLog.setRectangle(taskResult.getRectangle());//'格式：x1,y1,x2y2;x3,y3,x4,y4；多个报警框的左上角和右下角坐标'
        alarmLog.setDatastatus("1"); //初始创建
        alarmLog.setLastmodifier("系统创建");
        alarmLog.setLastmodifydate(new Timestamp(DateUtil.current()));
//        this.save(alarmLog);//保存此报警数据
        Map<String, Object> logMap = BeanUtil.beanToMap(alarmLog);
        String stationId = alarmLog.getStationId();
        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlarmLog::getDatastatus, "1").eq(AlarmLog::getStationId, stationId).eq(AlarmLog::getCheckFlag
                , 0);
        int count = this.count(queryWrapper);
        logMap.put("alarmCount", count);
        JSONObject jsonObject = new JSONObject(logMap);
        String stationCode = substation.getStationCode();
//        SysOrganization sysOrganization =
//                sysOrganizationMapper.selectOne(new LambdaUpdateWrapper<SysOrganization>().eq(SysOrganization::getOrgcode, stationCode));
//        String parentid = sysOrganization.getParentid();
        jsonObject.putOpt("deviceid", jsonObject.getStr("deviceId"));
        jsonObject.putOpt("channelId", taskResult.getPatroldeviceChannelcode());
        jsonObject.putOpt("deviceId", taskResult.getPatroldeviceCode());
        // 告警阈值
        jsonObject.putOpt("earlyMin", map.get("alertValue"));
        jsonObject.putOpt("earlyMax", map.get("alertValue"));
        jsonObject.putOpt("sameMin", map.get("alertValue"));
        jsonObject.putOpt("sameMax", map.get("alertValue"));
        jsonObject.putOpt("seriousMin", map.get("alertValue"));
        jsonObject.putOpt("seriousMax", map.get("alertValue"));
        jsonObject.putOpt("criticalMin", map.get("alertValue"));
        jsonObject.putOpt("criticalMax", map.get("alertValue"));
        // 如果是站端则区域也需要发送告警
//        if (!"0".equals(parentid)) {
//            WebSocketServer.sendInfo(parentid, jsonObject.toString());
//        }
        WebSocketServer.sendInfo(stationId, jsonObject.toString());
        return true;
    }

    /**********************************
     * 用途说明: 发送非同相告警
     * 参数说明 taskResult
     * 返回值说明: void
     ***********************************/
    private void sendNonCoherentMsg(TaskResult taskResult, double alertValue, String meterType) {
        String recognitionTypeList = taskResult.getRecognitionType();
        List<Map<String, Object>> nonCoherentAnalysis =
                taskResultMapper.getNonCoherentAnalysis(taskResult.getTaskTodoId(), null, null, null, null, null,
                        null, null);
        List<Map<String, Object>> mapList =
                nonCoherentAnalysis.stream().filter(m -> m.get("recognition_type").toString().equals(recognitionTypeList) && m.get("meterType").toString().equals(meterType)).collect(Collectors.toList());
        Set<String> phases = mapList.stream().map(m -> m.get("phase").toString()).collect(Collectors.toSet());
        Set<String> deviceIds = mapList.stream().map(m -> m.get("deviceId").toString()).collect(Collectors.toSet());
        // 如果包含相同相位或者相同点位则跳出
        if (phases.size() != mapList.size() || deviceIds.size() != mapList.size()) {
            return;
        }
        for (Map<String, Object> map : mapList) {
            if (ObjectUtil.isNotEmpty(map.get("value")) && StrUtil.isNotBlank(taskResult.getValue())) {
                BigDecimal value1 = new BigDecimal(taskResult.getValue());
                BigDecimal value2 = new BigDecimal(map.get("value").toString());
                double difference = Math.abs(value1.subtract(value2).doubleValue());
                if (difference <= alertValue) {
                    break;
                }
                Message message = new Message();
                TaskTodo taskTodo = taskTodoService.getById(taskResult.getTaskTodoId());
                String taskName = taskResult.getTaskName();
                // 消息标题
                String title = taskName + "（" + taskTodo.getStartTime() + "）";
                message.setTitle(title);
                message.setContent("表记巡视非同相结果差值超阈，结果一：" + map.get("value").toString() + "结果二：" + taskResult.getValue() +
                        "单位：" + taskResult.getUnit() + "阈值：" + alertValue);
                message.setCreatetime(new Timestamp(System.currentTimeMillis()));
                // 告警触发
                message.setType("4");
                message.setStatus("1");
                // 发送告警
                messageService.save(message);
                return;

            }
        }
    }

    /**********************************
     * 用途说明: 发送非同源告警
     * 参数说明 taskResult
     * 返回值说明: void
     ***********************************/
    private void sendNonHomologousMsg(TaskResult taskResult, double alertValue) {
        String deviceId = taskResult.getDeviceId();
        String taskTodoId = taskResult.getTaskTodoId();
        LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskResult::getTaskTodoId, taskTodoId).eq(TaskResult::getDeviceId, deviceId).ne(TaskResult::getResultId, taskResult.getResultId());
        List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
        String content = "";
        for (TaskResult taskresult : taskResultList) {
            // 表记
            if ("1".equals(taskResult.getRecognitionType()) && ObjectUtil.isNotEmpty(taskResult.getValue()) && ObjectUtil.isNotEmpty(taskresult.getValue())) {
                BigDecimal value1 = new BigDecimal(taskResult.getValue());
                BigDecimal value2 = new BigDecimal(taskresult.getValue());
                double difference = Math.abs(value1.subtract(value2).doubleValue());
                if (difference <= alertValue) {
                    break;
                }
                content =
                        "表记巡视非同源结果差值超阈，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() + "单位：" + taskResult.getUnit() + "阈值：" + alertValue;
            }
            // 测温
            if ("4".equals(taskResult.getRecognitionType()) && ObjectUtil.isNotEmpty(taskResult.getValue()) && ObjectUtil.isNotEmpty(taskresult.getValue())) {
                String value = taskResult.getValue();
                String value1 = taskresult.getValue();
                String[] split = value.split(",");
                String[] split1 = value1.split(",");
                if (split.length != 2 || split1.length != 2) {
                    break;
                }
//                BigDecimal v1 = new BigDecimal(split[0]);
                BigDecimal v2 = new BigDecimal(split[0]);
//                BigDecimal v3 = new BigDecimal(split1[0]);
                BigDecimal v4 = new BigDecimal(split1[0]);
                if (Math.abs(v2.subtract(v4).doubleValue()) <= alertValue) {
                    break;
                }
                content =
                        "红外测温非同源最大温度结果差值超阈，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() + "单位：" + taskResult.getUnit() + "阈值：" + alertValue;
            }

            if ("2".equals(taskResult.getRecognitionType())) {
                // 设备位置状态识别
                String desc1 = taskResult.getDesc();
                String desc2 = taskresult.getDesc();
                if (StrUtil.isNotBlank(desc1) && StrUtil.isNotBlank(desc2) && !desc1.equals(desc2)) {
                    // 报警
                    content = "设备位置状态识别非同源结果不一致，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() +
                            "单位：" + taskResult.getUnit();
                }
            }
            // 如果符合报警条件则报警
            if (StrUtil.isNotBlank(content)) {
                Message message = new Message();
                TaskTodo taskTodo = taskTodoService.getById(taskResult.getTaskTodoId());
                String taskName = taskResult.getTaskName();
                // 消息标题
                String title = taskName + "（" + taskTodo.getStartTime() + "）";
                message.setTitle(title);
                message.setContent(content);
                message.setCreatetime(new Timestamp(System.currentTimeMillis()));
                // 告警触发
                message.setType("4");
                message.setStatus("1");
                // 发送告警
                messageService.save(message);
            }
            break;
        }
    }

    /**********************************
     * 用途说明: 告警
     * 参数说明 taskResult 当前结果
     * 返回值说明: void
     ***********************************/
    private void sendMessage(TaskResult taskResult) {
        String deviceId = taskResult.getDeviceId();
        String taskTodoId = taskResult.getTaskTodoId();
        LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TaskResult::getTaskTodoId, taskTodoId).eq(TaskResult::getDeviceId, deviceId).ne(TaskResult::getResultId, taskResult.getResultId());
        List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
        SubstationDevice substationDevice = deviceMapper.selectById(taskResult.getDeviceId());
        String patroldeviceJson = substationDevice.getPatroldeviceJson();
        JSONArray jsonArray = JSONUtil.parseArray(patroldeviceJson);
        if (jsonArray.size() != 2) {
            return;
        }
        String alertvalue = "0.0";
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject jsonObject = jsonArray.getJSONObject(i);  //取第二条
            if (ObjectUtil.isEmpty(jsonObject.get("alertvalue"))) {
                continue;
            } else {
                alertvalue = jsonObject.get("alertvalue").toString();
            }
        }

        double alertValue = NumberUtil.parseDouble(alertvalue);
        String content = "";
        for (TaskResult taskresult : taskResultList) {
            if ("1".equals(taskResult.getRecognitionType()) || "4".equals(taskResult.getRecognitionType())) {
                // 表记和测温
                if (ObjectUtil.isNotEmpty(taskResult.getValue()) && ObjectUtil.isNotEmpty(taskresult.getValue())) {
                    BigDecimal value1 = new BigDecimal(taskResult.getValue());
                    BigDecimal value2 = new BigDecimal(taskresult.getValue());
                    double difference = Math.abs(value1.subtract(value2).doubleValue());
                    if (difference <= alertValue) {
                        break;
                    }
                    if ("1".equals(taskResult.getRecognitionType())) {
                        content =
                                "表记巡视非同源结果差值超阈，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() +
                                        "单位：" + taskResult.getUnit() + "阈值：" + alertvalue;
                    } else {
                        content =
                                "红外测温非同源结果差值超阈，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() +
                                        "单位：" + taskResult.getUnit() + "阈值：" + alertvalue;
                    }

                }

            }
            if ("2".equals(taskResult.getRecognitionType())) {
                // 设备位置状态识别
                String desc1 = taskResult.getDesc();
                String desc2 = taskresult.getDesc();
                if (StrUtil.isNotBlank(desc1) && StrUtil.isNotBlank(desc2) && !desc1.equals(desc2)) {
                    // 报警
                    content = "设备位置状态识别非同源结果不一致，结果一：" + taskresult.getValue() + "结果二：" + taskResult.getValue() +
                            "单位：" + taskResult.getUnit();
                }
            }
            // 如果符合报警条件则报警
            if (StrUtil.isNotBlank(content)) {
                Message message = new Message();
                TaskTodo taskTodo = taskTodoService.getById(taskResult.getTaskTodoId());
                String taskName = taskResult.getTaskName();
                // 消息标题
                String title = taskName + "（" + taskTodo.getStartTime() + "）";
                message.setTitle(title);
                message.setContent(content);
                message.setCreatetime(new Timestamp(System.currentTimeMillis()));
                // 告警触发
                message.setType("4");
                message.setStatus("1");
                // 发送告警
                messageService.save(message);
                long count =
                        messageService.count(new LambdaQueryWrapper<Message>().eq(Message::getStatus, "1"));
                ServerSendEventServer.sendMessage(count + "");
            }
            break;
        }
        if (!"1".equals(taskResult.getRecognitionType()) || StrUtil.isNotBlank(content)) {
            return;
        }

        // 相位
        String recognitionTypeList = substationDevice.getRecognitionTypeList();
        String meterType = substationDevice.getMeterType();
        List<Map<String, Object>> nonCoherentAnalysis =
                taskResultMapper.getNonCoherentAnalysis(taskResult.getTaskTodoId(), null, null, null, null, null,
                        null, null);
        List<Map<String, Object>> mapList =
                nonCoherentAnalysis.stream().filter(m -> m.get("recognition_type").toString().equals(recognitionTypeList) && m.get("meterType").toString().equals(meterType)).collect(Collectors.toList());
        Set<String> phases = mapList.stream().map(m -> m.get("phase").toString()).collect(Collectors.toSet());
        Set<String> deviceIds = mapList.stream().map(m -> m.get("deviceId").toString()).collect(Collectors.toSet());
        // 如果包含相同相位或者相同点位则跳出
        if (phases.size() != mapList.size() || deviceIds.size() != mapList.size()) {
            return;
        }
        for (Map<String, Object> map : mapList) {
            if (ObjectUtil.isNotEmpty(map.get("value")) && StrUtil.isNotBlank(taskResult.getValue())) {
                BigDecimal value1 = new BigDecimal(taskResult.getValue());
                BigDecimal value2 = new BigDecimal(map.get("value").toString());
                double difference = Math.abs(value1.subtract(value2).doubleValue());
                if (difference <= alertValue) {
                    break;
                }
                Message message = new Message();
                TaskTodo taskTodo = taskTodoService.getById(taskResult.getTaskTodoId());
                String taskName = taskResult.getTaskName();
                // 消息标题
                String title = taskName + "（" + taskTodo.getStartTime() + "）";
                message.setTitle(title);
                message.setContent("表记巡视非同相结果差值超阈，结果一：" + map.get("value").toString() + "结果二：" + taskResult.getValue() +
                        "单位：" + taskResult.getUnit() + "阈值：" + alertvalue);
                message.setCreatetime(new Timestamp(System.currentTimeMillis()));
                // 告警触发
                message.setType("4");
                message.setStatus("1");
                // 发送告警
                messageService.save(message);
                return;

            }
        }

    }

    /**********************************
     * 用途说明: 静默监视查询
     * 参数说明 stationId
     * 参数说明 areaId
     * 参数说明 patrolDeviceName
     * 参数说明 monitorType
     * 返回值说明: java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     ***********************************/
    @Override
    public Page<Map<String, Object>> getAlarmListByType(Page<Map<String, Object>> page, String stationId,
                                                        String areaId, String patrolDeviceName, String monitorType) {
        return alarmLogMapper.getAlarmListByType(page, stationId, areaId, patrolDeviceName, monitorType);
    }

    /**********************************
     * 用途说明: 根据设备编号查询告警列表
     * 参数说明 page
     * 参数说明 patrolDeviceCode
     * 参数说明 monitorType
     * 参数说明 startDate
     * 参数说明 endDate
     * 返回值说明: com.baomidou.mybatisplus.extension.plugins.pagination.Page<java.util.Map<java.lang.String,java.lang
     * .Object>>
     ***********************************/
    @Override
    public Page<Map<String, Object>> getAlarmListPage(Page<Map<String, Object>> page, String patrolDeviceCode,
                                                      String monitorType, String startDate, String endDate) {
        return alarmLogMapper.getAlarmListPage(page, patrolDeviceCode, monitorType, startDate, endDate);
    }

    @Override
    public Page<Map<String, Object>> getAlarmLogPage(Page<Map<String, Object>> page, String stationCode,
                                                     String taskAlarmType, String alarmLevel, String checkFlag, String alarmSourceType,
                                                     String startDate, String endDate) {
        return alarmLogMapper.getAlarmLogPage(page, stationCode, taskAlarmType,
                alarmLevel, checkFlag,alarmSourceType, startDate, endDate);
    }

    @Override
    public boolean setAlarmLogStatus(AlarmLog alarmLog) {
        String currentUsername = SecurityUtils.getCurrentUsername();
        //String currentUsername = "admin";
        Timestamp timestamp = new Timestamp(System.currentTimeMillis());
        String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(timestamp);
        alarmLog.setLastmodifier(currentUsername);
        alarmLog.setCheckUserName(currentUsername);
        alarmLog.setLastmodifydate(timestamp);
        alarmLog.setCheckDate(format);
        String custom1 = alarmLog.getCustom1();
        if (StrUtil.isNotBlank(custom1) && !"0".equals(custom1)) {
            int i = Integer.parseInt(custom1);
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime localDateTime = now.plusMinutes(i);
            if ("1".equals(alarmLog.getTaskAlarmType())) {
                String deviceId = alarmLog.getDeviceId();
                deviceMapper.update(null, new LambdaUpdateWrapper<SubstationDevice>().eq(SubstationDevice::getDeviceId,
                        deviceId).set(SubstationDevice::getDelayedAlarmDate, localDateTime));
            } else if ("2".equals(alarmLog.getTaskAlarmType())) {
                AlarmLog alarmLog1 = this.getById(alarmLog.getId());
                SubstationPatroldevice substationPatroldevice =
                        patroldeviceMapper.selectOne(new LambdaUpdateWrapper<SubstationPatroldevice>().eq(SubstationPatroldevice::getPatroldeviceCode, alarmLog1.getPatroldeviceCode()));
                String monitorType = this.getSlienceType(alarmLog1.getMonitorType());
                String slienceParams = substationPatroldevice.getSlienceParams();
                JSONArray jsonArray = JSONUtil.parseArray(slienceParams);
                JSONArray slienceArray = new JSONArray();
                // 维护延时报警截止时间
                for (Object o : jsonArray) {
                    JSONObject jsonObject = JSONUtil.parseObj(o);
                    if (monitorType.equals(jsonObject.getStr("type"))) {
                        jsonObject.putOpt("delayed_alarm_date", LocalDateTimeUtil.formatNormal(localDateTime));
                    }
                    slienceArray.add(jsonObject);
                }
                LambdaUpdateWrapper<SubstationPatroldevice> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper.eq(SubstationPatroldevice::getPatroldeviceId,
                        substationPatroldevice.getPatroldeviceId()).set(SubstationPatroldevice::getSlienceParams,
                        slienceArray.toString());
                patroldeviceMapper.update(null, updateWrapper);
            }
        }
        boolean ok = this.updateById(alarmLog);
        String id = alarmLog.getId();
        AlarmLog alarmLog1 = this.getById(id);
        Map<String, Object> logMap = BeanUtil.beanToMap(alarmLog1);
        String stationId = alarmLog.getStationId();
        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlarmLog::getDatastatus, "1").eq(AlarmLog::getStationId, stationId).eq(AlarmLog::getCheckFlag
                , 0);
        int count = this.count(queryWrapper);
        logMap.put("alarmCount", count);
        JSONObject jsonObject = new JSONObject(logMap);
        SysOrganization sysOrganization =
                sysOrganizationMapper.selectOne(new LambdaUpdateWrapper<SysOrganization>().eq(SysOrganization::getOrgcode, alarmLog1.getStationCode()));
        String parentid = sysOrganization.getParentid();
        if (!"0".equals(parentid)) {
            WebSocketServer.sendInfo("check_" + parentid, jsonObject.toString());
        }
        WebSocketServer.sendInfo("check_" + alarmLog1.getStationId(), jsonObject.toString());
        return ok;
    }

    /**********************************
     * 用途说明: 根据告警信息ID查询详情
     * 参数说明 id 告警id
     * 返回值说明: java.util.Map<java.lang.String,java.lang.Object>
     ***********************************/
    @Override
    public Map<String, Object> getAlarmLogById(String id) {
        Map<String, Object> alarmLog = alarmLogMapper.getAlarmLogById(id);

        if (ObjectUtil.isNotEmpty(alarmLog.get("deviceid"))) {
            Map<String, String> thresholdInterval = alarmThresholdService.getThresholdInterval(alarmLog.get("deviceId"
            ).toString());
            if (thresholdInterval != null) {
                alarmLog.putAll(thresholdInterval);
            }
        }

        return alarmLog;
    }

    private String getSlienceType(String type) {
        String sliencetype = "";
        if ("wcgz".equals(type) || "wcaqm".equals(type) || "ryjjph".equals(type) || "xy".equals(type) ||
                "person_enter".equals(type)) {
            sliencetype = "ryxw";
        } else {
            sliencetype = type;
        }
        return sliencetype;
    }

    //根据识别类型和结果值判断是否为异常
    //    private Map<String, Object> judgeAbnormal_bak(String type, String value, String conf, String deviceid,
    //                                                  String resultId) throws Exception {
    //        Map<String, Object> result = new HashMap<>();
    //        SubstationDevice substationDevice = deviceMapper.selectById(deviceid);
    //        String pictureAnalysisTypeList = substationDevice.getPictureAnalysisTypeList();
    //        JSONObject jsonObject = JSONUtil.parseObj(pictureAnalysisTypeList);
    //        String pictureDefectAnalysisType = jsonObject.getStr("PictureDefectAnalysisType");
    //        result.put("isNormal", "1");
    //        List<AlarmThreshold> list =
    //                alarmThresholdService.list(new LambdaQueryWrapper<AlarmThreshold>().eq
    //                (AlarmThreshold::getDeviceId,
    //                        deviceid));
    //        if (StrUtil.isNotBlank(pictureDefectAnalysisType)) {
    //            // 缺陷告警设置
    //            //            List<Map<String, Object>> mapList = sysDictionaryItemsService.getDeviceByType
    //            //            ("PictureDefectAnalysisType");
    //            if ("1".equals(value)) {
    //                result.put("isNormal", "0");
    //            }
    //            return result;
    //        }
    //        String PictureDiscriminateAnalysisType = jsonObject.getStr("PictureDiscriminateAnalysisType");
    //        if (StrUtil.isNotBlank(PictureDiscriminateAnalysisType)) {
    //            if ("1".equals(value)) {
    //                result.put("isNormal", "0");
    //            }
    //            return result;
    //        }
    //        if ("meter".equals(type)) {//仪表读数
    //            double resultvalue = Double.parseDouble(value);
    //            //String alarmlevel = "0";// '1:预警；2:一般；3:严重；4;危急',
    //            SubstationDevice device = deviceMapper.selectById(deviceid);
    //            if (ObjUtil.isEmpty(device.getEarlyMin()) || ObjUtil.isEmpty(device.getCriticalMax())) {
    //                //未设置上下限，判定为正常
    //                result.put("isNormal", "1");//判定为正常
    //            } else {
    //                if (NumberUtil.compare(resultvalue, device.getEarlyMin()) >= 0 && NumberUtil.compare(resultvalue,
    //                        device.getEarlyMax()) < 0) {
    //                    result.put("alarmlevel", "1");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getSameMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getSameMax()) < 0) {
    //                    result.put("alarmlevel", "2");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getSeriousMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getSeriousMax()) < 0) {
    //                    result.put("alarmlevel", "3");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getCriticalMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getCriticalMax()) < 0) {
    //                    result.put("alarmlevel", "4");
    //                    result.put("isNormal", "0");
    //                } else {
    //                    result.put("isNormal", "1");//判定为正常
    //                }
    //            }
    //
    //        } else if ("infrared".equals(type)) {
    //            //温度 最高温度，最低温度（以逗号分隔）
    //            String highTemp = value.split(",")[0];  //最高温度
    //            double resultvalue = Double.parseDouble(highTemp);
    //            //String alarmlevel = "0";// '1:预警；2:一般；3:严重；4;危急',
    //            SubstationDevice device = deviceMapper.selectById(deviceid);
    //            if (ObjUtil.isEmpty(device.getEarlyMin()) || ObjUtil.isEmpty(device.getCriticalMax())) {
    //                //未设置上下限，判定为正常
    //                result.put("isNormal", "1");//判定为正常
    //            } else {
    //                if (NumberUtil.compare(resultvalue, device.getEarlyMin()) >= 0 && NumberUtil.compare(resultvalue,
    //                        device.getEarlyMax()) < 0) {
    //                    result.put("alarmlevel", "1");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getSameMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getSameMax()) < 0) {
    //                    result.put("alarmlevel", "2");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getSeriousMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getSeriousMax()) < 0) {
    //                    result.put("alarmlevel", "3");
    //                    result.put("isNormal", "0");
    //                } else if (NumberUtil.compare(resultvalue, device.getCriticalMin()) >= 0 && NumberUtil.compare
    //                (resultvalue,
    //                        device.getCriticalMax()) < 0) {
    //                    result.put("alarmlevel", "4");
    //                    result.put("isNormal", "0");
    //                } else {
    //                    //判定为正常
    //                    result.put("isNormal", "1");
    //                }
    //            }
    //
    //        } else if ("isolator".equals(type)) {
    //            //刀闸状态
    //            if ("1".equals(value)) {
    //                result.put("desc", "分");
    //                result.put("isNormal", "1");
    //            }
    //            if ("2".equals(value)) {
    //                result.put("desc", "合");
    //                result.put("isNormal", "1");
    //            }
    //            if ("3".equals(value)) {
    //                result.put("desc", "分位异常");
    //                result.put("isNormal", "0");
    //            }
    //            if ("4".equals(value)) {
    //                result.put("desc", "合位异常");
    //                result.put("isNormal", "0");
    //            }
    //
    //        } else if ("yjsk".equals(type)) {
    //            //刀闸状态
    //            if ("2".equals(value) || "4".equals(value)) {
    //                result.put("isNormal", "0");
    //            } else {
    //                result.put("isNormal", "1");
    //            }
    //        } else if ("sound".equals(type)) {//声音  1 代表正常声音，2 代表异常声音
    //            double resultvalue = Double.parseDouble(value);
    //            //String alarmlevel = "0";// '1:预警；2:一般；3:严重；4;危急',
    //            SubstationDevice device = deviceMapper.selectById(deviceid);
    //            if (ObjUtil.isEmpty(device.getEarlyMin()) || ObjUtil.isEmpty(device.getCriticalMax())) {
    //                //未设置上下限，判定为正常
    //                result.put("isNormal", "1");//判定为正常
    //            } else {
    //                if (NumberUtil.compare(resultvalue, device.getEarlyMin()) >= 0 && NumberUtil.compare(resultvalue,
    //                        device.getCriticalMax()) < 0) { //异常
    //                    result.put("isNormal", "0");//判定为异常
    //                    result.put("alarmtype", "7");//<7>: = 声音超限制
    //                    if (NumberUtil.compare(resultvalue, device.getEarlyMin()) >= 0 && NumberUtil.compare
    //                    (resultvalue,
    //                            device.getEarlyMax()) < 0) {
    //                        result.put("alarmlevel", "1");
    //                    } else if (NumberUtil.compare(resultvalue, device.getSameMin()) >= 0 && NumberUtil.compare
    //                    (resultvalue,
    //                            device.getSameMax()) < 0) {
    //                        result.put("alarmlevel", "2");
    //                    } else if (NumberUtil.compare(resultvalue, device.getSeriousMin()) >= 0 && NumberUtil
    //                    .compare(resultvalue,
    //                            device.getSeriousMax()) < 0) {
    //                        result.put("alarmlevel", "3");
    //                    } else if (NumberUtil.compare(resultvalue, device.getCriticalMin()) >= 0 && NumberUtil
    //                    .compare(resultvalue,
    //                            device.getCriticalMax()) < 0) {
    //                        result.put("alarmlevel", "4");
    //                    } else {
    //                        result.put("alarmlevel", "4");
    //                    }
    //                } else if (NumberUtil.compare(resultvalue, device.getCriticalMax()) > 0) {
    //                    result.put("isNormal", "0");//判定为异常
    //                    result.put("alarmtype", "5");//<5>: = 声音异常
    //                } else {
    //                    result.put("isNormal", "1");//判定为正常
    //                }
    //            }
    //
    //        } else if ("tx_pb".equals(type)) {
    //            //缺陷判别
    //            if ("1".equals(value)) {
    //                result.put("isNormal", "0");
    //            } else {
    //                result.put("isNormal", "1");
    //            }
    //        } else if ("light".equals(type)) {
    //            if ("red_on".equals(value)) {
    //                result.put("isNormal", "0");
    //            } else {
    //                result.put("isNormal", "1");
    //            }
    //        } else if ("switch".equals(type)) {
    //            //switch,light
    //            result.put("isNormal", "1");//正常
    //        } else if ("qrcode".equals(type)) {
    //            // 实物 ID
    //        } else {
    //            if ("1".equals(value)) {//外观缺陷
    //                if ("ws_ywzc".equals(type)
    //                        || "fhz_f".equals(type) || "fhz_h".equals(type)
    //                        || "kgg_ybf".equals(type) || "kgg_ybh".equals(type)
    //                        || "kk_f".equals(type) || "kk_h".equals(type)
    //                        || "zsd_l".equals(type) || "zsd_m".equals(type)
    //                        || "hxq_gjzc".equals(type) || "ywzt_yfzc".equals(type)
    //                        || "bjzc".equals(type) || "xmbhzc".equals(type)
    //                        || "gzzc".equals(type) || "aqmzc".equals(type)) {
    //                    result.put("isNormal", "1");//正常
    //                } else {
    //                    result.put("isNormal", "0");//异常
    //                    result.put("alarmtype", "6");//<6>: = 外观异常
    //                }
    //
    //            } else {
    //                result.put("isNormal", "1");//正常
    //            }
    //        }
    //        return result;
    //    }

    //根据识别类型和结果值判断是否为异常
    private Map<String, Object> judgeAbnormal(String type, String value, String desc, String deviceid,
                                              String resultId) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", "0");
        result.put("isNormal", "1");
        result.put("link_point", deviceid);
        if ("sound".equals(type)) {
            if ("2".equals(value)) {
                result.put("isNormal", "0");
                result.put("alarmtype", "5");
            }
            return result;
        }
        if ("yjsk".equals(type)) {
            if (!("1".equals(value) || "3".equals(value))) {
                result.put("isNormal", "0");
            }
            return result;
        }
        List<AlarmThreshold> list =
                alarmThresholdService.list(new LambdaQueryWrapper<AlarmThreshold>().eq(AlarmThreshold::getDeviceId,
                        deviceid));
        SubstationDevice substationDevice = deviceMapper.selectById(deviceid);
        TaskResult taskResult = taskResultMapper.selectById(resultId);
        String pictureAnalysisTypeList = substationDevice.getPictureAnalysisTypeList();
        JSONObject jsonObject = JSONUtil.parseObj(pictureAnalysisTypeList);
        String pictureDefectAnalysisType = jsonObject.getStr("PictureDefectAnalysisType");
        if (StrUtil.isNotBlank(pictureDefectAnalysisType)) {
            // 缺陷告警设置
            //            List<Map<String, Object>> mapList = sysDictionaryItemsService.getDeviceByType
            //            ("PictureDefectAnalysisType");
            if ("1".equals(value)) {
                result.put("isNormal", "0");
                result.put("alarmAnalysisType", "2");
            }
            return result;
        }
        String PictureDiscriminateAnalysisType = jsonObject.getStr("PictureDiscriminateAnalysisType");
        if (StrUtil.isNotBlank(PictureDiscriminateAnalysisType)) {
            if ("1".equals(value)) {
                result.put("isNormal", "0");
                result.put("type", "1");
                result.put("alarmAnalysisType", "3");
            }
            return result;
        }
        if (list.size() <= 0) {
            return result;
        }
        AlarmThreshold alarmThreshold = list.get(0);
        if ("0".equals(alarmThreshold.getIsenable())) {
            return result;
        }
        // 阈值类型或趋势类getStationInfo
        if ("1".equals(alarmThreshold.getAlarmClass()) || "3".equals(alarmThreshold.getAlarmClass())) {
            Map<String, String> map = alarmThresholdService.getThresholdInterval(alarmThreshold.getDeviceId());
            if (map == null) {
                return result;
            }
            String commonLower = map.get("commonLower");
            String commonUpper = map.get("commonUpper");
            String seriousLower = map.get("seriousLower");
            String seriousUpper = map.get("seriousUpper");
            String dangerLower = map.get("dangerLower");
            String dangerUpper = map.get("dangerUpper");
            List<String> valueList = StrUtil.split(value, ",");
            double resultvalue = Double.parseDouble(valueList.get(0));
            // 判断是否是非同源
            String patroldeviceJson = substationDevice.getPatroldeviceJson();
            if (JSONUtil.isTypeJSONArray(patroldeviceJson) && !"3".equals(alarmThreshold.getAlarmType()) && !"9".equals(alarmThreshold.getAlarmType())) {
                JSONArray jsonArray = JSONUtil.parseArray(patroldeviceJson);
                if (jsonArray.size() > 1) {
                    // 非同源告警
                    LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
                    //                    TaskTodo taskTodo = taskTodoService.getById(taskResult.getResultId());
                    queryWrapper.eq(TaskResult::getDeviceId, deviceid).eq(TaskResult::getTaskTodoId,
                            taskResult.getTaskTodoId()).eq(TaskResult::getFlag, "2").ne(TaskResult::getResultId,
                            resultId);
                    List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
                    Optional<TaskResult> maxDifferenceTaskResult =
                            taskResultList.stream().filter(t -> StrUtil.isNotBlank(t.getValue())).max(Comparator.comparingDouble(t -> Math.abs(NumberUtil.parseDouble(t.getValue()) - NumberUtil.parseDouble(value))));
                    if (maxDifferenceTaskResult.isPresent()) {
                        TaskResult oldResult = maxDifferenceTaskResult.get();
                        resultvalue = Math.abs(resultvalue - NumberUtil.parseDouble(oldResult.getValue()));
                        result.put("isSame", "1");
                        result.put("oldContent",
                                oldResult.getPatroldeviceName() + "设备识别结果为" + oldResult.getValue() + "，");
                    } else {
                        return result;
                    }
                }
//                if (jsonArray.size() == 1) {
//                    // 非同源告警
//                    LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
//                    queryWrapper.eq(TaskResult::getDeviceId, deviceid).eq(TaskResult::getTaskTodoId,
//                            taskResult.getTaskTodoId()).eq(TaskResult::getFlag, "2").ne(TaskResult::getResultId,
//                            resultId);
//                    List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
//                    //                    List<String> values = taskResultList.stream().filter(v->StrUtil.isNotBlank
//                    //                    (v.getValue())).map(TaskResult::getValue).collect(Collectors.toList());
//                    Optional<TaskResult> maxDifferenceTaskResult =
//                            taskResultList.stream().filter(t -> StrUtil.isNotBlank(t.getValue())).max(Comparator.comparingDouble(t -> Math.abs(NumberUtil.parseDouble(t.getValue()) - NumberUtil.parseDouble(value))));
//                    if (maxDifferenceTaskResult.isPresent()) {
//                        TaskResult oldResult = maxDifferenceTaskResult.get();
//                        resultvalue = Math.abs(resultvalue - NumberUtil.parseDouble(oldResult.getValue()));
//                        result.put("isSame", "1");
//                        result.put("oldContent",
//                                oldResult.getPatroldeviceName() + "设备识别结果为" + oldResult.getValue() + "，");
//                    } else {
//                        return result;
//                    }
//                }
            }
            // 三相温差告警、仪表三项对比
            if ("3".equals(alarmThreshold.getAlarmType()) || "9".equals(alarmThreshold.getAlarmType())) {
                // 获取到不同相位的最新数据
                List<TaskResult> nonCoherentResult =
                        taskResultMapper.getNonCoherentResult(taskResult.getAreaId(), taskResult.getBayId(),
                                taskResult.getMainDeviceId(), taskResult.getComponentId(),
                                taskResult.getRecognitionType(), substationDevice.getMeterType(),
                                taskResult.getResultId(), taskResult.getTaskTodoId(), taskResult.getPhase());
                taskResult.setValue(value);
                nonCoherentResult.add(taskResult);
                if (nonCoherentResult.size() < 3) {
                    return result;
                }
                List<String> values =
                        nonCoherentResult.stream().filter(n -> ObjectUtil.isNotEmpty(n.getValue())).map(TaskResult::getValue).collect(Collectors.toList());
                // 将字符串转换为Double并过滤无效数值
                List<Double> numericValues = values.stream()
                        .map(str -> {
                            try {
                                return Double.parseDouble(str);
                            } catch (NumberFormatException e) {
                                return null; // 或记录日志并跳过无效值
                            }
                        })
                        .filter(Objects::nonNull)
                        .collect(Collectors.toList());

                if (numericValues.isEmpty()) {
                    // 处理空值情况（根据业务需求选择返回0/抛出异常等）
                    resultvalue = 0.0;
                }

                // 使用数值列表计算最大最小值
                double max = Collections.max(numericValues);
                double min = Collections.min(numericValues);
                // 最大值减去最小值
                resultvalue = NumberUtil.sub(max, min);
                Map<String, String> phaseToValueMap = nonCoherentResult.stream()
                        .collect(Collectors.toMap(
                                TaskResult::getPhase,
                                TaskResult::getValue,
                                (existingValue, newValue) -> existingValue
                        ));
                String phaseA = phaseToValueMap.get("1");
                String phaseB = phaseToValueMap.get("2");
                String phaseC = phaseToValueMap.get("3");
                result.put("oldContent", "[A]相结果" + phaseA + "，" + "[B]相结果" + phaseB + "，" + "[C]相结果" + phaseC +
                        "，");
                result.put("isSame", "0");
            }

            if ("3".equals(alarmThreshold.getAlarmClass())) {
                // 对比趋势变化率
                if ("1".equals(alarmThreshold.getIsLastContrast())) {
                    LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TaskResult::getDeviceId, deviceid).ne(TaskResult::getValue, "").isNotNull(TaskResult::getPatroldeviceDate).isNotNull(TaskResult::getValue).lt(TaskResult::getPatroldeviceDate,
                            taskResult.getPatroldeviceDate()).orderByDesc(TaskResult::getPatroldeviceDate).last(
                            "limit 0," +
                                    "1");
                    List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
                    if (taskResultList.size() <= 0) {
                        return result;
                    }
                    TaskResult taskResultBase = taskResultList.get(0);
                    // 基准值
                    double baseValue = Double.parseDouble(taskResultBase.getValue());
                    resultvalue = Math.abs(resultvalue - baseValue) / baseValue * 100;
                    result.put("oldContent", "点位上次识别结果为" + baseValue + "，");
                } else {
                    // 基准值
                    double alarmValue = Double.parseDouble(alarmThreshold.getBaseValue());
                    resultvalue = Math.abs(resultvalue - alarmValue) / alarmValue * 100;
                    result.put("oldContent", "点位基准值为" + alarmValue + "，");
                }
            }

            if (StrUtil.isNotBlank(commonLower) && StrUtil.isNotBlank(commonUpper)) {
                if (NumberUtil.compare(resultvalue, Double.parseDouble(commonLower)) >= 0 && NumberUtil.compare(resultvalue,
                        Double.parseDouble(commonUpper)) < 0) {
                    result.put("alarmlevel", "1");
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                }
            }
            if (StrUtil.isNotBlank(seriousLower) && StrUtil.isNotBlank(seriousUpper)) {
                if (NumberUtil.compare(resultvalue, Double.parseDouble(seriousLower)) >= 0 && NumberUtil.compare(resultvalue,
                        Double.parseDouble(seriousUpper)) < 0) {
                    result.put("alarmlevel", "2");
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                }
            }
            if (StrUtil.isNotBlank(dangerLower) && StrUtil.isNotBlank(dangerUpper)) {
                if (NumberUtil.compare(resultvalue, Double.parseDouble(dangerLower)) >= 0 && NumberUtil.compare(resultvalue,
                        Double.parseDouble(dangerUpper)) < 0) {
                    result.put("alarmlevel", "3");
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                }
            }
            return result;
        }
        // 状态分析类型
        if ("2".equals(alarmThreshold.getAlarmClass())) {
            // 三相对比告警
            if ("4".equals(alarmThreshold.getAlarmType())) {
                // 获取到不同相位的最新数据
                List<TaskResult> nonCoherentResult =
                        taskResultMapper.getNonCoherentResult(taskResult.getAreaId(), taskResult.getBayId(),
                                taskResult.getMainDeviceId(), taskResult.getComponentId(),
                                taskResult.getRecognitionType(), substationDevice.getMeterType(),
                                taskResult.getResultId(), taskResult.getTaskTodoId(), taskResult.getPhase());
                taskResult.setValue(value);
                taskResult.setDesc(desc);
                nonCoherentResult.add(taskResult);
                if (nonCoherentResult.size() < 3) {
                    return result;
                }
                Set<String> values =
                        nonCoherentResult.stream().filter(n -> ObjectUtil.isNotEmpty(n.getValue()))
                                .map(TaskResult::getValue).collect(Collectors.toSet());
                //                values.add(value);
                // 如果三相任意一相不等于基准值判定为异常
                if (values.size() > 1) {
                    Set<String> ids =
                            nonCoherentResult.stream().filter(n -> ObjectUtil.isNotEmpty(n.getValue())).map(TaskResult::getDeviceId).collect(Collectors.toSet());
                    result.put("link_point", StrUtil.join(",", ids));
                    ids.add(deviceid);
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                    Map<String, String> phaseToValueMap = nonCoherentResult.stream()
                            .collect(Collectors.toMap(
                                    TaskResult::getPhase,
                                    TaskResult::getDesc,
                                    (existingValue, newValue) -> existingValue
                            ));
                    String phaseA = phaseToValueMap.get("1");
                    String phaseB = phaseToValueMap.get("2");
                    String phaseC = phaseToValueMap.get("3");
                    result.put("oldContent", "[A]相结果" + phaseA + "，" + "[B]相结果" + phaseB + "，" + "[C]相结果" + phaseC +
                            "，");
                    result.put("isSame", "0");
                }
                return result;
            }
            String patroldeviceJson = substationDevice.getPatroldeviceJson();
            if (JSONUtil.isTypeJSONArray(patroldeviceJson)) {
                JSONArray jsonArray = JSONUtil.parseArray(patroldeviceJson);
                if (jsonArray.size() > 1) {
                    // 非同源告警
                    LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(TaskResult::getDeviceId, deviceid).eq(TaskResult::getTaskTodoId,
                            taskResult.getTaskTodoId()).eq(TaskResult::getFlag, "2").ne(TaskResult::getResultId,
                            resultId);
                    List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
                    Optional<TaskResult> first =
                            taskResultList.stream().filter(f -> StrUtil.isNotBlank(f.getValue()) && !value.equals(f.getValue())).findFirst();
                    if (!first.isPresent()) {
                        return result;
                    }
                    TaskResult oldResult = first.get();
                    result.put("oldContent",
                            oldResult.getPatroldeviceName() + "设备识别结果为" + oldResult.getDesc() + "，");
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                    result.put("alarmlevel", "4");
                    result.put("isSame", "1");
                    return result;
                }
//                if (jsonArray.size() == 1) {
//                    // 非同源告警
//                    LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
//                    queryWrapper.eq(TaskResult::getDeviceId, deviceid).eq(TaskResult::getTaskTodoId,
//                            taskResult.getTaskTodoId()).eq(TaskResult::getFlag, "2").ne(TaskResult::getResultId,
//                            resultId);
//                    List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
//                    Optional<TaskResult> first =
//                            taskResultList.stream().filter(f -> StrUtil.isNotBlank(f.getValue()) && !value.equals(f.getValue())).findFirst();
//                    if (!first.isPresent()) {
//                        return result;
//                    }
//                    TaskResult oldResult = first.get();
//                    result.put("oldContent",
//                            oldResult.getPatroldeviceName() + "设备识别结果为" + oldResult.getDesc() + "，");
//                    result.put("isNormal", "0");
//                    result.put("alarmtype", alarmThreshold.getAlarmType());
//                    result.put("alarmlevel", "4");
//                    result.put("isSame", "1");
//                }

            }
            if ("1".equals(alarmThreshold.getIsLastContrast())) {
                LambdaQueryWrapper<TaskResult> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.ne(TaskResult::getResultId,resultId).eq(TaskResult::getDeviceId, deviceid).isNotNull(TaskResult::getPatroldeviceDate).lt(TaskResult::getPatroldeviceDate,
                        taskResult.getPatroldeviceDate()).orderByDesc(TaskResult::getPatroldeviceDate).last("limit 0," +
                        "1");
                List<TaskResult> taskResultList = taskResultMapper.selectList(queryWrapper);
                if (taskResultList.size() <= 0) {
                    return result;
                }
                TaskResult taskResultBase = taskResultList.get(0);
                // 基准值
                String baseValue = taskResultBase.getValue();
                if (!baseValue.equals(value)) {
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                    String oldValue = "fhz".equals(type) ? taskResultBase.getDesc() : baseValue;
                    result.put("oldContent", "点位上次识别结果为" + oldValue + "，");
                }
            } else {
                // 基准值
                String alarmValue = alarmThreshold.getBaseValue();
                if (!value.equals(alarmValue)) {
                    String oldValue = alarmValue;
                    result.put("isNormal", "0");
                    result.put("alarmtype", alarmThreshold.getAlarmType());
                    if ("fhz".equals(type)) {
                        if ("1".equals(alarmValue)) {
                            oldValue = "分合闸_分";
                        }
                        if ("2".equals(alarmValue)) {
                            oldValue = "分合闸_合";
                        }
                        if ("3".equals(alarmValue)) {
                            oldValue = "分合闸_状态异常";
                        }
                    }
                    result.put("oldContent", "点位基准值为" + oldValue + "，");
                }
            }
            return result;
        }
        return result;
    }

    /**********************************
     * 用途说明: 生成报警记录(点位)
     * 参数说明 taskResult
     * 参数说明 map
     * 返回值说明: boolean
     ***********************************/
    private boolean createTaskAlarmLog(TaskResult taskResult, Map<String, Object> map) throws UnsupportedEncodingException {
        log.info("===========================" + taskResult.toString());
        AlarmLog alarmLog = new AlarmLog();
        alarmLog.setId(IdUtil.fastSimpleUUID());
        String deviceid = taskResult.getDeviceId();
        SubstationDevice device = deviceMapper.selectById(deviceid);
        String alarmDate = DateUtil.now();
        Substation substation = stationMapper.selectOne(new LambdaQueryWrapper<Substation>().
                eq(Substation::getStationCode, device.getStationCode()));
        alarmLog.setStationCode(device.getStationCode());
        alarmLog.setStationId(substation.getStationId());
        alarmLog.setStationName(substation.getStationName());
        alarmLog.setAreaId(taskResult.getAreaId());
        alarmLog.setAreaName(taskResult.getAreaName());
        alarmLog.setBayId(taskResult.getBayId());
        alarmLog.setBayName(taskResult.getBayName());
        alarmLog.setMainDeviceId(taskResult.getMainDeviceId());
        alarmLog.setMainDeviceName(taskResult.getMainDeviceName());
        alarmLog.setComponentId(taskResult.getComponentId());
        alarmLog.setComponentName(taskResult.getComponentName());
        alarmLog.setDeviceId(taskResult.getDeviceId());
        alarmLog.setDeviceName(taskResult.getDeviceName());
        alarmLog.setAlarmSourceType("1");
        alarmLog.setPatroldeviceCode(taskResult.getPatroldeviceCode());
        alarmLog.setPatroldeviceName(taskResult.getPatroldeviceName());
        alarmLog.setMaterialId(taskResult.getMaterialId());
        TaskTodo taskTodo = taskTodoMapper.selectById(taskResult.getTaskTodoId());
        alarmLog.setTaskId(taskTodo.getTaskId());
        alarmLog.setTaskPatrolledId(taskResult.getTaskTodoId());
        alarmLog.setTaskResultId(taskResult.getResultId());
        alarmLog.setTaskCode(taskResult.getTaskCode());
        alarmLog.setTaskName(taskResult.getTaskName());
        alarmLog.setTaskAlarmType("1"); //'1:巡视任务告警；2:静默任务告警，3：巡视设备告警',
        //alarmLog.setMonitorType("");//非静默监视不填
        alarmLog.setAlarmType(ObjUtil.isNotEmpty(map.get("alarmtype")) ? map.get("alarmtype").toString() : "");//'字典表<1>: = 超温报警<2>: = 温升报警<3>: = 三相温差报警<4>: = 三相对比报警<5>: = 声音异常<6>: = 外观异常<7>: = 仪表越限报警<8>: = 仪表超量程报警<9>: = 仪表三相对比<10>: = 变位报警',
        alarmLog.setAlarmLevel(ObjUtil.isNotEmpty(map.get("alarmlevel")) ? map.get("alarmlevel").toString() : "3");// '1:预警；2:一般；3:严重；4;危急',  待判断细分
        alarmLog.setRecognitionType(taskResult.getRecognitionType());//'1:表计读取；2:位置状态识别；3:设备外观查看；4:红外测温；5:声音检测；6:闪烁检测11:局放超声波检测12:局放地电压检测13:局放特高频检测101:环境温度检测102:环境湿度检测103:氧气浓度检测104SF6浓度检测',
        alarmLog.setFileType(taskResult.getFileType());//'1:红外图谱；2:可见光照片；3:音频4:视频5:识别图片，存在多个文件，文件类型用逗号分隔',
        //告警文件目录规范：地市名/区域名/变电站名/分类/年月
        String type = "缺陷";//缺陷、判别
        String alarmfilepath = String.format("%s/%s/%s/%s/%s/",
                substation.getCityName(),
                substation.getSectionName(),
                substation.getStationName(),
                type,
                DateUtil.format(DateUtil.date(), "yyyyMM")
        );
        //拷贝原图到报警目录下
        String fullfilename = URLDecoder.decode(taskResult.getFilePath(), "utf-8");
        String alarmfullfilename = alarmfilepath + StrUtil.subAfter(fullfilename, "/", true);
        FileUtil.copy(Config.getSnapFilePath() + fullfilename, Config.getAlarmFilePath() + alarmfullfilename, true);
        alarmLog.setFilePath(URLEncoder.encode(alarmfullfilename, "utf-8"));//原图文件名称（含路径）
        alarmLog.setDefectType(taskResult.getValueType());//'缺陷类别'

        //拷贝识别图到报警目录下
        if (ObjUtil.isNotEmpty(taskResult.getDefectFilePath())) {
            if (!taskResult.getFilePath().equals(taskResult.getDefectFilePath())) {
                String fulldefectfilename = URLDecoder.decode(taskResult.getDefectFilePath(), "utf-8");
                String alarmfilename = StrUtil.replace(StrUtil.subAfter(fulldefectfilename, "/", true), "识别", "缺陷告警");
                String fullalarmfile = alarmfilepath + alarmfilename;
                FileUtil.copy(Config.getSnapFilePath() + fulldefectfilename, Config.getAlarmFilePath() + fullalarmfile,
                        true);
                alarmLog.setDefectFilePath(URLEncoder.encode(fullalarmfile, "utf-8"));//标注了识别框和信息
            } else {
                alarmLog.setDefectFilePath(alarmLog.getFilePath());//标注了识别框和信息
            }

        }
        alarmLog.setValue(taskResult.getValue());//图形识别结果（值）
        alarmLog.setUnit(taskResult.getUnit());
        String alarminfo = "";
        String value = taskResult.getValue();
        String unit = "";
        if (StrUtil.isNotBlank(taskResult.getUnit())) {
            unit = taskResult.getUnit();
        }
        List<AlarmThreshold> list =
                alarmThresholdService.list(new LambdaQueryWrapper<AlarmThreshold>().eq(AlarmThreshold::getDeviceId,
                        deviceid));
        String alarmDesc = "";
        if (list.size() > 0) {
            AlarmThreshold alarmThreshold = list.get(0);
            String alarmClass = "";
            if ("1".equals(alarmThreshold.getAlarmClass())) {
                alarmClass = "[阈值类]";
            }
            if ("2".equals(alarmThreshold.getAlarmClass())) {
                alarmClass = "[状态类]";
            }
            if ("3".equals(alarmThreshold.getAlarmClass())) {
                alarmClass = "[趋势类]";
            }
            if (ObjectUtil.isNotEmpty(map.get("isSame")) && "1".equals(map.get("isSame").toString())) {
                alarmDesc = "，" + alarmClass + "告警类型为：非同源告警";
            } else {
                List<SysDictionaryItems> itemsList = sysDictionaryItemsService.getDictItemByType("AlarmType",
                        alarmThreshold.getAlarmType());
                if (itemsList.size() == 1) {
                    SysDictionaryItems sysDictionaryItems = itemsList.get(0);

                    alarmDesc = "，" + alarmClass + "告警类型为：" + sysDictionaryItems.getDictName();
                }
            }
        }
        String oldContent = ObjectUtil.isEmpty(map.get("oldContent")) ? "" : map.get("oldContent").toString();
        if ("meter".equals(taskResult.getValueType()) || "partial".equals(taskResult.getValueType())) {
            alarminfo = String.format("%s-%s的%s%s，%s本次识别结果为%s%s，判定为[%s]异常", taskResult.getMainDeviceName(),
                    taskResult.getComponentName(), taskResult.getDeviceName(), alarmDesc, oldContent,
                    taskResult.getValue(),
                    unit, taskResult.getDesc());
        }
        if ("infrared".equals(taskResult.getValueType())) {
            alarminfo = String.format("%s-%s的%s%s，%s本次识别温度：%s单位：%s，判定为[%s]超限缺陷！", taskResult.getMainDeviceName(),
                    taskResult.getComponentName(), taskResult.getDeviceName(), alarmDesc, oldContent,
                    taskResult.getValue(),
                    unit, taskResult.getDesc());
        }
        if ("sound".equals(taskResult.getValueType())) {
            //            alarminfo = "声音检测异常,本次识别结果为[" + taskResult.getDesc() + "]";
            alarminfo = String.format("声音检测异常,%s本次识别结果为[%s]", taskResult.getDeviceName(), taskResult.getDesc());
        }
        String pictureAnalysisTypeList = device.getPictureAnalysisTypeList();
        if (StrUtil.isNotBlank(pictureAnalysisTypeList)) {
            JSONObject pictureAnalysisType = JSONUtil.parseObj(pictureAnalysisTypeList);
            if (StrUtil.isNotBlank(pictureAnalysisType.getStr("PictureDefectAnalysisType"))) {
                alarminfo = String.format("%s-%s的%s%s，%s本次识别结果为%s，判定为[%s]异常！", taskResult.getMainDeviceName(),
                        taskResult.getComponentName(), taskResult.getDeviceName(), alarmDesc, oldContent,
                        taskResult.getDesc(),
                        taskResult.getDesc());
            }
        }
        if (ObjectUtil.isNotEmpty(map.get("isSame")) && "0".equals(map.get("isSame").toString())) {
            alarminfo = String.format("%s-%s的%s%s，%s判定为三相对比异常！", taskResult.getMainDeviceName(),
                    taskResult.getComponentName(), taskResult.getDeviceName(), alarmDesc, oldContent);
        }
        if (StrUtil.isBlank(alarminfo)) {
            alarminfo = String.format("%s-%s的%s%s，%s本次识别结果为%s%s，判定为[%s]异常！", taskResult.getMainDeviceName(),
                    taskResult.getComponentName(), taskResult.getDeviceName(), alarmDesc, oldContent,
                    taskResult.getDesc(),
                    unit, taskResult.getDesc());
        }
        alarmLog.setContent(alarminfo);//告警描述信息
        alarmLog.setAlarmDate(alarmDate);//发送报警时间
        alarmLog.setCheckFlag("0");//'0:未核查；1:已审核；2.已修正'
        alarmLog.setRectangle(taskResult.getRectangle());//'格式：x1,y1,x2y2;x3,y3,x4,y4；多个报警框的左上角和右下角坐标'
        alarmLog.setDatastatus("1"); //初始创建
        alarmLog.setLastmodifier("系统创建");
        alarmLog.setLastmodifydate(new Timestamp(DateUtil.current()));
        this.save(alarmLog);//保存此报警数据
        LocalDateTime delayedAlarmDate = device.getDelayedAlarmDate();
        // 如果当前时间小于报警延迟时间则不报警
        if (delayedAlarmDate != null) {
            LocalDateTime parse = LocalDateTimeUtil.parse(alarmDate, "yyyy-MM-dd HH:mm:ss");
            if (!parse.isAfter(delayedAlarmDate)) {
                return true;
            }
        }
        Map<String, Object> logMap = BeanUtil.beanToMap(alarmLog);
        String stationId = alarmLog.getStationId();
        LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlarmLog::getDatastatus, "1").eq(AlarmLog::getStationId, stationId).eq(AlarmLog::getCheckFlag
                , 0);
        int count = this.count(queryWrapper);
        logMap.put("alarmCount", count);
        JSONObject jsonObject = new JSONObject(logMap);
        String stationCode = substation.getStationCode();
        SysOrganization sysOrganization =
                sysOrganizationMapper.selectOne(new LambdaUpdateWrapper<SysOrganization>().eq(SysOrganization::getOrgcode, stationCode));
        String parentid = sysOrganization.getParentid();
        jsonObject.putOpt("deviceid", jsonObject.getStr("deviceId"));
        //        if (ObjectUtil.isNotEmpty(map.get("patroldeviceCode")) && ObjectUtil.isNotEmpty(map.get(
        //                "patroldeviceChannelcode"))) {
        //            jsonObject.putOpt("channelId", map.get("patroldeviceChannelcode").toString());
        //            jsonObject.putOpt("deviceId", map.get("patroldeviceCode").toString());
        //        }
        jsonObject.putOpt("channelId", taskResult.getPatroldeviceChannelcode());
        jsonObject.putOpt("deviceId", taskResult.getPatroldeviceCode());
        // 告警阈值
        if (list.size() > 0) {
            Map<String, String> thresholdInterval = alarmThresholdService.getThresholdInterval(deviceid);
            jsonObject.putAll(thresholdInterval);
        }
        // 如果是站端则区域也需要发送告警
        if (!"0".equals(parentid)) {
            WebSocketServer.sendInfo(parentid, jsonObject.toString());
        }
        WebSocketServer.sendInfo("check_" + alarmLog.getStationId(), jsonObject.toString());
        WebSocketServer.sendInfo(stationId, jsonObject.toString());
        //        this.sendTaskData("62", "", alarmLog.getStationCode(), alarmData.toString());
        return true;
    }

    public void sendTaskData(String Type, String Command, String Code, String Items) {
        String xml = MyXmlUtil.getXml(httpServerConfig.getPatrolServerid(), parentConfig.getParentId(), Type
                , Command, Code, Items);
        MyMessageProtocol messageProtocol = new MyMessageProtocol();
        messageProtocol.setSenderSerialNo(BootSessionCache.getRequestSessionID());
        messageProtocol.setReceiverSerialNo(new Long(0L));
        messageProtocol.setSessionflag(0);
        messageProtocol.setXmllen(xml.getBytes(CharsetUtil.UTF_8).length);
        messageProtocol.setXmlcontent(xml.getBytes(CharsetUtil.UTF_8));
        if (BootNettyClientChannelCache.channelMapCache.size() > 0) {
            for (Map.Entry<String, BootNettyClientChannel> entry :
                    BootNettyClientChannelCache.channelMapCache.entrySet()) {
                BootNettyClientChannel bootNettyChannel = entry.getValue();
                if (bootNettyChannel != null && bootNettyChannel.getChannel().isOpen()) {
                    bootNettyChannel.getChannel().writeAndFlush(messageProtocol);
                } else {
                    BootNettyClientThread thread = new BootNettyClientThread(parentConfig.getParentIp(),
                            Integer.parseInt(parentConfig.getTcpPort()), parentConfig);
                    thread.start();
                }
            }
        } else {
            BootNettyClientThread thread = new BootNettyClientThread(parentConfig.getParentIp(),
                    Integer.parseInt(parentConfig.getTcpPort()), parentConfig);
            thread.start();
        }
    }

    /**********************************
     * 用途说明: 生成报警记录(静默)
     * 参数说明 jsonObject
     * 返回值说明: boolean
     ***********************************/
    @Override
    public boolean createAlarm(JSONObject jsonObject) throws Exception {
        JSONArray jsonArray = jsonObject.getJSONArray("resultList");
        if (jsonArray.size() > 0) {
            JSONObject jsonResult = jsonArray.getJSONObject(0);
            JSONArray results = jsonResult.getJSONArray("results");
            for (int i = 0; i < results.size(); i++) {
                JSONObject result = results.getJSONObject(i);
                if (result.getStr("type").equals("gzzc") || result.getStr("type").equals("aqmzc")) {
                    //工装和安全帽正常
                    continue;
                }
                //正确 2000  图像数据错误 2001  算法分析失败 2002
                String code = result.getStr("code");
                if ("2000".equals(code)) {
                    Thread.sleep(1500);//延迟1.5秒
                    AlarmLog alarmLog = new AlarmLog();
                    alarmLog.setAlarmSourceType("1");
                    alarmLog.setId(IdUtil.fastSimpleUUID());
                    //摄像机ID
                    String deviceid = jsonObject.getStr("requestId");
                    //摄像机信息
                    SubstationPatroldevice patroldevice = patroldeviceMapper.selectById(deviceid);
                    String alarmDate = DateUtil.now();
                    String monitorType = this.getSlienceType(result.getStr("type"));
                    LocalDateTime delayedAlarmDate = null;
                    String slienceParams = patroldevice.getSlienceParams();
                    if (StrUtil.isNotEmpty(slienceParams)) {
                        JSONArray slienceArray = JSONUtil.parseArray(slienceParams);
                        //获取报警时间判断是否报警
                        for (Object o : slienceArray) {
                            JSONObject silentData = JSONUtil.parseObj(o);
                            if (monitorType.equals(silentData.getStr("type"))) {
                                String delayedAlarmDateStr = silentData.getStr("delayed_alarm_date");
                                // 将日期转换成yyyy-MM-dd HH:mm:ss格式
                                delayedAlarmDate = LocalDateTimeUtil.parse(delayedAlarmDateStr,
                                        DatePattern.NORM_DATETIME_PATTERN);
                            }
                        }
                    }

                    Substation substation = stationMapper.selectOne(new LambdaQueryWrapper<Substation>().
                            eq(Substation::getStationCode, patroldevice.getStationCode()));
                    alarmLog.setStationCode(patroldevice.getStationCode());
                    alarmLog.setStationId(substation.getStationId());
                    alarmLog.setStationName(substation.getStationName());
                    alarmLog.setAreaId(patroldevice.getAreaId());
                    alarmLog.setAreaName(patroldevice.getAreaName());
                    alarmLog.setBayId("");
                    alarmLog.setBayName("");
                    alarmLog.setMainDeviceId("");
                    alarmLog.setMainDeviceName("");
                    alarmLog.setComponentId("");
                    alarmLog.setComponentName(patroldevice.getCustom2()); //监视位置
                    alarmLog.setDeviceId("");
                    alarmLog.setDeviceName(patroldevice.getCustom2());//静默监视点位
                    alarmLog.setPatroldeviceCode(patroldevice.getPatroldeviceCode());
                    alarmLog.setPatroldeviceName(patroldevice.getPatroldeviceName());
                    alarmLog.setTaskName(result.getStr("desc") + "静默监视");
                    alarmLog.setTaskAlarmType("2"); //'1:巡视任务告警；2:静默任务告警，3：巡视设备告警',
                    alarmLog.setMonitorType(result.getStr("type"));//监视类型
                    alarmLog.setAlarmType("");//'字典表<1>: = 超温报警<2>: = 温升报警<3>: = 三相温差报警<4>: = 三相对比报警<5>: = 声音异常<6>: =
                    // 外观异常<7>: = 仪表越限报警<8>: = 仪表超量程报警<9>: = 仪表三相对比<10>: = 变位报警',
                    alarmLog.setAlarmLevel("2");// '1:预警；2:一般；3:严重；4;危急',  待判断细分
                    alarmLog.setRecognitionType("");//'1:表计读取；2:位置状态识别；3:设备外观查看；4:红外测温；5:声音检测；6:闪烁检测11:局放超声波检测12
                    // :局放地电压检测13:局放特高频检测101:环境温度检测102:环境湿度检测103:氧气浓度检测104SF6浓度检测',
                    alarmLog.setFileType(patroldevice.getVideoMode());//'1:红外图谱；2:可见光照片；3:音频4:视频5:识别图片，存在多个文件，文件类型用逗号分隔',
                    //告警文件目录规范：地市名/区域名/变电站名/分类/年月
                    String type = "缺陷";//缺陷、判别
                    String alarmfilepath = String.format("%s/%s/%s/%s/%s/",
                            substation.getCityName(),
                            substation.getSectionName(),
                            substation.getStationName(),
                            type,
                            DateUtil.format(DateUtil.date(), "yyyyMM")
                    );
                    //文件命名格式为：日期_时间_间隔名_设备名_点位名_类型.jpg
//                    String alarmfilename = String.format("%s_%s_%s_%s_%s_%s.jpg",
//                            DateUtil.format(DateUtil.date(), "yyyyMMdd"),
//                            DateUtil.format(DateUtil.date(), "HHmmss"),
//                            patroldevice.getAreaName(),
//                            patroldevice.getPatroldeviceName(),
//                            patroldevice.getCustom2(),
//                            "原图"
//                    );
                    String alarmfilename = String.format("%s_%s_%s.jpg",
                            patroldevice.getPatroldeviceId(),
                            patroldevice.getPatroldeviceCode(),
                            DateUtil.format(DateUtil.date(), "yyyyMMddHHmmss")
                    );
                    String resImageUrl = result.getStr("resImagePath");
                    String fullfilename = URLDecoder.decode(resImageUrl.split("=")[1], "utf-8");
                    String alarmfullfilename = alarmfilepath + alarmfilename;

                    FileUtil.copy(Config.getSnapFilePath() + fullfilename,
                            Config.getAlarmFilePath() + alarmfullfilename, true);
                    alarmLog.setFilePath(URLEncoder.encode(alarmfullfilename, "utf-8"));//原图文件名称（含路径）

                    String markedfilename = StrUtil.replace(alarmfullfilename, ".jpg", "判别.jpg");
                    String markedfullfilename = Config.getAlarmFilePath() + markedfilename;
                    FileUtil.MarkImageRectangle(Config.getAlarmFilePath() + alarmfullfilename, result.getStr("pos"),
                            markedfullfilename);
                    //水印字体
                    Font font = new Font("微软雅黑", Font.PLAIN, 40);
                    //水印图片色彩
                    Color color1 = new Color(31, 183, 55);
                    FileUtil.addWaterMark(markedfullfilename, markedfullfilename, patroldevice.getCustom2(), 20, -40,
                            color1, font);
                    Color color2 = new Color(226, 7, 24);
                    String alertinfo =
                            result.getStr("desc") + "   " + "置信度:" + result.getStr("conf") + "   " + result.getStr(
                                    "time");
                    FileUtil.addWaterMark(markedfullfilename, markedfullfilename, alertinfo, 600, -40, color2, font);

                    alarmLog.setDefectFilePath(URLEncoder.encode(markedfilename, "utf-8"));//标注了识别框和信息
                    alarmLog.setDefectType(result.getStr("type"));//'缺陷类别'
                    alarmLog.setValue(result.getStr("value"));//图形识别结果（值）
                    alarmLog.setAlarmDate(alarmDate);//发送报警时间
                    String alarminfo = getTemplateContent(result.getStr("type"), substation.getStationName(),
                            patroldevice.getAreaName(), patroldevice.getPatroldeviceName(), alarmLog.getAlarmDate(),
                            result.getStr("conf"), result.getStr("desc"));
                    alarmLog.setContent(alarminfo);//告警描述信息
                    alarmLog.setCheckFlag("0");//'0:未核查；1:已审核；2.已修正'
                    alarmLog.setRectangle(JSONUtil.toJsonStr(result.getJSONArray("pos")));//'格式：x1,y1,x2y2;x3,y3,x4,
                    // y4；多个报警框的左上角和右下角坐标'
                    alarmLog.setDatastatus("1"); //初始创建
                    alarmLog.setLastmodifier("系统创建");
                    alarmLog.setLastmodifydate(new Timestamp(DateUtil.current()));
                    this.save(alarmLog);//保存此报警数据
                    // 如果当前时间小于报警延迟时间则不报警(zhengsl)
                    if (delayedAlarmDate != null) {
                        LocalDateTime parse = LocalDateTimeUtil.parse(alarmDate, "yyyy-MM-dd HH:mm:ss");
                        if (!parse.isAfter(delayedAlarmDate)) {
                            return true;
                        }
                    }
                    Map<String, Object> logMap = BeanUtil.beanToMap(alarmLog);
                    String stationId = alarmLog.getStationId();
                    LambdaQueryWrapper<AlarmLog> queryWrapper = new LambdaQueryWrapper<>();
                    queryWrapper.eq(AlarmLog::getDatastatus, "1").eq(AlarmLog::getStationId, stationId).eq(AlarmLog::getCheckFlag, 0);
                    int count = this.count(queryWrapper);
                    logMap.put("alarmCount", count);
                    JSONObject jsonObject1 = new JSONObject(logMap);
                    String stationCode = substation.getStationCode();
                    SysOrganization sysOrganization =
                            sysOrganizationMapper.selectOne(new LambdaUpdateWrapper<SysOrganization>().eq(SysOrganization::getOrgcode, stationCode));
                    String parentid = sysOrganization.getParentid();
                    String channelinfo = patroldevice.getChannelinfo();
                    if (StrUtil.isNotBlank(channelinfo)) {
                        JSONArray jsonArray1 = JSONUtil.parseArray(channelinfo);
                        for (int j = 0; j < jsonArray1.size(); j++) {
                            JSONObject channelData = jsonArray1.getJSONObject(j);
                            // channel_type 1：可见光 2：红外
                            if ("1".equals(channelData.getStr("channel_type"))) {
                                String fromDevice = channelData.getStr("from_device");
                                // 1：摄像机
                                if ("1".equals(fromDevice)) {
                                    jsonObject1.putOpt("deviceId", patroldevice.getInternationalId());
                                    jsonObject1.putOpt("channelId", channelData.getStr("channel_code"));
                                } else {
                                    // 2：来源录像机
                                    jsonObject1.putOpt("deviceId", channelData.getStr("recorder_code"));
                                    jsonObject1.putOpt("channelId", channelData.getStr("recorder_channelcode"));
                                }
                                break;
                            }
                        }

                    }
                    if (!"0".equals(parentid)) {
                        WebSocketServer.sendInfo(parentid, jsonObject1.toString());
                    }
                    WebSocketServer.sendInfo(stationId, jsonObject1.toString());
                    // 区域巡视主机生成告警数据时，主动向上级系统上报告警并接收响应消息。 郑顺利注释 ，暂时不用向主机发送消息
//                    JSONObject alarmData = new JSONObject();
//                    alarmData.set("patroldevice_name",alarmLog.getPatroldeviceName());
//                    alarmData.set("patroldevice_code",alarmLog.getPatroldeviceCode());
//                    alarmData.set("alarm_level",alarmLog.getAlarmLevel());
//                    alarmData.set("monitor_type",alarmLog.getMonitorType());
//                    alarmData.set("file_type",alarmLog.getFileType());
//                    alarmData.set("file_path",alarmLog.getFilePath());
//                    alarmData.set("time",alarmLog.getAlarmDate());
//                    alarmData.set("content",alarmLog.getContent());
//                    this.sendTaskData("63","",alarmLog.getStationCode(),alarmData.toString());
                }
            }

        }

        return true;
    }

    /**********************************
     * 用途说明: 获取模板内容
     * 参数说明
     * 返回值说明: java.lang.String
     ***********************************/
    private String getTemplateContent(String type, String stationName, String areaName, String patrolDeviceName,
                                      String time, String value, String desc) {
        String templateContent = "";
        switch (type) {
            // 未戴安全帽
            case "wcaqm":
                templateContent = alarmTemplateConfig.getHelmetCamera();
                break;
            // 未穿工装
            case "wcgz":
                templateContent = alarmTemplateConfig.getClothCamera();
                break;
            // 人员聚集、徘徊
            case "ryjjph":
                templateContent = alarmTemplateConfig.getIntensiveCamera();
                break;
            // 烟火
            case "hzyw":
                templateContent = alarmTemplateConfig.getFireCamera();
                break;
            // 渗漏油
            case "sly_dmyw":
                templateContent = alarmTemplateConfig.getLeakageCamera();
                break;
            // 人员进入
            case "person_enter":
                templateContent = alarmTemplateConfig.getpersonEnter();
                break;
            // 人员吸烟
            case "xy":
                templateContent = alarmTemplateConfig.getpersonSmoke();
                break;
        }
        if (StrUtil.isNotBlank(templateContent)) {
            return String.format(templateContent, stationName, areaName, patrolDeviceName, time, value, desc);
        } else {
            return "";
        }
    }

    /**********************************
     * 用途说明: 生成报警记录（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);
                    doAlarmAction(alarmLog);
                    WebSocketServer.sendInfo(alarmLog.getStationId(), JSONUtil.parseObj(alarmLog).toString());
                }
            }
        }
        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);
                            //  新增
                            alarmLogMapper.insert(alarmLog);
                            //TODO 邮件推送暂时删除了
                            WebSocketServer.sendInfo(alarmLog.getStationId(), JSONUtil.parseObj(alarmLog).toString());
                        }
                    }
                }
            }
        }
        log.info("-----------------------------告警创建完毕------------------------------------");

    }

    /**
     * 填充告警记录表
     *
     * @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.setDatastatus("1");
//        alarmLog.setLastmodifier(SecurityUtils.getCurrentUsername());
        alarmLog.setLastmodifier("admin");
        alarmLog.setLastmodifydate(new Timestamp(System.currentTimeMillis()));
        alarmLog.setTaskAlarmType("4");
        alarmLog.setId(IdUtil.fastSimpleUUID());
        // 创建 SimpleDateFormat 对象，指定日期格式
        if ("yx".equals(type)) {
            alarmLog.setNormalRange(signalDate.get("normalRange").toString());
            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.setMainDeviceId(signalDate.get("mainDeviceId").toString());
            alarmLog.setComponentId(signalDate.get("mainComponentId").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.setPatroldeviceCode(signalDate.get("deviceCode").toString());
            //告警设名称
            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("3");
            alarmLog.setAlarmClass("2");
            //2-设备报警
            alarmLog.setRegion(meterDevice.getRegion());
            //区域标识
        }
        if ("yc".equals(type)) {
            //变电站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.setMainDeviceId(signalDate.get("mainDeviceId").toString());
            alarmLog.setComponentId(signalDate.get("mainComponentId").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.setPatroldeviceCode(signalDate.get("deviceCode").toString());
            //告警信号id
            alarmLog.setDeviceId(signalDate.get("signalId").toString());
            //告警信号名称
            alarmLog.setDeviceName(signalDate.get("signalName").toString());
            //告警类型
            alarmLog.setFkAlarmType(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("signalName").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);

    }

}
