package com.zd.laboratory.service.impl;

import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSONArray;
import com.zd.common.core.constant.Constants;
import com.zd.common.core.domain.R;
import com.zd.common.core.enums.HardwareTypeEnum;
import com.zd.common.core.enums.SenseType;
import com.zd.common.core.enums.WarnMessageTypeEnum;
import com.zd.common.core.exception.ServiceException;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.core.web.domain.ResultData;
import com.zd.common.redis.service.RedisService;
import com.zd.common.security.service.TokenService;
import com.zd.laboratory.config.HardwareFunctionStatusConfig;
import com.zd.laboratory.domain.*;
import com.zd.laboratory.domain.dto.LabRiskPlanDTO;
import com.zd.laboratory.domain.vo.LabRiskPlanAbnormalGroupVO;
import com.zd.laboratory.domain.vo.LabRiskPlanVO;
import com.zd.laboratory.domain.vo.LabRiskPlanjoinsubVO;
import com.zd.laboratory.mapper.*;
import com.zd.laboratory.mqtt.enums.BigViewDataType;
import com.zd.laboratory.mqtt.service.impl.SubMessageSendManager;
import com.zd.laboratory.service.ILabMessageContentService;
import com.zd.laboratory.service.ILabOperateHardwareService;
import com.zd.laboratory.service.ILabRiskPlanService;
import com.zd.laboratory.socket.command.Symbol;
import com.zd.system.api.domain.ParamVo;
import com.zd.system.api.domain.PlayVo;
import com.zd.system.api.domain.SysUser;
import com.zd.system.api.laboratory.domain.FunctionStatus;
import com.zd.system.api.laboratory.domain.LabMessageContent;
import com.zd.system.api.laboratory.domain.SensorFunctionStatus;
import com.zd.system.api.laboratory.domain.vo.SubFunction;
import com.zd.system.api.speak.RemoteSpeakService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 风险预案Service业务层处理
 *
 * @author liubo
 * @date 2021-09-03
 */
@Service
public class LabRiskPlanServiceImpl implements ILabRiskPlanService {
    @Autowired
    private LabRiskPlanMapper labRiskPlanMapper;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private LabRiskPlanHardwareRelationMapper labRiskPlanHardwareRelationMapper;
    @Autowired
    private LabRiskPlanSensorRelationMapper labRiskPlanSensorRelationMapper;
    @Autowired
    private ILabOperateHardwareService labOperateHardwareService;
    @Autowired
    private LabRiskPlanAbnormalLogMapper labRiskPlanAbnormalLogMapper;
    @Autowired
    private LabSubjectMapper labSubjectMapper;
    @Autowired
    private LabRiskPlanAbnormalGroupMapper labRiskPlanAbnormalGroupMapper;
    @Autowired
    private LabSensorMapper labSensorMapper;
    @Autowired
    private SubMessageSendManager messageSendService;
    @Autowired
    private LabWarnPushMessageMapper labWarnPushMessageMapper;
    @Autowired
    public HardwareFunctionStatusConfig hardwareFunctionStatusConfig;
    @Autowired
    private LabSubjectManagerService labSubjectManagerService;
    @Autowired
    private LabHardwareMapper labHardwareMapper;
    @Autowired
    LabSubjectManagerService subjectManagerService;
    @Autowired
    ILabMessageContentService labMessageContentService;

    @Autowired
    RedisService redisService;

    @Autowired
    LabRiskPlanjoinsubMapper labRiskPlanjoinsubMapper;

    @Autowired
    LabRiskPlanDistributionMapper labRiskPlanDistributionMapper;

    @Autowired
    private LabNoticeconfigMapper labNoticeconfigMapper;

    @Autowired
    private RemoteSpeakService remoteSpeakService;

    @Autowired
    private LabAudioSynthesisMapper labAudioSynthesisMapper;

    private static final Logger log = LoggerFactory.getLogger(LabRiskPlanServiceImpl.class);


    /**
     * 查询风险预案
     *
     * @param id 风险预案主键
     * @return 风险预案
     */
    @Override
    public LabRiskPlan selectLabRiskPlanById(Long id) {
        LabRiskPlan labRiskPlan = labRiskPlanMapper.selectLabRiskPlanById(id);
        final Map<SenseType, List<SensorFunctionStatus>> sensorFunctionStatusListMap = hardwareFunctionStatusConfig.getSensorFunctionStatusListMap();
        final Map<HardwareTypeEnum, List<FunctionStatus>> functionStatusListMap = hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
        for(LabRiskPlanSensorRelation sensorRelation:labRiskPlan.getRiskPlanSensorList()){
            for(Map.Entry<SenseType, List<SensorFunctionStatus>> entry :sensorFunctionStatusListMap.entrySet()){
                for(SensorFunctionStatus sensor:entry.getValue()){
                    if(sensor.getFunNum().equals(sensorRelation.getFunNum()) && !entry.getKey().equals(SenseType.TEMPERATURE_AND_HUMIDITY)){
                        sensorRelation.setDescribe(sensor.getDescribe());
                    }
                }
            }
        }

        for(LabRiskPlanHardwareRelation hardwareRelation:labRiskPlan.getRiskPlanHardwareList()){
            for(Map.Entry<HardwareTypeEnum, List<FunctionStatus>> entry :functionStatusListMap.entrySet()){
                if(hardwareRelation.getHardwareType().equals(entry.getKey().getCode())){
                    hardwareRelation.setHardwareTypeName(entry.getKey().getName());
                }
                for(FunctionStatus functionStatus:entry.getValue()){
                    if(functionStatus.getCode().equals(hardwareRelation.getOperate())){
                        hardwareRelation.setOperateName(functionStatus.getDescribe());
                    }
                }
                for(FunctionStatus functionStatus:entry.getValue()){
                    if(functionStatus.getCode().equals(hardwareRelation.getOverAct())){
                        hardwareRelation.setOperateName(functionStatus.getDescribe());
                    }
                }
            }
        }

        return labRiskPlan;
    }

    /**
     * 查询风险预案列表
     *
     * @param labRiskPlan 风险预案
     * @return 风险预案
     */
    @Override
    public List<LabRiskPlan> selectLabRiskPlanList(LabRiskPlan labRiskPlan) {
        return labRiskPlanMapper.selectLabRiskPlanList(labRiskPlan);
    }

    /**
     * 新增风险预案
     *
     * @param labRiskPlan 风险预案
     * @return 结果
     */
    @Override
    @Transactional
    public void insertLabRiskPlan(LabRiskPlan labRiskPlan) {
        SysUser user = tokenService.getLoginUser().getSysUser();
        labRiskPlan.setUserId(user.getUserId());
        labRiskPlan.setCreateBy(user.getNickName());
        labRiskPlan.setDeptId(user.getDeptId());
        labRiskPlan.setDeptName(user.getDeptName());
        labRiskPlan.setCreateTime(DateUtils.getNowDate());
        labRiskPlan.setUpdateTime(DateUtils.getNowDate());
        labRiskPlanMapper.insertLabRiskPlan(labRiskPlan);

        insertOrUpdateRelation(labRiskPlan);

    }

    /**
     * 获取预案关联实验室信息
     *
     * @param labRiskPlan 风险预案
     * @return 结果
     */
    @Override
    public  Map<String,Object> getLabRiskPlanJoinSub(LabRiskPlan labRiskPlan) {
        List<LabRiskPlanjoinsub> labRiskPlanjoinsubList = labRiskPlan.getLabRiskPlanjoinsubList();
        LabRiskPlan newLabRiskPlan=labRiskPlanMapper.selectLabRiskPlanById(labRiskPlan.getId());
        newLabRiskPlan.setLabRiskPlanjoinsubList(labRiskPlanjoinsubList);
        Map<String,Object> resultStr = getLabRiskPlanRepeat(newLabRiskPlan);
//        LabRiskPlanjoinsubVO labRiskPlanjoinsubVO = new LabRiskPlanjoinsubVO();
//        labRiskPlanjoinsubVO.setRiskPlanId(labRiskPlan.getId());
//        Optional.ofNullable(labRiskPlan.getLabRiskPlanjoinsubList()).orElseGet(Collections::emptyList)
//                .stream().forEach(a->{
//            labRiskPlanjoinsubVO.getSubIds().add(a.getSubjectId());
//        });
//        List<LabRiskPlanjoinsubVO> riskPlanjoinsubVOList = labRiskPlanjoinsubMapper.getPlanjoinsubNoRiskList(labRiskPlanjoinsubVO);
//
//        Map<String,Object> resultStr = new HashMap<>();
//        StringBuffer tipsStr = new StringBuffer();
//        if(riskPlanjoinsubVOList.size()>0){
//            Optional.ofNullable(riskPlanjoinsubVOList).orElseGet(Collections::emptyList)
//                    .stream().forEach(a->{
//                tipsStr.append(","+a.getSubName());
//            });
//            resultStr.put("tipsStr",tipsStr.substring(1)+"实验室已经关联了预案，是否绑定到当前预案");
//            resultStr.put("riskPlanjoinsubList",riskPlanjoinsubVOList);
//            resultStr.put("repeat",true);
//        }else{
//            resultStr.put("tipsStr","");
//            resultStr.put("riskPlanjoinsubList","");
//            resultStr.put("repeat",false);
//        }
        return resultStr;
    }


