package jtznyj.engineer.service.dataDiagnosticService;

import com.alibaba.fastjson.JSON;
import jtznyj.engineer.entity.BWellOwnEngineer;
import jtznyj.engineer.service.dataDiagnosticService.data.*;
import jtznyj.engineer.service.dataDiagnosticService.models.AlarmType;
import jtznyj.engineer.service.dataDiagnosticService.models.FieldRule;
import jtznyj.engineer.vo.LtdRecord;
import jtznyj.engineer.service.dataDiagnosticService.models.WellOwn;
import jtznyj.engineer.service.winform.data.MonitorContext;
import jtznyj.engineer.service.winform.data.RealDataField;
import jtznyj.engineer.service.winform.data.RecordHashTable;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;

import java.util.*;

/**
 * 数据诊断引擎诊断
 */
@Slf4j
public class DataDiagnosticEngineer {
    public final static String calleeStart = "analyseDataList";
    private final static String TRACE_ID = "TRACE_ID";

    private WellOwn wellOwn;
    /**
     * 参数模板列表
     */
    public Hashtable<String, DataDiagnosticParameters> mcpsList = new Hashtable<String, DataDiagnosticParameters>();

    private RecordHashTable _prevDrillStateData = null;

    public boolean _isPumpRun = true;
    public Date _dtPumpRunTime = new Date();
    public Date _dtPumpStopTime = new Date();
    public String jh = "";
    public final static String DateTimeFormat = "yyyy-MM-dd HH:mm:ss.SSS";

    /**
     * 实时数据字段
     */
    public static ArrayList<RealDataField> RealDataFields = new ArrayList<RealDataField>() {
        {
            add(new RealDataField("JS", "时间", "秒", 0f, 5000f));
            add(new RealDataField("[实测井深(M)]", "井深", "m", 0f, 5000f));
            add(new RealDataField("[钻时(MIN/M)]", "钻时", "min/m", 0f, 5000f));
            add(new RealDataField("[转速(RPM)]", "转盘转速", "rpm", 0f, 5000f));
            add(new RealDataField("[钻压(kN)]", "钻压", "kN", 0f, 5000f));
            add(new RealDataField("[大钩负荷(kN)]", "大钩负荷", "kN", 0f, 5000f, 9.8f));
            add(new RealDataField("[立压(MPa)]", "立管压力", "MPa", 0f, 5000f));
            add(new RealDataField("[扭矩(kN.m)]", "转盘扭矩", "kN.m", 0f, 5000f));
            add(new RealDataField("[泵冲1(SPM)]", "一号泵冲", "spm", 0f, 5000f));
            add(new RealDataField("[泵冲2(SPM)]", "二号泵冲", "spm", 0f, 5000f));
            add(new RealDataField("[一号池体积(m3)]", "池体积1", "m3", 0f, 5000f));
            add(new RealDataField("[二号池体积(m3)]", "池体积2", "m3", 0f, 5000f));
            add(new RealDataField("[三号池体积(m3)]", "池体积3", "m3", 0f, 5000f));
            add(new RealDataField("[四号池体积(m3)]", "池体积4", "m3", 0f, 5000f));
            add(new RealDataField("[总体积(m3)]", "总池体积", "m3", 0f, 5000f));
            add(new RealDataField("[体积变化量(%)]", "泥浆溢漏", "%", 0f, 5000f));
            add(new RealDataField("[入口温度(degC)]", "入口温度", "degC", 0f, 5000f));
            add(new RealDataField("[出口温度(degC)]", "出口温度", "degC", 0f, 5000f));
            add(new RealDataField("[入口电导(ms)]", "入口电导", "ms", 0f, 5000f));
            add(new RealDataField("[出口电导(ms)]", "出口电导", "ms", 0f, 5000f));
            add(new RealDataField("[入口密度(g/cm3)]", "入口密度", "g/cm3", 0f, 5000f));
            add(new RealDataField("[出口密度(g/cm3)]", "出口密度", "g/cm3", 0f, 5000f));
            add(new RealDataField("[入口流量(1/min)]", "入口流量", "L/min", 0f, 5000f));
            add(new RealDataField("[出口流量(%)]", "出口流量%", "%", 0f, 5000f));
            add(new RealDataField("[出口流量(l/min)]", "出口流量", "L/min", 0f, 5000f));
            add(new RealDataField("[D指数]", "", "", 0f, 5000f));
            add(new RealDataField("[DC指数]", "", "", 0f, 5000f));
            add(new RealDataField("[循环当量密度]", "", "", 0f, 5000f));
            add(new RealDataField("[压力梯度]", "", "", 0f, 5000f));
            add(new RealDataField("[破裂梯度]", "", "", 0f, 5000f));
            add(new RealDataField("[迟到井深(m)]", "迟到井深", "m", 0f, 5000f));
            add(new RealDataField("[总烃(%)]", "总烃", "%", 0f, 5000f));
            add(new RealDataField("[C1(%)]", "C1", "%", 0f, 5000f));
            add(new RealDataField("[C2(%)]", "C2", "%", 0f, 5000f));
            add(new RealDataField("[C3(%)]", "C3", "%", 0f, 5000f));
            add(new RealDataField("[iC4(%)]", "iC4", "%", 0f, 5000f));
            add(new RealDataField("[nC4(%)]", "nC4", "%", 0f, 5000f));
            add(new RealDataField("[iC5(%)]", "iC5", "%", 0f, 5000f));
            add(new RealDataField("[nC5(%)]", "nC5", "%", 0f, 5000f));
            add(new RealDataField("[Co2(%)]", "Co2", "%", 0f, 5000f));
            add(new RealDataField("[H(%)]", "H2", "%", 0f, 5000f));
            add(new RealDataField("[一号H2s(%)]", "H2S_1", "%", 0f, 5000f));
            add(new RealDataField("[二号H2s(%)]", "H2S_2", "%", 0f, 5000f));
            add(new RealDataField("[三号H2s(%)]", "H2S_3", "%", 0f, 5000f));
            add(new RealDataField("[湿度比]", "", "", 0f, 5000f));
            add(new RealDataField("[平衡比]", "", "", 0f, 5000f));
            add(new RealDataField("[特性比]", "", "", 0f, 5000f));
            add(new RealDataField("[垂直井深(m)]", "垂直井深", "m", 0f, 5000f));
            add(new RealDataField("[钻头位置(m)]", "钻头位置", "m", 0f, 5000f));
            add(new RealDataField("[大钩高度(m)]", "大钩位置", "m", 0f, 5000f));
            add(new RealDataField("[泵冲3(SPM)]", "三号泵冲", "spm", 0f, 5000f));
            add(new RealDataField("[Temp1]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp2]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp3]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp4]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp5]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp6]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp7]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp8]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp9]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp10]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp11]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp12]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp13]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp14]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp15]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp16]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp17]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp18]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp19]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp20]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp21]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp22]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp23]", "", "", 0f, 5000f));
            add(new RealDataField("[Temp24]", "", "", 0f, 5000f));
        }
    };

