package com.yeejoin.equipmanage.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

//import net.sf.json.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.feign.systemctl.model.MessageModel;
import com.yeejoin.equipmanage.common.datasync.entity.FireEquipment;
import com.yeejoin.equipmanage.common.datasync.entity.FireEquipmentDefectAlarm;
import com.yeejoin.equipmanage.common.datasync.entity.FireEquipmentFaultAlarm;
import com.yeejoin.equipmanage.common.datasync.entity.FireEquipmentFireAlarm;
import com.yeejoin.equipmanage.common.dto.TemperatureAlarmDto;
import com.yeejoin.equipmanage.common.entity.CarProperty;
import com.yeejoin.equipmanage.common.entity.EquipmentAlarmReportDay;
import com.yeejoin.equipmanage.common.entity.EquipmentDetail;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecific;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificAlarm;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificAlarmLog;
import com.yeejoin.equipmanage.common.entity.EquipmentSpecificIndex;
import com.yeejoin.equipmanage.common.entity.FireFightingSystemEntity;
import com.yeejoin.equipmanage.common.entity.publics.BaseEntity;
import com.yeejoin.equipmanage.common.entity.vo.CarIndexVo;
import com.yeejoin.equipmanage.common.entity.vo.CarPropertyVo;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentIndexVO;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentSpecificVo;
import com.yeejoin.equipmanage.common.entity.vo.EquipmentStateVo;
import com.yeejoin.equipmanage.common.entity.vo.IndexStateVo;
import com.yeejoin.equipmanage.common.enums.AlarmStatusEnum;
import com.yeejoin.equipmanage.common.enums.AlarmTypeEnum;
import com.yeejoin.equipmanage.common.enums.CarForGisEnum;
import com.yeejoin.equipmanage.common.enums.EquipAndCarEnum;
import com.yeejoin.equipmanage.common.enums.EquipmentIndexLabelsEnum;
import com.yeejoin.equipmanage.common.enums.EquipmentRiskTypeEnum;
import com.yeejoin.equipmanage.common.enums.NBalarmEnum;
import com.yeejoin.equipmanage.common.enums.RiskLeverForAutoSys;
import com.yeejoin.equipmanage.common.enums.TemperatureAlarm;
import com.yeejoin.equipmanage.common.enums.TopicEnum;
import com.yeejoin.equipmanage.common.enums.TrueOrFalseEnum;
import com.yeejoin.equipmanage.common.utils.DateUtils;
import com.yeejoin.equipmanage.common.utils.EquipmentStateUtil;
import com.yeejoin.equipmanage.common.utils.StringUtil;
import com.yeejoin.equipmanage.common.vo.CarIndexGisVo;
import com.yeejoin.equipmanage.common.vo.EquipmentIndexLabelsVo;
import com.yeejoin.equipmanage.common.vo.EquipmentVo;
import com.yeejoin.equipmanage.common.vo.IotDataVO;
import com.yeejoin.equipmanage.common.vo.Token;
import com.yeejoin.equipmanage.common.vo.TopicEntityVo;
import com.yeejoin.equipmanage.fegin.SystemctlFeign;
import com.yeejoin.equipmanage.mapper.CarMapper;
import com.yeejoin.equipmanage.mapper.EquipmentSpecificAlarmMapper;
import com.yeejoin.equipmanage.mapper.EquipmentSpecificIndexMapper;
import com.yeejoin.equipmanage.mapper.EquipmentSpecificMapper;
import com.yeejoin.equipmanage.mapper.FireFightingSystemMapper;
import com.yeejoin.equipmanage.remote.RemoteSecurityService;
import com.yeejoin.equipmanage.service.ICarPropertyService;
import com.yeejoin.equipmanage.service.IEquipmentAlarmReportDayService;
import com.yeejoin.equipmanage.service.IEquipmentDetailService;
import com.yeejoin.equipmanage.service.IEquipmentIndexService;
import com.yeejoin.equipmanage.service.IEquipmentService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificAlarmLogService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificAlarmService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificIndexSerivce;
import com.yeejoin.equipmanage.service.IEquipmentSpecificIndexService;
import com.yeejoin.equipmanage.service.IEquipmentSpecificSerivce;
import com.yeejoin.equipmanage.service.IFireFightingSystemService;
import com.yeejoin.equipmanage.service.IMainIotMonitorSerivce;
import com.yeejoin.equipmanage.service.ISyncDataService;
import com.yeejoin.equipmanage.service.MqttReceiveService;
import com.yeejoin.equipmanage.service.MqttSendGateway;
import com.yeejoin.equipmanage.utils.BeanUtil;

import lombok.extern.slf4j.Slf4j;

/**
 * @author keyong
 * @title: MqttReceiveServiceImpl
 * <pre>
 * @description: 增量数据处理
 * </pre>
 * @date 2020/11/3 13:39
 */
@Slf4j
@Service
public class MqttReceiveServiceImpl implements MqttReceiveService {

    private static Map<String, TemperatureAlarmDto> temperatureMap = new HashMap<>();

    @Autowired
    IEquipmentSpecificIndexService equipmentSpecificIndexService;

    @Autowired
    ICarPropertyService carPropertyService;

    @Autowired
    IEquipmentSpecificAlarmService equipmentSpecificAlarmService;

    @Autowired
    IEquipmentSpecificAlarmLogService equipmentSpecificAlarmLogService;

    @Autowired
    EquipmentSpecificAlarmMapper equipmentSpecificAlarmMapper;

    @Autowired
    @Lazy
    IEquipmentIndexService equipmentIndexService;

    @Autowired
    EquipmentSpecificIndexMapper equipmentSpecificIndexMapper;

    @Autowired
    EquipmentSpecificMapper equipmentSpecificMapper;

    @Autowired
    FireFightingSystemMapper FireFightingSystemMapper;

    @Autowired
    IFireFightingSystemService fireFightingSystemService;

    @Autowired
    MqttSendGateway mqttSendGateway;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    CarMapper carMapper;

    @Autowired
    IMainIotMonitorSerivce iMainIotMonitorSerivce;

    @Autowired
    private IEquipmentSpecificIndexSerivce equipmentSpecificIndexSerivce;

    @Autowired
    private ISyncDataService syncDataService;

    @Autowired
    private IEquipmentAlarmReportDayService iEquipmentAlarmReportDayService;

    @Autowired
    private IEquipmentDetailService iEquipmentDetailService;

    @Autowired
    private IEquipmentSpecificSerivce iEquipmentSpecificSerivce;

    @Autowired
    FireFightingSystemMapper fireFightingSystemMapper;

    @Autowired
    private SystemctlFeign systemctlFeign;

    @Autowired
    private TopographyService topographyService;

    @Autowired
    private IEquipmentService equipmentService;