    /**
     * 预案关联实验室提交
     *
     * @param labRiskPlan 风险预案
     * @return 结果
     */
    @Override
    @Transactional
    public void riskPlanJoinSub(LabRiskPlan labRiskPlan) {
        List<LabRiskPlanjoinsub> labRiskPlanjoinsubList = labRiskPlan.getLabRiskPlanjoinsubList();
        LabRiskPlan newLabRiskPlan=labRiskPlanMapper.selectLabRiskPlanById(labRiskPlan.getId());
        newLabRiskPlan.setLabRiskPlanjoinsubList(labRiskPlanjoinsubList);
        newLabRiskPlan.setJoinSubOper(labRiskPlan.getJoinSubOper());
        newLabRiskPlan.setYesOrNo(labRiskPlan.getYesOrNo());
        bindSubRelation(newLabRiskPlan);
//        labRiskPlanjoinsubMapper.deleteByPlanjoinsubId(labRiskPlan.getId());
//        Optional.ofNullable(labRiskPlan.getLabRiskPlanjoinsubList()).orElseGet(Collections::emptyList)
//                    .stream().forEach(a->{
//                LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
//                labRiskPlanjoinsub.setJoinStatus(a.getJoinStatus());
//                labRiskPlanjoinsub.setSubjectId(a.getSubjectId());
//                labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
//                labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                labRiskPlanjoinsub.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                labRiskPlanjoinsub.setCreateTime(DateUtils.getNowDate());
//                labRiskPlanjoinsubMapper.insertLabRiskPlanjoinsub(labRiskPlanjoinsub);
//                //插入分配记录日志信息
//                LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
//                labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
//                labRiskPlanDistribution.setSubId(a.getSubjectId());
//                labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
//                labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                labRiskPlanDistribution.setDistrStatus(1L);
//                labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
//                labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
//        });
//        Map<String,Object> riskPlanMap = getLabRiskPlanJoinSub(labRiskPlan);
//        Map<Long,Long> subIdsMap = new HashMap<>();
//        if(labRiskPlan.getYesOrNo()){
//            if(Boolean.parseBoolean(riskPlanMap.get("repeat")+"")){
//                List<LabRiskPlanjoinsubVO> planJoinSubList = (List <LabRiskPlanjoinsubVO>) riskPlanMap.get("riskPlanjoinsubList");
//                Optional.ofNullable(planJoinSubList).orElseGet(Collections::emptyList).stream()
//                        .forEach(a->{
//                            labRiskPlanjoinsubMapper.deleteLabRiskPlanjoinsubById(a.getId());
//                            subIdsMap.put(a.getSubjectId(),a.getSubjectId());
//                        });
//            }
//            Optional.ofNullable(labRiskPlan.getLabRiskPlanjoinsubList()).orElseGet(Collections::emptyList)
//                    .stream().forEach(a->{
//                LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
//                labRiskPlanjoinsub.setJoinStatus(a.getJoinStatus());
//                labRiskPlanjoinsub.setSubjectId(a.getSubjectId());
//                labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
//                labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                labRiskPlanjoinsub.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                labRiskPlanjoinsub.setCreateTime(DateUtils.getNowDate());
//                labRiskPlanjoinsubMapper.insertLabRiskPlanjoinsub(labRiskPlanjoinsub);
//
//                //插入分配记录日志信息
//                LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
//                labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
//                labRiskPlanDistribution.setSubId(a.getSubjectId());
//                labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
//                labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                if(subIdsMap.get(a.getSubjectId())!=null){
//                    labRiskPlanDistribution.setDistrStatus(1L);
//                    labRiskPlanDistribution.setRemark("创建的预案替换相同启动条件的预案");
//                }else{
//                    labRiskPlanDistribution.setDistrStatus(1L);
//                }
//
//                labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
//                labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
//
//            });
//        }else{
//            if(Boolean.parseBoolean(riskPlanMap.get("repeat")+"")){
//                List<LabRiskPlanjoinsubVO> planJoinSubList = (List <LabRiskPlanjoinsubVO>) riskPlanMap.get("riskPlanjoinsubList");
//                Optional.ofNullable(planJoinSubList).orElseGet(Collections::emptyList).stream()
//                        .forEach(a->{
//                            subIdsMap.put(a.getSubjectId(),a.getSubjectId());
//                        });
//            }
//            Optional.ofNullable(labRiskPlan.getLabRiskPlanjoinsubList()).orElseGet(Collections::emptyList)
//                    .stream().forEach(a->{
//                if(subIdsMap.get(a.getSubjectId())==null){
//                    LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
//                    labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
//                    labRiskPlanjoinsub.setSubjectId(a.getSubjectId());
//                    labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                    labRiskPlanjoinsub.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                    labRiskPlanjoinsub.setCreateTime(DateUtils.getNowDate());
//                    labRiskPlanjoinsubMapper.insertLabRiskPlanjoinsub(labRiskPlanjoinsub);
//
//                    //插入分配记录日志信息
//                    LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
//                    labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
//                    labRiskPlanDistribution.setSubId(a.getSubjectId());
//                    labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
//                    labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                    labRiskPlanDistribution.setDistrStatus(1L);
//                    labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
//                    labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                    labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
//                }else{
//                    //插入分配记录日志信息
//                    LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
//                    labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
//                    labRiskPlanDistribution.setSubId(a.getSubjectId());
//                    labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
//                    labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
//                    labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
//                    labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
//                    labRiskPlanDistribution.setDistrStatus(2L);
//                    labRiskPlanDistribution.setRemark("实验室存在启动条件相同的预案");
//                    labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
//                }
//            });
//        }
    }


    /**
     * 校验实验室关联的预案是否有重合的，如果有，需要提示，没有就放过
     *
     * @param labRiskPlan 风险预案
     * @return 结果
     */
    @Override
    public  Map<String,Object> getLabRiskPlanRepeat(LabRiskPlan labRiskPlan) {
        SysUser user = tokenService.getLoginUser().getSysUser();
        //获取页面传感器列表
        List<LabRiskPlanSensorRelation> newRiskPlanSesorList = new ArrayList<>();
        List<LabRiskPlanSensorRelation> labRiskPlanSensorRelationList = labRiskPlan.getRiskPlanSensorList();
        LabRiskPlanSensorRelation labRiskPlanSensorRelation = new LabRiskPlanSensorRelation();
        labRiskPlanSensorRelation.setRiskPlanId(labRiskPlan.getId());
        List<LabRiskPlanSensorRelation> sensorRelationList = labRiskPlanSensorRelationMapper.selectLabRiskPlanSensorRelationListNoSelf(labRiskPlanSensorRelation);
        LinkedHashMap<Long, List<LabRiskPlanSensorRelation>> collect = Optional.ofNullable(sensorRelationList).orElseGet(Collections::emptyList).stream()
                .collect(Collectors.groupingBy(LabRiskPlanSensorRelation::getRiskPlanId,LinkedHashMap::new,Collectors.toList()));
        collect.forEach((key,value)->{
            Integer setCount = 0;
            for(LabRiskPlanSensorRelation sensorRelation:value){
                for(LabRiskPlanSensorRelation newSensor:labRiskPlanSensorRelationList){
                    if(sensorRelation.getFunNum().equals(newSensor.getFunNum())){
                        if(newSensor.getMinMonitor().floatValue()>=sensorRelation.getMinMonitor().floatValue() && newSensor.getMinMonitor().floatValue()<=sensorRelation.getMaxMonitor().floatValue()){
                            setCount++;
                        }else if(newSensor.getMaxMonitor().floatValue()>=sensorRelation.getMinMonitor().floatValue() && newSensor.getMaxMonitor().floatValue()<=sensorRelation.getMaxMonitor().floatValue()){
                            setCount++;
                        }
                    }
                }
                if(setCount==labRiskPlanSensorRelationList.size() && labRiskPlanSensorRelationList.size()==value.size() && labRiskPlanSensorRelationList.size()!=0){
                    newRiskPlanSesorList.add(sensorRelation);
                }
            }
        });
//        Optional.ofNullable(sensorRelationList).orElseGet(Collections::emptyList).stream()
//                .forEach(a->Optional.ofNullable(labRiskPlanSensorRelationList)
//                .orElseGet(Collections::emptyList).stream().forEach(b->{
//                            if(a.getFunNum().equals(b.getFunNum())){
//                                if(b.getMinMonitor().floatValue()>=a.getMinMonitor().floatValue() && b.getMinMonitor().floatValue()<=a.getMaxMonitor().floatValue()){
//                                    newRiskPlanSesorList.add(a);
//                                }else if(b.getMaxMonitor().floatValue()>=a.getMinMonitor().floatValue() && b.getMaxMonitor().floatValue()<=a.getMaxMonitor().floatValue()){
//                                    newRiskPlanSesorList.add(a);
//                                }
//                            }
//                        }));
        //根据预案id和实验室id查询当前用户是否有冲突的预案
        List<LabRiskPlanjoinsub> labRiskPlanjoinsubList = labRiskPlan.getLabRiskPlanjoinsubList();
        List<LabRiskPlanjoinsubVO> riskPlanjoinsubList = new ArrayList<>();
        Optional.ofNullable(labRiskPlanjoinsubList).orElseGet(Collections::emptyList)
                .stream().forEach(a->{
            LabRiskPlanjoinsubVO labRiskPlanjoinsubVO = new LabRiskPlanjoinsubVO();
            labRiskPlanjoinsubVO.setSubjectId(a.getSubjectId());
            for(int i=0;i<newRiskPlanSesorList.size();i++){
                labRiskPlanjoinsubVO.getRiskPlanIds().add(newRiskPlanSesorList.get(i).getRiskPlanId());
            }
            if(labRiskPlanjoinsubVO.getRiskPlanIds().size()>0){
                riskPlanjoinsubList.addAll(labRiskPlanjoinsubMapper.getLabRiskPlanjoinsubList(labRiskPlanjoinsubVO));
            }
        });
        Map<String,Object> resultStr = new HashMap<>();
        StringBuffer tipsStr = new StringBuffer();
        if(riskPlanjoinsubList.size()>0){
            Optional.ofNullable(riskPlanjoinsubList).orElseGet(Collections::emptyList)
                    .stream().forEach(a->{
                tipsStr.append(","+a.getSubName());
            });
            resultStr.put("tipsStr",tipsStr.substring(1)+"实验室已经关联了预案，是否绑定到当前预案");
            resultStr.put("riskPlanjoinsubList",riskPlanjoinsubList);
            resultStr.put("repeat",true);
        }else{
            resultStr.put("tipsStr","");
            resultStr.put("riskPlanjoinsubList","");
            resultStr.put("repeat",false);
        }
        return resultStr;
    }

    /**
     * 修改风险预案
     *
     * @param labRiskPlan 风险预案
     * @return 结果
     */
    @Override
    @Transactional
    public int updateLabRiskPlan(LabRiskPlan labRiskPlan) {

        SysUser user = tokenService.getLoginUser().getSysUser();
        labRiskPlan.setUpdateBy(user.getNickName());
        labRiskPlan.setUpdateTime(DateUtils.getNowDate());
        int num = labRiskPlanMapper.updateLabRiskPlan(labRiskPlan);
        if (num == 0) {
            throw new ServiceException("修改失败，未查询到数据，请刷新重试！");
        }

        insertOrUpdateRelation(labRiskPlan);

        return num;
    }

    private void insertOrUpdateRelation(LabRiskPlan labRiskPlan) {
        List<LabRiskPlanHardwareRelation> labRiskPlanRiskPlanHardwareList = labRiskPlan.getRiskPlanHardwareList();
        /*if(CollectionUtils.isEmpty(labRiskPlanRiskPlanHardwareList)) {
            throw new ServiceException("硬件不能为空！");
        }*/

        List<LabRiskPlanSensorRelation> labRiskPlanSensorRelationList = labRiskPlan.getRiskPlanSensorList();
        if(CollectionUtils.isEmpty(labRiskPlanSensorRelationList)) {
            throw new ServiceException("传感器不能为空！");
        }

        // 先删除
        labRiskPlanHardwareRelationMapper.deleteByPlanId(labRiskPlan.getId());

        if (CollectionUtils.isNotEmpty(labRiskPlanRiskPlanHardwareList)) {
            for (LabRiskPlanHardwareRelation labRiskPlanHardwareRelation : labRiskPlanRiskPlanHardwareList) {
                if (labRiskPlanHardwareRelation.getHardwareType() == null) {
                    throw new ServiceException("硬件不能为空！");
                }
                labRiskPlanHardwareRelation.setId(null);
                labRiskPlanHardwareRelation.setRiskPlanId(labRiskPlan.getId());
                labRiskPlanHardwareRelation.setCreateTime(DateUtils.getNowDate());
            }
            labRiskPlanHardwareRelationMapper.insertOrUpdateLabRiskPlanHardwareRelation(labRiskPlanRiskPlanHardwareList);
        }

        // 先删除
        labRiskPlanSensorRelationMapper.deleteByPlanId(labRiskPlan.getId());

        if (CollectionUtils.isNotEmpty(labRiskPlanSensorRelationList)) {
            for (LabRiskPlanSensorRelation labRiskPlanSensorRelation : labRiskPlanSensorRelationList) {
                if (labRiskPlanSensorRelation.getFunNum() == null) {
                    throw new ServiceException("传感器不能为空！");
                }
                labRiskPlanSensorRelation.setId(null);
                labRiskPlanSensorRelation.setRiskPlanId(labRiskPlan.getId());
                labRiskPlanSensorRelation.setCreateTime(DateUtils.getNowDate());
            }
            labRiskPlanSensorRelationMapper.insertOrUpdateLabRiskPlanSensorRelation(labRiskPlanSensorRelationList);
        }

        //绑定实验室关系
        bindSubRelation(labRiskPlan);


    }