    public DataDiagnosticEngineer(String jh) {
        this.jh = jh;
        MDC.put(TRACE_ID, UUID.randomUUID().toString().replace("-", ""));
    }

    /**
     * 字段规则转换--强制将字段配置规范：Trim+toLowerCase
     *
     * @param src
     * @return
     */
    private DataDiagnosticParameter convertToDiagnosticParameter(FieldRule src) {
        // color, upDownRangeTotalNum 未转译
        DataDiagnosticParameter mcp = new DataDiagnosticParameter();
        if (src.fieldHandleType != -1) {
            mcp._fieldHandleType = FieldHandleType.valueOf(src.fieldHandleType);
        }
        mcp._fzNum = src.fzNum;
        mcp._continue = src.Continue;
        mcp._continueValue = src.continueValue;
        mcp._analyseType = AnalyseType.valueOf(src.analyseType);
        mcp._fieldUseable = src.fieldUseable;
        mcp._name = src.name;
        //强制将字段配置规范：Trim+toLowerCase
        mcp._originalField = this.getFieldName(src.realField == null ? "" : src.realField);
        mcp._realField = src.realField == null ? "" : src.realField.trim().toLowerCase();
        String field = src.realField == null ? "" : src.realField.trim();
        try {
            mcp._unit = field.substring(field.indexOf("(") + 1, field.indexOf(")"));
        } catch (Exception e) {

        }

        mcp._monitorTime = src.monitorTime;
        mcp._continuedTime = src.continuedTime;
        mcp._maxTotalNum = src.maxTotalNum;
        mcp._minTotalNum = src.minTotalNum;
        mcp._zdCount = src.zdCount;
        mcp._bdLtValue = src.bdLtValue;
        mcp._trendType = TrendType.valueOf(src.trendType);
        mcp._totalNum = src.TotalNum;
        mcp._trendTypeParam = TrendTypeParam.valueOf(src.trendTypeParam);
        mcp._beginValue = src.beginValue;
        if (mcp._beginValue <= 0.0001) {
            mcp._beginValue = 0.0;
        }
        mcp._endValue = src.endValue;
        mcp._mul = src.mul;
        mcp._isPumpRunJump = src.isPumpRunJump;
        mcp._isPumpRunJumpTime = src.isPumpRunJumpTime;
        mcp._isPumpStopJump = src.isPumpStopJump;
        mcp._isPumpStopJumpTime = src.isPumpStopJumpTime;
        mcp._pchx = src.pchx;
        mcp._pchxTime = src.pchxTime;

        //门限新增的几个判断条件
        mcp._preconditions = src.preconditions;
        mcp._preconditionsField = src.preconditionsField;
        mcp._doorList.clear();
        mcp._doorList.addAll(src.doorList);

        return mcp;
    }

