package com.ho.business.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONObject;
import com.ho.business.constant.DeviceTypeConstant;
import com.ho.business.entity.*;
import com.ho.business.service.*;
import com.ho.business.vo.DeviceTransfer;
import com.ho.business.vo.req.DeviceReqVO;
import com.ho.business.vo.req.carbin.EarningsCalculateReq;
import com.ho.business.vo.req.device.CommonQuery;
import com.ho.business.vo.req.device.DeviceTreeReq;
import com.ho.business.vo.resp.DeviceRespVO;
import com.ho.business.vo.resp.EnvironmentalControlVo;
import com.ho.business.vo.resp.VirtualDeviceColResp;
import com.ho.business.vo.resp.cabin.PackData;
import com.ho.business.vo.resp.cabin.TemperatureVoltageNew;
import com.ho.business.vo.resp.cabin.TemperatureVoltageNewResp;
import com.ho.business.vo.resp.point.ElecDataResp;
import com.ho.common.tools.constant.CommonConstant;
import com.ho.common.tools.exception.AirConditionCode;
import com.ho.common.tools.service.RedisService;
import com.ho.common.tools.util.BigDecimalUtil;
import com.ho.datacollect.api.constant.DataCollectConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author fancl
 * @desc:
 * @date 2023/5/8
 */
@Service
@Slf4j
public class CommonServiceImpl implements CommonService {

    @Autowired
    RedisService redisService;

    @Autowired
    DeviceService deviceService;

    @Autowired
    BigDecimalUtil bigDecimalUtil;

    @Autowired
    VirtualDeviceColService virtualDeviceColService;

    @Autowired
    ColCountService colCountService;

    @Autowired
    DeviceModelService deviceModelService;

    @Autowired
    PageConfigService pageConfigService;

    @Autowired
    EarningsCalculateService earningsCalculateService;