    private void bindSubRelation(LabRiskPlan labRiskPlan){
        if(labRiskPlan.getJoinSubOper()){
            if(labRiskPlan.getYesOrNo()){

                if(labRiskPlan.getId()!=null){
                    LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
                    labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
                    labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                    labRiskPlanjoinsubMapper.deleteByPlanjoinsub(labRiskPlanjoinsub);
                }
                Map<Long,Long> subIdsMap = new HashMap<>();
                //这里需要判断，传感器是否有重叠数据
                Map<String,Object> repeatMap = getLabRiskPlanRepeat(labRiskPlan);

                if(Boolean.parseBoolean(repeatMap.get("repeat")+"")){
                    List<LabRiskPlanjoinsub> planJoinSubList = (List <LabRiskPlanjoinsub>) repeatMap.get("riskPlanjoinsubList");
                    Optional.ofNullable(planJoinSubList).orElseGet(Collections::emptyList).stream()
                            .forEach(a->{
                                labRiskPlanjoinsubMapper.deleteLabRiskPlanjoinsubById(a.getId());
                                subIdsMap.put(a.getSubjectId(),a.getSubjectId());
                            });

                }


                //建立预案和实验室的关联数据
                List<LabRiskPlanjoinsub> labRiskPlanjoinsubList = labRiskPlan.getLabRiskPlanjoinsubList();
                Optional.ofNullable(labRiskPlanjoinsubList).orElseGet(Collections::emptyList).stream()
                        .forEach(a->{
                            LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
                            labRiskPlanjoinsub.setJoinStatus(a.getJoinStatus());
                            labRiskPlanjoinsub.setSubjectId(a.getSubjectId());
                            labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
                            labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                            labRiskPlanjoinsub.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
                            labRiskPlanjoinsub.setCreateTime(DateUtils.getNowDate());
                            labRiskPlanjoinsubMapper.insertLabRiskPlanjoinsub(labRiskPlanjoinsub);

                            //插入分配记录日志信息
                            LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
                            labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
                            labRiskPlanDistribution.setSubId(a.getSubjectId());
                            labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
                            labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                            if(subIdsMap.get(a.getSubjectId())!=null){
                                labRiskPlanDistribution.setDistrStatus(1L);
                                labRiskPlanDistribution.setRemark("创建的预案替换相同启动条件的预案");
                            }else{
                                labRiskPlanDistribution.setDistrStatus(1L);
                            }

                            labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
                            labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
                            labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
                        });
            }else{
                if(labRiskPlan.getId()!=null){
                    LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
                    labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
                    labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                    labRiskPlanjoinsubMapper.deleteByPlanjoinsub(labRiskPlanjoinsub);
                }
                //这里需要判断，传感器是否有重叠数据
                Map<String,Object> repeatMap = getLabRiskPlanRepeat(labRiskPlan);
                Map<Long,Long> subIdsMap = new HashMap<>();
                if(Boolean.parseBoolean(repeatMap.get("repeat")+"")){
                    List<LabRiskPlanjoinsub> planJoinSubList = (List <LabRiskPlanjoinsub>) repeatMap.get("riskPlanjoinsubList");
                    Optional.ofNullable(planJoinSubList).orElseGet(Collections::emptyList).stream()
                            .forEach(a->{
                                subIdsMap.put(a.getSubjectId(),a.getSubjectId());
                            });
                }

                //建立预案和实验室的关联数据
                List<LabRiskPlanjoinsub> labRiskPlanjoinsubList = labRiskPlan.getLabRiskPlanjoinsubList();
                Optional.ofNullable(labRiskPlanjoinsubList).orElseGet(Collections::emptyList).stream()
                        .forEach(a->{
                            if(subIdsMap.get(a.getSubjectId())!=null){
                                //插入分配记录日志信息
                                LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
                                labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
                                labRiskPlanDistribution.setSubId(a.getSubjectId());
                                labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
                                labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                                labRiskPlanDistribution.setDistrStatus(2L);
                                labRiskPlanDistribution.setRemark("实验室存在启动条件相同的预案");
                                labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
                                labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
                                labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
                            }else{
                                LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
                                labRiskPlanjoinsub.setJoinStatus(a.getJoinStatus());
                                labRiskPlanjoinsub.setSubjectId(a.getSubjectId());
                                labRiskPlanjoinsub.setRiskPlanId(labRiskPlan.getId());
                                labRiskPlanjoinsub.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                                labRiskPlanjoinsub.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
                                labRiskPlanjoinsub.setCreateTime(DateUtils.getNowDate());
                                labRiskPlanjoinsubMapper.insertLabRiskPlanjoinsub(labRiskPlanjoinsub);

                                //插入分配记录日志信息
                                LabRiskPlanDistribution labRiskPlanDistribution = new LabRiskPlanDistribution();
                                labRiskPlanDistribution.setRiskPlanId(labRiskPlan.getId());
                                labRiskPlanDistribution.setSubId(a.getSubjectId());
                                labRiskPlanDistribution.setGroupDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
                                labRiskPlanDistribution.setUserId(tokenService.getLoginUser().getSysUser().getUserId());
                                labRiskPlanDistribution.setDistrStatus(1L);
                                labRiskPlanDistribution.setCreateTime(DateUtils.getNowDate());
                                labRiskPlanDistribution.setCreateBy(tokenService.getLoginUser().getSysUser().getNickName());
                                labRiskPlanDistributionMapper.insertLabRiskPlanDistribution(labRiskPlanDistribution);
                            }
                        });
            }
        }
    }

    /**
     * 批量删除风险预案
     *
     * @param ids 需要删除的风险预案主键
     * @return 结果
     */
    @Override
    public int deleteLabRiskPlanByIds(Long[] ids) {
        LabRiskPlanjoinsub labRiskPlanjoinsub = new LabRiskPlanjoinsub();
        labRiskPlanjoinsub.setRiskPlanId(ids[0]);
        List<LabRiskPlanjoinsub> planjoinsubs = labRiskPlanjoinsubMapper.selectLabRiskPlanjoinsubList(labRiskPlanjoinsub);
        if(planjoinsubs.size()>0){
            throw new ServiceException("该预案已经绑定实验室，请先解除绑定关系再删除！");
        }
        for (Long id : ids) {
            labRiskPlanHardwareRelationMapper.deleteByPlanId(id);
            labRiskPlanSensorRelationMapper.deleteByPlanId(id);
            labRiskPlanjoinsubMapper.deleteByPlanjoinsubId(id);
        }
        return labRiskPlanMapper.deleteLabRiskPlanByIds(ids);
    }

    /**
     * 批量删除风险预案
     *
     * @param labRiskPlanjoinsub 需要删除的风险预案主键
     * @return 结果
     */
    @Override
    public int removeByPlanJoinSub(LabRiskPlanjoinsub labRiskPlanjoinsub) {
        return labRiskPlanjoinsubMapper.removeByPlanjoinsubId(labRiskPlanjoinsub);
    }

    /**
     * 删除风险预案信息
     *
     * @param id 风险预案主键
     * @return 结果
     */
    @Override
    public int deleteLabRiskPlanById(Long id) {
        return labRiskPlanMapper.deleteLabRiskPlanById(id);
    }