    /**
     * 加载监控曲线参数
     *
     * @param src
     * @return
     */
    private DataDiagnosticParameters translate(AlarmType src) {
        DataDiagnosticParameters parameters = new DataDiagnosticParameters();
        parameters._isEnable = src.isEnable;
        parameters._drillState = src.drillState;

        for (FieldRule field : src.FieldRules) {
            parameters.parameters.add(convertToDiagnosticParameter(field));
        }

        return parameters;
    }

    /**
     * 解析模板数据
     *
     * @return
     */
    public boolean parseTemplate(BWellOwnEngineer template) {
        //解析预警参数
        wellOwn = JSON.parseObject(template.getLargeText(), WellOwn.class);

        //初始化预警参数列表
        for (AlarmType alarmType : wellOwn.AlarmTypeList) {
            mcpsList.put(alarmType.name, translate(alarmType));
        }

        return true;
    }

    /// <summary>
    /// 预警分析
    /// </summary>
    /// <param name="record">预警的单条数据记录</param>
    /// <param name="monitorAlarmRecords">预警结果</param>
    /// <param name="ds"></param>
    /// <returns></returns>
    public void analyseDataList(List<RecordHashTable> dataList, Map<String, MonitorAlarmRanges> alarmRangeMap, boolean testAllData) {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        String stackStr = packStackStr(stack);
        log.debug(" {}, 开始计算", stackStr);
        //当前钻井状态
        DrillState drillState = DrillState.None;
        boolean bAlarm;
        for (Map.Entry<String, DataDiagnosticParameters> entry : mcpsList.entrySet()) {
            if (entry.getValue()._isEnable) {
                log.debug(" {}, 计算类型{}", stackStr, entry.getKey());
                MonitorAlarmRanges alarmRanges = new MonitorAlarmRanges(entry.getKey());
                bAlarm = this.doPerformDiagnoseModel(entry.getKey(), entry.getValue(), dataList, drillState, alarmRanges, testAllData);
                if (bAlarm && !alarmRanges.isEmpty()) {
                    alarmRangeMap.putIfAbsent(entry.getKey(), alarmRanges);
                }
            } else {
                log.debug(" {}, 跳过计算类型a{}", stackStr, entry.getKey());
            }
        }
        log.debug(" {}, 结束计算,共{}种报警", stackStr, alarmRangeMap.keySet().size());
    }

    /**
     * 根据诊断参数获得单井诊断模型
     *
     * @return
     */
    private WellTrendDataDiagnostic getWellTrendDataDiagnosticByParameter(DataDiagnosticParameter parameter) {
        if (null != parameter.dataDiagnostic) {
            return parameter.dataDiagnostic;
        }
        WellTrendDataDiagnostic dataDiagnostic = null;
        switch (parameter._analyseType) {
            case AT_Trend:
                //趋势分析
                if (parameter._trendType == TrendType.TT_Up) {
                    dataDiagnostic = new WellUpTrendDataDiagnostic();
                } else {
                    dataDiagnostic = new WellDownTrendDataDiagnostic();
                }

                break;
            case AT_MinMax:
                //门限分析
                dataDiagnostic = new WellMinMaxTrendDataDiagnostic();
                break;
            case AT_Range:
                //振幅分析
                dataDiagnostic = new WellRangeTrendDataDiagnostic();
                break;
            case AT_BdRange:
                //波动分析
                dataDiagnostic = new WellFluctuantTrendDataDiagnostic();
                break;
            default:
                //默认门限分析
                dataDiagnostic = new WellMinMaxTrendDataDiagnostic();
                break;
        }
        if (null != dataDiagnostic) {
            dataDiagnostic.setParameter(parameter);
        }
        return dataDiagnostic;
    }