    //真实设备信息
    @Override
    public JSONObject getRealInfo(Device device, List<String> cols) {
        Integer stationId = device.getStationId();
        Integer srcId = device.getSrcId();
        String deviceType = device.getDeviceType();
        //返回对象
        JSONObject jsonObject = new JSONObject();
        //拼redis key
        String deviceKey = deviceType + ":" + stationId + ":" + srcId;
        if (redisService.hasKey(deviceKey)) {
            Map<Object, Object> infos = redisService.hgetall(deviceKey);
            for (String col : cols) {
                if (infos.containsKey(col)) {
                    Object o = infos.get(col);
                    //保留2位小数
                    if (o instanceof DeviceTransfer) {
                        DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(col);
                        if (null != deviceTransfer) {
                            BigDecimal value = deviceTransfer.getValue();
                            if (value != null) {
                                String result = String.format("%.2f", value);
                                deviceTransfer.setValue(new BigDecimal(result));
                            }
                        }
                        jsonObject.putIfAbsent(col, deviceTransfer);
                    }
                }
                //没有这个值,创建一个空对象
                else {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    jsonObject.putIfAbsent(col, deviceTransfer);
                }
            }
            //当电站点表中单独配置了PCS运行状态runningState，此时取3合一判断
            DeviceTransfer runningStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runningState);
            if (runningStateDeviceTransfer != null && runningStateDeviceTransfer.getValue() != null) {
                //215kW标准柜获取运行状态
                Integer pcsRunState = getRunState(infos);
                if (null != pcsRunState) {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    deviceTransfer.setUpdateTime(new Date());
                    deviceTransfer.setValue(new BigDecimal(pcsRunState));
                    jsonObject.put("runState", deviceTransfer);
                }
            }
            //正向有功费率1电能（尖）为空的情况下去取计算值合并
            extracted(stationId, jsonObject);
        }
        return jsonObject;
    }

    /**
     * 根据冻结值获取电表尖峰平谷数据
     *
     * @param stationId
     * @param jsonObject
     */
    private void extracted(Integer stationId, JSONObject jsonObject) {
        Object obj = jsonObject.get(DataCollectConstant.Elec_Meter.FORWARD_ACT_E1);
        if (obj != null && CommonConstant.BRACE.equals(obj.toString())) {
            EarningsCalculateReq earningsCalculateReq = new EarningsCalculateReq();
            earningsCalculateReq.setStationId(stationId);
            List<EarningsCalculate> list = earningsCalculateService.totalList(earningsCalculateReq);
            if (!list.isEmpty()) {
                BigDecimal chargeTip = BigDecimal.ZERO;
                BigDecimal chargePeak = BigDecimal.ZERO;
                BigDecimal chargeFlat = BigDecimal.ZERO;
                BigDecimal chargeValley = BigDecimal.ZERO;
                BigDecimal chargeDeepValley = BigDecimal.ZERO;
                BigDecimal dischargeTip = BigDecimal.ZERO;
                BigDecimal dischargePeak = BigDecimal.ZERO;
                BigDecimal dischargeFlat = BigDecimal.ZERO;
                BigDecimal dischargeValley = BigDecimal.ZERO;
                BigDecimal dischargeDeepValley = BigDecimal.ZERO;
                Date d = new Date();
                for (EarningsCalculate e : list) {
                    if (CommonConstant.ZERO.equals(e.getType())) {
                        //充电数据
                        if (CommonConstant.RateType.TIP.equals(e.getRateType())) {
                            chargeTip = e.getElec();
                        } else if (CommonConstant.RateType.PEAK.equals(e.getRateType())) {
                            chargePeak = e.getElec();
                        } else if (CommonConstant.RateType.FLAT.equals(e.getRateType())) {
                            chargeFlat = e.getElec();
                        } else if (CommonConstant.RateType.VALLEY.equals(e.getRateType())) {
                            chargeValley = e.getElec();
                        } else if (CommonConstant.RateType.DEEP_VALLEY.equals(e.getRateType())) {
                            chargeDeepValley = e.getElec();
                        }
                    } else if (CommonConstant.ONE.equals(e.getType())) {
                        //放电数据
                        if (CommonConstant.RateType.TIP.equals(e.getRateType())) {
                            dischargeTip = e.getElec();
                        } else if (CommonConstant.RateType.PEAK.equals(e.getRateType())) {
                            dischargePeak = e.getElec();
                        } else if (CommonConstant.RateType.FLAT.equals(e.getRateType())) {
                            dischargeFlat = e.getElec();
                        } else if (CommonConstant.RateType.VALLEY.equals(e.getRateType())) {
                            dischargeValley = e.getElec();
                        } else if (CommonConstant.RateType.DEEP_VALLEY.equals(e.getRateType())) {
                            dischargeDeepValley = e.getElec();
                        }
                    }
                }
                DeviceTransfer deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(chargeTip);
                jsonObject.put(DataCollectConstant.Elec_Meter.FORWARD_ACT_E1, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(chargePeak);
                jsonObject.put(DataCollectConstant.Elec_Meter.FORWARD_ACT_E2, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(chargeFlat);
                jsonObject.put(DataCollectConstant.Elec_Meter.FORWARD_ACT_E3, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(chargeValley);
                jsonObject.put(DataCollectConstant.Elec_Meter.FORWARD_ACT_E4, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(chargeDeepValley);
                jsonObject.put(DataCollectConstant.Elec_Meter.FORWARD_ACT_E5, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(dischargeTip);
                jsonObject.put(DataCollectConstant.Elec_Meter.BACKWARD_ACT_E1, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(dischargePeak);
                jsonObject.put(DataCollectConstant.Elec_Meter.BACKWARD_ACT_E2, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(dischargeFlat);
                jsonObject.put(DataCollectConstant.Elec_Meter.BACKWARD_ACT_E3, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(dischargeValley);
                jsonObject.put(DataCollectConstant.Elec_Meter.BACKWARD_ACT_E4, deviceTransfer);
                deviceTransfer = new DeviceTransfer();
                deviceTransfer.setUpdateTime(d);
                deviceTransfer.setValue(dischargeDeepValley);
                jsonObject.put(DataCollectConstant.Elec_Meter.BACKWARD_ACT_E5, deviceTransfer);
            }
        }
    }

    /**
     * PCS获取运行状态
     *
     * @param infos
     * @return
     */
    private Integer getRunState(Map<Object, Object> infos) {
        Integer runState = null;
        //PCS待机状态
        DeviceTransfer deviceStateStandDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.deviceStateStand);
        //PCS运行状态
        DeviceTransfer runningStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runningState);
        //PCS停机状态
        DeviceTransfer runStateDeviceTransfer = (DeviceTransfer) infos.get(DataCollectConstant.PCS_POINT.runState);
        //停机
        if (runStateDeviceTransfer != null && runStateDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(runStateDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.ZERO;
            }
        }
        //运行
        if (runningStateDeviceTransfer != null && runningStateDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(runningStateDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.ONE;
            }
        }
        //待机
        if (deviceStateStandDeviceTransfer != null && deviceStateStandDeviceTransfer.getValue() != null) {
            if (BigDecimal.ONE.compareTo(deviceStateStandDeviceTransfer.getValue()) == 0) {
                runState = CommonConstant.TWO;
            }
        }
        return runState;
    }


    @Override
    public Map<Object, Object> getInfoFromRedis(Device device) {
        String key = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
        if (redisService.hasKey(key)) {
            Map<Object, Object> infos = redisService.hgetall(key);
            return infos;
        }
        Map<Object, Object> info = new HashMap<>();
        return info;
    }

    @Override
    public JSONObject dealFire(Map<Object, Object> deviceInfo, List<String> cols, Device device) {
        //中间处理结果
        JSONObject infos = new JSONObject();
        String deviceKey = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
        if (redisService.hasKey(deviceKey)) {
            //对每个传感器进行解析处理
            //烟感 ,温感, 都有6个
            for (int i = 1; i <= 6; i++) {
                //烟感
                String smokeKey = "storageSmoke" + i;
                Object obj = redisService.hget(deviceKey, smokeKey);
                if (obj != null && obj instanceof DeviceTransfer) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                    //这个值用于处理
                    BigDecimal value = deviceTransfer.getValue();
                    String prefix = "storageSmoke" + i + "Bit";
                    JSONObject jsonObject = binaryDeal(prefix, 16, value);
                    infos.putAll(jsonObject);
                }
                String temperatureKey = "storageTemperature" + i;
                //温感
                obj = redisService.hget(deviceKey, temperatureKey);
                if (obj != null && obj instanceof DeviceTransfer) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                    //这个值用于处理  storageTemperature1Bit0
                    BigDecimal value = deviceTransfer.getValue();
                    String prefix = "storageTemperature" + i + "Bit";
                    JSONObject jsonObject = binaryDeal(prefix, 16, value);
                    infos.putAll(jsonObject);
                }
            }
            //紧急启停按钮
            String subKey = "storageEmergencyButton";
            Object obj = redisService.hget(deviceKey, subKey);
            if (obj != null && obj instanceof DeviceTransfer) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                BigDecimal value = deviceTransfer.getValue();
                String prefix = "storageEmergencyButtonBit";
                JSONObject jsonObject = binaryDeal(prefix, 16, value);
                infos.putAll(jsonObject);
            }
            //手动转换开关
            subKey = "storageTransferSwitch";
            obj = redisService.hget(deviceKey, subKey);
            if (obj != null && obj instanceof DeviceTransfer) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                BigDecimal value = deviceTransfer.getValue();
                String prefix = "storageTransferSwitchBit";
                JSONObject jsonObject = binaryDeal(prefix, 16, value);
                infos.putAll(jsonObject);
            }
            //气体释放灯
            subKey = "storageOutgassingLamp";
            obj = redisService.hget(deviceKey, subKey);
            if (obj != null && obj instanceof DeviceTransfer) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                BigDecimal value = deviceTransfer.getValue();
                String prefix = "storageOutgassingLampBit";
                JSONObject jsonObject = binaryDeal(prefix, 16, value);
                infos.putAll(jsonObject);
            }
            //声光报警器
            subKey = "storagEaudibleVisualAlarm";
            obj = redisService.hget(deviceKey, subKey);
            if (obj != null && obj instanceof DeviceTransfer) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                BigDecimal value = deviceTransfer.getValue();
                String prefix = "storagEaudibleVisualAlarmBit";
                JSONObject jsonObject = binaryDeal(prefix, 16, value);
                infos.putAll(jsonObject);
            }
        }
        //返回结果
        JSONObject retInfo = new JSONObject();
        //匹配入参
        for (String col : cols) {
            if (infos.containsKey(col)) {
                Object o = infos.get(col);
                retInfo.put(col, o);
            } else {
                DeviceTransfer deviceTransfer = new DeviceTransfer();
                retInfo.put(col, deviceTransfer);
            }
        }
        return retInfo;
    }
    /*public JSONObject getRealInfo(Device device, List<String> cols) {
        Integer stationId = device.getStationId();
        Integer srcId = device.getSrcId();
        String deviceType = device.getDeviceType();
        //返回对象
        JSONObject jsonObject = new JSONObject();
        //拼redis key
        String deviceKey = deviceType + ":" + stationId + ":" + srcId;
        if (redisService.hasKey(deviceKey)) {
            Map<Object, Object> infos = redisService.hgetall(deviceKey);

            for (String col : cols) {
                if (infos.containsKey(col)) {
                    Object o = infos.get(col);
                    //保留2位小数
                    if (o instanceof DeviceTransfer) {
                        DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(col);
                        BigDecimal value = deviceTransfer.getValue();
                        if (value != null) {
                            String result = String.format("%.2f", value);
                            deviceTransfer.setValue(new BigDecimal(result));
                        }
                        jsonObject.putIfAbsent(col, deviceTransfer);
                    }
                }
                //没有这个值,创建一个空对象
                else {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    jsonObject.putIfAbsent(col, deviceTransfer);
                }
            }
            //PCS特殊处理
            if (deviceType != null && deviceType.contains(DeviceTypeConstant.PCS)) {
                Device deviceReq = new Device();
                deviceReq.setStationId(stationId);
                //PCS 和 BMS为同级 所以查这个同级的BMS使用 PCS的 父id
                deviceReq.setPid(device.getPid());
                deviceReq.setDeviceType(DeviceTypeConstant.BMS);
                JSONObject dealInfo = dealPCS(infos, jsonObject, deviceReq);
                return dealInfo;
            }
            //bms特殊处理
            else if (deviceType != null && deviceType.contains(DeviceTypeConstant.BMS)) {
                Device deviceReq = new Device();
                deviceReq.setStationId(stationId);
                //PCS 和 BMS为同级 所以查这个同级的BMS使用 PCS的 父id
                deviceReq.setPid(device.getPid());
                deviceReq.setDeviceType(DeviceTypeConstant.PCS);
                JSONObject dealInfo = dealBMS(infos, jsonObject, deviceReq);
                return dealInfo;
            }
            //aircondition特殊处理
            else if (deviceType != null && deviceType.contains(DeviceTypeConstant.AIR_CONDITION)) {

        }
        //其他的设备,后续继续
        return jsonObject;
    }*/


    //虚拟设备的处理
    @Override
    public JSONObject getVirtualInfo(Device device, Device parentDevice, List<String> cols) {
        Integer stationId = device.getStationId();
        Integer srcId = device.getSrcId();
        //从virtual_device_col 根据站id,srcId查询出这个设备的点列表集合
        VirtualDeviceCol virtualDeviceColReq = new VirtualDeviceCol();
        virtualDeviceColReq.setStationId(stationId);
        virtualDeviceColReq.setSrcId(srcId);
        List<VirtualDeviceColResp> virtualList = virtualDeviceColService.getList(virtualDeviceColReq);
        //这个设备的父设备
        String parentDeviceType = parentDevice.getDeviceType();
        Integer parentSrcId = parentDevice.getSrcId();

        //父设备没有类型肯定查不到缓存
        if (parentDeviceType == null) {
            return new JSONObject();
        }
        //结果需要的
        Map<String, String> colMap = cols.stream().collect(Collectors.toMap(Function.identity(), Function.identity(), (k1, k2) -> k2));
        //返回的设备对象
        JSONObject info = new JSONObject();
        String parentDeviceKey = parentDeviceType + ":" + stationId + ":" + parentSrcId;
        if (redisService.hasKey(parentDeviceKey)) {
            Map<Object, Object> deviceInfos = redisService.hgetall(parentDeviceKey);
            //目的是根据虚拟设备的映射字段到真实设备对应的缓存找信息
            //遍历虚拟的设备的点集合, 然后在真实设备中取值
            //若包含告警
            if (colMap.containsKey(DataCollectConstant.BMS_POINT.clusterAlarmCodeLBit + CommonConstant.ZERO)) {
                //一级告警低16位状态字
                DeviceTransfer oneClusterAlarmCodeLBitLow = (DeviceTransfer) deviceInfos.get(DataCollectConstant.BMS_POINT.oneClusterAlarmCodeLBitLow);
                //一级告警高16位状态字
                DeviceTransfer oneClusterAlarmCodeLBitHigh = (DeviceTransfer) deviceInfos.get(DataCollectConstant.BMS_POINT.oneClusterAlarmCodeLBitHigh);
                //二级告警低16位状态字
                DeviceTransfer twoClusterAlarmCodeLBitLow = (DeviceTransfer) deviceInfos.get(DataCollectConstant.BMS_POINT.twoClusterAlarmCodeLBitLow);
                //二级告警高16位状态字
                DeviceTransfer twoClusterAlarmCodeLBitHigh = (DeviceTransfer) deviceInfos.get(DataCollectConstant.BMS_POINT.twoClusterAlarmCodeLBitHigh);
                //使用数字代替1代表一级告警，2代表二级告警
                if (null != oneClusterAlarmCodeLBitLow && null != oneClusterAlarmCodeLBitHigh) {
                    BigDecimal lowValue = oneClusterAlarmCodeLBitLow.getValue();
                    BigDecimal highValue = oneClusterAlarmCodeLBitHigh.getValue();
                    String prefix = DataCollectConstant.BMS_POINT.clusterAlarmCodeLBit;
                    JSONObject jsonObject = binaryDeal(prefix, CommonConstant.SIXTEEN, CommonConstant.ZERO, lowValue);
                    info.putAll(jsonObject);
                    jsonObject = binaryDeal(prefix, CommonConstant.SIXTEEN, CommonConstant.SIXTEEN, highValue);
                    info.putAll(jsonObject);
                }
                if (null != twoClusterAlarmCodeLBitLow && null != twoClusterAlarmCodeLBitHigh) {
                    JSONObject infoTwo = new JSONObject();
                    BigDecimal lowValue = twoClusterAlarmCodeLBitLow.getValue();
                    BigDecimal highValue = twoClusterAlarmCodeLBitHigh.getValue();
                    String prefix = DataCollectConstant.BMS_POINT.clusterAlarmCodeLBit;
                    JSONObject jsonObject = binaryDeal(prefix, CommonConstant.SIXTEEN, CommonConstant.ZERO, lowValue);
                    infoTwo.putAll(jsonObject);
                    jsonObject = binaryDeal(prefix, CommonConstant.SIXTEEN, CommonConstant.SIXTEEN, highValue);
                    infoTwo.putAll(jsonObject);
                    for (int i = 0; i < infoTwo.size(); i++) {
                        JSONObject obj = (JSONObject) infoTwo.get(DataCollectConstant.BMS_POINT.clusterAlarmCodeLBit + i);
                        Integer num = Integer.valueOf(String.valueOf(obj.get("value")));
                        if (CommonConstant.ONE.equals(num)) {
                            obj.put("value", CommonConstant.TWO);
                            info.put(DataCollectConstant.BMS_POINT.clusterAlarmCodeLBit + i, obj);
                        }
                    }
                }
            } else {
                Map<Integer,List<VirtualDeviceColResp>> map = new HashMap<>();
                for (VirtualDeviceColResp virtualDeviceColResp : virtualList) {
                    String col = virtualDeviceColResp.getCol();
                    String typeName = virtualDeviceColResp.getType();
                    BigDecimal factor = virtualDeviceColResp.getFactor();
                    //计算单体电压簇单体电压组合以及位置标志位
                    countNumByConfigure(info, deviceInfos, col, typeName, map, stationId, srcId);
//                    countNum(info, deviceInfos, col, typeName);
                    //原始值有这个并且
                    if (deviceInfos.containsKey(col) && colMap.containsKey(typeName)) {
                        Object obj = deviceInfos.get(col);
                        if (obj instanceof DeviceTransfer && obj != null) {
                            DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                            //保留2位小数
                            if (null != deviceTransfer) {
                                BigDecimal value = deviceTransfer.getValue();
                                if (value != null) {
                                    value = (factor == null ? value : value.multiply(factor));
                                    String result = String.format("%.3f", value);
                                    deviceTransfer.setValue(new BigDecimal(result));
                                }
                            }
                            info.put(typeName, deviceTransfer);
                        }
                    }
                }
            }
        }
        return info;
    }

    /**
     * 计算单体电压簇单体电压组合以及位置标志位
     *
     * @param info
     * @param deviceInfos
     * @param col
     * @param typeName
     * @param map
     * @param stationId
     * @param srcId
     */
    private void countNumByConfigure(JSONObject info, Map<Object, Object> deviceInfos, String col, String typeName,Map<Integer,List<VirtualDeviceColResp>> map,Integer stationId,Integer srcId ) {
        if (deviceInfos.containsKey(col)) {
            Object obj = deviceInfos.get(col);
            Integer val = null;
            if (obj instanceof DeviceTransfer && obj != null) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                //保留2位小数
                if (null != deviceTransfer) {
                    BigDecimal value = deviceTransfer.getValue();
                    if (value != null) {
                        val = deviceTransfer.getValue().intValue();
                        if (typeName != null && typeName.contains(DeviceTypeConstant.VOLCOMPUTE)) {
                            Integer configureNum = getConfigureNum(map, stationId, srcId, DeviceTypeConstant.VOLTAGE);
                            DeviceTransfer count = new DeviceTransfer();
                            count.setUpdateTime(deviceTransfer.getUpdateTime());
                            if(configureNum>0){
                                //val值与16取余，,余数为0则电压电池组号直接，取val值除以16的商，否则在val值除以16的商的基础上加1
                                count.setValue(new BigDecimal(val % configureNum == CommonConstant.ZERO ? val / configureNum : (val / configureNum + CommonConstant.ONE)));
                                info.put(typeName.replaceAll(DeviceTypeConstant.VOLCOMPUTE, DeviceTypeConstant.VOL_BMU_NUM), count);
                                //val值与16取余，,余数为0则电压电芯位置直接，取值为16，否则取val值与16取余的余数
                                count.setValue(new BigDecimal(val % configureNum == CommonConstant.ZERO ? configureNum : val % configureNum));
                                info.put(typeName.replaceAll(DeviceTypeConstant.VOLCOMPUTE, DeviceTypeConstant.VOL_BOX_NUM), count);
                            }
                        } else if (typeName != null && typeName.contains(DeviceTypeConstant.TEMCOMPUTE)) {
                            Integer configureNum = getConfigureNum(map, stationId, srcId, DeviceTypeConstant.TEMPERATURE);
                            DeviceTransfer count = new DeviceTransfer();
                            count.setUpdateTime(deviceTransfer.getUpdateTime());
                            if(configureNum>0){
                                //val值与8取余，,余数为0则温度电池组号直接，取val值除以8的商，否则在val值除以8的商的基础上加1
                                count.setValue(new BigDecimal(val % configureNum == CommonConstant.ZERO ? val / configureNum : (val / configureNum + CommonConstant.ONE)));
                                info.put(typeName.replaceAll(DeviceTypeConstant.TEMCOMPUTE, DeviceTypeConstant.TEM_BMU_NUM), count);
                                //val值与8取余，,余数为0则温度电芯位置直接，取值为8，否则取val值与8取余的余数
                                count.setValue(new BigDecimal(val % configureNum == CommonConstant.ZERO ? configureNum : val % CommonConstant.EIGHTEEN));
                                info.put(typeName.replaceAll(DeviceTypeConstant.TEMCOMPUTE, DeviceTypeConstant.TEM_BOX_NUM), count);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 获取单体电压，单体温度个数
     * @param map
     * @param stationId
     * @param srcId
     * @param type
     * @return
     */
    private Integer getConfigureNum(Map<Integer, List<VirtualDeviceColResp>> map, Integer stationId, Integer srcId,String type) {
        List<VirtualDeviceColResp> virtualDeviceColResps = map.get(srcId);
        Integer configureNum = CommonConstant.ZERO;
        if(virtualDeviceColResps==null){
            List<DeviceRespVO> deviceRespVOS = deviceService.selectByStationIdAndPId(stationId, srcId);
            if(deviceRespVOS!=null){
                DeviceRespVO deviceRespVO = deviceRespVOS.get(0);
                VirtualDeviceCol virtualDeviceColReq = new VirtualDeviceCol();
                virtualDeviceColReq.setStationId(stationId);
                virtualDeviceColReq.setSrcId(deviceRespVO.getSrcId());
                virtualDeviceColResps = virtualDeviceColService.getList(virtualDeviceColReq);
            }
        }
        if(virtualDeviceColResps!=null){
            configureNum = virtualDeviceColResps.stream().filter(i -> i.getType().contains(type)).collect(Collectors.toList()).size();
            map.put(srcId,virtualDeviceColResps);
        }
        log.info("getConfigureNum stationId:{},type:{},num:{}", stationId, type, configureNum);
        return configureNum;
    }

//    /**
//     * 计算单体电压簇单体电压组合以及位置标志位
//     *
//     * @param info
//     * @param deviceInfos
//     * @param col
//     * @param typeName
//     */
//    private void countNum(JSONObject info, Map<Object, Object> deviceInfos, String col, String typeName) {
//        if (deviceInfos.containsKey(col)) {
//            Object obj = deviceInfos.get(col);
//            Integer val = null;
//            if (obj instanceof DeviceTransfer && obj != null) {
//                DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
//                //保留2位小数
//                if (null != deviceTransfer) {
//                    BigDecimal value = deviceTransfer.getValue();
//                    if (value != null) {
//                        val = deviceTransfer.getValue().intValue();
//                        if (typeName != null && typeName.contains(DeviceTypeConstant.VOLCOMPUTE)) {
//                            //todo 目前只有海南亚信这几个站要计算，1簇是16个电压，8个温度
//                            DeviceTransfer count = new DeviceTransfer();
//                            count.setUpdateTime(deviceTransfer.getUpdateTime());
//                            //val值与16取余，,余数为0则电压电池组号直接，取val值除以16的商，否则在val值除以16的商的基础上加1
//                            count.setValue(new BigDecimal(val % CommonConstant.SIXTEEN == CommonConstant.ZERO ? val / CommonConstant.SIXTEEN : (val / CommonConstant.SIXTEEN + CommonConstant.ONE)));
//                            info.put(typeName.replaceAll(DeviceTypeConstant.VOLCOMPUTE, DeviceTypeConstant.VOL_BMU_NUM), count);
//                            //val值与16取余，,余数为0则电压电芯位置直接，取值为16，否则取val值与16取余的余数
//                            count.setValue(new BigDecimal(val % CommonConstant.SIXTEEN == CommonConstant.ZERO ? CommonConstant.SIXTEEN : val % CommonConstant.SIXTEEN));
//                            info.put(typeName.replaceAll(DeviceTypeConstant.VOLCOMPUTE, DeviceTypeConstant.VOL_BOX_NUM), count);
//                        } else if (typeName != null && typeName.contains(DeviceTypeConstant.TEMCOMPUTE)) {
//                            DeviceTransfer count = new DeviceTransfer();
//                            count.setUpdateTime(deviceTransfer.getUpdateTime());
//                            //val值与8取余，,余数为0则温度电池组号直接，取val值除以8的商，否则在val值除以8的商的基础上加1
//                            count.setValue(new BigDecimal(val % CommonConstant.EIGHTEEN == CommonConstant.ZERO ? val / CommonConstant.EIGHTEEN : (val / CommonConstant.EIGHTEEN + CommonConstant.ONE)));
//                            info.put(typeName.replaceAll(DeviceTypeConstant.TEMCOMPUTE, DeviceTypeConstant.TEM_BMU_NUM), count);
//                            //val值与8取余，,余数为0则温度电芯位置直接，取值为8，否则取val值与8取余的余数
//                            count.setValue(new BigDecimal(val % CommonConstant.EIGHTEEN == CommonConstant.ZERO ? CommonConstant.EIGHTEEN : val % CommonConstant.EIGHTEEN));
//                            info.put(typeName.replaceAll(DeviceTypeConstant.TEMCOMPUTE, DeviceTypeConstant.TEM_BOX_NUM), count);
//                        }
//                    }
//                }
//            }
//        }
//    }

    @Override
    public JSONObject getVirtualClusterInfo(List<DeviceRespVO> deviceList, Device parentDevice, List<String> cols) {
        List<Integer> srcIdList = deviceList.stream().map(DeviceRespVO::getSrcId).collect(Collectors.toList());
        Integer stationId = parentDevice.getStationId();
        //从virtual_device_col 根据站id,srcId查询出这个设备的点列表集合
        VirtualDeviceCol virtualDeviceColReq = new VirtualDeviceCol();
        virtualDeviceColReq.setStationId(stationId);
        virtualDeviceColReq.setSrcIdList(srcIdList);
        List<VirtualDeviceColResp> virtualList = virtualDeviceColService.getList(virtualDeviceColReq);
        Map<Integer, List<VirtualDeviceColResp>> virtualMap = virtualList.stream().collect(Collectors.groupingBy(VirtualDeviceColResp::getSrcId));

        //返回的设备对象
        JSONObject info = new JSONObject();
        String parentDeviceKey = parentDevice.getDeviceType() + ":" + stationId + ":" + parentDevice.getSrcId();
        if (redisService.hasKey(parentDeviceKey)) {
            Map<Object, Object> deviceInfos = redisService.hgetall(parentDeviceKey);
            int len = srcIdList.size();
            for (int i = 0; i < srcIdList.size(); i++) {
                Integer srcId = srcIdList.get(i);
                //按照包设备迭代
                List<VirtualDeviceColResp> virtualDeviceColList = virtualMap.get(srcId);
                DeviceTransfer transferV = new DeviceTransfer();
                transferV.setValue(new BigDecimal(0));
                DeviceTransfer transferT = new DeviceTransfer();
                transferT.setValue(new BigDecimal(0));
                int vNum = 0, tNum = 0;
                if (virtualDeviceColList == null || virtualDeviceColList.isEmpty()) {
                    continue;
                }
                for (VirtualDeviceColResp virtualDeviceColResp : virtualDeviceColList) {
                    String col = virtualDeviceColResp.getCol();
                    String typeName = virtualDeviceColResp.getType();
                    //原始值有这个并且
                    if (deviceInfos.containsKey(col)) {
                        Object obj = deviceInfos.get(col);
                        if (obj instanceof DeviceTransfer && obj != null) {
                            DeviceTransfer deviceTransfer = (DeviceTransfer) obj;
                            if (null != deviceTransfer) {
                                BigDecimal value = deviceTransfer.getValue();
                                if (value != null && typeName.contains(DeviceTypeConstant.VOLTAGE)) {
                                    vNum++;
                                    transferV.setValue(transferV.getValue().add(value));
                                    transferV.setUpdateTime(deviceTransfer.getUpdateTime());
                                } else if (value != null && typeName.contains(DeviceTypeConstant.TEMPERATURE)) {
                                    tNum++;
                                    transferT.setValue(transferT.getValue().add(value));
                                    transferT.setUpdateTime(deviceTransfer.getUpdateTime());
                                }
                            }
                        }
                    }
                }
                vNum = vNum == 0 ? 1 : vNum;
                tNum = tNum == 0 ? 1 : tNum;
                if (null != transferV.getValue()) {
                    transferV.setValue(transferV.getValue().divide(new BigDecimal(vNum), 3, BigDecimal.ROUND_UP));
                }
                if (null != transferT.getValue()) {
                    transferT.setValue(transferT.getValue().divide(new BigDecimal(tNum), 3, BigDecimal.ROUND_UP));
                }
                //增加一层判断，防止虚拟设备加多了超过传参，引发越界错误
                int num = i * 2 + 1;
                if (num < cols.size()) {
                    info.put(cols.get(i * 2), transferV);
                    info.put(cols.get(i * 2 + 1), transferT);
                }
            }
        }
        return info;
    }

    @Override
    public JSONObject dealPCS(JSONObject deviceInfo, Device device) {
        //并离网状态 onOffGrid ,包含两个字段 onGrid,offGrid
        /*if (allInfo.containsKey("onGrid") && allInfo.containsKey("offGrid")) {
            DeviceTransfer onGridTransfer = (DeviceTransfer) allInfo.get("onGrid");
            DeviceTransfer offGridTransfer = (DeviceTransfer) allInfo.get("offGrid");
            //把包含1的值放入到 onOffGrid
            if (BigDecimal.ONE.compareTo(onGridTransfer.getValue()) == 0) {
                deviceInfo.putIfAbsent("onOffGrid", onGridTransfer);
            }
            if (BigDecimal.ONE.compareTo(offGridTransfer.getValue()) == 0) {
                deviceInfo.putIfAbsent("onOffGrid", offGridTransfer);
            }
        }*/
        //充放电状态 stateChargeDisharge,包含两个 stateCharging,stateDischarging
        /*DeviceTransfer stateChargingTransfer = (DeviceTransfer) allInfo.get("stateCharging");
        DeviceTransfer stateDischargingTransfer = (DeviceTransfer) allInfo.get("stateDischarging");
        if (stateChargingTransfer != null && BigDecimal.ONE.compareTo(stateChargingTransfer.getValue()) == 0) {
            deviceInfo.putIfAbsent("stateChargeDisharge", stateChargingTransfer);
        }
        if (stateDischargingTransfer != null && BigDecimal.ONE.compareTo(stateDischargingTransfer.getValue()) == 0) {
            deviceInfo.putIfAbsent("stateChargeDisharge", stateDischargingTransfer);
        }*/
        //soc来自于PCS下面的BMS
        Integer stationId1 = device.getStationId();
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceType(stationId1, DeviceTypeConstant.BMS);
        if (deviceList.isEmpty()) {
            deviceList = deviceService.getListByFuzzyDeviceType(stationId1, DeviceTypeConstant.BMS);
        }
        if (!deviceList.isEmpty()) {
            //这个设备就是那个BMS
            Integer pid = device.getPid();
            Map<Integer, List<DeviceRespVO>> pidMap = deviceList.stream().collect(Collectors.groupingBy(DeviceRespVO::getPid));
            DeviceRespVO deviceRespVO = deviceList.get(0);
            if(null != pidMap.get(pid)){
                deviceRespVO = pidMap.get(pid).get(0);
            }
            //找SOC
            Integer stationId = device.getStationId();
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) redisService.hget(key, "soc");
                if (null != deviceTransfer) {
                    BigDecimal value = deviceTransfer.getValue();
                    if (value != null) {
                        String result = String.format("%.2f", value);
                        deviceTransfer.setValue(new BigDecimal(result));
                    }
                }
                deviceInfo.put("soc", deviceTransfer);
            }
        }
        //IO设备
        deviceList = deviceService.getListByDeviceType(stationId1, DeviceTypeConstant.IO_MODULE);
        if (deviceList.isEmpty()) {
            deviceList = deviceService.getListByFuzzyDeviceType(stationId1, DeviceTypeConstant.IO_MODULE);
        }
        if (!deviceList.isEmpty()) {
            Integer pid = device.getPid();
            Map<Integer, List<DeviceRespVO>> pidMap = deviceList.stream().collect(Collectors.groupingBy(DeviceRespVO::getPid));
            DeviceRespVO deviceRespVO = deviceList.get(0);
            if(null != pidMap.get(pid)){
                deviceRespVO = pidMap.get(pid).get(0);
            }
            Integer stationId = device.getStationId();
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) redisService.hget(key, DataCollectConstant.IO_POINT.AC_BREAKER);
                if (null != deviceTransfer) {
                    BigDecimal value = deviceTransfer.getValue();
                    if (value != null) {
                        String result = String.format("%.2f", value);
                        deviceTransfer.setValue(new BigDecimal(result));
                    }
                }
                deviceInfo.put(DataCollectConstant.IO_POINT.AC_BREAKER, deviceTransfer);
            }
        }
        return deviceInfo;
    }

    @Override
    public JSONObject dealBMS(JSONObject deviceInfo, Device device) {
        //交流有功功率来自于PCS
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceTypeAndPid(device.getStationId(), device.getPid(), device.getDeviceType());
        if (!deviceList.isEmpty()) {
            //这个设备就是那个pcs
            DeviceRespVO deviceRespVO = deviceList.get(0);
            //找有功
            Integer stationId = device.getStationId();
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                DeviceTransfer deviceTransfer = (DeviceTransfer) redisService.hget(key, "outputPower");
                if (null != deviceTransfer) {
                    BigDecimal value = deviceTransfer.getValue();
                    if (value != null) {
                        String result = String.format("%.2f", value);
                        deviceTransfer.setValue(new BigDecimal(result));
                    }
                }
                deviceInfo.put("outputPower", deviceTransfer);
            }
        }
        return deviceInfo;
    }

    @Override
    public JSONObject dealEMU(Device device, List<String> cols) {
        JSONObject retInfo = new JSONObject();
        Integer stationId = device.getStationId();
        Integer srcId = device.getSrcId();
        List<DeviceRespVO> deviceRespVOS = deviceService.selectByStationIdAndPId(stationId, srcId);
        deviceRespVOS = deviceRespVOS.stream().filter(s -> {
            return s.getVirtual().equals(CommonConstant.ONE);
        }).collect(Collectors.toList());
        List<String> colList = cols;
        //如果不包含EMU信号,则直接加上
        //EMU 温控的信号
        String emuTempControl = DeviceTypeConstant.SignalPrefix.emuTempControl;
        //EMU 除湿器
        String emuDehumi = DeviceTypeConstant.SignalPrefix.emuDehumi;
        for (DeviceRespVO deviceRespVO : deviceRespVOS) {
            JSONObject virtualInfo = getVirtualInfo(deviceRespVO, device, colList);
            retInfo.putAll(virtualInfo);
        }
        //
        if (retInfo.containsKey(emuTempControl)) {
            JSONObject deviceTransfer = (JSONObject) retInfo.get(emuTempControl);
            BigDecimal value = (BigDecimal) deviceTransfer.get("value");
            JSONObject jsonObject = binaryDeal(DeviceTypeConstant.SignalPrefix.emuTempControlPrefix, 16, value);
            retInfo.putAll(jsonObject);
        }

        if (retInfo.containsKey(emuDehumi)) {
            JSONObject deviceTransfer = (JSONObject) retInfo.get(emuDehumi);
            BigDecimal value = (BigDecimal) deviceTransfer.get("value");
            JSONObject jsonObject = binaryDeal(DeviceTypeConstant.SignalPrefix.emuDehumiPrefix, 16, value);
            retInfo.putAll(jsonObject);
        }
        if (retInfo.containsKey("EMUPTotal")) {
            BigDecimal emuAll = BigDecimal.ZERO;
            JSONObject EMUPA = (JSONObject) retInfo.get("EMUPA");
            if (EMUPA.containsKey("value")) {
                BigDecimal aValue = (BigDecimal) EMUPA.get("value");
                emuAll = emuAll.add(aValue);
            }
            JSONObject EMUPB = (JSONObject) retInfo.get("EMUPB");
            if (EMUPB.containsKey("value")) {
                BigDecimal aValue = (BigDecimal) EMUPB.get("value");
                emuAll = emuAll.add(aValue);
            }
            JSONObject EMUPC = (JSONObject) retInfo.get("EMUPC");
            if (EMUPC.containsKey("value")) {
                BigDecimal aValue = (BigDecimal) EMUPC.get("value");
                emuAll = emuAll.add(aValue);
                //emuAll = emuAll.divide(new BigDecimal(1000),2,BigDecimal.ROUND_HALF_UP);
            }
            JSONObject EMUPTotal = (JSONObject) retInfo.get("EMUPTotal");
            EMUPTotal.put("value", emuAll);

        }
        return retInfo;
    }

    @Override
    public JSONObject binaryDeal(String colPrefix, int len, BigDecimal inputInteger) {
        return binaryDeal(colPrefix, len, CommonConstant.ZERO, inputInteger);
    }

    /**
     * yc转yx
     *
     * @param colPrefix    前缀
     * @param len          长度
     * @param addNum       偏差值
     * @param inputInteger 输入的遥测值
     * @return
     */
    public JSONObject binaryDeal(String colPrefix, int len, int addNum, BigDecimal inputInteger) {
        JSONObject jsonObject = new JSONObject();
        //传入的遥测值需要转为Int
        if (inputInteger != null) {
            Integer v = inputInteger.intValue();
            //得到的二进制字符串
            String s = Integer.toBinaryString(v);
            if (s.length() != 16) {
                s = String.format("%16s", s).replace(" ", "0");
            }
            //j是拼接字符串的后缀的
            int j = 0 + addNum;
            char[] chars = s.toCharArray();
            for (int i = chars.length - 1; i >= 0; i--) {
                System.out.println(chars[i]);
                String key = colPrefix + j;
                DeviceTransfer deviceTransfer = new DeviceTransfer();
                char aChar = chars[i];
                Integer value = Integer.valueOf(String.valueOf(aChar));
                deviceTransfer.setValue(new BigDecimal(String.valueOf(value)));
                jsonObject.put(key, deviceTransfer);
                j++;
            }
        }
        return jsonObject;
    }

    @Override
    public JSONObject dealAirCondition(Device device, List<String> cols) {
        //查询入参需要返回的字段
        JSONObject jsonObject = getRealInfo(device, cols);
        //获取预制空调故障字段集合
        List<AirConditionCode> airConditionCodes = AirConditionCode.setList();
        //把所有的故障字段添加到新map中
        JSONObject map = new JSONObject();
        for (AirConditionCode airConditionCode : airConditionCodes) {
            DeviceTransfer deviceTransfer = new DeviceTransfer();
            deviceTransfer.setValue(BigDecimal.ZERO);
            map.put(airConditionCode.getMsg(), deviceTransfer);
        }
        //入参遍历字段进行对比
        for (String col : cols) {
            Object deviceTransfer = map.get(col);
            if (deviceTransfer != null) {
                jsonObject.put(col, deviceTransfer);
            }
        }
        //遍历故障字段进行对比赋值
        for (AirConditionCode airConditionCode : airConditionCodes) {
            JSONObject object = (JSONObject) jsonObject.get(DeviceTypeConstant.AIRCONDITIONFAULT);
            int code = airConditionCode.getCode();
            if (object != null) {
                BigDecimal value = (BigDecimal) object.get(CommonConstant.value);
                if (value != null && code == value.intValue()) {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    deviceTransfer.setValue(BigDecimal.ONE);
                    jsonObject.put(airConditionCode.getMsg(), deviceTransfer);
                }
            }
        }
        //移除内置的故障字段
        jsonObject.remove(DeviceTypeConstant.AIRCONDITIONFAULT);
        return jsonObject;
    }

    @Override
    public JSONObject getLiquidCooling(Device device, List<String> cols) {
        JSONObject jsonObject = new JSONObject();
        if (device.getStationId().equals(CommonConstant.SPECIALSTATION.QTSTATION)) {
            //根据父id和除湿器常量模糊查询 查询设备
            Device deviceValue = new Device();
            deviceValue.setPid(device.getPid());
            deviceValue.setStationId(device.getStationId());
            deviceValue.setDeviceType(CommonConstant.TRANSMITTER);
            List<Device> list = deviceService.selectBySelect(deviceValue);
            if (!list.isEmpty()) {
                Device device1 = list.get(CommonConstant.ZERO);
                String deviceKey = device1.getDeviceType() + ":" + device1.getStationId() + ":" + device1.getSrcId();
                if (redisService.hasKey(deviceKey)) {
                    Map<Object, Object> infos = redisService.hgetall(deviceKey);
                    for (String col : cols) {
                        if (infos.containsKey(col)) {
                            Object o = infos.get(col);
                            //保留2位小数
                            if (o instanceof DeviceTransfer) {
                                DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(col);
                                if (null != deviceTransfer) {
                                    BigDecimal value = deviceTransfer.getValue();
                                    if (value != null) {
                                        String result = String.format("%.2f", value);
                                        deviceTransfer.setValue(new BigDecimal(result));
                                    }
                                }
                                jsonObject.putIfAbsent(col, deviceTransfer);
                            }
                        }
                    }
                }
            }
        }
        String deviceKey = device.getDeviceType() + ":" + device.getStationId() + ":" + device.getSrcId();
        if (redisService.hasKey(deviceKey)) {
            Map<Object, Object> infos = redisService.hgetall(deviceKey);
            for (String col : cols) {
                if (infos.containsKey(col)) {
                    Object o = infos.get(col);
                    //保留2位小数
                    if (o instanceof DeviceTransfer) {
                        DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(col);
                        if (null != deviceTransfer) {
                            BigDecimal value = deviceTransfer.getValue();
                            if (value != null) {
                                String result = String.format("%.2f", value);
                                deviceTransfer.setValue(new BigDecimal(result));
                            }
                        }
                        jsonObject.putIfAbsent(col, deviceTransfer);
                    }
                }
                //没有这个值,创建一个空对象
                else {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    jsonObject.putIfAbsent(col, deviceTransfer);
                }
            }
        }

        return jsonObject;
    }

    @Override
    public Map<Object, Object> dealTransmitter(Device deviceRespVO) {
        //返回值
        Map<Object, Object> result = new HashMap<>();
        Map<Object, Object> transmitterMap = getInfoFromRedis(deviceRespVO);
        if (deviceRespVO.getDeviceName().contains("左")) {
            //
            if (transmitterMap != null) {
                Object wet = transmitterMap.get("wet");
                Map<Object, Object> left = new HashMap<>();
                if (wet != null) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) wet;
                    left.put("cabinetHumidityLeft", deviceTransfer);
                }
                Object temperature = transmitterMap.get("temperature");
                if (temperature != null) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) temperature;
                    left.put("cabinetTemperatureLeft", deviceTransfer);
                }
                result.putAll(left);
            }
        } else if (deviceRespVO.getDeviceName().contains("右")) {
            if (transmitterMap != null) {
                Object wet = transmitterMap.get("wet");
                Map<Object, Object> right = new HashMap<>();
                if (wet != null) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) wet;
                    right.put("cabinetHumidityRight", deviceTransfer);
                }
                Object temperature = transmitterMap.get("temperature");
                if (temperature != null) {
                    DeviceTransfer deviceTransfer = (DeviceTransfer) temperature;
                    right.put("cabinetTemperatureRight", deviceTransfer);
                }
                result.putAll(right);
            }
        }
        return result;
    }

    @Override
    public TemperatureVoltageNewResp getTemperatureVoltageData(DeviceTreeReq vo) {
        TemperatureVoltageNewResp temperatureVoltageResp = new TemperatureVoltageNewResp();
        Integer stationId = vo.getStationId();
        Integer srcId = vo.getSrcId();
        Device device = deviceService.selectByStationIdAndSrcId(stationId, srcId);
        if (device == null) {
            log.info("对应设备不存在");
            return temperatureVoltageResp;
        }
        Device parentDevice = deviceService.selectByStationIdAndSrcId(stationId, device.getFromId());
        if (parentDevice == null) {
            log.info("该虚拟设备没找到父设备");
            return temperatureVoltageResp;
        }
        if (parentDevice.getDeviceType() == null) {
            log.info("该虚拟来源的设备没有配置设备类型");
            return temperatureVoltageResp;
        }
        VirtualDeviceCol virtualDeviceCol = new VirtualDeviceCol();
        virtualDeviceCol.setStationId(stationId);
        virtualDeviceCol.setSrcId(srcId);
        List<VirtualDeviceColResp> virtualList = virtualDeviceColService.getList(virtualDeviceCol);
        String parentDeviceKey = parentDevice.getDeviceType() + ":" + stationId + ":" + parentDevice.getSrcId();
        if (redisService.hasKey(parentDeviceKey)) {
            Map<Object, Object> deviceInfos = redisService.hgetall(parentDeviceKey);
            //电压合集
            List<TemperatureVoltageNew> voltageList = new ArrayList<>();
            //温度合集
            List<TemperatureVoltageNew> temperatureList = new ArrayList<>();
            TemperatureVoltageNew temperatureVoltage = null;
            for (VirtualDeviceColResp virtualDeviceColResp : virtualList) {
                String col = virtualDeviceColResp.getCol();
                String typeName = virtualDeviceColResp.getType();
                DeviceTransfer deviceTransfer = (DeviceTransfer) deviceInfos.get(col);
                if (null != deviceTransfer) {
                    if (typeName.contains(DeviceTypeConstant.VOLTAGE)) {
                        //电压
                        String xValue = typeName.replaceAll(DeviceTypeConstant.VOLTAGE, "");
                        temperatureVoltage = new TemperatureVoltageNew();
                        temperatureVoltage.setXValue(xValue);
                        temperatureVoltage.setYValue(NumberUtil.round(deviceTransfer.getValue(), 3));
                        voltageList.add(temperatureVoltage);

                    } else if (typeName.contains(DeviceTypeConstant.TEMPERATURE)) {
                        //温度
                        String xValue = typeName.replaceAll(DeviceTypeConstant.TEMPERATURE, "");
                        temperatureVoltage = new TemperatureVoltageNew();
                        temperatureVoltage.setXValue(xValue);
                        temperatureVoltage.setYValue(NumberUtil.round(deviceTransfer.getValue(),3));
                        temperatureList.add(temperatureVoltage);
                    }
                }
            }
            PackData packData = new PackData();
            if (voltageList.size() > 0) {
                TemperatureVoltageNew maxV = voltageList.stream().max(Comparator.comparing(TemperatureVoltageNew::getYValue)).get();
                TemperatureVoltageNew minV = voltageList.stream().min(Comparator.comparing(TemperatureVoltageNew::getYValue)).get();
                packData.setCsingleMaxVolData(maxV.getYValue());
                packData.setCsingleMinVolData(minV.getYValue());
                packData.setCsingleMaxVolPosition(maxV.getXValue());
                packData.setCsingleMinVolPosition(minV.getXValue());
            }
            if (temperatureList.size() > 0) {
                TemperatureVoltageNew maxT = temperatureList.stream().max(Comparator.comparing(TemperatureVoltageNew::getYValue)).get();
                TemperatureVoltageNew minT = temperatureList.stream().min(Comparator.comparing(TemperatureVoltageNew::getYValue)).get();
                packData.setCsingleMaxTemData(maxT.getYValue());
                packData.setCsingleMinTemData(minT.getYValue());
                packData.setCsingleMaxTemPosition(maxT.getXValue());
                packData.setCsingleMinTemPosition(minT.getXValue());
            }
            temperatureVoltageResp.setVoltageList(voltageList);
            temperatureVoltageResp.setTemperatureList(temperatureList);
            temperatureVoltageResp.setPackData(packData);
        }
        return temperatureVoltageResp;
    }

    @Override
    public Object getMiddlePart(CommonQuery vo) {
        HashMap<String, Object> retInfo = new LinkedHashMap<>();
        Integer stationId = vo.getStationId();
        String deviceType = colCountService.getDeviceType(vo.getStationId());
        if (null == deviceType) {
            return retInfo;
        }
        List<DeviceRespVO> ddbList = deviceService.getListByDeviceType(stationId, deviceType);
        if (!ddbList.isEmpty()) {
            BigDecimal power = BigDecimal.ZERO;
            for (DeviceRespVO deviceRespVO : ddbList) {
                //在缓存里拿映射字段
                String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
                if (redisService.hasKey(key)) {
                    Map<Object, Object> infos = redisService.hgetall(key);
                    DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(DeviceTypeConstant.ACTIVE_POWER);
                    power = power.add(deviceTransfer == null ?BigDecimal.ZERO:deviceTransfer.getValue());
                }
            }
            retInfo.put(DeviceTypeConstant.ACTIVE_POWER, power.setScale(2, BigDecimal.ROUND_HALF_UP));
        }
        return retInfo;
    }

    @Override
    public List<EnvironmentalControlVo> getAirCondition(CommonQuery vo) {
        List<EnvironmentalControlVo> resultList = new ArrayList<>();
        Integer stationId = vo.getStationId();
        String type = DeviceTypeConstant.AIR_CONDITION;
        PageConfig pageConfig = new PageConfig();
        pageConfig.setModelType(type);
        pageConfig.setStationId(stationId);
        List<PageConfig> list = pageConfigService.selectPage(pageConfig);
        if (list.isEmpty()) {
            //因为新的空调已经融合到bms中，所有默认先查空调，没有就查bms,后续若bms也是可配的这块就需要修改
            type = DeviceTypeConstant.BMS;
            pageConfig.setModelType(DeviceTypeConstant.BMS);
            list = pageConfigService.selectPage(pageConfig);
            if (list.isEmpty()) {
                //空调里面也没有的话，去查液冷，若没有则直接返回
                type = DeviceTypeConstant.LIQUID_COOLING;
                pageConfig.setModelType(null);
                pageConfig.setDeviceType(type + "_" + stationId);
                list = pageConfigService.selectPage(pageConfig);
                if (list.isEmpty()) {
                    type = DeviceTypeConstant.MANAGEMENT_MACHINE;
                    pageConfig.setModelType(type);
                    pageConfig.setDeviceType(null);
                    list = pageConfigService.selectPage(pageConfig);
                    if (list.isEmpty()) {
                        return resultList;
                    }
                }
            }
        }
        List<String> colList = list.stream().sorted(Comparator.comparing(PageConfig::getModelColIdName)).map(s -> {
                    return s.getModelCol();
                }
        ).collect(Collectors.toList());
        Map<String, PageConfig> nameMap = list.stream().collect(Collectors.toMap(s -> s.getModelCol(), PageConfig -> PageConfig, (k1, k2) -> k1));

        //先查这个站下的空调
        List<DeviceRespVO> airList = deviceService.getListByDeviceType(stationId, type);
        //匹配不到模糊匹配
        if (airList.isEmpty()) {
            airList = deviceService.getListByFuzzyDeviceType(stationId, type);
        }

        if (!airList.isEmpty()) {
            boolean flag = airList.size() > 1;
            int num = 1;
            //适配多个设备
            EnvironmentalControlVo env = null;
            List<Integer> ids = list.stream().map(PageConfig::getDeviceColId).collect(Collectors.toList());
            List<DeviceTypeCol> deviceTypeCols = deviceModelService.selectByIds(ids);
            Map<String, BigDecimal> map = new HashMap<>();
            for (DeviceTypeCol col : deviceTypeCols) {
                map.put(col.getDeviceType() + CommonConstant.JOIN + col.getCol(), col.getFactor());
            }
            for (DeviceRespVO deviceRespVO : airList) {
                //在缓存里拿映射字段
                String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
                if (redisService.hasKey(key)) {
                    Map<Object, Object> infos = redisService.hgetall(key);
                    for (String col : colList) {
                        PageConfig page = nameMap.get(col);
                        env = new EnvironmentalControlVo();
                        env.setDeviceType(deviceRespVO.getDeviceType());
                        env.setDeviceCol(page.getDeviceCol());
                        env.setModelCol(page.getModelCol());
                        env.setModelType(page.getModelType());
                        env.setName(flag ? num + "#" + page.getModelColIdName() : page.getModelColIdName());
                        if (infos.containsKey(col)) {
                            DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(col);
                            env.setValue(deviceTransfer == null ? BigDecimal.ZERO : (page.getDeviceCol().contains(CommonConstant.YC) ? NumberUtil.round(deviceTransfer.getValue(), 2) : NumberUtil.round(deviceTransfer.getValue(), 0)));
                        } else {
                            env.setValue(BigDecimal.ZERO);
                        }
                        BigDecimal factor = map.get(page.getDeviceType() + CommonConstant.JOIN + page.getDeviceCol());
                        env.setValue(factor == null ? env.getValue() : NumberUtil.round(env.getValue().multiply(factor), 2));
                        resultList.add(env);
                    }
                }
                num++;
            }

        }
        return resultList;
    }

    @Override
    public List<ElecDataResp> getElec(CommonQuery vo) {
        Integer stationId = vo.getStationId();
        DeviceReqVO deviceReqVO = new DeviceReqVO();
        deviceReqVO.setStationId(stationId);
        //并网侧电表
        List<DeviceRespVO> bmsList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.MAINS_POWER);
        if (bmsList.isEmpty()) {
            bmsList = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.MAINS_POWER);
        }
        List<ElecDataResp> list = new ArrayList<>();
        for (int i = 0; i < bmsList.size(); i++) {
            DeviceRespVO deviceRespVO = bmsList.get(i);
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                ElecDataResp wareHouse = new ElecDataResp();
                DeviceTransfer activePower = (DeviceTransfer) redisService.hget(key, "activePower");
                DeviceTransfer reactivePower = (DeviceTransfer) redisService.hget(key, "reactivePower");
                if (activePower != null) {
                    wareHouse.setActivePowerBY(activePower.getValue());
                }
                if (reactivePower != null) {
                    wareHouse.setReactivePowerBY(reactivePower.getValue());
                }
                list.add(wareHouse);
            }
        }

        deviceReqVO = new DeviceReqVO();
        deviceReqVO.setStationId(stationId);
        List<DeviceRespVO> pcsList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.LOAD_SIDE_METER);
        if (pcsList.isEmpty()) {
            pcsList = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.LOAD_SIDE_METER);
        }
        int len = pcsList.size() - 1;
        if (!pcsList.isEmpty()) {
            //总有功, 总无功
            for (int i = 0; i < pcsList.size(); i++) {
                String key = pcsList.get(i).getDeviceType() + ":" + stationId + ":" + pcsList.get(i).getSrcId();
                if (redisService.hasKey(key)) {
                    DeviceTransfer outputPower = (DeviceTransfer) redisService.hget(key, "activePower");
                    DeviceTransfer reactivePowerPCS = (DeviceTransfer) redisService.hget(key, "reactivePower");
                    //根据
                    ElecDataResp wareHouse = null;
                    if (!list.isEmpty() && i < list.size()) {
                        wareHouse = list.get(i);
                    } else {
                        wareHouse = new ElecDataResp();
                        list.add(wareHouse);
                    }
                    if (outputPower != null) {
                        wareHouse.setActivePowerFZ(outputPower.getValue());
                    }
                    if (reactivePowerPCS != null) {
                        wareHouse.setReactivePowerFZ(reactivePowerPCS.getValue());
                    }
                }
            }
        }

        return list;
    }

    @Override
    public JSONObject getElecData(Device device, String col) {
        //判断传输过来的字段
        String deviceType = null;
        List<DeviceRespVO> deviceRespVOList = new ArrayList<>();
        if ("torageMeter".equals(col)) {
            // * 储能侧电表	torageMeter
            deviceType = DeviceTypeConstant.ELE_METER;
            deviceRespVOList = deviceService.getListByDeviceType(device.getStationId(), deviceType);
            if (deviceRespVOList.isEmpty()) {
                deviceRespVOList = deviceService.getListByFuzzyDeviceType(device.getStationId(), deviceType);
            }

        } else if ("loadMeter".equals(col)) {
            //* 负载侧电表	loadMeter
            deviceType = DeviceTypeConstant.LOAD_SIDE_METER;
            deviceRespVOList = deviceService.getListByDeviceType(device.getStationId(), deviceType);
            if (deviceRespVOList.isEmpty()) {
                deviceRespVOList = deviceService.getListByFuzzyDeviceType(device.getStationId(), deviceType);
            }
        } else if ("gridMeter".equals(col)) {
            // * 并网侧电表	gridMeter
            deviceType = DeviceTypeConstant.MAINS_POWER;
            //并网侧电表
            deviceRespVOList = deviceService.getListByDeviceType(device.getStationId(), deviceType);
            if (deviceRespVOList.isEmpty()) {
                deviceRespVOList = deviceService.getListByFuzzyDeviceType(device.getStationId(), deviceType);
            }
        }
        //返回对象
        JSONObject jsonObject = new JSONObject();
        if (deviceRespVOList.isEmpty()) {
            DeviceTransfer deviceTransfer = new DeviceTransfer();
            jsonObject.putIfAbsent(col, deviceTransfer);
            return jsonObject;
        }
        String activePower = "activePower";
        for (int i = 0; i < deviceRespVOList.size(); i++) {
            DeviceRespVO deviceRespVO = deviceRespVOList.get(i);
            String key = deviceRespVO.getDeviceType() + ":" + device.getStationId() + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                Map<Object, Object> infos = redisService.hgetall(key);
                if (infos.containsKey(activePower)) {
                    Object o = infos.get(activePower);
                    //保留2位小数
                    if (o instanceof DeviceTransfer) {
                        DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(activePower);
                        if (null != deviceTransfer) {
                            BigDecimal value = deviceTransfer.getValue();
                            if (value != null) {
                                String result = String.format("%.2f", value);
                                deviceTransfer.setValue(new BigDecimal(result));
                            }
                        }
                        jsonObject.putIfAbsent(col, deviceTransfer);
                    }
                }
                //没有这个值,创建一个空对象
                else {
                    DeviceTransfer deviceTransfer = new DeviceTransfer();
                    jsonObject.putIfAbsent(col, deviceTransfer);
                }
            }
        }
        return jsonObject;
    }

    @Override
    public Object getEleMeter(CommonQuery vo) {
        List<HashMap<String, Object>> result = new ArrayList<>();
        Integer stationId = vo.getStationId();
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.ELE_METER);
        if (deviceList.isEmpty()) {
            deviceList = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.ELE_METER);
        }
        if (!deviceList.isEmpty()) {
            for (DeviceRespVO deviceRespVO : deviceList) {
                //在缓存里拿映射字段
                HashMap<String, Object> retInfo = new LinkedHashMap<>();
                String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
                if (redisService.hasKey(key)) {
                    Map<Object, Object> infos = redisService.hgetall(key);
                    DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(DeviceTypeConstant.ACTIVE_POWER);
                    retInfo.put(DeviceTypeConstant.ACTIVE_POWER, deviceTransfer == null ? "" : NumberUtil.round(deviceTransfer.getValue(), 2));
                    deviceTransfer = (DeviceTransfer) infos.get(DeviceTypeConstant.REACTIVE_POWER);
                    retInfo.put(DeviceTypeConstant.REACTIVE_POWER, deviceTransfer == null ? "" : NumberUtil.round(deviceTransfer.getValue(), 2));
                    result.add(retInfo);
                }
            }
        }
        return result;
    }

    @Override
    public Object getPVElec(CommonQuery vo) {
        HashMap<String, Object> retInfo = new LinkedHashMap<>();
        Integer stationId = vo.getStationId();
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.PHON_GRID);
        if (!deviceList.isEmpty()) {
            DeviceRespVO deviceRespVO = deviceList.get(0);
            //在缓存里拿映射字段
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            if (redisService.hasKey(key)) {
                Map<Object, Object> infos = redisService.hgetall(key);
                DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(DeviceTypeConstant.ACTIVE_POWER);
                retInfo.put(DeviceTypeConstant.ACTIVE_POWER, deviceTransfer == null ? "" : NumberUtil.round(deviceTransfer.getValue(), 2));
            }
        }
        return retInfo;
    }

    @Override
    public Object getOpticalStorage(CommonQuery vo) {
        List<HashMap<String, Object>> result = new ArrayList<>();

        Integer stationId = vo.getStationId();
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.OPTICAL_STORAGE);
        if (deviceList.isEmpty()) {
            deviceList = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.OPTICAL_STORAGE);
        }
        if (!deviceList.isEmpty()) {
            for (DeviceRespVO deviceRespVO : deviceList) {
                //在缓存里拿映射字段
                HashMap<String, Object> retInfo = new LinkedHashMap<>();
                String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
                if (redisService.hasKey(key)) {
                    Map<Object, Object> infos = redisService.hgetall(key);
                    DeviceTransfer deviceTransfer = (DeviceTransfer) infos.get(DeviceTypeConstant.AC_ACTIVE_POWER);
                    retInfo.put(DeviceTypeConstant.AC_ACTIVE_POWER, deviceTransfer == null ? "" : NumberUtil.round(deviceTransfer.getValue(), 2));
                    DeviceTransfer transfer = (DeviceTransfer) infos.get(DeviceTypeConstant.OUTPUT_POWER);
                    retInfo.put(DeviceTypeConstant.ACTIVE_POWER, transfer == null ? "" : NumberUtil.round(transfer.getValue(), 2));
                    result.add(retInfo);
                }
            }
        }
        return result;
    }

    @Override
    public Object getSummaryData(CommonQuery vo) {
        HashMap<String, Object> retInfo = new LinkedHashMap<>();
        Integer stationId = vo.getStationId();
        List<DeviceRespVO> deviceList = deviceService.getListByDeviceType(stationId, DeviceTypeConstant.BMS);
        if (deviceList.isEmpty()) {
            deviceList = deviceService.getListByFuzzyDeviceType(stationId, DeviceTypeConstant.BMS);
        }
        //bms系统可放电量
        BigDecimal dischargeCapacity = BigDecimal.ZERO;
        for (DeviceRespVO deviceRespVO : deviceList) {
            String key = deviceRespVO.getDeviceType() + ":" + stationId + ":" + deviceRespVO.getSrcId();
            DeviceTransfer deviceTransfer = (DeviceTransfer) redisService.hget(key, DeviceTypeConstant.DISCHARGE_CAPACITY);
            dischargeCapacity = dischargeCapacity.add(deviceTransfer == null ? BigDecimal.ZERO : deviceTransfer.getValue());
        }
        retInfo.put(DeviceTypeConstant.DISCHARGE_CAPACITY, dischargeCapacity);
        return retInfo;
    }
}