    @Autowired
    private RemoteSecurityService remoteSecurityService;

    @Value("${equipManage.name}")
    private String serverName;

    @Value("${mqtt.vehicle.topic}")
    private String carTopic;

    @Value("${equip.point.equipmentdata.topic}")
    private String canvasTopic;

    @Value("${equip.index.topic}")
    private String indexTopic;

    @Value("${spring.redis.expire.time}")
    private long redisExpireTime;

    @Value("${systemctl.sync.switch}")
    private Boolean syncSwitch;

    @Value("${systemctl.amos.switch}")
    private Boolean amosSwitch;

    private static final String A = "A";

    private final static Map staticMap = new HashMap();

    static {
        staticMap.put("FireCar_GDLongitude", "0");
        staticMap.put("FireCar_GDLatitude", "0");
        staticMap.put("FireCar_Speed", "0");
        staticMap.put("FireCar_Power", "0");
        staticMap.put("FireCar_CourseOverGround", "0");
        staticMap.put("time", System.currentTimeMillis());
        staticMap.put("state", "false");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerMqttIncrementMessage(String topic, String message) {

        TopicEntityVo topicEntity = new TopicEntityVo();
        topicEntity.setTopic(topic);
        topicEntity.setMessage(message);
        int endIndex = topic.lastIndexOf("/");
        String iotCode = topic.substring(0, endIndex).replace("/", "");
        topicEntity.setIotCode(iotCode);
        List<EquipmentSpecificVo> eqIotCodeList = iEquipmentSpecificSerivce.getEquipAndCarIotcodeByIotcode(iotCode);
//        		equipmentSpecificMapper.getEquipOrCarByIotCode(iotCode);
        if (eqIotCodeList.isEmpty()) {
            log.info("该数据{}不存在！", iotCode);
            return;
        }
        if (eqIotCodeList.size() > 1) {
            log.info("有重复的{}数据！", iotCode);
        }
        EquipmentSpecificVo vo = eqIotCodeList.get(0);
        topicEntity.setType(vo.getType());
        topicEntity.setCode(vo.getCode());

        JSONObject json = JSONObject.parseObject(message);
        Iterator it = json.entrySet().iterator();
        List<IotDataVO> iotDatalist = new ArrayList<IotDataVO>();
        while (it.hasNext()) {
            IotDataVO iotDataVO = new IotDataVO();
            Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
            iotDataVO.setKey(entry.getKey());
            iotDataVO.setValue(entry.getValue());
            iotDatalist.add(iotDataVO);
        }
        if (ObjectUtils.isEmpty(iotDatalist)) {
            return;
        }
        log.info(String.format("收到mqtt消息：%s", message));
        saveDataToDB(topicEntity, iotDatalist);
    }

    /**
     * <pre>
     * @Description: 持久化数据
     * </pre>
     *
     * @MethodName:
     * @Param:
     * @Return:
     * @Throws
     * @Author keyong
     * @Date 2021/1/7 18:17
     */
    public void saveDataToDB(TopicEntityVo topicEntity, List<IotDataVO> iotDatalist) {
        String iotCode = topicEntity.getIotCode();
        List<EquipmentSpecificIndex> indexList = equipmentSpecificIndexService.getEquipmentSpeIndexBySpeIotCode(iotCode);
        List<CarProperty> carProperties = carPropertyService.getCarPropListByIotCode(iotCode);
        if (ObjectUtils.isEmpty(indexList) && ObjectUtils.isEmpty(carProperties)) {
            return;
        }

        // 存储温度告警（火眼）
        iotDataListToCacheMap(iotDatalist);

        iotDatalist.forEach(iotDataVO -> {
            if (EquipAndCarEnum.equip.type.equals(topicEntity.getType())) {
                // 装备指标信息存储，装备信息系统不存在的指标不做更新处理也不添加
                List<EquipmentSpecificIndex> equipmentSpecificIndexList = new ArrayList<>();
                List<EquipmentSpecificAlarm> equipmentSpecificAlarms = new ArrayList<>();
                List<EquipmentAlarmReportDay> equipmentAlarmReports = new ArrayList<>();
                List<EquipmentSpecificAlarmLog> equipmentAlarmLogs = new ArrayList<>();
                List<IndexStateVo> indexStateList = new ArrayList<>();
                EquipmentStateVo equipmentStateVo = new EquipmentStateVo();
                List<EquipmentSpecificIndex> newIndexList = new ArrayList<>();
                for (EquipmentSpecificIndex equipmentSpecificIndex : indexList) {
                    EquipmentSpecificIndex equipmentSpeIndex = new EquipmentSpecificIndex();
                    IndexStateVo indexStateVo = new IndexStateVo();
                    newIndexList.add(equipmentSpecificIndex);

                    if (equipmentSpecificIndex.getNameKey() != null && equipmentSpecificIndex.getNameKey().toLowerCase().equals(iotDataVO.getKey().toLowerCase())) {
                        BeanUtils.copyProperties(equipmentSpecificIndex, equipmentSpeIndex);
                        String value = iotDataVO.getValue().toString();
                        equipmentSpeIndex.setValue(value);
                        equipmentSpecificIndex.setValue(value);
                        String enumStr = equipmentSpecificIndex.getValueEnum();
                        if (!ObjectUtils.isEmpty(enumStr)) {
                          try {
                            JSONArray jsonArray = JSONArray.parseArray(enumStr);
                            for (int i = 0; i < jsonArray.size(); i++) {
                              JSONObject jsonObject = jsonArray.getJSONObject(i);
                              if (jsonObject.get("key").equals(value)) {
                                equipmentSpeIndex.setValueLabel(jsonObject.getString("label"));
                                equipmentSpecificIndex.setValueLabel(jsonObject.getString("label"));
                              }
                            }
                          } catch (Exception e) {

                          }
                        }
                        
                        
                        equipmentSpecificIndexList.add(equipmentSpeIndex);
                        equipmentSpecificAlarms.addAll(addIndexAlarmRecord(equipmentSpeIndex, iotDatalist));
                        equipmentAlarmReports.add(addEquipAlarmReportRecord(equipmentSpeIndex));

                        // 封装用于性能指标状态变化的实体
                        indexStateVo.setId(iotCode + "_" + equipmentSpecificIndex.getNameKey());
                        indexStateVo.setData((String.valueOf(iotDataVO.getValue())));
                        indexStateVo.setIndexKey(equipmentSpecificIndex.getNameKey());
                        indexStateVo.setIndexName(equipmentSpecificIndex.getIndexName());
                        indexStateVo.setTypeCode(equipmentSpecificIndex.getTypeCode());
                        indexStateVo.setTypeName(equipmentSpecificIndex.getTypeName());
                        indexStateList.add(indexStateVo);


                        // 发送数据至换流站
                        TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                            @Override
                            public void afterCommit() {
                                String topic = "";
                                if (TrueOrFalseEnum.real.value.equals(value) && EquipmentRiskTypeEnum.HZGJ.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
                                    equipmentSpeIndex.setType(EquipmentRiskTypeEnum.HZGJ.getCode());
                                    topic = String.format("%s.%s%s", serverName, "equipment/", RiskLeverForAutoSys.BJ.getCode());
                                } else if (TrueOrFalseEnum.real.value.equals(value) && EquipmentRiskTypeEnum.GZ.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
                                    equipmentSpeIndex.setType(EquipmentRiskTypeEnum.GZ.getCode());
                                    topic = String.format("%s.%s%s", serverName, "equipment/", RiskLeverForAutoSys.GZ.getCode());
                                } else {
                                    equipmentSpeIndex.setType(EquipmentRiskTypeEnum.QT.getCode());
                                    topic = String.format("%s.%s%s", serverName, "equipment/", RiskLeverForAutoSys.JC.getCode());
                                }
                                TopicEntityVo topicEntityVo = new TopicEntityVo();
                                BeanUtils.copyProperties(topicEntity, topicEntityVo);
                                topicEntityVo.setTopic(topic);
                                topicEntityVo.setMessage(JSON.toJSONString(equipmentSpeIndex));
                                mqttSendGateway.sendToMqtt(topic, JSON.toJSONString(topicEntityVo));
                            }
                        });


                        equipmentStateVo.setEquipName(equipmentSpecificIndex.getEquipmentSpecificName());
                        equipmentStateVo.setOrgCode(equipmentSpecificIndex.getOrgCode());
                        equipmentStateVo.setSpecificId(equipmentSpecificIndex.getEquipmentSpecificId());
                        equipmentStateVo.setEquipCode(equipmentSpecificIndex.getQrCode());
                        equipmentStateVo.setEquipIotCode(iotCode);
                        List<EquipmentSpecificIndex> tempIndexList = new ArrayList<>();
                        tempIndexList = newIndexList.stream().filter(x -> x.getEquipmentIndexId().equals(equipmentSpeIndex.getEquipmentIndexId())).collect(Collectors.toList());
                        tempIndexList.get(0).setValue(value);
                        tempIndexList.get(0).setUpdateDate(new Date());
                    }
                }

                if (equipmentSpecificIndexList.size() > 0) {
                    boolean updateBatchById = equipmentSpecificIndexService.updateBatchById(equipmentSpecificIndexList);
                    if (updateBatchById && syncSwitch) {
                        //  数据同步
                        List<Long> specificIndexIds = new ArrayList<>();
                        equipmentSpecificIndexList.forEach(x -> specificIndexIds.add(x.getId()));
                        List<EquipmentIndexVO> specificIndexList = equipmentSpecificIndexSerivce.getEquipIndexByIdIn(specificIndexIds);
                        List<EquipmentIndexVO> fireEquipmentInfoCollect = specificIndexList.stream().filter(vo -> 0 == vo.getIsIot()).collect(Collectors.toList());
                        List<EquipmentIndexVO> fireEquipMeasurementCollect = specificIndexList.stream().filter(vo -> 1 == vo.getIsIot()).collect(Collectors.toList());
                        if (0 < fireEquipmentInfoCollect.size()) {
                            syncDataService.syncCreatedEquipmentSpecificInfo(fireEquipmentInfoCollect);
                        }
                        if (0 < fireEquipMeasurementCollect.size()) {
                            syncDataService.syncCreatedFireEquipMeasurement(fireEquipMeasurementCollect);
                        }
                    }
                    String status = EquipmentStateUtil.judgeEquipState(newIndexList);
                    equipmentStateVo.setStatus(status);
                    // 添加性能指标项
                    equipmentStateVo.setSpeindexList(fireFightingSystemService.getSpeIndex(equipmentSpecificIndexList.get(0).getEquipmentSpecificId()));
                    //平台数据结构调整，equipCode、status 放到一个对象里
                    Map<String, Object> topicObject = new HashMap<>();
                    topicObject.put("equipCode", equipmentStateVo.getEquipCode());
                    topicObject.put("status", equipmentStateVo.getStatus());
                    Map<String, Object> map = JSON.parseObject(JSON.toJSONString(equipmentStateVo));
                    map.put(canvasTopic, topicObject);
                    // 发送数据至画布
                    mqttSendGateway.sendToMqtt(canvasTopic, JSON.toJSONString(map));
                }

                // 设备报警日报表数据储存更新
                SimpleDateFormat sdf = new SimpleDateFormat(DateUtils.DATE_PATTERN);
                if (!equipmentAlarmReports.isEmpty()) {
                    equipmentAlarmReports.forEach(x -> {
                        LambdaQueryWrapper<EquipmentAlarmReportDay> wrapper = new LambdaQueryWrapper<>();
                        wrapper.eq(EquipmentAlarmReportDay::getReportDate, sdf.format(x.getReportDate())).eq(EquipmentAlarmReportDay::getIndexId, x.getIndexId())
                                .eq(EquipmentAlarmReportDay::getEquipmentSpecificId, x.getEquipmentSpecificId());
                        List<EquipmentAlarmReportDay> reportDayList = iEquipmentAlarmReportDayService.list(wrapper);
                        if (reportDayList.isEmpty()) {
                            x.setReportDate(new Date());
                            x.setFrequency(1);
                            iEquipmentAlarmReportDayService.save(x);
                        } else {
                            EquipmentAlarmReportDay reportDay = reportDayList.get(0);
                            reportDay.setLastReportDate(new Date());
                            reportDay.setValue(x.getValue());
                            reportDay.setFrequency(reportDay.getFrequency() + 1);
                            reportDay.setIndexTrueNum(reportDay.getIndexTrueNum() == null ? x.getIndexTrueNum() : reportDay.getIndexTrueNum() + x.getIndexTrueNum());
                            iEquipmentAlarmReportDayService.updateById(reportDay);
                        }
                    });
                    mqttSendGateway.sendToMqtt(TopicEnum.EQXXTJ.getTopic(), "");
                }

                Long alarmId = 0L;
                if (!ObjectUtils.isEmpty(equipmentSpecificAlarms)) {
                    List<Long> specificAlarmIds = new ArrayList<>();
                    List<Long> equipIndexIds = new ArrayList<>();
                    for (EquipmentSpecificAlarm action : equipmentSpecificAlarms) {
                        //	通过设备ID，查询设备位置
                        EquipmentSpecific specific = new EquipmentSpecific();
                        specific.setId(action.getEquipmentSpecificId());
                        FireEquipment fireEquipment = iEquipmentSpecificSerivce.getEquipSpecificDetail(specific);
                        if (!ObjectUtils.isEmpty(fireEquipment)) {
                            action.setLocation(fireEquipment.getPosition());
                            action.setCode(fireEquipment.getCode());
                            action.setBuildId(fireEquipment.getBuildId());
                        }
                        equipmentSpecificAlarmService.saveOrUpdate(action);
                        if (AlarmStatusEnum.BJ.getCode() == action.getStatus()) {
                            equipmentAlarmLogs.add(addEquipAlarmLogRecord(action));
                            if (ValidationUtil.isEmpty(action.getAlamContent())){
                                action.setAlamContent(action.getEquipmentSpecificName() + action.getEquipmentSpecificIndexName());
                            }
                            mqttSendGateway.sendToMqtt(TopicEnum.EQDQR.getTopic(), JSONArray.toJSON(action).toString());
                        }
                        specificAlarmIds.add(action.getId());
                        equipIndexIds.add(action.getEquipmentIndexId());
                    }
                    if (syncSwitch) {
                        List<FireEquipmentFireAlarm> alarmList = equipmentSpecificAlarmService.getFireEquipAlarmDetailsByAlarmId(specificAlarmIds, equipIndexIds);
                        if (!CollectionUtils.isEmpty(alarmList)) {
                            Map<String, List<FireEquipmentFireAlarm>> collect = alarmList.stream().collect(Collectors.groupingBy(FireEquipmentFireAlarm::getType));
                            for (String key : collect.keySet()) {
                                List<FireEquipmentFireAlarm> list = collect.get(key);
                                if (!CollectionUtils.isEmpty(list)) {
                                    if ("FIREALARM".equalsIgnoreCase(key)) {
                                        syncDataService.syncCreatedFireEquipAlarm(list);
                                    } else if ("BREAKDOWN".equalsIgnoreCase(key)) {
                                        List<FireEquipmentFaultAlarm> faultAlarms = list.stream().map(x -> {
                                            FireEquipmentFaultAlarm fireEquipmentFaultAlarm = new FireEquipmentFaultAlarm();
                                            BeanUtils.copyProperties(x, fireEquipmentFaultAlarm);
                                            return fireEquipmentFaultAlarm;
                                        }).collect(Collectors.toList());
                                        syncDataService.syncCreatedFireEquiptFaultAlarm(faultAlarms);
                                    } else if ("SHIELD".equalsIgnoreCase(key)) {
                                        List<FireEquipmentDefectAlarm> defectAlarms = list.stream().map(x -> {
                                            FireEquipmentDefectAlarm fireEquipmentFaultAlarm = new FireEquipmentDefectAlarm();
                                            BeanUtils.copyProperties(x, fireEquipmentFaultAlarm);
                                            return fireEquipmentFaultAlarm;
                                        }).collect(Collectors.toList());
                                        syncDataService.syncCreatedFireEquipDefectAlarm(defectAlarms);
                                    }
                                }
                            }
                        }
                        syncDataService.syncCreatedSendAlarm(equipmentAlarmLogs);
                    }
                }

                // 首页性能指标数据订阅
                mqttSendGateway.sendToMqtt(indexTopic, JSON.toJSONString(indexStateList));

                //TODO 数字化换流站组态屏数据推送,需要在事务提交之后，否侧事务隔离查询不出数据
                TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
                    @Override
                    public void afterCommit() {
                        iEquipmentSpecificSerivce.integrationPageSysDataRefresh(topicEntity.getCode());
                        iEquipmentSpecificSerivce.updateEquipmentSpecIndexRealtimeData(equipmentSpecificIndexList);
                        //数字换流站站使用
                        mqttSendGateway.sendToMqtt(TopicEnum.EQZXDT.getTopic(), "");
                        if (!equipmentAlarmLogs.isEmpty()) {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put("seqNo", UUID.randomUUID().toString().replace("-", "").toLowerCase());
                            mqttSendGateway.sendToMqtt(TopicEnum.ALARM_LOG_INSERT.getTopic(), jsonObject.toString());
                            if (syncSwitch) {
                                syncDataService.syncCreatedSendAlarm(equipmentAlarmLogs);
                            }
                        }
                    }
                });

            } else {
                // 对指标key为labels的数据处理
                if (EquipmentIndexLabelsEnum.labels.name.equals(iotDataVO.getKey())) {
                    StringBuilder sb = new StringBuilder("equipmentOnCar_");
                    EquipmentIndexLabelsVo labelsVo = new EquipmentIndexLabelsVo();
                    Object obj = iotDataVO.getValue();
                    if (obj instanceof JSONArray) {
                        List<String> labelList = (List<String>) obj;
                        labelList.forEach(code -> {
                            String key = sb.append(code).toString();
                            labelsVo.setEquipmentIotCode(code);
                            labelsVo.setTime(new Date());
                            redisUtils.set(key, com.alibaba.fastjson.JSONObject.toJSONString(labelsVo), redisExpireTime);
                        });
                    }
                }

                // 车辆指标信息存储
                List<CarProperty> carPropList = carPropertyService.getCarPropListByIotCode(iotCode);
                List<CarProperty> carList = new ArrayList<>();
                List<CarIndexVo> cars = carMapper.getCarsIotInfoByIotCode(iotCode);
                List<CarIndexGisVo> list = new ArrayList<>();
                long id = 0;
                boolean bool = cars.size() > 0;
                if (bool) {
                    id = cars.get(0).getId();
                }
                if (carPropList.size() > 0) {
                    for (CarProperty carProperty : carPropList) {
                        CarProperty property = new CarProperty();
                        if (iotDataVO.getKey().equals(carProperty.getNameKey())) {
                            BeanUtils.copyProperties(carProperty, property);
                            property.setValue(iotDataVO.getValue().toString());
                            carProperty.setValue(iotDataVO.getValue().toString());
                            carList.add(property);
                        }

                        if (bool) {
                            CarIndexGisVo carIndexGisVo = new CarIndexGisVo();
                            for (CarIndexVo carIndexVo : cars) {
                                carIndexGisVo.setId(carIndexVo.getId());
                                carIndexGisVo.setIotCode(iotCode);
                                if (CarForGisEnum.JD.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.JD.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.JD.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.WD.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.WD.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.WD.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.SD.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.SD.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.SD.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.DL.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.DL.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.DL.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.DDHX.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.DDHX.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.DDHX.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.SJ.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.SJ.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.SJ.getNameKey()).toString());
                                    }
                                } else if (CarForGisEnum.QT.getNameKey().equals(carProperty.getNameKey()) && CarForGisEnum.QT.getNameKey().equals(carIndexVo.getNameKey())) {
                                    if (StringUtil.isNotEmpty(carProperty.getValue())) {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(carProperty.getValue());
                                    } else {
                                        carIndexGisVo.setNameKey(carProperty.getNameKey());
                                        carIndexGisVo.setValue(staticMap.get(CarForGisEnum.QT.getNameKey()).toString());
                                    }
                                }
                            }
                            list.add(carIndexGisVo);
                        }
                    }
                }


                if (list.size() > 0) {
                    if (0 == list.stream().filter(index -> CarForGisEnum.JD.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.JD.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.JD.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.WD.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.WD.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.WD.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.SD.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.SD.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.SD.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.DL.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.DL.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.DL.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.DDHX.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.DDHX.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.DDHX.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.SJ.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.SJ.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.SJ.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                    if (0 == list.stream().filter(index -> CarForGisEnum.QT.getNameKey().equals(index.getNameKey())).collect(Collectors.toList()).size()) {
                        CarIndexGisVo indexGisVo = new CarIndexGisVo();
                        indexGisVo.setId(id);
                        indexGisVo.setIotCode(iotCode);
                        indexGisVo.setNameKey(CarForGisEnum.QT.getNameKey());
                        indexGisVo.setValue(staticMap.get(CarForGisEnum.QT.getNameKey()).toString());
                        list.add(indexGisVo);
                    }
                } else {
                    CarIndexGisVo gisVo1 = new CarIndexGisVo();
                    gisVo1.setId(id);
                    gisVo1.setIotCode(iotCode);
                    gisVo1.setNameKey(CarForGisEnum.JD.getNameKey());
                    gisVo1.setValue(staticMap.get(CarForGisEnum.JD.getNameKey()).toString());
                    list.add(gisVo1);
                    CarIndexGisVo gisVo2 = new CarIndexGisVo();
                    gisVo2.setId(id);
                    gisVo2.setIotCode(iotCode);
                    gisVo2.setNameKey(CarForGisEnum.WD.getNameKey());
                    gisVo2.setValue(staticMap.get(CarForGisEnum.WD.getNameKey()).toString());
                    list.add(gisVo2);
                    CarIndexGisVo gisVo3 = new CarIndexGisVo();
                    gisVo3.setId(id);
                    gisVo3.setIotCode(iotCode);
                    gisVo3.setNameKey(CarForGisEnum.SD.getNameKey());
                    gisVo3.setValue(staticMap.get(CarForGisEnum.SD.getNameKey()).toString());
                    list.add(gisVo3);
                    CarIndexGisVo gisVo4 = new CarIndexGisVo();
                    gisVo4.setId(id);
                    gisVo4.setIotCode(iotCode);
                    gisVo4.setNameKey(CarForGisEnum.DL.getNameKey());
                    gisVo4.setValue(staticMap.get(CarForGisEnum.DL.getNameKey()).toString());
                    list.add(gisVo4);
                    CarIndexGisVo gisVo5 = new CarIndexGisVo();
                    gisVo5.setId(id);
                    gisVo5.setIotCode(iotCode);
                    gisVo5.setNameKey(CarForGisEnum.DDHX.getNameKey());
                    gisVo5.setValue(staticMap.get(CarForGisEnum.DDHX.getNameKey()).toString());
                    list.add(gisVo5);
                    CarIndexGisVo gisVo6 = new CarIndexGisVo();
                    gisVo6.setId(id);
                    gisVo6.setIotCode(iotCode);
                    gisVo6.setNameKey(CarForGisEnum.SJ.getNameKey());
                    gisVo6.setValue(staticMap.get(CarForGisEnum.SJ.getNameKey()).toString());
                    list.add(gisVo6);
                    CarIndexGisVo gisVo7 = new CarIndexGisVo();
                    gisVo7.setId(id);
                    gisVo7.setIotCode(iotCode);
                    gisVo7.setNameKey(CarForGisEnum.QT.getNameKey());
                    gisVo7.setValue(staticMap.get(CarForGisEnum.QT.getNameKey()).toString());
                    list.add(gisVo7);
                }
                boolean flag = ifSendToGis(list);
                if (flag) {
                    mqttSendGateway.sendToMqtt(carTopic, JSON.toJSONString(list));
                }
                if (carList.size() > 0) {
                    boolean updateBatchById = carPropertyService.updateBatchById(carList);
                    if (updateBatchById && syncSwitch) {
                        List<Long> carIds = new ArrayList<>();
                        carList.forEach(x -> carIds.add(x.getCarId()));
                        List<CarPropertyVo> propertyList = carPropertyService.getCarPropertyListByCarIds(carIds);
                        List<CarPropertyVo> fireVehicleInfoList = propertyList.stream().filter(propertyVo -> propertyVo.getIsIot() == null || 0 == propertyVo.getIsIot()).collect(Collectors.toList());
                        List<CarPropertyVo> fireVehicleMeasurementList = propertyList.stream().filter(propertyVo -> propertyVo.getIsIot() != null && 1 == propertyVo.getIsIot()).collect(Collectors.toList());
                        syncDataService.syncCreatedFireVehicleInfo(fireVehicleInfoList);
                        syncDataService.syncCreatedFireVehicleMeasurement(fireVehicleMeasurementList);
                    }
                }
            }

        });

        //若为物联设备，则更新拓扑节点数据及告警状态
        if (!ObjectUtils.isEmpty(indexList)) {
            EquipmentVo equipmentVo = equipmentService.getEquipBySpecific(indexList.get(0).getEquipmentSpecificId());
            if (equipmentVo.getIsIot().equals("1")) {
                List<EquipmentSpecificAlarm> alarmList = equipmentSpecificAlarmService.getEquipListBySpecific(true, indexList.get(0).getEquipmentSpecificId());
                topographyService.updateNodeDateByEquipId(indexList.get(0).getEquipmentSpecificId(), indexList, alarmList);
            }
        }
    }

    void syncSystemctlMsg(EquipmentSpecificAlarmLog equipmentSpecificAlarmLog) {
        try {
            MessageModel model = new MessageModel();
            String alarmReason = ValidationUtil.isEmpty(equipmentSpecificAlarmLog.getAlarmReason()) ? "" : equipmentSpecificAlarmLog.getAlarmReason();
            if (alarmReason.contains("：")) {
                String[] split = alarmReason.split("：");
                alarmReason = split[1];
            }
            model.setTitle(equipmentSpecificAlarmLog.getEquipmentSpecificIndexName());
            String body = String.format("警情类型：%s；报警设备：%s；报警位置：%s；报警原因：%s；报警时间：%s",
                    equipmentSpecificAlarmLog.getEquipmentSpecificIndexName(), equipmentSpecificAlarmLog.getEquipmentSpecificName(),
                    equipmentSpecificAlarmLog.getLocation(), alarmReason,
                    DateUtils.date2LongStr(equipmentSpecificAlarmLog.getCreateDate()));
            model.setBody(body);
            model.setMsgType("iotMonitor");
            model.setIsSendApp(true);
            model.setIsSendWeb(true);
            model.setTerminal("APP/WEB");
            model.setCategory(1);
            model.setRelationId(String.valueOf(equipmentSpecificAlarmLog.getId()));
            Token token = remoteSecurityService.getServerToken();
            systemctlFeign.create(token.getAppKey(), token.getProduct(), token.getToke(), model);
            log.info(String.format("调用平台消息服务成功：%s", JSON.toJSONString(model)));
        } catch (InnerInvokException e) {
//			e.printStackTrace();
            log.error("告警消息同步平台失败：syncSystemctlMsg，===>>>" + e.getMessage());
        }
    }

    public List<EquipmentSpecificAlarm> addIndexAlarmRecord(EquipmentSpecificIndex equipmentSpcIndex, List<IotDataVO> iotDatalist) {
        // 处理火眼视频异常
        EquipmentSpecificIndex equipmentSpecificIndex = handleTemperatureAlarm(equipmentSpcIndex, iotDatalist);
        List<EquipmentSpecificAlarm> equipmentSpecificAlarms = new ArrayList<>();
        EquipmentSpecificAlarm equipmentSpecificAlarm = new EquipmentSpecificAlarm();

        if (EquipmentRiskTypeEnum.GZ.getCode().equals(equipmentSpecificIndex.getTypeCode()) || EquipmentRiskTypeEnum.HZGJ.getCode().equals(equipmentSpecificIndex.getTypeCode())
                || EquipmentRiskTypeEnum.PB.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
            List<EquipmentSpecificAlarm> indexAlarms = equipmentSpecificAlarmMapper.findEquipmentSpecificAlarmByEquipmentSpecificIdAndEquipmentIndexIdAndStatusIstrue(equipmentSpecificIndex.getEquipmentSpecificId(), equipmentSpecificIndex.getEquipmentIndexId());
            // NB设备告警
            if (verifyNB(equipmentSpecificIndex.getNameKey())) {
                return getNbEquipAlarmList(indexAlarms, equipmentSpecificIndex, equipmentSpecificAlarm);
            }

            // 报警表新增信息
            if (ObjectUtils.isEmpty(indexAlarms) && (TrueOrFalseEnum.real.value.equals(equipmentSpecificIndex.getValue()))) {
                addEquipmentSpecificAlarm(equipmentSpecificAlarms, equipmentSpecificIndex, equipmentSpecificAlarm);
            } else {
                // 报警表更新信息
                indexAlarms.forEach(action -> {
                    if (TrueOrFalseEnum.real.value.equals(equipmentSpecificIndex.getValue())) {
                        // 报警，修改发生频率
                        action.setFrequency((action.getFrequency() + 1));
                    } else {
                        // 报警恢复，修改数据为恢复状态
                        action.setRecoveryDate(new Date());
                        action.setEquipmentSpecificIndexValue(TrueOrFalseEnum.fake.value);
                        action.setStatus(AlarmStatusEnum.HF.getCode());
                    }
                    action.setUpdateDate(new Date());
                    equipmentSpecificAlarms.add(action);
                });
            }
        }

        return equipmentSpecificAlarms;
    }

    public String getSystemCodeBySpeId(EquipmentSpecific equipmentSpecific) {
        List<FireFightingSystemEntity> sys = new ArrayList<>();
        String[] ids;
        String sysIds = equipmentSpecific.getSystemId();
        if (StringUtil.isNotEmpty(sysIds)) {
            if (-1 != sysIds.indexOf(",")) {
                ids = sysIds.split(",");
                sys = fireFightingSystemMapper.getFightingSysByIds(ids);
            } else {
                FireFightingSystemEntity entity = fireFightingSystemMapper.selectById(Long.valueOf(sysIds));
                sys.add(entity);
            }
        }
        StringBuilder sb = new StringBuilder();
        sys.forEach(x -> {
            if (0 < sb.length()) {
                sb.append(",");
            }
            sb.append(x.getCode());
        });
        return sb.toString();
    }

    private EquipmentAlarmReportDay addEquipAlarmReportRecord(EquipmentSpecificIndex equipmentSpecificIndex) {
        EquipmentAlarmReportDay equipmentAlarmReportDay = new EquipmentAlarmReportDay();
        LambdaQueryWrapper<EquipmentSpecific> speWrapper = new LambdaQueryWrapper<>();
        EquipmentSpecific equipmentSpecific = iEquipmentSpecificSerivce.getOne(speWrapper.eq(BaseEntity::getId, equipmentSpecificIndex.getEquipmentSpecificId()));
        LambdaQueryWrapper<EquipmentDetail> speDetailWrapper = new LambdaQueryWrapper<>();
        EquipmentDetail detail = iEquipmentDetailService.getOne(speDetailWrapper.eq(BaseEntity::getId, equipmentSpecific.getEquipmentDetailId()));
        equipmentAlarmReportDay.setOrgCode(equipmentSpecific.getOrgCode());
        equipmentAlarmReportDay.setReportDate(new Date());
        equipmentAlarmReportDay.setSystemIds(equipmentSpecific.getSystemId());
        equipmentAlarmReportDay.setLastReportDate(new Date());
        equipmentAlarmReportDay.setEquipmentSpecificId(equipmentSpecific.getId());
        equipmentAlarmReportDay.setEquipmentSpecificName(detail.getName());
        equipmentAlarmReportDay.setEquipmentDetailId(detail.getId());
        equipmentAlarmReportDay.setEquipmentId(detail.getEquipmentId());
        equipmentAlarmReportDay.setEquipmentCode(detail.getCode());
        equipmentAlarmReportDay.setIndexTrueNum(TrueOrFalseEnum.real.value.equals(equipmentSpecificIndex.getValue()) ? 1L : 0L);
        equipmentAlarmReportDay.setAlarmType(equipmentSpecificIndex.getTypeCode());
        equipmentAlarmReportDay.setAlarmTypeName(equipmentSpecificIndex.getTypeName());
        equipmentAlarmReportDay.setIndexId(equipmentSpecificIndex.getEquipmentIndexId());
        equipmentAlarmReportDay.setIndexName(equipmentSpecificIndex.getEquipmentSpecificIndexName());
        equipmentAlarmReportDay.setIndexType(equipmentSpecificIndex.getNameKey());
        equipmentAlarmReportDay.setValue(equipmentSpecificIndex.getValue());
        return equipmentAlarmReportDay;
    }

    private EquipmentSpecificAlarmLog addEquipAlarmLogRecord(EquipmentSpecificAlarm equipmentSpecificAlarm) {
        EquipmentSpecificAlarmLog equipmentSpecificAlarmLog = new EquipmentSpecificAlarmLog();
        equipmentSpecificAlarmLog.setOrgCode(equipmentSpecificAlarm.getOrgCode());
        equipmentSpecificAlarmLog.setCreateDate(new Date());
        equipmentSpecificAlarmLog.setSystemIds(equipmentSpecificAlarm.getSystemIds());
        equipmentSpecificAlarmLog.setEquipmentSpecificId(equipmentSpecificAlarm.getEquipmentSpecificId());
        equipmentSpecificAlarmLog.setIotCode(equipmentSpecificAlarm.getIotCode());
        equipmentSpecificAlarmLog.setSystemCodes(equipmentSpecificAlarm.getSystemCodes());
        equipmentSpecificAlarmLog.setEquipmentCode(equipmentSpecificAlarm.getEquipmentCode());
        equipmentSpecificAlarmLog.setEquipmentSpecificName(equipmentSpecificAlarm.getEquipmentSpecificName());
        equipmentSpecificAlarmLog.setEquipmentDetailId(equipmentSpecificAlarm.getEquipmentDetailId());
        equipmentSpecificAlarmLog.setEquipmentId(equipmentSpecificAlarm.getEquipmentId());
        equipmentSpecificAlarmLog.setType(equipmentSpecificAlarm.getType());
        equipmentSpecificAlarmLog.setEquipmentSpecificIndexValue(equipmentSpecificAlarm.getEquipmentSpecificIndexValue());
        equipmentSpecificAlarmLog.setEquipmentSpecificIndexKey(equipmentSpecificAlarm.getEquipmentSpecificIndexKey());
        equipmentSpecificAlarmLog.setEquipmentSpecificIndexName(equipmentSpecificAlarm.getEquipmentSpecificIndexName());
        equipmentSpecificAlarmLog.setEquipmentIndexId(equipmentSpecificAlarm.getEquipmentIndexId());
        equipmentSpecificAlarmLog.setEquipmentSpecificAlarmId(equipmentSpecificAlarm.getId());
        equipmentSpecificAlarmLog.setLocation(equipmentSpecificAlarm.getLocation());
        equipmentSpecificAlarmLog.setAlarmReason(equipmentSpecificAlarm.getAlamReason());
        equipmentSpecificAlarmLog.setEquipmentSpecificCode(equipmentSpecificAlarm.getCode());
        equipmentSpecificAlarmLog.setBuildId(equipmentSpecificAlarm.getBuildId());
        equipmentSpecificAlarmLog.setStatus(equipmentSpecificAlarm.getStatus());
        equipmentSpecificAlarmLogService.save(equipmentSpecificAlarmLog);
        //  同步告警消息给平台
        if (amosSwitch) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    syncSystemctlMsg(equipmentSpecificAlarmLog);
                }
            }).start();
        }
        return equipmentSpecificAlarmLog;
    }

    /**
     * 添加告警
     *
     * @param equipmentSpecificAlarms
     * @param equipmentSpecificIndex
     * @return
     */
    private List<EquipmentSpecificAlarm> addEquipmentSpecificAlarm(List<EquipmentSpecificAlarm> equipmentSpecificAlarms, EquipmentSpecificIndex equipmentSpecificIndex, EquipmentSpecificAlarm equipmentSpecificAlarm) {
        BeanUtils.copyProperties(equipmentSpecificIndex, equipmentSpecificAlarm);
        equipmentSpecificAlarm.setId(null);
        equipmentSpecificAlarm.setFrequency(1);
        equipmentSpecificAlarm.setStatus(AlarmStatusEnum.BJ.getCode());
        equipmentSpecificAlarm.setEquipmentSpecificIndexKey(equipmentSpecificIndex.getNameKey());
        equipmentSpecificAlarm.setEquipmentSpecificIndexValue(equipmentSpecificIndex.getValue());
        equipmentSpecificAlarm.setEquipmentSpecificIndexLabel(equipmentSpecificIndex.getValueLabel());
        if (EquipmentRiskTypeEnum.HZGJ.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
            equipmentSpecificAlarm.setType(EquipmentRiskTypeEnum.HZGJ.getCode());
        } else if (EquipmentRiskTypeEnum.GZ.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
            equipmentSpecificAlarm.setType(EquipmentRiskTypeEnum.GZ.getCode());
        } else if (EquipmentRiskTypeEnum.PB.getCode().equals(equipmentSpecificIndex.getTypeCode())) {
            equipmentSpecificAlarm.setType(EquipmentRiskTypeEnum.PB.getCode());
        }

        equipmentSpecificAlarm.setCreateDate(new Date());
        equipmentSpecificAlarm.setUpdateDate(new Date());
        QueryWrapper<EquipmentSpecific> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", equipmentSpecificIndex.getEquipmentSpecificId());
        EquipmentSpecific specific = equipmentSpecificMapper.selectOne(queryWrapper);
        equipmentSpecificAlarm.setSystemIds(specific.getSystemId());
        if (!ValidationUtil.isEmpty(specific.getSystemId())) {
            String codes = this.getSystemCodeBySpeId(specific);
            equipmentSpecificAlarm.setSystemCodes(codes);
        }
        equipmentSpecificAlarm.setEquipmentCode(equipmentSpecificIndex.getEquipmentCode());
        equipmentSpecificAlarm.setEquipmentId(equipmentSpecificIndex.getEquipmentId());
        equipmentSpecificAlarm.setEquipmentDetailId(equipmentSpecificIndex.getEquipmentDetailId());
        equipmentSpecificAlarm.setCode(specific.getCode());
        equipmentSpecificAlarms.add(equipmentSpecificAlarm);
        
        return equipmentSpecificAlarms;
    }

    // NB装备告警
    private List<EquipmentSpecificAlarm> getNbEquipAlarmList(List<EquipmentSpecificAlarm> indexAlarms, EquipmentSpecificIndex equipmentSpecificIndex, EquipmentSpecificAlarm equipmentSpecificAlarm) {
        List<EquipmentSpecificAlarm> equipmentSpecificAlarmList = new ArrayList<>();
        if (ValidationUtil.isEmpty(indexAlarms)) { // 告警表为空，新增告警数据
            addEquipmentSpecificAlarm(equipmentSpecificAlarmList, equipmentSpecificIndex, equipmentSpecificAlarm);
            if (!checkStateIsNormal(equipmentSpecificAlarm, equipmentSpecificIndex)){
                return equipmentSpecificAlarmList;
            } else {
                equipmentSpecificAlarmList.clear();
            }
        } else {
            indexAlarms.forEach(action -> {
                // 状态为正常或报警解除
                if (checkStateIsNormal(action, equipmentSpecificIndex)) {
                    //修改报警数据为正常
                    action.setRecoveryDate(new Date());
                    action.setStatus(AlarmStatusEnum.HF.getCode());
                    // 修改之前数据为已处理
                    action.setResolveResult(action.getAlamReason());
                    action.setConfirmUserName("系统");
                    action.setConfirmType(action.getType());
                    equipmentSpecificAlarmLogService.updateAlarmLogByIotCodeAndIndexKey(action);
                } else {
                    action.setFrequency((action.getFrequency() + 1));
                }
                action.setUpdateDate(new Date());
                equipmentSpecificAlarmList.add(action);
            });
        }
        return equipmentSpecificAlarmList;
    }

    private boolean ifSendToGis(List<CarIndexGisVo> list) {
        boolean flag = true;
        List<CarIndexGisVo> list1 = list.stream().filter(x -> CarForGisEnum.JD.getNameKey().equals(x.getNameKey())).collect(Collectors.toList());
        List<CarIndexGisVo> list2 = list.stream().filter(x -> CarForGisEnum.WD.getNameKey().equals(x.getNameKey())).collect(Collectors.toList());
        for (CarIndexGisVo gisVo : list) {
            if (CarForGisEnum.JD.getNameKey().equals(gisVo.getNameKey())) {
                if (!StringUtil.isNotEmpty(gisVo.getValue()) || "0".equals(gisVo.getValue())) {
                    flag = false;
                    continue;
                }
            }
            if (CarForGisEnum.WD.getNameKey().equals(gisVo.getNameKey()) || "0".equals(gisVo.getValue())) {
                if (!StringUtil.isNotEmpty(gisVo.getValue())) {
                    flag = false;
                    continue;
                }
            }
        }
        if (list1.size() == 0 || list2.size() == 0) {
            flag = false;
        }
        return flag;
    }

    /**
     * 接收到的IOT数据为火眼存储到Map中
     */
    private void iotDataListToCacheMap(List<IotDataVO> iotDatalist) {
        List<IotDataVO> iotDataVOs = iotDatalist.stream().filter(x -> "alarmLevel".equals(x.getKey()) || "alarmType".equals(x.getKey()) || "temperature".equals(x.getKey())
                || "ruleTemperature".equals(x.getKey()) || "thermometryUnit".equals(x.getKey()) || "alarmRule".equals(x.getKey())).collect(Collectors.toList());
        if (iotDataVOs.size() > 0) {
            Map<String, Object> map = iotDatalist.stream().collect(Collectors.toMap(IotDataVO::getKey, IotDataVO::getValue));
            putTemperatureMap(map.get("traceId").toString(), map);
        }
    }

    /**
     * 处理火眼逻辑合并为一条告警
     */
    private EquipmentSpecificIndex handleTemperatureAlarm(EquipmentSpecificIndex equipmentSpecificIndex, List<IotDataVO> iotDatalist) {
        List<IotDataVO> collect = iotDatalist.stream().filter(x -> "traceId".equals(x.getKey())).collect(Collectors.toList());
        if (collect.size() > 0 && temperatureMapIsEmpty(String.valueOf(collect.get(0).getValue()))) {
            String traceId = String.valueOf(collect.get(0).getValue());
            TemperatureAlarmDto dto = temperatureMap.get(traceId);
            equipmentSpecificIndex.setEquipmentSpecificIndexName(AlarmTypeEnum.getTypeByCode(AlarmTypeEnum.GZGJ.getCode()));
            equipmentSpecificIndex.setNameKey(AlarmTypeEnum.GZGJ.getCode());
            equipmentSpecificIndex.setAlamReason(TemperatureAlarm.getAlarmContent(dto.getAlarmLevel(), dto.getAlarmType(), dto.getAlarmRule(), dto.getRuleTemperature(), dto.getTemperature(), dto.getThermometryUnit()));
            equipmentSpecificIndex.setValue("true");
            temperatureMap.remove(traceId);
        }
        return equipmentSpecificIndex;
    }

    /**
     * temperatureMap存储数据
     */
    private void putTemperatureMap(String traceId, Map<String, Object> map) {
        TemperatureAlarmDto cacheTemperatureAlarmDto = temperatureMap.get(traceId);
        if (ValidationUtil.isEmpty(cacheTemperatureAlarmDto)) {
            cacheTemperatureAlarmDto = new TemperatureAlarmDto();
        }
        TemperatureAlarmDto newMap = JSON.parseObject(JSON.toJSONString(map), TemperatureAlarmDto.class);
        BeanUtil.copyPropertiesIgnoreNull(newMap, cacheTemperatureAlarmDto);
        temperatureMap.put(traceId, cacheTemperatureAlarmDto);
    }

    private boolean temperatureMapIsEmpty(String traceId) {
        TemperatureAlarmDto dto = temperatureMap.get(traceId);
        if (!ValidationUtil.isEmpty(dto) && !ValidationUtil.isEmpty(dto.getAlarmLevel()) && !ValidationUtil.isEmpty(dto.getAlarmType()) && !ValidationUtil.isEmpty(dto.getAlarmRule())
                && !ValidationUtil.isEmpty(dto.getRuleTemperature()) && !ValidationUtil.isEmpty(dto.getTemperature()) && !ValidationUtil.isEmpty(dto.getThermometryUnit())) {
            return true;
        }
        return false;
    }


    /**
     * 判断是否为NB物联监测设备参数
     *
     * @param nameKey
     * @return
     */
    private boolean verifyNB(String nameKey) {
        return nameKey.startsWith("NB_");
    }

    /**
     * 判断状态为正常或报警解除
     */
    private boolean checkStateIsNormal(EquipmentSpecificAlarm equipmentSpecificAlarm, EquipmentSpecificIndex equipmentSpecificIndex) {
        String enumKey = String.format("%s_%s", equipmentSpecificAlarm.getEquipmentSpecificIndexKey(), equipmentSpecificIndex.getValue());
        equipmentSpecificAlarm.setAlamReason(equipmentSpecificAlarm.getEquipmentSpecificIndexName().replace("NB_", "")
                + "：" + NBalarmEnum.getDescByKey(enumKey));
        boolean flag = false;
        if (!ValidationUtil.isEmpty(equipmentSpecificAlarm.getType())
                && !ValidationUtil.isEmpty(equipmentSpecificAlarm.getIotCode())
                && !ValidationUtil.isEmpty(equipmentSpecificAlarm.getEquipmentSpecificIndexKey())
                && (NBalarmEnum.NB_liquid_level_state_0.getKey().equals(enumKey)
                || NBalarmEnum.NB_error_code_0.getKey().equals(enumKey)
                || NBalarmEnum.NB_battery_state_0.getKey().equals(enumKey)
                || NBalarmEnum.NB_hydraulic_state_0.getKey().equals(enumKey)
                || NBalarmEnum.NB_hydraulic_state_2.getKey().equals(enumKey)
                || NBalarmEnum.NB_hydraulic_state_4.getKey().equals(enumKey)
                || NBalarmEnum.NB_alarm_status_4.getKey().equals(enumKey))) {
            flag = true;
        }
        return flag;
    }
}