    /**
     * 根据一个具体诊断模型诊断给定的一段数据(倒推)
     *
     * @param alarmName
     * @param dataDiagnosticParameters:模型所有参数
     * @param drillState
     * @param alarmRanges
     * @return 返回值 false:没有异常 true:有异常
     */
    private boolean doPerformDiagnoseModel(String alarmName, DataDiagnosticParameters dataDiagnosticParameters,
                                           List<RecordHashTable> dataList, DrillState drillState, MonitorAlarmRanges alarmRanges, boolean testAllData) {
        String stackStr = packStackStr(Thread.currentThread().getStackTrace());
        // 多个预警模型， 每个模型多个参数， 每个条件对应一个字段？
        dataDiagnosticParameters.sortByGroupNum();
        //参数分组，将每组参数的flag值设置为1，其中1表示当前参数组报警
        Hashtable groups = new Hashtable();
        for (DataDiagnosticParameter diagnosticParameter : dataDiagnosticParameters.parameters) {
            if (!groups.containsKey(diagnosticParameter._fzNum)) {
                groups.put(diagnosticParameter._fzNum, 1);
            }
        }
        log.debug(" {}, 初始化分组完成", stackStr);

        boolean result = false;
        //模型参数总数
        int iParamCount = dataDiagnosticParameters.parameters.size();
        if (iParamCount < 1) {
            log.debug(" {}, 模型参数个数为0终止计算", stackStr);
            return false;
        }

        //监控信息列表
        ArrayList<AlarmPoint> monitorDescriptions = new ArrayList<AlarmPoint>();
        int nGroupAlarmState = 1;
        double percent = 0.0;

        //初始化算法
        for (int iParam = 0; iParam < iParamCount; iParam++) {
            DataDiagnosticParameter diagnosticParameter = dataDiagnosticParameters.parameters.get(iParam);//监控参数
            if (diagnosticParameter._fieldUseable) {
                WellTrendDataDiagnostic dataDiagnostic = this.getWellTrendDataDiagnosticByParameter(diagnosticParameter);
                diagnosticParameter.dataDiagnostic = dataDiagnostic;
                dataDiagnostic.setDataList(dataList);
                dataDiagnostic.init();
                log.debug(" {}, 参数" + diagnosticParameter._name + "已加载数据并初始化完成", stackStr);
            } else {
                log.debug(" {}, 参数" + diagnosticParameter._name + "禁用已跳过", stackStr);
            }
        }

        //从头开始诊断数据za
        int iDataCount = dataList.size();
        log.debug(" {}, 准备开始遍历ltd数据,共" + iDataCount + "条", stackStr);
        RecordHashTable curDataItem;
        DrillStateResult drillStateResult;
        //按照时间线向后退倒推---12:30:00->12:00:00;
        boolean canMoveNext = true;
        Date preDate, curDate = null;
        for (int iData = 0; iData < iDataCount; iData++) {
            if (!canMoveNext) {
                //有参数项已经循环到尾部（尾部仅仅指当前诊断点的时间+监控时间）
                break;
            }
            preDate = curDate;
            curDataItem = dataList.get(iData);
            curDate = (Date) curDataItem.get(MonitorContext.fieldTime);

            if (iData == iDataCount - 1) {
                //半小时数据的最后一条
                drillStateResult = WellTrendDataDiagnostic.GetDrillState(null, curDataItem);
            } else {
                drillStateResult = WellTrendDataDiagnostic.GetDrillState(dataList.get(iData + 1), curDataItem);
            }
            monitorDescriptions.clear();
            //================================================================
            //遍历所有模型参数--Begin
            for (int iParam = 0; iParam < iParamCount; iParam++) {
                DataDiagnosticParameter diagnosticParameter = dataDiagnosticParameters.parameters.get(iParam);//监控参数
                if (diagnosticParameter._fieldUseable) {
                    nGroupAlarmState = (int) groups.get(diagnosticParameter._fzNum);
                    AlarmPoint monitorDescription;
                    boolean bAlarm;//是否报警

                    double percentItem = 0.0;
                    double mulItem = 1.0 / (double) iParamCount;
                    WellTrendDataDiagnostic dataDiagnostic = diagnosticParameter.dataDiagnostic;
                    dataDiagnostic.setData(curDataItem);
                    dataDiagnostic.jh = this.jh;
                    DataDiagnosticAnalyzeResult results = dataDiagnostic.performAnalyze(drillStateResult);

                    bAlarm = results.result;
                    percentItem = results.percent;
                    monitorDescription = results.description;
                    if (percentItem > 1.0) {
                        percentItem = 1.0;
                    }
                    percent += percentItem * mulItem;
                    if (percent > 1.0) {
                        percent = 1.0;
                    }
                    //重置有参数的--退出模型的所有参数诊断循环
                    if (results.resetAllParams) {
                        for (DataDiagnosticParameter item : dataDiagnosticParameters.parameters) {
                            if (item._fieldUseable) {
                                item.dataDiagnostic.reset();
                            }
                        }
                        break;
                    }
                    if (bAlarm) {
                        monitorDescriptions.add(monitorDescription);
                        if (diagnosticParameter._fieldHandleType == FieldHandleType.FHT_Or) {
                            nGroupAlarmState |= 1;
                        }
                    }
                    if (!bAlarm && diagnosticParameter._fieldHandleType == FieldHandleType.FHT_And) {
                        nGroupAlarmState = 0;
                    }
                    groups.put(diagnosticParameter._fzNum, nGroupAlarmState);

                    //尝试移动到下一条诊断数据
                    canMoveNext = canMoveNext && dataDiagnostic.moveNext();
                    if (!canMoveNext) {
                        //已经诊断到尾部
                        continue;//return result;
                    }
                }
            }

            //遍历所有模型--end
            //================================================================

            //按照分组设计，对预警状态进行分析
            int nAllAlarmState = 1;//预警状态值
            Enumeration<Object> k5 = groups.keys();
            while (k5.hasMoreElements()) {
                Object key = k5.nextElement();
                int nAlarmState = (int) groups.get(key);
                nAllAlarmState &= nAlarmState;
                //将参数组的flag值重置为初始状态
                groups.put(key, 1);
            }
            if ((dataDiagnosticParameters._drillState & drillState.value()) == drillState.value()) {
                //有了报警的情况，我们可以不迭代下条记录，这个可以根据外面传递过来的参数确定
                if (nAllAlarmState > 0 && monitorDescriptions.size() > 0) {
                    percent = 1.0;
//                    monitorDescriptions.sort(MonitorDescription.McpSortByStartTime);
//                    for (int i = 0; i < monitorDescriptions.size(); i++) {
//
//                    }
                    this.UpdateListMonitorDescriptions(alarmRanges, preDate, curDate, monitorDescriptions);

                    result = true;
                    log.debug(" {}, 发生报警，位置{}", stackStr, iData);
                    //是否测试所有的样本数据
                    if (!testAllData) {
                        return result;
                    }
                }
                //矫正百分数（确保0<=percent<=1）
                percent = Math.min(Math.max(0, percent), 1.0);
                dataDiagnosticParameters.percent = percent;
            }
        }

        log.debug(" {}, 遍历数据结束", stackStr);

        return result;
    }