    /**
     * 查询风险预案列表（带占比统计数据）
     */
    @Override
//    @DataScope(deptAlias = "ur")
    public List<LabRiskPlanDTO> selectLabRiskPlanStatisticList(LabRiskPlanDTO labRiskPlan) {
        labRiskPlan.setDeptId(tokenService.getLoginUser().getSysUser().getDeptId());
        List<LabRiskPlanDTO> labRiskPlanDTOList = labRiskPlanMapper.selectLabRiskPlanStatisticList(labRiskPlan);
        final Map<SenseType, List<SensorFunctionStatus>> sensorFunctionStatusListMap = hardwareFunctionStatusConfig.getSensorFunctionStatusListMap();
        Optional.ofNullable(labRiskPlanDTOList).orElseGet(Collections::emptyList).stream()
                .forEach(a->{
                    if(a.getFunNum()!=null){
                        String[] funNums = a.getFunNum().split(",");
                        String[] funMonitors = a.getFunMonitor().split(",");
                        String funStr = "";
                        for(int i=0;i<funNums.length;i++){
                            for(Map.Entry<SenseType, List<SensorFunctionStatus>> entry :sensorFunctionStatusListMap.entrySet()){
                                for(SensorFunctionStatus sensor:entry.getValue()){
                                    if(sensor.getFunNum().equals(funNums[i]) && !entry.getKey().equals(SenseType.TEMPERATURE_AND_HUMIDITY)){
                                        funStr += "、"+sensor.getDescribe()+""+funMonitors[i];
                                    }
                                }
                            }

                        }
                        a.setFunNum(funStr.substring(1));
                    }

                    a.setLabRiskPlanjoinsubList(labRiskPlanjoinsubMapper.selectLabRiskPlanjoinsubByPlanId(a.getId(), SecurityUtils.getUserId()));
                });
        return labRiskPlanDTOList;
    }


//    /**
//     * 执行传感器对应的风险预案
//     *
//     * @param subFunction 传感器Vo
//     * @return 结果
//     */
//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    public synchronized int triggerRiskPlan(SubFunction<SensorFunctionStatus> subFunction) {
//        int flag = 0;
////        LabSensorVO sensorVo = new LabSensorVO();
////        if(senseFuncList.size()>0){
////            LabSensor sensorPo = new LabSensor();
////            sensorPo.setGatewayId(senseFuncList.get(0).getHardwareNum());
////            List<LabSensorVO> sensorList = labSensorMapper.selectLabSensorList(sensorPo);
////            if(sensorList.size()>0){
////                sensorVo = sensorList.get(0);
////            }else{
////                return flag;
////            }
////        }
//
//        log.error("预案开始，获取实验室ID======================================================="+subFunction.getSubId());
//
//
//        LabRiskPlanVO riskPlanVo = new LabRiskPlanVO();
//        //这里需要接收对应的实验室id
//        riskPlanVo.setSubjectId(subFunction.getSubId());
//        List<LabRiskPlan> riskPlanList = labRiskPlanMapper.selectLabRiskPlanBySubjectList(riskPlanVo);
//        LabRiskPlan newRiskPlan = matchingRiskPlan(riskPlanList,subFunction);
//
////        log.error("获取匹配成功的预案id======================================================="+newRiskPlan.getId());
//
//        //将风险预案写入归属组级表里面
//        LabRiskPlanAbnormalGroup labRiskPlanAbnormalGroup = new LabRiskPlanAbnormalGroup();
//        labRiskPlanAbnormalGroup.setSubjectId(subFunction.getSubId());
//        labRiskPlanAbnormalGroup.setStatus(1L);
//        List <LabRiskPlanAbnormalGroupVO> groupList = labRiskPlanAbnormalGroupMapper.selectLabRiskPlanAbnormalGroupList(labRiskPlanAbnormalGroup);
//        //如果预案里面配置传感器都达标，需要执行预案对应的硬件操作
//        if(newRiskPlan!=null){
//
//            //处理预案下的传感器翻译
//            JSONArray riskPlanJson = new JSONArray();
//
//            for(LabRiskPlanSensorRelation rps:newRiskPlan.getRiskPlanSensorList()){
//                //硬件社保统一传入的传感器设备列表
//                for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
//                    if(rps.getFunNum().equals(sensorFunc.getFunNum())){
//                        getJsonStr(riskPlanJson,sensorFunc);
//                    }
//                }
//            }
//
//            //查询实验室名称
//            LabSubject subjectPo = labSubjectMapper.selectLabSubjectById(subFunction.getSubId());
//            //将风险预案写入日志表
//            LabRiskPlanAbnormalLog labRiskPlanAbnormalLog = new LabRiskPlanAbnormalLog();
//            labRiskPlanAbnormalLog.setRiskPlanId(newRiskPlan.getId());
//            labRiskPlanAbnormalLog.setRiskPlanName(newRiskPlan.getName());
//            labRiskPlanAbnormalLog.setSubjectId(subFunction.getSubId());
//            labRiskPlanAbnormalLog.setCreateTime(new Date());
//            labRiskPlanAbnormalLog.setDeptId(subjectPo.getDeptId());
//            labRiskPlanAbnormalLog.setDeptName(subjectPo.getDeptName());
//            labRiskPlanAbnormalLog.setSensorJson(riskPlanJson.toString());
//            labRiskPlanAbnormalLog.setRiskStatus(1L);
//
//            log.error("获取预案组，如果是0，需要新建组，如果大于0，进入组======================================================="+groupList.size());
//
//            if(groupList.size()>0){
//                //如果查询到是当前组，那么就给日志表插入的时候，补上组id
//                labRiskPlanAbnormalLog.setGroupId(groupList.get(0).getId());
//                //查询风险日志，启动的预案是不是同一个，如果不是，执行插入日志
//                LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByGroupId = new LabRiskPlanAbnormalLog();
//                labRiskPlanAbnormalLogByGroupId.setGroupId(groupList.get(0).getId());
//                List<LabRiskPlanAbnormalLog> newPlanAbnormalLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLogByGroupId);
//                if(newPlanAbnormalLogList.size()>0){
//                    LabRiskPlanAbnormalLog checkLog = newPlanAbnormalLogList.get(0);
//                    //判断如果当前传感器匹配预案和日志表的预案相同，则不插入日志。过滤重复预案
//                    if(newRiskPlan.getId()!=checkLog.getRiskPlanId() && !newRiskPlan.getId().equals(checkLog.getRiskPlanId())){
//                        //这里调用旧预案结束动作的方法
//                        overRiskPlanAction(checkLog.getRiskPlanId(),checkLog.getSubjectId());
//                        //插入风险日志
//                        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
//                        //插入风险硬件日志
//                        operateHardWareInfo(newRiskPlan,subFunction.getSubId(),groupList.get(0).getId(),labRiskPlanAbnormalLog);
//                        //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
//                        //增加预警缓存
//                        Optional.ofNullable(newRiskPlan.getRiskPlanSensorList())
//                                .ifPresent(f->{
//                                    Set<String> funSet = newRiskPlan.getRiskPlanSensorList().stream().map(d -> d.getFunNum()).collect(Collectors.toSet());
//                                    redisService.setCacheSetV2(Constants.WRAN_KEY+subFunction.getSubId(),funSet);
//                                });
//
//
//
//                    }
//                }
//            }else{
//                //如果找不到组，先插入组数据
//                labRiskPlanAbnormalGroup = new LabRiskPlanAbnormalGroup();
//                labRiskPlanAbnormalGroup.setGroupName(newRiskPlan.getName());
//                labRiskPlanAbnormalGroup.setSubjectId(subFunction.getSubId());
//                labRiskPlanAbnormalGroup.setStatus(1L);
//                labRiskPlanAbnormalGroup.setCreateTime(new Date());
//                labRiskPlanAbnormalGroup.setCreateBy("自动");
//                labRiskPlanAbnormalGroupMapper.insertLabRiskPlanAbnormalGroup(labRiskPlanAbnormalGroup);
//                //给风险日志表关联组
//                labRiskPlanAbnormalLog.setGroupId(labRiskPlanAbnormalGroup.getId());
//                //插入风险日志
//                labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
//                //插入风险硬件日志
//                operateHardWareInfo(newRiskPlan,subFunction.getSubId(),labRiskPlanAbnormalGroup.getId(),labRiskPlanAbnormalLog);
//                //发送大屏左下角预警消息
//                labMessageContentService.sendWranMessage(subFunction.getSubId(),newRiskPlan,labRiskPlanAbnormalGroup.getId());
//                //将风险预案写入日志表（语音电话通知）
//                LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByVoicePhone = new LabRiskPlanAbnormalLog();
//                labRiskPlanAbnormalLogByVoicePhone.setRiskPlanId(newRiskPlan.getId());
//                labRiskPlanAbnormalLogByVoicePhone.setRiskPlanName("语音电话");
//                labRiskPlanAbnormalLogByVoicePhone.setSubjectId(subFunction.getSubId());
//                labRiskPlanAbnormalLogByVoicePhone.setCreateTime(new Date());
//                labRiskPlanAbnormalLogByVoicePhone.setGroupId(labRiskPlanAbnormalGroup.getId());
//                labRiskPlanAbnormalLogByVoicePhone.setSensorJson("");
//                labRiskPlanAbnormalLogByVoicePhone.setRiskStatus(4L);
//                labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLogByVoicePhone);
//                //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
//                //增加预警缓存
//                Optional.ofNullable(newRiskPlan.getRiskPlanSensorList())
//                        .ifPresent(f->{
//                            Set<String> funSet = newRiskPlan.getRiskPlanSensorList().stream().map(d -> d.getFunNum()).collect(Collectors.toSet());
//                            redisService.setCacheSetV2(Constants.WRAN_KEY+subFunction.getSubId(),funSet);
//                        });
//            }
//            //首页预案流程通知
//            messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_LOG);
//            //首页预案组通知
//            messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_GROUP);
//
//
//
//
//        }else {
//            for(LabRiskPlanAbnormalGroup groupVo : groupList){
//                LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByGroupId = new LabRiskPlanAbnormalLog();
//                labRiskPlanAbnormalLogByGroupId.setGroupId(groupVo.getId());
//                List<LabRiskPlanAbnormalLog> newPlanAbnormalLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLogByGroupId);
//                JSONArray allRiskPlanJson = new JSONArray();
//                Map<String,String> checkMap = new HashMap <>();
//
//                Long riskPlanId = null;
//                for(LabRiskPlanAbnormalLog newAbnormalLog:newPlanAbnormalLogList){
//                    //这里通过预案日志获取预案id
//                    riskPlanId = newAbnormalLog.getRiskPlanId();
//
//                    JSONArray json = JSONArray.parseArray(newAbnormalLog.getSensorJson());
//                    if(json!=null){
//                        for(int i=0;i<json.size();i++){
//                            //硬件社保统一传入的传感器设备列表
//                            for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
//                                String describe = json.getJSONObject(i).get("describe")+"";
//                                String checkDescribe = checkMap.get(sensorFunc.getDescribe());
//                                if(describe.equals(sensorFunc.getDescribe())&&!sensorFunc.getDescribe().equals(checkDescribe)){
//                                    getJsonStr(allRiskPlanJson,sensorFunc);
//                                    checkMap.put(sensorFunc.getDescribe(),sensorFunc.getDescribe());
//                                }
//                            }
//                        }
//                    }
//                }
//                //这里调用结束预案的方法
//                overRiskPlanAction(riskPlanId,groupVo.getSubjectId());
//                //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
//                redisService.deleteObject(Constants.WRAN_KEY+subFunction.getSubId());
//                LabRiskPlanAbnormalGroup newGroupOP = new LabRiskPlanAbnormalGroup();
//                newGroupOP.setId(groupVo.getId());
//                newGroupOP.setStatus(0L);
//                labRiskPlanAbnormalGroupMapper.updateLabRiskPlanAbnormalGroup(newGroupOP);
//                //查询实验室名称
//                LabSubject subjectPo = labSubjectMapper.selectLabSubjectById(subFunction.getSubId());
//                //将风险预案写入日志表
//                LabRiskPlanAbnormalLog labRiskPlanAbnormalLog = new LabRiskPlanAbnormalLog();
//                labRiskPlanAbnormalLog.setRiskPlanName("风险解除");
//                labRiskPlanAbnormalLog.setSubjectId(subFunction.getSubId());
//                labRiskPlanAbnormalLog.setCreateTime(new Date());
//                labRiskPlanAbnormalLog.setDeptId(subjectPo.getDeptId());
//                labRiskPlanAbnormalLog.setDeptName(subjectPo.getDeptName());
//                labRiskPlanAbnormalLog.setGroupId(groupVo.getId());
//                labRiskPlanAbnormalLog.setSensorJson(allRiskPlanJson.toString());
//                labRiskPlanAbnormalLog.setRiskStatus(2L);
//                //插入风险日志
//                labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
//                //向一体机传感器预警
//                messageSendService.sendWranFunctionToSub(subFunction.getSubId());
//                //首页预案流程通知
//                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_GROUP);
//                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_LOG);
//
//            }
//        }
//        flag = 200;
//        return flag;
//    }
//
//    /**
//     * 调用结束预案需要执行的动作
//     *
//     * @param riskPlanId
//     * @return 结果
//     */
//    public void overRiskPlanAction(Long riskPlanId,Long subjectId){
//        log.error("这里需要开始调用预案结束相关硬件设备=======================================================");
//        //这里通过预案日志找到预案id
//        List<LabRiskPlanHardwareRelation> riskPlanHardwareList = labRiskPlanHardwareRelationMapper.selectLabRiskPlanHardwareRelationByRiskPlanIdId(riskPlanId);
//        Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunList = hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
//        for(int i=0;i<riskPlanHardwareList.size();i++){
//            List<FunctionStatus> funList = hardwareFunList.get(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
//            for(FunctionStatus status:funList){
//                if(riskPlanHardwareList.get(i).getOverAct()!=null && status.getCode().equals(riskPlanHardwareList.get(i).getOverAct())){
//                    //根据实验室id和设备类型查询硬件列表
//                    LabHardware labHardware = new LabHardware();
//                    labHardware.setSubjectId(subjectId);
//                    labHardware.setType(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
//                    List<LabHardware> hardwareList = labHardwareMapper.selectLabHardwareListBySubject(labHardware);
//                    //循环执行实验室下的硬件功能
//                    for(LabHardware hard:hardwareList){
//                        log.error("调用硬件，获取硬件id======================================================="+hard.getId());
//                        labSubjectManagerService.excutingComm(hard,status);
//                        try {
//                            Thread.sleep(500);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }
//        }
//        log.error("这里硬件调用结束=======================================================");
//    }
//
//
//    /**
//     * 调用执行硬件的接口，交由接口实现具体的设备开启或关闭
//     *
//     * @param newRiskPlan 预案PO，subjectId 实验室id
//     * @return 结果
//     */
//    public void operateHardWareInfo(LabRiskPlan newRiskPlan,Long subjectId,Long groupId,LabRiskPlanAbnormalLog labRiskPlanAbnormalLog){
//        log.error("这里需要开始调用相关硬件设备=======================================================");
//        //这里获取预案下的硬件关联列表
//        List<LabRiskPlanHardwareRelation> riskPlanHardwareList = newRiskPlan.getRiskPlanHardwareList();
////        Map <HardwareTypeEnum,String> hardWareMap = new LinkedHashMap <>();
////        for(int i=0;i<riskPlanHardwareList.size();i++) {
////            hardWareMap.put(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()), riskPlanHardwareList.get(i).getOperate());
////        }
//        //调用执行硬件的接口，交由接口实现具体的设备开启或关闭
////        labSubjectManagerService.excutingComm()
////        labOperateHardwareService.operateHardWare(hardWareMap,subjectId);
//        //这里需要执行预案对应的硬件相关操作
//        Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunList = hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
//        for(int i=0;i<riskPlanHardwareList.size();i++){
//            List<FunctionStatus> funList = hardwareFunList.get(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
//            for(FunctionStatus status:funList){
//                if(status.getCode().equals(riskPlanHardwareList.get(i).getOperate())){
//                    //根据实验室id和设备类型查询硬件列表
//                    LabHardware labHardware = new LabHardware();
//                    labHardware.setSubjectId(subjectId);
//                    labHardware.setType(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
//                    List<LabHardware> hardwareList = labHardwareMapper.selectLabHardwareListBySubject(labHardware);
//                    //循环执行实验室下的硬件功能
//                    log.error("获取硬件列表list======================================================="+hardwareList.size());
//                    for(LabHardware hard:hardwareList){
//                        log.error("调用硬件，获取硬件id======================================================="+hard.getId());
//                        log.error("调用硬件，获取缓存cmd======================================================="+status.getCmd());
//                        log.error("调用硬件，获取继电器几路======================================================="+hard.getBit());
//                        log.error("调用硬件，获取继电器编码======================================================="+hard.getRelayCode());
//                        ResultData result = labSubjectManagerService.excutingComm(hard,status);
//                        log.error("硬件调用结束，获取是否成功"+result.getCode());
//                        try {
//                            Thread.sleep(500);
//                        } catch (InterruptedException e) {
//                            e.printStackTrace();
//                        }
//                    }
//                }
//            }
//            log.error("打开硬件记录风险日志");
//            String operate=hardwareFunctionStatusConfig.getCache().get(riskPlanHardwareList.get(i).getHardwareType()+"-"+riskPlanHardwareList.get(i).getOperate()).getDescribe();
//            labRiskPlanAbnormalLog.setRiskPlanId(newRiskPlan.getId());
//            labRiskPlanAbnormalLog.setRiskPlanName(operate+""+HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()).getName());
//            labRiskPlanAbnormalLog.setCreateTime(new Date());
//            if(riskPlanHardwareList.get(i).getHardwareType().equals(1)){
//                //电源开关
//                labRiskPlanAbnormalLog.setRiskStatus(0L);
//            }else{
//                //智能通风
//                labRiskPlanAbnormalLog.setRiskStatus(3L);
//            }
//            labRiskPlanAbnormalLog.setGroupId(groupId);
//            labRiskPlanAbnormalLog.setOpreateAct(riskPlanHardwareList.get(i).getOperate());
//            labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
//            log.error("结束硬件记录风险日志");
//        }
//        log.error("这里硬件调用结束=======================================================");
//        //这里给消息记录表插入数据(给一体机设备发送语音通知)
//        log.error("这里调用一体机语音开始=======================================================");
//        LabWarnPushMessage labWarnPushMessage = new LabWarnPushMessage();
//        labWarnPushMessage.setRiskGroup(groupId);
//        labWarnPushMessage.setContext(newRiskPlan.getInformation());
//        labWarnPushMessage.setPushType(WarnMessageTypeEnum.voice);
//        labWarnPushMessage.setWarnId(newRiskPlan.getId());
//        labWarnPushMessage.setSubId(subjectId);
//        labWarnPushMessage.setCreateTime(new Date());
//        labWarnPushMessageMapper.insertLabWarnPushMessage(labWarnPushMessage);
//        log.error("这里调用一体机语音结束=======================================================");
//        //将风险预案写入日志表（语音播报通知）
//        log.error("这里调用语音播报通知开始=======================================================");
//        LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByVoicePhone = new LabRiskPlanAbnormalLog();
//        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanId(newRiskPlan.getId());
//        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanName("语音播报");
//        labRiskPlanAbnormalLogByVoicePhone.setSubjectId(subjectId);
//        labRiskPlanAbnormalLogByVoicePhone.setCreateTime(new Date());
//        labRiskPlanAbnormalLogByVoicePhone.setGroupId(groupId);
//        labRiskPlanAbnormalLogByVoicePhone.setSensorJson("");
//        labRiskPlanAbnormalLogByVoicePhone.setRiskStatus(5L);
//        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLogByVoicePhone);
//        log.error("这里调用语音播报通知结束=======================================================");
//        //向一体机推送语音播报
//        messageSendService.sendOnepcSubNews(subjectId,newRiskPlan.getVoicebroadcast());
//        //向一体机传感器预警
//        messageSendService.sendWranFunctionToSub(subjectId);
//        //首页消息通知
//        messageSendService.SendBigViewUpdate(BigViewDataType.SUB_WRAN_MESSAGE);
//    }