    public String getFieldName(String sName) {
        RealDataField field;
        sName = sName.toLowerCase();
        for (int i = 0; i < DataDiagnosticEngineer.RealDataFields.size(); i++) {
            field = DataDiagnosticEngineer.RealDataFields.get(i);
            if (sName.equals(field.get_realField().toLowerCase()) || sName.equals(field.get_displayName().toLowerCase())) {
                return field.StandardName;
            }
        }

        return "";
    }

    public static String getRealFieldName(String sName) {
        RealDataField field;
        sName = sName.toLowerCase();
        for (int i = 0; i < DataDiagnosticEngineer.RealDataFields.size(); i++) {
            field = DataDiagnosticEngineer.RealDataFields.get(i);
            if (sName.equals(field.get_realField().toLowerCase()) || sName.equals(field.get_displayName().toLowerCase())) {
                return field.StandardName;
            }
        }

        return "";
    }

    public static String getFieldUnit(String sName) {
        RealDataField field;
        sName = sName.toLowerCase();
        for (int i = 0; i < DataDiagnosticEngineer.RealDataFields.size(); i++) {
            field = DataDiagnosticEngineer.RealDataFields.get(i);
            if (sName.equals(field.get_realField().toLowerCase()) || sName.equals(field.get_displayName().toLowerCase())) {
                return field.get_unit();
            }
        }

        return "";
    }

    /**
     * 将诊断的数据（数据库）转为哈希表--KEY值小写
     *
     * @param src
     * @return
     */
    private static Hashtable LtdToHashtable(LtdRecord src) {
        Hashtable result = new Hashtable();
        result.put("钻压", src.WOB); //钻压 0
        result.put("h2s_2", src.H2S2); //h2s_2 0
        result.put("h2s_3", src.H2S3); //h2s_3 0
        result.put("转盘转速", src.RPM);//转盘转速 0.1786
        result.put("h2s_1", src.H2S1);//h2s_1 0
        result.put("出口电导", src.CONDOUT);//出口电导 0
        result.put("大钩负荷", src.WOH);//大钩负荷 290.421
        result.put("入口密度", src.MWIN);//入口密度 1.4265
        result.put("池体积2", src.PIT2);//池体积2 27.219
        result.put("二号泵冲", src.PUMP2);//二号泵冲 0
        result.put("三号泵冲", src.PUMP3);//三号泵冲 0
        result.put("井深", src.DEPTH);//井深 4232
        result.put("入口流量", src.FLOWIN);//入口流量 0
        result.put("c3", src.C3);//c3 0.0011
        result.put("出口密度", src.MWOUT);//出口密度 0.96
        result.put("迟到井深", src.LAGDEPTH);//迟到井深 4232
        result.put("池体积1", src.PIT1);//池体积1 25.2598
        result.put("出口流量", src.FLOWOUT);//出口流量 - 999.25
        result.put("出口流量%", src.FLOWOUTPERCENT);//出口流量 - 999.25
        result.put("立管压力", src.SPP);//立管压力 0
        result.put("时间", src.TIME);//时间 2021 / 9 / 6 0:00:22
        result.put("垂直井深", src.VDEPTH);//垂直井深 4013.48
        result.put("c1", src.C1);//c1 0.0025
        result.put("转盘扭矩", src.TORQUE);//转盘扭矩 0
        result.put("nc5", src.NC5);//nc5 0
        result.put("池体积5", src.PIT5);//池体积5 0
        result.put("co2", src.CO2);//co2 0.0396
        result.put("钻时", src.ROP_MAVG);//钻时 16.2108
        result.put("总池体积", src.PITTOTAL);//总池体积 78.0719
        result.put("套压", src.WHP);//套压 0
        result.put("ic4", src.IC4);//ic4 0.0011
        result.put("h2", src.H2);//h2 - 0.9999
        result.put("总烃", src.TG);//总烃 0
        result.put("ic5", src.IC5);//ic5 0.0018
        result.put("池体积4", src.PIT4);//池体积4 0
        result.put("nc4", src.NC4);//nc4 0
        result.put("一号泵冲", src.PUMP1);//一号泵冲 0
        result.put("大钩位置", src.HKH);//大钩位置 35.9999
        result.put("c2", src.C2);//c2 0.0014
        result.put("入口温度", src.TEMPIN);//入口温度 48.285
        result.put("泥浆溢漏", src.GAINLOSSVOL);//泥浆溢漏 - 999.25
        result.put("出口温度", src.TEMPOUT);//出口温度 27.97
        result.put("钻头位置", src.BITDEPTH);//钻头位置 8.9763
        result.put("入口电导", src.CONDIN);//入口电导 442.495
        result.put("池体积3", src.PIT3);//池体积3 25.5931

        return result;
    }