    /**
     * 执行传感器对应的风险预案
     *
     * @param subFunction 传感器Vo
     * @return 结果
     */
    @Override
    public synchronized int triggerRiskPlan(SubFunction<SensorFunctionStatus> subFunction) {
        log.info("****************进入triggerRiskPlan****************");
        int flag = 200;

        //调用烟雾特殊处理方法
//        intelligentMotionCompensation(subFunction);

        LabRiskPlanVO riskPlanVo = new LabRiskPlanVO();
        //这里需要接收对应的实验室id
        riskPlanVo.setSubjectId(subFunction.getSubId());
        //通过实验室ID查询到对应的预案列表
        List<LabRiskPlan> riskPlanList = labRiskPlanMapper.selectLabRiskPlanBySubjectList(riskPlanVo);
        LabRiskPlan newRiskPlan = matchingRiskPlan(riskPlanList,subFunction);

        //获取通知配置信息
        List<LabNoticeconfig> noticeconfigList = labNoticeconfigMapper.selectLabNoticeconfigList(new LabNoticeconfig());
        StringBuffer radioStr = new StringBuffer();
        if(noticeconfigList.size()>0 && newRiskPlan!=null){
            //语音播报 短信 电话内容
            LabNoticeconfig labNoticeconfig = noticeconfigList.get(0);
            newRiskPlan.setVoicebroadcast(labNoticeconfig.getRiskVoice());
            newRiskPlan.setMessage(labNoticeconfig.getRiskMessage());
            newRiskPlan.setInformation(labNoticeconfig.getRiskPhone());
            //预案广播通知
            radioStr.append(labNoticeconfig.getRiskRadio());
        }

        //将风险预案写入归属组级表里面
        LabRiskPlanAbnormalGroup labRiskPlanAbnormalGroup = new LabRiskPlanAbnormalGroup();
        labRiskPlanAbnormalGroup.setSubjectId(subFunction.getSubId());
        labRiskPlanAbnormalGroup.setStatus(1L);
        //查询风险异常组级列表
        List <LabRiskPlanAbnormalGroupVO> groupList = labRiskPlanAbnormalGroupMapper.selectLabRiskPlanAbnormalGroupList(labRiskPlanAbnormalGroup);

        //如果预案里面配置传感器都达标，需要执行预案对应的硬件操作
        if(newRiskPlan!=null){
            //这里处理，如果是火焰预案，需要redis额外缓存
            Optional.ofNullable(subFunction.getFunctionStatuses()).orElseGet(Collections::emptyList)
                    .stream()
                    .filter(a->"huoyan".equals(a.getFunNum()))
                    .forEach(a->{
                        if(redisService.getCacheObject("subjectByHuoyan"+subFunction.getSubId())==null){
                            redisService.setCacheObject("subjectByHuoyan"+subFunction.getSubId(), subFunction.getSubId(), 1L, TimeUnit.HOURS);
                        }
                    });
            //有效预案延长一分钟
//            if(redisService.getCacheObject("subjectByYa"+subFunction.getSubId())==null){
                redisService.setCacheObject("subjectByYa"+subFunction.getSubId(), subFunction.getSubId(), 3L, TimeUnit.MINUTES);
                log.info("@@@@@@@@@@@@@@@@@@@@预案延长3分钟@@@@@@@@@@@@@@@@@@@@");
//            }
            //处理预案下的传感器翻译
            JSONArray riskPlanJson = new JSONArray();
            for(LabRiskPlanSensorRelation rps:newRiskPlan.getRiskPlanSensorList()){
                //硬件社保统一传入的传感器设备列表
                for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
                    if(rps.getFunNum().equals(sensorFunc.getFunNum())){
                        getJsonStr(riskPlanJson,sensorFunc);
                        newRiskPlan.setTopName(newRiskPlan.getTopName()+" "+sensorFunc.getDescribe());
                    }
                }
            }

            //插入风险日志
            Long groupId = insertPlanAbnormalLog(newRiskPlan,riskPlanJson,groupList,1L,subFunction.getSubId());
            log.info("####################groupId:"+groupId);
            if(groupId!=null){
                log.error("这里记录预警消息记录开始=======================================================");
                insertWarnPushMessageByOnePc(newRiskPlan,subFunction.getSubId(),groupId);
                log.error("这里记录预警消息记录结束=======================================================");

                log.error("这里记录语音播报开始=======================================================");
                insertPlanAbnormalLogByVoice(newRiskPlan,subFunction.getSubId(),groupId);
                log.error("这里记录语音播报结束=======================================================");

                log.error("这里记录语音电话开始=======================================================");
                insertPlanAbnormalLogByPhone(newRiskPlan,subFunction.getSubId(),groupId);
                log.error("这里记录语音电话结束=======================================================");

                //向一体机推送语音播报
                log.error("向一体机推送语音播报开始=======================================================");
                try{
                    messageSendService.sendOnepcSubNews(subFunction.getSubId(),2,newRiskPlan.getTopName()+""+newRiskPlan.getVoicebroadcast());
                }catch (Exception e){
                    log.error("向一体机推送语音播报异常:"+e);
                }

                log.error("向一体机推送语音播报结束=======================================================");
                //向一体机传感器预警
                log.error("向一体机传感器预警开始=======================================================");
                messageSendService.sendWranFunctionToSub(subFunction.getSubId());
                log.error("向一体机传感器预警结束=======================================================");
                //向一体机发送预警消息展示
                log.error("向一体机发送预警消息展示开始=======================================================");
                insertMachineContent(subFunction.getSubId(),newRiskPlan.getTopName()+""+newRiskPlan.getVoicebroadcast());
                log.error("向一体机发送预警消息展示结束=======================================================");

                //首页消息通知
                log.error("首页消息通知开始=======================================================");
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_WRAN_MESSAGE);
                log.error("首页消息通知结束=======================================================");
                //发送大屏左下角预警消息
                log.error("发送大屏左下角预警消息开始=======================================================");
                labMessageContentService.sendWranMessage(subFunction.getSubId(),newRiskPlan,labRiskPlanAbnormalGroup.getId());
                log.error("发送大屏左下角预警消息结束=======================================================");
                try{
                    //这里查询预案下的合成音乐
                    LabAudioSynthesis labAudioSynthesis = new LabAudioSynthesis();
                    labAudioSynthesis.setRiskPlanId(newRiskPlan.getId());
                    List<LabAudioSynthesis> audioSyntheses = labAudioSynthesisMapper.selectLabAudioSynthesisList(labAudioSynthesis);
                    if(audioSyntheses.size()>0){
                        //预案调用喇叭
                        R deviceList = remoteSpeakService.getDeviceList(1,10,newRiskPlan.getFloorId());
                        if(deviceList.getCode()==200){
                            List<Map<String,Object>> mapList = (List <Map <String, Object>>) deviceList.getData();

                            for(Map<String,Object> map:mapList){
                                log.info("喇叭日志============================="+map);
                                if(StringUtils.isNotNull(map.get("deviceSn")) && StringUtils.isNotNull(map.get("port"))){
                                    List<PlayVo> playVoList = new ArrayList<>();
                                    PlayVo playVo = new PlayVo();
                                    playVo.setSn(map.get("deviceSn")+"");
                                    playVo.setDeviceIp(map.get("deviceIp")+"");
                                    playVo.setPort(Integer.parseInt(map.get("port")+""));
                                    ParamVo paramVo=new ParamVo();
                                    playVo.setParams(paramVo);
                                    playVoList.add(playVo);
                                    remoteSpeakService.textParseUrlAppIps(audioSyntheses.get(0).getNewMusicUrl(),playVoList);
                                }
                            }


                        }
                    }
                }catch (Exception e){
                    log.error("开启喇叭失败！！！！！:"+e);
                }

//                // TODO: 2022/3/26  目前只有c111外的响
//                List<PlayVo> playVoList = new ArrayList<>();
//                PlayVo playVo = new PlayVo();
//                playVo.setSn("ls20://0201BFB9D686");
//                playVo.setPort(18884);
//                ParamVo paramVo=new ParamVo();
//                playVo.setParams(paramVo);
//                playVoList.add(playVo);
//                if(radioStr.length()>0){
//                    remoteSpeakService.textParseUrlAppIps(radioStr.toString(),playVoList);
//                    log.info("喇叭播放完成！");
//                }

                //首页预案流程通知
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_LOG);
                //首页预案组通知
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_GROUP);
                //首页预案是否同步疏散线路
                if(newRiskPlan.getEvacuation()!=null && newRiskPlan.getEvacuation()==1){
                    redisService.setCacheObject("subjectByExit"+subFunction.getSubId(), subFunction.getSubId(), 30L, TimeUnit.SECONDS);
                    messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_EXIT);
                }

            }

        }else{
            if(redisService.getCacheObject("subjectByYa"+subFunction.getSubId())!=null){
                return flag;
            }

            for(LabRiskPlanAbnormalGroupVO groupVo : groupList){
                try{
                    //预案关闭喇叭
                    //这里查询预案下的合成音乐
                    LabAudioSynthesis labAudioSynthesis = new LabAudioSynthesis();
                    labAudioSynthesis.setRiskPlanId(groupVo.getRiskPlanId());
                    List<LabAudioSynthesis> audioSyntheses = labAudioSynthesisMapper.selectLabAudioSynthesisList(labAudioSynthesis);
                    if(audioSyntheses.size()>0){
                        R deviceList = remoteSpeakService.getDeviceList(1,10,groupVo.getFloorId());
                        if(deviceList.getCode()==200){
                            List<Map<String,Object>> mapList = (List <Map <String, Object>>) deviceList.getData();
                            List<PlayVo> playVoList = new ArrayList<>();
                            for(Map<String,Object> map:mapList){
                                log.info("关闭喇叭日志============================="+map);
                                if(StringUtils.isNotNull(map.get("deviceSn")) && StringUtils.isNotNull(map.get("port"))){
                                    PlayVo playVo = new PlayVo();
                                    playVo.setSn(map.get("deviceSn")+"");
                                    playVo.setPort(Integer.parseInt(map.get("port")+""));
                                    ParamVo paramVo=new ParamVo();
                                    playVo.setParams(paramVo);
                                    playVoList.add(playVo);
                                    remoteSpeakService.stopPlayMusic(map.get("deviceSn")+"",audioSyntheses.get(0).getNewMusicUrl());

                                }
                            }

                        }
                    }
                }catch (Exception e){
                    log.error("关闭喇叭失败！！！！！:"+e);
                }


                //查询风险日志下，根据预案ID查询风险日志
                LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByGroupId = new LabRiskPlanAbnormalLog();
                labRiskPlanAbnormalLogByGroupId.setGroupId(groupVo.getId());
                List<LabRiskPlanAbnormalLog> newPlanAbnormalLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLogByGroupId);
                JSONArray allRiskPlanJson = new JSONArray();
                Map<String,String> checkMap = new HashMap <>();

                Long riskPlanId = null;
                for(LabRiskPlanAbnormalLog newAbnormalLog:newPlanAbnormalLogList){
                    //这里通过预案日志获取预案id
                    riskPlanId = newAbnormalLog.getRiskPlanId();

                    JSONArray json = JSONArray.parseArray(newAbnormalLog.getSensorJson());
                    if(json!=null){
                        for(int i=0;i<json.size();i++){
                            //硬件社保统一传入的传感器设备列表
                            for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
                                String describe = json.getJSONObject(i).get("describe")+"";
                                String checkDescribe = checkMap.get(sensorFunc.getDescribe());
                                if(describe.equals(sensorFunc.getDescribe())&&!sensorFunc.getDescribe().equals(checkDescribe)){
                                    getJsonStr(allRiskPlanJson,sensorFunc);
                                    checkMap.put(sensorFunc.getDescribe(),sensorFunc.getDescribe());
                                }
                            }
                        }
                    }
                }
                //这里调用结束预案的方法
                overRiskPlanAction(riskPlanId,groupVo.getSubjectId());
                //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
                redisService.deleteObject(Constants.WRAN_KEY+subFunction.getSubId());

                LabRiskPlanAbnormalGroup newGroupOP = new LabRiskPlanAbnormalGroup();
                newGroupOP.setId(groupVo.getId());
                newGroupOP.setStatus(0L);
                labRiskPlanAbnormalGroupMapper.updateLabRiskPlanAbnormalGroup(newGroupOP);
                //插入预案结束日志
                insertPlanAbnormalLogByOver(groupVo,allRiskPlanJson,subFunction);
                //向一体机传感器预警
                messageSendService.sendWranFunctionToSub(subFunction.getSubId());
                //首页预案流程通知
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_GROUP);
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_LOG);
                //首页预案是否同步疏散线路
                messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_EXIT);
            }
        }

        return flag;
    }

    @Override
    public int closeRiskPlan(SubFunction<SensorFunctionStatus> subFunction) {
        //将风险预案写入归属组级表里面
        LabRiskPlanAbnormalGroup labRiskPlanAbnormalGroup = new LabRiskPlanAbnormalGroup();
        labRiskPlanAbnormalGroup.setSubjectId(subFunction.getSubId());
        labRiskPlanAbnormalGroup.setStatus(1L);
        List <LabRiskPlanAbnormalGroupVO> groupList = labRiskPlanAbnormalGroupMapper.selectLabRiskPlanAbnormalGroupList(labRiskPlanAbnormalGroup);
        if(redisService.getCacheObject("subjectByYa"+subFunction.getSubId())!=null){
            redisService.deleteObject("subjectByYa"+subFunction.getSubId());
        }

        for(LabRiskPlanAbnormalGroupVO groupVo : groupList){
            try{
                //预案关闭喇叭
                //这里查询预案下的合成音乐
                LabAudioSynthesis labAudioSynthesis = new LabAudioSynthesis();
                labAudioSynthesis.setRiskPlanId(groupVo.getRiskPlanId());
                List<LabAudioSynthesis> audioSyntheses = labAudioSynthesisMapper.selectLabAudioSynthesisList(labAudioSynthesis);
                if(audioSyntheses.size()>0){
                    R deviceList = remoteSpeakService.getDeviceList(1,10,groupVo.getFloorId());
                    if(deviceList.getCode()==200){
                        List<Map<String,Object>> mapList = (List <Map <String, Object>>) deviceList.getData();
                        List<PlayVo> playVoList = new ArrayList<>();
                        for(Map<String,Object> map:mapList){
                            log.info("关闭喇叭日志============================="+map);
                            if(StringUtils.isNotNull(map.get("deviceSn")) && StringUtils.isNotNull(map.get("port"))){
                                PlayVo playVo = new PlayVo();
                                playVo.setSn(map.get("deviceSn")+"");
                                playVo.setPort(Integer.parseInt(map.get("port")+""));
                                ParamVo paramVo=new ParamVo();
                                playVo.setParams(paramVo);
                                playVoList.add(playVo);
                                remoteSpeakService.stopPlayMusic(map.get("deviceSn")+"",audioSyntheses.get(0).getNewMusicUrl());

                            }
                        }

                    }
                }
            }catch (Exception e){
                log.error("关闭喇叭失败！！！！！:"+e);
            }


            LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByGroupId = new LabRiskPlanAbnormalLog();
            labRiskPlanAbnormalLogByGroupId.setGroupId(groupVo.getId());
            List<LabRiskPlanAbnormalLog> newPlanAbnormalLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLogByGroupId);
            JSONArray allRiskPlanJson = new JSONArray();
            Map<String,String> checkMap = new HashMap <>();

            Long riskPlanId = null;
            for(LabRiskPlanAbnormalLog newAbnormalLog:newPlanAbnormalLogList){
                //这里通过预案日志获取预案id
                riskPlanId = newAbnormalLog.getRiskPlanId();

                JSONArray json = JSONArray.parseArray(newAbnormalLog.getSensorJson());
                if(json!=null){
                    for(int i=0;i<json.size();i++){
                        //硬件社保统一传入的传感器设备列表
                        for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
                            String describe = json.getJSONObject(i).get("describe")+"";
                            String checkDescribe = checkMap.get(sensorFunc.getDescribe());
                            if(describe.equals(sensorFunc.getDescribe())&&!sensorFunc.getDescribe().equals(checkDescribe)){
                                getJsonStr(allRiskPlanJson,sensorFunc);
                                checkMap.put(sensorFunc.getDescribe(),sensorFunc.getDescribe());
                            }
                        }
                    }
                }
            }
            //这里调用结束预案的方法
            overRiskPlanAction(riskPlanId,groupVo.getSubjectId());
            //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
            redisService.deleteObject(Constants.WRAN_KEY+subFunction.getSubId());

            LabRiskPlanAbnormalGroup newGroupOP = new LabRiskPlanAbnormalGroup();
            newGroupOP.setId(groupVo.getId());
            newGroupOP.setStatus(0L);
            labRiskPlanAbnormalGroupMapper.updateLabRiskPlanAbnormalGroup(newGroupOP);
            //插入预案结束日志
            insertPlanAbnormalLogByOver(groupVo,allRiskPlanJson,subFunction);
            //向一体机传感器预警
            messageSendService.sendWranFunctionToSub(subFunction.getSubId());
            //首页预案流程通知
            messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_GROUP);
            messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_LOG);
            //首页预案是否同步疏散线路
            messageSendService.SendBigViewUpdate(BigViewDataType.SUB_RISKPLAN_EXIT);
        }
        return 0;
    }


    private void insertMachineContent(Long subId,String message){
        log.info("*********************insertMachineContent开始********************");
        LabMessageContent labMessageContent = new LabMessageContent();
        labMessageContent.setSubIds(subId+"");
        labMessageContent.setCreateBy("系统消息");
        labMessageContent.setCreateTime(new Date());
        labMessageContent.setContent(message);
        labMessageContent.setSendRange(4);
        labMessageContent.setMessClass(3);
        labMessageContentService.sendMessage(labMessageContent);
        log.info("*********************insertMachineContent结束********************");
    }


    public LabRiskPlanAbnormalGroup insertPlanAbnormalGroup(LabRiskPlan newRiskPlan,Long subjectId){
        //如果找不到组，先插入组数据
        LabRiskPlanAbnormalGroup labRiskPlanAbnormalGroup = new LabRiskPlanAbnormalGroup();
        labRiskPlanAbnormalGroup.setGroupName(newRiskPlan.getName());
        labRiskPlanAbnormalGroup.setStatus(1L);
        labRiskPlanAbnormalGroup.setCreateTime(new Date());
        labRiskPlanAbnormalGroup.setCreateBy("自动");
        labRiskPlanAbnormalGroup.setSubjectId(subjectId);
        labRiskPlanAbnormalGroupMapper.insertLabRiskPlanAbnormalGroup(labRiskPlanAbnormalGroup);
        return labRiskPlanAbnormalGroup;
    }


    public Long insertPlanAbnormalLog(LabRiskPlan newRiskPlan,JSONArray riskPlanJson,List <LabRiskPlanAbnormalGroupVO> groupList,Long riskStatus,Long subjectId){
        LabRiskPlanAbnormalGroup labRiskPlanAbnormalGroup;
        Long groupId;
        //将风险预案写入日志表
        LabRiskPlanAbnormalLog labRiskPlanAbnormalLog = new LabRiskPlanAbnormalLog();
        labRiskPlanAbnormalLog.setRiskPlanId(newRiskPlan.getId());
        labRiskPlanAbnormalLog.setRiskPlanName(newRiskPlan.getName());
        labRiskPlanAbnormalLog.setCreateTime(new Date());
        labRiskPlanAbnormalLog.setSensorJson(riskPlanJson.toString());
        labRiskPlanAbnormalLog.setRiskStatus(riskStatus);
        labRiskPlanAbnormalLog.setSubjectId(subjectId);
        if(groupList==null || groupList.size()==0){
            labRiskPlanAbnormalGroup = insertPlanAbnormalGroup(newRiskPlan,subjectId);
            groupId = labRiskPlanAbnormalGroup.getId();
            //给风险日志表关联组
            labRiskPlanAbnormalLog.setGroupId(labRiskPlanAbnormalGroup.getId());
            //插入风险日志
            labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
            //todo 后面放入老柴的事件中 或者订阅老柴的事件处理
            //增加预警缓存
            Optional.ofNullable(newRiskPlan.getRiskPlanSensorList())
                    .ifPresent(f->{
                        Set<String> funSet = newRiskPlan.getRiskPlanSensorList().stream().map(d -> d.getFunNum()).collect(Collectors.toSet());
                        redisService.setCacheSetV2(Constants.WRAN_KEY+subjectId,funSet);
                    });
            try{
                //插入风险硬件日志
                operateHardWareInfo(newRiskPlan,labRiskPlanAbnormalGroup.getSubjectId(),labRiskPlanAbnormalLog.getGroupId(),riskPlanJson.toString());
            }catch (Exception e){
                log.error("操作硬件设备异常::::"+e);
            }finally {
                return groupId;
            }
        }else{
            labRiskPlanAbnormalGroup = groupList.get(0);
            //如果查询到是当前组，那么就给日志表插入的时候，补上组id
            labRiskPlanAbnormalLog.setGroupId(labRiskPlanAbnormalGroup.getId());
            //查询风险日志，启动的预案是不是同一个，如果不是，执行插入日志
            LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByGroupId = new LabRiskPlanAbnormalLog();
            labRiskPlanAbnormalLogByGroupId.setGroupId(groupList.get(0).getId());
            List<LabRiskPlanAbnormalLog> newPlanAbnormalLogList = labRiskPlanAbnormalLogMapper.selectLabRiskPlanAbnormalLogOrderByList(labRiskPlanAbnormalLogByGroupId);
            if(newPlanAbnormalLogList.size()>0){
                LabRiskPlanAbnormalLog checkLog = newPlanAbnormalLogList.get(0);
                //判断如果当前传感器匹配预案和日志表的预案相同，则不插入日志。过滤重复预案
                if(newRiskPlan.getId()!=checkLog.getRiskPlanId() && !newRiskPlan.getId().equals(checkLog.getRiskPlanId())){
                    //这里调用旧预案结束动作的方法
                    overRiskPlanAction(checkLog.getRiskPlanId(),checkLog.getSubjectId());
                    groupId = labRiskPlanAbnormalGroup.getId();
                    //插入风险日志
                    labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
                    try{
                        //插入风险硬件日志
                        operateHardWareInfo(newRiskPlan,labRiskPlanAbnormalGroup.getSubjectId(),groupList.get(0).getId(),riskPlanJson.toString());
//                        todo 后面放入老柴的事件中 或者订阅老柴的事件处理
                        //增加预警缓存
                        Optional.ofNullable(newRiskPlan.getRiskPlanSensorList())
                                .ifPresent(f->{
                                    Set<String> funSet = newRiskPlan.getRiskPlanSensorList().stream().map(d -> d.getFunNum()).collect(Collectors.toSet());
                                    redisService.setCacheSetV2(Constants.WRAN_KEY+subjectId,funSet);
                                });
                    }catch (Exception e){
                        log.error("操作硬件设备异常::::"+e);
                    }finally {
                        return groupId;
                    }
                }
            }
            //插入风险日志

            return null;
        }
    }


    public void insertPlanAbnormalLogByHard(LabRiskPlan newRiskPlan,LabRiskPlanHardwareRelation hardRelation,Long subjectId,Long groupId,String riskPlanJson){
        log.error("打开硬件记录风险日志");
        LabRiskPlanAbnormalLog labRiskPlanAbnormalLog = new LabRiskPlanAbnormalLog();
        String operate=hardwareFunctionStatusConfig.getCache().get(hardRelation.getHardwareType()+"-"+hardRelation.getOperate()).getDescribe();
        labRiskPlanAbnormalLog.setRiskPlanId(newRiskPlan.getId());
        labRiskPlanAbnormalLog.setRiskPlanName(operate+""+HardwareTypeEnum.getByCode(hardRelation.getHardwareType()).getName());
        labRiskPlanAbnormalLog.setCreateTime(new Date());
        if(hardRelation.getHardwareType().equals(1)){
            //电源开关
            labRiskPlanAbnormalLog.setRiskStatus(0L);
        }else{
            //智能通风
            labRiskPlanAbnormalLog.setRiskStatus(3L);
        }
        labRiskPlanAbnormalLog.setGroupId(groupId);
        labRiskPlanAbnormalLog.setOpreateAct(hardRelation.getOperate());
        labRiskPlanAbnormalLog.setSubjectId(subjectId);
        labRiskPlanAbnormalLog.setSensorJson(riskPlanJson);
        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
    }


    public void insertWarnPushMessageByOnePc(LabRiskPlan newRiskPlan,Long subjectId,Long groupId){
        //这里给消息记录表插入数据(给一体机设备发送语音通知)
        LabWarnPushMessage labWarnPushMessage = new LabWarnPushMessage();
        labWarnPushMessage.setRiskGroup(groupId);
        labWarnPushMessage.setContext(newRiskPlan.getTopName()+""+newRiskPlan.getInformation());
        labWarnPushMessage.setPushType(WarnMessageTypeEnum.voice);
        labWarnPushMessage.setWarnId(newRiskPlan.getId());
        labWarnPushMessage.setSubId(subjectId);
        labWarnPushMessage.setCreateTime(new Date());
        labWarnPushMessageMapper.insertLabWarnPushMessage(labWarnPushMessage);
    }


    public void insertPlanAbnormalLogByVoice(LabRiskPlan newRiskPlan,Long subjectId,Long groupId){
        LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByVoicePhone = new LabRiskPlanAbnormalLog();
        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanId(newRiskPlan.getId());
        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanName("语音播报");
        labRiskPlanAbnormalLogByVoicePhone.setSubjectId(subjectId);
        labRiskPlanAbnormalLogByVoicePhone.setCreateTime(new Date());
        labRiskPlanAbnormalLogByVoicePhone.setGroupId(groupId);
        labRiskPlanAbnormalLogByVoicePhone.setRiskStatus(5L);
        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLogByVoicePhone);
    }

    public void insertPlanAbnormalLogByPhone(LabRiskPlan newRiskPlan,Long subjectId,Long groupId){
        //将风险预案写入日志表（语音电话通知）
        LabRiskPlanAbnormalLog labRiskPlanAbnormalLogByVoicePhone = new LabRiskPlanAbnormalLog();
        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanId(newRiskPlan.getId());
        labRiskPlanAbnormalLogByVoicePhone.setRiskPlanName("语音电话");
        labRiskPlanAbnormalLogByVoicePhone.setSubjectId(subjectId);
        labRiskPlanAbnormalLogByVoicePhone.setCreateTime(new Date());
        labRiskPlanAbnormalLogByVoicePhone.setGroupId(groupId);
        labRiskPlanAbnormalLogByVoicePhone.setRiskStatus(4L);
        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLogByVoicePhone);
    }


    public void insertPlanAbnormalLogByOver(LabRiskPlanAbnormalGroup groupVo,JSONArray allRiskPlanJson,SubFunction<SensorFunctionStatus> subFunction){
        //将风险预案写入日志表
        LabRiskPlanAbnormalLog labRiskPlanAbnormalLog = new LabRiskPlanAbnormalLog();
        labRiskPlanAbnormalLog.setRiskPlanId(groupVo.getId());
        labRiskPlanAbnormalLog.setRiskPlanName("风险解除");
        labRiskPlanAbnormalLog.setSubjectId(subFunction.getSubId());
        labRiskPlanAbnormalLog.setCreateTime(new Date());
        labRiskPlanAbnormalLog.setGroupId(groupVo.getId());
        labRiskPlanAbnormalLog.setSensorJson(allRiskPlanJson.toString());
        labRiskPlanAbnormalLog.setRiskStatus(2L);
        //插入风险日志
        labRiskPlanAbnormalLogMapper.insertLabRiskPlanAbnormalLog(labRiskPlanAbnormalLog);
    }

    /**
     * 调用执行硬件的接口，交由接口实现具体的设备开启或关闭
     *
     * @param newRiskPlan 预案PO，subjectId 实验室id
     * @return 结果
     */
    public void operateHardWareInfo(LabRiskPlan newRiskPlan,Long subjectId,Long groupId,String riskPlanJson){
        log.error("这里需要开始调用相关硬件设备=======================================================");
        //这里获取预案下的硬件关联列表
        List<LabRiskPlanHardwareRelation> riskPlanHardwareList = newRiskPlan.getRiskPlanHardwareList();
        Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunList = hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
        for(int i=0;i<riskPlanHardwareList.size();i++){
            List<FunctionStatus> funList = hardwareFunList.get(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
            for(FunctionStatus status:funList){
                if(status.getCode().equals(riskPlanHardwareList.get(i).getOperate())){
                    //根据实验室id和设备类型查询硬件列表
                    LabHardware labHardware = new LabHardware();
                    labHardware.setSubjectId(subjectId);
                    labHardware.setType(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
                    List<LabHardware> hardwareList = labHardwareMapper.selectLabHardwareListBySubject(labHardware);
                    //循环执行实验室下的硬件功能
                    for(LabHardware hard:hardwareList){
                        ResultData result = labSubjectManagerService.excutingComm(hard,status);
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            log.error("打开硬件记录风险日志");
            insertPlanAbnormalLogByHard(newRiskPlan,riskPlanHardwareList.get(i),subjectId,groupId,riskPlanJson);
        }
    }



    /**
     * 调用结束预案需要执行的动作
     *
     * @param riskPlanId
     * @return 结果
     */
    public void overRiskPlanAction(Long riskPlanId,Long subjectId){
        log.error("这里需要开始调用预案结束相关硬件设备=======================================================");
        //这里通过预案日志找到预案id
        List<LabRiskPlanHardwareRelation> riskPlanHardwareList = labRiskPlanHardwareRelationMapper.selectLabRiskPlanHardwareRelationByRiskPlanIdId(riskPlanId);
        Map<HardwareTypeEnum, List<FunctionStatus>> hardwareFunList = hardwareFunctionStatusConfig.getHardwareFunctionStatusListMap();
        for(int i=0;i<riskPlanHardwareList.size();i++){
            List<FunctionStatus> funList = hardwareFunList.get(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
            for(FunctionStatus status:funList){
                if(riskPlanHardwareList.get(i).getOverAct()!=null && status.getCode().equals(riskPlanHardwareList.get(i).getOverAct())){
                    //根据实验室id和设备类型查询硬件列表
                    LabHardware labHardware = new LabHardware();
                    labHardware.setSubjectId(subjectId);
                    labHardware.setType(HardwareTypeEnum.getByCode(riskPlanHardwareList.get(i).getHardwareType()));
                    List<LabHardware> hardwareList = labHardwareMapper.selectLabHardwareListBySubject(labHardware);
                    //循环执行实验室下的硬件功能
                    for(LabHardware hard:hardwareList){
                        log.error("调用硬件，获取硬件id======================================================="+hard.getId());
                        labSubjectManagerService.excutingComm(hard,status);
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        log.error("这里硬件调用结束=======================================================");
    }



    /**
     * 预案传感器json处理
     *
     * @param allRiskPlanJson 预案json，sensorFunc 传感器功能
     * @return 结果
     */
    public void getJsonStr(JSONArray allRiskPlanJson,SensorFunctionStatus sensorFunc){
        JSONObject jsonObj=new JSONObject();
        jsonObj.putOnce("value",sensorFunc.getVal());
        jsonObj.putOnce("describe",sensorFunc.getDescribe());
        jsonObj.putOnce("unit",sensorFunc.getUnit());
        jsonObj.putOnce("funNum",sensorFunc.getFunNum());
        allRiskPlanJson.add(jsonObj);
    }


    /**
     * 智能匹配预案
     *
     * @param riskPlanList 预案列表，senseFuncList 传感器功能列表
     * @return 结果
     */
    public LabRiskPlan matchingRiskPlan(List<LabRiskPlan> riskPlanList,SubFunction<SensorFunctionStatus> subFunction){
        LabRiskPlan newRiskPlan=null;
//        //预案列表循环
//        int maxCount = 0;
//        for(int i=0;i<riskPlanList.size();i++){
//            int count = 0;
//            List<LabRiskPlanSensorRelation> riskPlanSensorList = riskPlanList.get(i).getRiskPlanSensorList();
//            //预案关联的传感器关联表
//            for(LabRiskPlanSensorRelation rps:riskPlanSensorList){
//                //硬件社保统一传入的传感器设备列表
//                for(SensorFunctionStatus sensorFunc:subFunction.getFunctionStatuses()){
//                    if(sensorFunc.getFunNum().equals(rps.getFunNum())){
//                        Float senseVal = Float.parseFloat(sensorFunc.getVal());
//                        Float minMonitor = rps.getMinMonitor().floatValue();
//                        Float maxMonitor = rps.getMaxMonitor().floatValue();
//                        if((senseVal>=minMonitor) && (senseVal<=maxMonitor)){
//                            count++;
//                        }
//                    }
//                }
//            }
//            //判断贪婪模式，根据不同预案匹配传感器最多的执行对应预案
//            if(maxCount<=count && count == riskPlanSensorList.size()){
//                maxCount = count;
//                newRiskPlan = riskPlanList.get(i);
//            }
//        }

        List<LabRiskPlan> riskList = new ArrayList <>();
        Map<Long,Set> riskMap = new HashMap <>();
        //预案列表循环
        Optional.ofNullable(riskPlanList).filter(a -> a.size() > 0).orElseGet(Collections::emptyList).stream().
                forEach(a->Optional.ofNullable(a.getRiskPlanSensorList()).filter(c-> c.size() > 0).orElseGet(Collections::emptyList).stream().forEach(c->{
                    Optional.ofNullable(subFunction.getFunctionStatuses()).filter(t -> t.size() > 0).orElseGet(Collections::emptyList).stream().forEach(t->{
                       if(t.getFunNum().equals(c.getFunNum())){
                           Float senseVal = null;
                           try {
                               senseVal = Float.parseFloat(t.getVal());
                           } catch (NumberFormatException e) {
                               return;
                           }
                           //判断值范围  在范围内存储预案ID和类型名称 （火焰，温度，湿度）
                           if((senseVal>=c.getMinMonitor().floatValue()) && (senseVal<=c.getMaxMonitor().floatValue())){
                               if(riskMap.get(a.getId())!=null){
                                   riskMap.get(a.getId()).add(t.getFunNum());
                               }else{
                                   Set newSet = new HashSet();
                                   newSet.add(t.getFunNum());
                                   riskMap.put(a.getId(),newSet);
                               }
                           }
                       }
                    });
                    //根据传感器匹配的数量相等，把当前预案放入list里面
                    if(riskMap.get(a.getId())!=null && riskMap.get(a.getId()).size() == a.getRiskPlanSensorList().size()){
                        a.setRiskPlanSensorSize(a.getRiskPlanSensorList().size());
                        riskList.add(a);
                    }
                }));
        //判断贪婪模式，根据不同预案匹配传感器最多的执行对应预案
        newRiskPlan =  Optional.ofNullable(riskList).filter(a -> a.size() > 0).orElseGet(Collections::emptyList).stream().max(
                Comparator.comparingInt(LabRiskPlan::getRiskPlanSensorSize)
        ).orElse(null);


        return newRiskPlan;
    }

//    /**
//     * 烟雾传感器特殊处理，根据一段时间智能分析补偿动作
//     *
//     * @param subFunction 传感器上报数据
//     * @return 结果
//     */
//    public void intelligentMotionCompensation(SubFunction<SensorFunctionStatus> subFunction){
//        Optional.ofNullable(subFunction.getFunctionStatuses()).filter(t -> t.size() > 0).orElseGet(Collections::emptyList).stream().forEach(t->{
//            if(t.getFunNum()!=null && t.getFunNum().equals("yanwu")){
//                if(t.getVal()!=null && t.getVal().equals("1")){
//                    redisService.setCacheObject("subjectByYw", t.getVal(), 1L, TimeUnit.MINUTES);
//                }else{
//                    if(redisService.getCacheObject("subjectByYw")!=null){
//                        t.setVal(redisService.getCacheObject("subjectByYw"));
//                    }
//                }
//            }
//        });
//    }



    /**
     * 预案触发的时候，关闭所有实验室下的电源
     *
     * @param subId 实验室id
     * @return 结果
     */
    @Override
    public int closePower(Long subId) {
        //根据实验室id和设备类型查询硬件列表
        LabHardware labHardware = new LabHardware();
        labHardware.setSubjectId(subId);
        labHardware.setType(HardwareTypeEnum.SWITCH);
        List<LabHardware> hardwareList = labHardwareMapper.selectLabHardwareListBySubject(labHardware);
        //循环执行实验室下的硬件功能
        Optional.ofNullable(hardwareList).filter(a->a.size()>0).orElseGet(Collections::emptyList).stream().forEach(a->{
            subjectManagerService.control(a.getId(), Symbol.command.close);
        });
        return 200;
    }
}