    /**
     * 将诊断的数据（数据库）转为哈希表--KEY值小写
     *
     * @param src
     * @return
     */
    public static RecordHashTable LtdToRecordHashTable(LtdRecord src) {
        RecordHashTable result = new RecordHashTable();
        result.put("钻压", src.WOB); //钻压 0
        result.put("h2s_2", src.H2S2); //h2s_2 0
        result.put("转盘转速", src.RPM);//转盘转速 0.1786
        result.put("h2s_1", src.H2S1);//h2s_1 0
        result.put("h2s_3", src.H2S3);//h2s_3 0
        result.put("出口电导", src.CONDOUT);//出口电导 0
        result.put("大钩负荷", src.WOH);//大钩负荷 290.421
        result.put("入口密度", src.MWIN);//入口密度 1.4265
        result.put("池体积2", src.PIT2);//池体积2 27.219
        result.put("二号泵冲", src.PUMP2);//二号泵冲 0
        result.put("三号泵冲", src.PUMP3);//三号泵冲 0
        result.put("井深", src.DEPTH);//井深 4232
        result.put("入口流量", src.FLOWIN);//入口流量 0
        result.put("c3", src.C3);//c3 0.0011
        result.put("出口密度", src.MWOUT);//出口密度 0.96
        result.put("迟到井深", src.LAGDEPTH);//迟到井深 4232
        result.put("池体积1", src.PIT1);//池体积1 25.2598
        result.put("出口流量", src.FLOWOUT);//出口流量 - 999.25
        result.put("出口流量%", src.FLOWOUTPERCENT);//出口流量 - 999.25
        result.put("立管压力", src.SPP);//立管压力 0
        try {
            Date dtTime = org.jeecg.common.util.DateUtils.parseDate(src.TIME.trim(), DateTimeFormat);
            result.put("时间", dtTime);//时间 2021 / 9 / 6 0:00:22
        } catch (Exception ex) {

        }
        //result.put("时间", src.TIME);//时间 2021 / 9 / 6 0:00:22
        result.put("垂直井深", src.VDEPTH);//垂直井深 4013.48
        result.put("c1", src.C1);//c1 0.0025
        result.put("转盘扭矩", src.TORQUE);//转盘扭矩 0
        result.put("nc5", src.NC5);//nc5 0
        result.put("池体积5", src.PIT5);//池体积5 0
        result.put("co2", src.CO2);//co2 0.0396
        result.put("钻时", src.ROP_MAVG);//钻时 16.2108
        result.put("总池体积", src.PITTOTAL);//总池体积 78.0719
        result.put("套压", src.WHP);//套压 0
        result.put("ic4", src.IC4);//ic4 0.0011
        result.put("h2", src.H2);//h2 - 0.9999
        result.put("总烃", src.TG);//总烃 0
        result.put("ic5", src.IC5);//ic5 0.0018
        result.put("池体积4", src.PIT4);//池体积4 0
        result.put("nc4", src.NC4);//nc4 0
        result.put("一号泵冲", src.PUMP1);//一号泵冲 0
        result.put("大钩位置", src.HKH);//大钩位置 35.9999
        result.put("c2", src.C2);//c2 0.0014
        result.put("入口温度", src.TEMPIN);//入口温度 48.285
        result.put("泥浆溢漏", src.GAINLOSSVOL);//泥浆溢漏 - 999.25
        result.put("出口温度", src.TEMPOUT);//出口温度 27.97
        result.put("钻头位置", src.BITDEPTH);//钻头位置 8.9763
        result.put("入口电导", src.CONDIN);//入口电导 442.495
        result.put("池体积3", src.PIT3);//池体积3 25.5931

        return result;
    }


    /**
     * 合并监控预警信息
     *
     * @param alarmRanges
     * @param alarmPoints
     */
    private void UpdateListMonitorDescriptions(MonitorAlarmRanges alarmRanges, Date preSiblingDate, Date currentDate, ArrayList<AlarmPoint> alarmPoints) {

        if (alarmPoints.size() > 0) {
            alarmRanges.tryAddMonitorDescriptions(preSiblingDate, currentDate, alarmPoints, this.jh);
        }
    }

    public static String packStackStr(StackTraceElement[] stack) {
        int levels = Math.min(stack.length, 5);
        String result = "";
        for (int i = 1; i < levels; i++) {
            String[] temp = stack[i].getMethodName().split("\\.");
            result += " " + temp[temp.length - 1];
            if (stack[i].getMethodName().endsWith(calleeStart)) {
                break;
            }
        }
        return result;
    }
}
