import pandas as pd

from pot_libs.settings import SETTING
from pot_libs.utils.exc_util import BusinessException
from unify_api.constants import POINT_LEVEL_MAP, U_THRESHOLD, COSTTL_THRESHOLD, \
    LF_THRESHOLD, THDU_THRESHOLD, BL_THRESHOLD, THDI_THRESHOLD
from unify_api.modules.common.procedures.points import points_by_storeys, \
    get_meter_by_point_new15
from unify_api.modules.common.service.td_engine_service import \
    get_td_engine_data
from unify_api.modules.electric.dao.electric_dao import \
    monitor_point_join_by_points, get_electric_datas_dao
from unify_api.modules.electric.procedures.electric_pds import \
    elec_current_data, qual_current_data, elec_current_data_new15
from unify_api.modules.electric.procedures.electric_util import \
    batch_get_wiring_type
from unify_api.utils import time_format
from unify_api.utils.common_utils import round_2, round_4, multiplication_two
from unify_api.modules.electric.procedures.electric_util import \
    get_wiring_type, get_wiring_type_new15
from pot_libs.utils.pendulum_wrapper import my_pendulum
from datetime import datetime
from pot_libs.es_util.es_query import EsQuery
from pot_libs.es_util.es_utils import EsUtil
from pot_libs.logger import log
from unify_api.modules.common.procedures.location_temp_rcurrent import \
    location_stats_statics, location_stats_statics_new15
from unify_api import constants
from pot_libs.common.components.query import PageRequest, Range, Equal, Filter
from unify_api.modules.electric.components.electric import (
    ElecIndexResponse, ElecIndex, EscResp, QcsResp, EclResp, QclResp,
)
from unify_api.utils.taos_new import parse_td_columns


async def elec_current_storeys_service(storeys):
    """用电监测-实时监测-楼层"""
    # 1.根据storeys获取points信息
    point_list = await points_by_storeys(storeys)
    # mtids
    mtids = [i.get("mtid") for i in point_list]
    cid = point_list[0]['cid'] if len(point_list) > 0 else 0
    # 2.获取mid, ctnum
    # point_mid = await batch_get_wiring_type(points)
    # # 3. 获取redis数据
    # res = await elec_current_data(point_mid)
    res = await elec_current_data_new15(mtids, cid)
    # 4. 返回数据
    elec_data = {}
    for info in point_list:
        storey_name = info.get("storey_name")
        storey_id = info.get("storey_id")
        point_id = info.get("point_id")
        room_name = info.get("room_name")
        mtid = info.get("mtid")
        ctnum = info.get("ctnum")
        # 初始化返回dic
        if res.get(mtid):
            # 识电U只有一项有数据,返回具体的项
            res[mtid] = get_sdu_i_and_u(res[mtid], ctnum)
            time_str = res[mtid]["ts"][:-4]
            res_dic = {
                "room_name": room_name,
                "storey_id": storey_id,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": time_str,
                "ua": round_2(res[mtid].get("ua")),
                "ia": round_2(res[mtid].get("ia")),
                "ub": round_2(res[mtid].get("ub")),
                "ib": round_2(res[mtid].get("ib")),
                "uc": round_2(res[mtid].get("uc")),
                "ic": round_2(res[mtid].get("ic")),
                "pttl": round_2(res[mtid].get("pttl")),
                "qttl": round_2(res[mtid].get("qttl")),
                "freq": round_2(res[mtid].get("freq")),
                "costtl": round_2(res[mtid].get("costtl")),
                "lf": round_2(res[mtid].get("lf")),
                "sdu_i": res[mtid].get('sdu_i'),
                "sdu_u": res[mtid].get('sdu_u'),
            }
        # redis数据过期,或者没有数据
        else:
            res_dic = {
                "room_name": room_name,
                "point_id": point_id,
                "storey_id": storey_id,
                "ctnum": ctnum,
                "real_time": "",
                "ua": "",
                "ia": "",
                "ub": "",
                "ib": "",
                "uc": "",
                "ic": "",
                "pttl": "",
                "qttl": "",
                "freq": "",
                "costtl": "",
                "lf": "",
                "sdu_i": "",
                "sdu_u": "",
            }
        # 组装返回格式为dic
        if storey_name in elec_data:
            elec_data[storey_name].append(res_dic)
        else:
            elec_data[storey_name] = [res_dic]
    # 转换成list格式, 可以按照storey_name排序
    if elec_data:
        # 房间排序, 并返回数据转化为list
        elec_list = [{"name": key, "storey_id": value[0]["storey_id"],
                      "room_data": sorted(value, key=lambda i: i["room_name"])}
                     for key, value in elec_data.items()]
        # 楼层排序
        elec_list = sorted(elec_list, key=lambda x: x["storey_id"])
    else:
        elec_list = []
    return EscResp(elec_data=elec_list)


async def qual_current_storeys_service(storeys):
    """电能质量-实时参数-楼层"""
    # 1.根据storeys获取points信息
    point_list = await points_by_storeys(storeys)
    # 获取point_id列表
    # points = [i.get("point_id") for i in point_list]
    # # 2.获取mid, ctnum
    # point_mid = await batch_get_wiring_type(points)
    # # 3. 获取redis数据
    # res = await qual_current_data(point_mid)
    mtids = [point["mtid"] for point in point_list if point["mtid"]]
    cid = point_list[0]['cid'] if len(point_list) > 0 else 0
    res = await elec_current_data_new15(mtids, cid)
    # 4. 返回数据
    qual_data = {}
    for info in point_list:
        storey_name = info.get("storey_name")
        storey_id = info.get("storey_id")
        point_id = info.get("point_id")
        room_name = info.get("room_name")
        mtid = info.get("mtid")
        ctnum = info.get("ctnum") if info.get("ctnum") == 2 else 3
        # 初始化返回dic
        if res.get(mtid):
            res[mtid] = get_sdu_i_and_u(res[mtid], ctnum)
            time_str = res[mtid]["ts"][:-4]
            res_dic = {
                "room_name": room_name,
                "storey_id": storey_id,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": time_str,
                # 电流/电压谐波畸变率
                "thdia": round_4(res[mtid].get("thdia")),
                "thdib": round_4(res[mtid].get("thdib")),
                "thdic": round_4(res[mtid].get("thdic")),
                "thdua": round_4(res[mtid].get("thdua")),
                "thdub": round_4(res[mtid].get("thdub")),
                "thduc": round_4(res[mtid].get("thduc")),
                # 电压偏差
                "ua_dev": round_4(res[mtid].get("ua_dev")),
                "ub_dev": round_4(res[mtid].get("ub_dev")),
                "uc_dev": round_4(res[mtid].get("uc_dev")),
                "sdu_i": res[mtid].get("sdu_i"),
                "sdu_u": res[mtid].get("sdu_u"),
            }
        # redis数据过期,或者没有数据
        else:
            res_dic = {
                "room_name": room_name,
                "storey_id": storey_id,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": "",
                "thdia": "",
                "thdib": "",
                "thdic": "",
                "thdua": "",
                "thdub": "",
                "thduc": "",
                "ua_dev": "",
                "ub_dev": "",
                "uc_dev": "",
                "sdu_i": "",
                "sdu_u": "",
            }
        # 组装返回格式为dic
        if storey_name in qual_data:
            qual_data[storey_name].append(res_dic)
        else:
            qual_data[storey_name] = [res_dic]
    # 转换成list格式, 可以按照storey_name排序
    if qual_data:
        # 房间排序, 并返回数据转化为list
        qual_list = [{"name": key, "storey_id": value[0]["storey_id"],
                      "room_data": sorted(value,
                                          key=lambda i: i["room_name"])}
                     for key, value in qual_data.items()]
        # 楼层排序
        qual_list = sorted(qual_list, key=lambda x: x["storey_id"])
    else:
        qual_list = []
    return QcsResp(qual_data=qual_list)


async def elec_card_level_service(point_list):
    """用电监测-卡片信息-level"""
    # 1. 获取每个point_id的详细信息
    monitor_point_list = await monitor_point_join_by_points(point_list)
    # # 2.获取mid, ctnum
    # point_mid = await batch_get_wiring_type(point_list)
    # # 3. 获取redis数据
    # res_redis = await elec_current_data(point_mid)
    mtids = [monitor["mtid"] for monitor in monitor_point_list if monitor["mtid"]]
    cid = monitor_point_list[0]['cid'] if len(monitor_point_list) > 0 else 0
    results = await elec_current_data_new15(mtids, cid)
    # 4. 返回数据
    ret_data = {
        "inline": [],
        "transformer": [],
        "feeder": [],
        "power_dist": [],
        "device": []
    }
    for info in monitor_point_list:
        m_name = info.get("name")
        m_type = POINT_LEVEL_MAP[info.get("m_type")]
        point_id = info.get("pid")
        mtid = info.get("mtid")
        ctnum = info.get("ctnum") if info.get("ctnum") == 2 else 3
        # 初始化返回dic
        if results.get(mtid):
            time_str = results[mtid]["ts"][:-4]
            res_dic = {
                "name": m_name,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": time_str,
                "ua": round_2(results[mtid].get("ua")),
                "ia": round_2(results[mtid].get("ia")),
                "ub": round_2(results[mtid].get("ub")),
                "ib": round_2(results[mtid].get("ib")),
                "uc": round_2(results[mtid].get("uc")),
                "ic": round_2(results[mtid].get("ic")),
                "pttl": round_2(results[mtid].get("pttl")),
                "qttl": round_2(results[mtid].get("qttl")),
                "freq": round_2(results[mtid].get("freq")),
                "costtl": round_2(results[mtid].get("costtl")),
                "lf": round_2(results[mtid].get("lf")),
                "sdu_i": results[mtid].get("sdu_i"),
                "sdu_u": results[mtid].get("sdu_u"),
                # 增加电压偏差,用于判断是否超过阈值标红
                "ua_dev": round_4(results[mtid].get("ua_dev")),
                "ub_dev": round_4(results[mtid].get("ub_dev")),
                "uc_dev": round_4(results[mtid].get("uc_dev")),
                "uab_dev": round_4(results[mtid].get("uab_dev")),
                "ucb_dev": round_4(results[mtid].get("ucb_dev")),
                # 增加阈值
                "u_threshold": U_THRESHOLD,
                "costtl_threshold": COSTTL_THRESHOLD,
                "lf_threshold": LF_THRESHOLD,
            }
        # redis数据过期,或者没有数据
        else:
            res_dic = {
                "name": m_name,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": "",
                "ua": "",
                "ia": "",
                "ub": "",
                "ib": "",
                "uc": "",
                "ic": "",
                "pttl": "",
                "qttl": "",
                "freq": "",
                "costtl": "",
                "lf": "",
                "sdu_i": "",
                "sdu_u": "",
                # 增加电压偏差,用于判断是否超过阈值标红
                "ua_dev": "",
                "ub_dev": "",
                "uc_dev": "",
            }

        ret_data[m_type].append(res_dic)
    return EclResp(
        inline=ret_data["inline"],
        transformer=ret_data["transformer"],
        feeder=ret_data["feeder"],
        power_dist=ret_data["power_dist"],
        device=ret_data["device"],
    )


async def qual_current_level_service(point_list):
    """电能质量-卡片信息-level"""
    # 1. 获取每个point_id的详细信息
    monitor_point_list = await monitor_point_join_by_points(point_list)
    # # 2.获取mid, ctnum
    # point_mid = await batch_get_wiring_type(point_list)
    # # 3. 获取redis数据
    # res_redis = await qual_current_data(point_mid)
    mtids = [monitor["mtid"] for monitor in monitor_point_list if
             monitor["mtid"]]
    cid = monitor_point_list[0]['cid'] if len(monitor_point_list) > 0 else 0
    res = await elec_current_data_new15(mtids, cid)
    # 4. 返回数据
    ret_data = {
        "inline": [],
        "transformer": [],
        "feeder": [],
        "power_dist": [],
        "device": []
    }
    for info in monitor_point_list:
        m_name = info.get("name")
        m_type = POINT_LEVEL_MAP[info.get("m_type")]
        point_id = info.get("pid")
        mtid = info.get("mtid")
        ctnum = info.get("ctnum") if info.get("ctnum") == 2 else 3
        # 初始化返回dic
        if res.get(mtid):
            time_str = res[mtid]["ts"][:-4]

            fdia = round_2(res[mtid].get("fdia"))
            fdib = round_2(res[mtid].get("fdib"))
            fdic = round_2(res[mtid].get("fdic"))

            thdia = round_4(res[mtid].get("thdia"))
            thdib = round_4(res[mtid].get("thdib"))
            thdic = round_4(res[mtid].get("thdic"))

            res_dic = {
                "name": m_name,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": time_str,
                # 电流/电压谐波畸变率
                "thdia": thdia,
                "thdib": thdib,
                "thdic": thdic,

                "thdua": round_4(res[mtid].get("thdua")),
                "thdub": round_4(res[mtid].get("thdub")),
                "thduc": round_4(res[mtid].get("thduc")),
                "thduab": round_4(res[mtid].get("thduab")),
                "thducb": round_4(res[mtid].get("thducb")),
                # 基波电流
                "fdia": fdia,
                "fdib": fdib,
                "fdic": fdic,
                # 三相不平衡
                "ubl": round_4(res[mtid].get("ubl")),
                "ibl": round_4(res[mtid].get("ibl")),
                # 电压偏差
                "ua_dev": round_4(res[mtid].get("ua_dev")),
                "ub_dev": round_4(res[mtid].get("ub_dev")),
                "uc_dev": round_4(res[mtid].get("uc_dev")),
                "uab_dev": round_4(res[mtid].get("uab_dev")),
                "ucb_dev": round_4(res[mtid].get("ucb_dev")),
                # 电流总谐波有效值 = 基波电流 * 电流总谐波畸变率
                "thdia_virtual": round_2(multiplication_two(fdia, thdia)),
                "thdib_virtual": round_2(multiplication_two(fdib, thdib)),
                "thdic_virtual": round_2(multiplication_two(fdic, thdic)),
                # 增加阈值 web
                "thdu_threshold": THDU_THRESHOLD,  # 电压总谐波畸变
                "bl_threshold": BL_THRESHOLD,  # 三相不平衡
                # 增加阈值 小程序
                "thdi_threshold": THDI_THRESHOLD,  # 电流总谐波畸变
                "u_threshold": U_THRESHOLD,  # 电压偏差
            }
        # redis数据过期,或者没有数据
        else:
            res_dic = {
                "name": m_name,
                "point_id": point_id,
                "ctnum": ctnum,
                "real_time": "",
                # 电流/电压谐波畸变率
                "thdia": "",
                "thdib": "",
                "thdic": "",

                "thdua": "",
                "thdub": "",
                "thduc": "",
                "thduab": "",
                "thducb": "",
                # 基波电流
                "fdia": "",
                "fdib": "",
                "fdic": "",
                # 三相不平衡
                "ubl": "",
                "ibl": "",
                # 电压偏差
                "ua_dev": "",
                "ub_dev": "",
                "uc_dev": "",
                "uab_dev": "",
                "ucb_dev": "",
                # 电流总谐波有效值 = 基波电流 * 电流总谐波畸变率
                "thdia_virtual": "",
                "thdib_virtual": "",
                "thdic_virtual": "",
            }

        ret_data[m_type].append(res_dic)
    return QclResp(
        inline=ret_data["inline"],
        transformer=ret_data["transformer"],
        feeder=ret_data["feeder"],
        power_dist=ret_data["power_dist"],
        device=ret_data["device"],
    )


async def elec_index_service(cid, point_id, date_start, date_end):
    # 2. 获取几表法
    ctnum, _ = 3, 0  # await get_wiring_type(point_id)
    if ctnum not in [2, 3]:
        # 给默认值3表法
        ctnum = 3
    # 起始时间分别转化为时间戳
    start_tt = time_format.get_date_timestamp(date_start)
    end_tt = time_format.get_date_timestamp(date_end)
    es_start_dt = str(
        my_pendulum.from_format(date_start, "YYYY-MM-DD HH:mm:ss"))
    es_end_dt = str(my_pendulum.from_format(date_end, "YYYY-MM-DD HH:mm:ss"))
    range = Range(field="quarter_time", start=es_start_dt, end=es_end_dt)
    equal = Equal(field="pid", value=point_id)
    filter = Filter(equals=[equal], ranges=[range], in_groups=[], keywords=[])
    page_request = PageRequest(page_size=1, page_num=1, sort=None,
                               filter=filter)
    # TODO频率偏差和电压偏差后期直接通过硬件取值，暂时忽略
    if ctnum == 2:
        common_items = [
            "lf_mean",
            "lf_min",
            "lf_max",
            "pttl_mean",
            "pttl_min",
            "pttl_max",
            "qttl_mean",
            "qttl_min",
            "qttl_max",
            "costtl_mean",
            "costtl_min",
            "costtl_max",
            "uab_mean",
            "uab_min",
            "uab_max",
            "ucb_mean",
            "ucb_min",
            "ucb_max",
            "ia_mean",
            "ia_min",
            "ia_max",
            "ic_mean",
            "ic_min",
            "ic_max",
            "freq_mean",
            "freq_min",
            "freq_max",
        ]
        elec_qual_items = [
            "ubl_mean",
            "ubl_min",
            "ubl_max",
            "ibl_mean",
            "ibl_min",
            "ibl_max",
            "thduab_mean",
            "thduab_min",
            "thduab_max",
            "thducb_mean",
            "thducb_min",
            "thducb_max",
            "thdia_mean",
            "thdia_min",
            "thdia_max",
            "thdic_mean",
            "thdic_min",
            "thdic_max",
            "uab_dev_mean",
            "uab_dev_min",
            "uab_dev_max",
            "freq_dev_mean",
            "freq_dev_min",
            "freq_dev_max",
        ]
    else:
        common_items = [
            "lf_mean",
            "lf_min",
            "lf_max",
            "pttl_mean",
            "pttl_min",
            "pttl_max",
            "qttl_mean",
            "qttl_min",
            "qttl_max",
            "costtl_mean",
            "costtl_min",
            "costtl_max",
            "ua_mean",
            "ua_min",
            "ua_max",
            "ub_mean",
            "ub_min",
            "ub_max",
            "uc_mean",
            "uc_min",
            "uc_max",
            "ia_mean",
            "ia_min",
            "ia_max",
            "ib_mean",
            "ib_min",
            "ib_max",
            "ic_mean",
            "ic_min",
            "ic_max",
            "freq_mean",
            "freq_min",
            "freq_max",
        ]
        elec_qual_items = [
            "ubl_mean",
            "ubl_min",
            "ubl_max",
            "ibl_mean",
            "ibl_min",
            "ibl_max",
            "thdua_mean",
            "thdua_min",
            "thdua_max",
            "thdub_mean",
            "thdub_min",
            "thdub_max",
            "thduc_mean",
            "thduc_min",
            "thduc_max",
            "thdia_mean",
            "thdia_min",
            "thdia_max",
            "thdib_mean",
            "thdib_min",
            "thdib_max",
            "thdic_mean",
            "thdic_min",
            "thdic_max",
            "ua_dev_mean",
            "ua_dev_min",
            "ua_dev_max",
            "freq_dev_mean",
            "freq_dev_min",
            "freq_dev_max",
        ]

    query_body = EsQuery.aggr_index(page_request,
                                    stats_items=common_items + elec_qual_items)

    async with EsUtil() as es:
        es_results = await es.search_origin(body=query_body,
                                            index=constants.POINT_15MIN_INDEX)

    aggregations = es_results.get("aggregations", {})
    # 常规参数统计
    common_indexes = []
    _common_items = {i.rsplit("_", 1)[0] for i in common_items}
    for item in _common_items:
        # 最大值
        max_info = aggregations.get(f"{item}_max_max", {})
        hits = max_info.get("hits", {}).get("hits")
        if hits:
            source = hits[0].get("_source", {})
            max_value = source.get(f"{item}_max")
            max_value = max_value if max_value is not None else ""
            max_dt = source.get(f"{item}_max_time")
            if max_dt is None:
                log.error(
                    f"错误{item}_max_time: item={item} ctnum={ctnum} point_id={point_id}")
            max_value_time = (
                str(datetime.strptime(max_dt,
                                      "%Y-%m-%dT%H:%M:%S+08:00")) if max_dt else ""
            )
        else:
            max_value = ""
            max_value_time = ""

        # 最小值
        min_info = aggregations.get(f"{item}_min_min", {})
        hits = min_info.get("hits", {}).get("hits")
        if hits:
            source = hits[0].get("_source", {})
            min_value = source.get(f"{item}_min")
            min_value = min_value if min_value is not None else ""
            min_dt = source.get(f"{item}_min_time")
            min_value_time = (
                str(datetime.strptime(min_dt,
                                      "%Y-%m-%dT%H:%M:%S+08:00")) if min_dt else ""
            )
        else:
            min_value = ""
            min_value_time = ""

        avg = aggregations.get(f"{item}_mean_avg", {}).get("value")
        avg = round(avg, 2) if avg is not None else ""

        elec_index = ElecIndex(
            stats_index=item,
            max=max_value,
            max_time=max_value_time,
            min=min_value,
            min_time=min_value_time,
            avg=avg,
        )
        common_indexes.append(elec_index)

    # 电能质量统计
    elec_qual_indexes = []
    _elec_qual_items = {i.rsplit("_", 1)[0] for i in elec_qual_items}
    for item in _elec_qual_items:
        # 最大值
        max_info = aggregations.get(f"{item}_max_max", {})
        hits = max_info.get("hits", {}).get("hits")
        if hits:
            source = hits[0].get("_source", {})
            max_value = source.get(f"{item}_max", 0)
            max_value = max_value if max_value is not None else ""
            max_dt = source.get(f"{item}_max_time", 0)
            max_value_time = str(
                datetime.strptime(max_dt,
                                  "%Y-%m-%dT%H:%M:%S+08:00")) if max_dt else ""
        else:
            max_value = ""
            max_value_time = ""

        # 最小值
        min_info = aggregations.get(f"{item}_min_min", {})
        hits = min_info.get("hits", {}).get("hits")
        if hits:
            source = hits[0].get("_source", {})
            min_value = source.get(f"{item}_min", 0)
            min_value = min_value if min_value is not None else ""
            min_dt = source.get(f"{item}_min_time")
            min_value_time = str(
                datetime.strptime(min_dt,
                                  "%Y-%m-%dT%H:%M:%S+08:00")) if min_dt else ""
        else:
            min_value = ""
            min_value_time = ""

        avg = aggregations.get(f"{item}_mean_avg", {}).get("value")
        avg = avg if avg is not None else ""

        elec_index = ElecIndex(
            stats_index=item,
            max=max_value,
            max_time=max_value_time,
            min=min_value,
            min_time=min_value_time,
            avg=avg,
        )
        elec_qual_indexes.append(elec_index)

    if cid:
        # 小程序需要这漏电流和温度
        residual_current_map = await location_stats_statics(
            cid, point_id, start_tt, end_tt, _type="residual_current"
        )
        if residual_current_map:
            residual_current_map = residual_current_map["漏电流"]
            common_indexes.append(
                ElecIndex(
                    stats_index="residual_current",
                    name="漏电流(mA)",
                    max=residual_current_map["value_max"]["value"]
                    if "value_max" in residual_current_map
                    else None,
                    max_time=residual_current_map["value_max"]["time"]
                    if "value_max" in residual_current_map
                    else None,
                    min=residual_current_map["value_min"]["value"]
                    if "value_min" in residual_current_map
                    else None,
                    min_time=residual_current_map["value_min"]["time"]
                    if "value_min" in residual_current_map
                    else None,
                    avg=residual_current_map["value_avg"]
                    if "value_avg" in residual_current_map
                    else None,
                )
            )

        temp_map = await location_stats_statics(
            cid, point_id, start_tt, end_tt, _type="temperature"
        )
        if temp_map:
            for item_name, agg_info_map in temp_map.items():
                common_indexes.append(
                    ElecIndex(
                        stats_index="temperature",
                        name=f"{item_name}(℃)",
                        max=agg_info_map["value_max"]["value"]
                        if "value_max" in agg_info_map
                        else None,
                        max_time=agg_info_map["value_max"]["time"]
                        if "value_max" in agg_info_map
                        else None,
                        min=agg_info_map["value_min"]["value"]
                        if "value_min" in agg_info_map
                        else None,
                        min_time=agg_info_map["value_min"]["time"]
                        if "value_min" in agg_info_map
                        else None,
                        avg=agg_info_map[
                            "value_avg"] if "value_avg" in agg_info_map else None,
                    )
                )
    return ElecIndexResponse(
        ctnum=ctnum, common_indexes=common_indexes,
        elec_qual_indexes=elec_qual_indexes
    )


async def elec_index_service_new15(cid, point_id, start, end):
    ctnum = await get_wiring_type_new15(point_id)
    ctnum = ctnum if ctnum == 2 else 3
    now = str(datetime.now())
    if start[:10] == now[:10] and end[:10] == now[:10]:
        table_name = "point_15min_electric"
        redi_table_name = "location_15min_aiao"
    else:
        table_name = "point_1day_electric"
        redi_table_name = "location_1day_aiao"
    if ctnum == 2:
        common_items = ["lf_mean", "lf_min", "lf_max", "pttl_mean", "pttl_min",
                        "pttl_max", "qttl_mean", "qttl_min", "qttl_max",
                        "costtl_mean", "costtl_min", "costtl_max", "uab_mean",
                        "uab_min", "uab_max", "ucb_mean", "ucb_min", "ucb_max",
                        "ia_mean", "ia_min", "ia_max", "ic_mean", "ic_min",
                        "ic_max", "freq_mean", "freq_min", "freq_max"]
        elec_qual_items = ["ubl_mean", "ubl_min", "ubl_max", "ibl_mean",
                           "ibl_min", "ibl_max", "thduab_mean", "thduab_min",
                           "thduab_max", "thducb_mean", "thducb_min",
                           "thducb_max", "thdia_mean", "thdia_min",
                           "thdia_max", "thdic_mean", "thdic_min", "thdic_max",
                           "uab_dev_mean", "uab_dev_min", "uab_dev_max",
                           "freq_dev_mean", "freq_dev_min", "freq_dev_max", ]
    else:
        common_items = ["lf_mean", "lf_min", "lf_max", "pttl_mean", "pttl_min",
                        "pttl_max", "qttl_mean", "qttl_min", "qttl_max",
                        "costtl_mean", "costtl_min", "costtl_max", "ua_mean",
                        "ua_min", "ua_max", "ub_mean", "ub_min", "ub_max",
                        "uc_mean", "uc_min", "uc_max", "ia_mean", "ia_min",
                        "ia_max", "ib_mean", "ib_min", "ib_max", "ic_mean",
                        "ic_min", "ic_max", "freq_mean", "freq_min",
                        "freq_max"]
        elec_qual_items = ["ubl_mean", "ubl_min", "ubl_max", "ibl_mean",
                           "ibl_min", "ibl_max", "thdua_mean", "thdua_min",
                           "thdua_max", "thdub_mean", "thdub_min", "thdub_max",
                           "thduc_mean", "thduc_min", "thduc_max",
                           "thdia_mean", "thdia_min", "thdia_max",
                           "thdib_mean", "thdib_min", "thdib_max",
                           "thdic_mean", "thdic_min", "thdic_max",
                           "ua_dev_mean", "ua_dev_min", "ua_dev_max",
                           "freq_dev_mean", "freq_dev_min", "freq_dev_max"]
    datas = await get_electric_datas_dao(table_name, point_id, start, end)
    if not datas:
        return ElecIndexResponse(
            ctnum=ctnum, common_indexes=[],
            elec_qual_indexes=[]
        )
    df = pd.DataFrame(list(datas))
    # 常规参数统计
    common_indexes = []
    _common_items = {i.rsplit("_", 1)[0] for i in common_items}
    for item in _common_items:
        item_name = item.rsplit("_", 1)[0]
        max_item_name = f"{item}_max"
        max_value = df[max_item_name].max()
        if not pd.isna(max_value):
            max_datas = df.loc[df[max_item_name].idxmax()].to_dict()
            max_time = max_datas.get(f"{item_name}_max_time")
            max_time = '' if pd.isnull(max_time) else str(max_time)
        else:
            max_value, max_time = "", ""
        min_item_name = f"{item}_min"
        min_value = df[min_item_name].min()
        if not pd.isna(min_value):
            min_datas = df.loc[df[min_item_name].idxmin()].to_dict()
            min_time = min_datas.get(f"{item_name}_min_time")
            min_time = '' if pd.isnull(min_time) else str(min_time)
        else:
            min_value, min_time = "", ""
        mean_item_name = f"{item}_mean"
        avg_value = df[mean_item_name].mean()
        if not pd.isna(avg_value):
            avg_value = round(avg_value, 2) if avg_value else ""
        else:
            avg_value = ""
        elec_index = ElecIndex(
            stats_index=item_name,
            max=max_value,
            max_time=max_time or "",
            min=min_value,
            min_time=min_time or "",
            avg=avg_value,
        )
        common_indexes.append(elec_index)
    # 电能质量统计
    elec_qual_indexes = []
    _elec_qual_items = {i.rsplit("_", 1)[0] for i in elec_qual_items}
    for item in _elec_qual_items:
        item_name = item.rsplit("_", 1)[0]
        max_item_name = f"{item}_max"
        max_value = df[max_item_name].max()
        if not pd.isna(max_value):
            max_datas = df.loc[df[max_item_name].idxmax()].to_dict()
            max_time = max_datas.get(f"{item_name}_max_time")
            max_time = '' if pd.isnull(max_time) else str(max_time)
        else:
            max_value, max_time = "", ""
        min_item_name = f"{item}_min"
        min_value = df[min_item_name].min()
        if not pd.isna(min_value):
            min_datas = df.loc[df[min_item_name].idxmin()].to_dict()
            min_time = min_datas.get(f"{item_name}_min_time")
            min_time = '' if pd.isnull(min_time) else str(min_time)
        else:
            min_value, min_time = "", ""
        mean_item_name = f"{item}_mean"
        avg_value = df[mean_item_name].mean()
        if not pd.isna(avg_value):
            avg_value = round(avg_value, 2) if avg_value else ""
        else:
            avg_value = ""
        elec_index = ElecIndex(
            stats_index=item_name,
            max=max_value,
            max_time=max_time,
            min=min_value,
            min_time=min_time,
            avg=avg_value,
        )
        elec_qual_indexes.append(elec_index)
    # 小程序需要这漏电流和温度
    if cid:
        location_datas = await location_stats_statics_new15(redi_table_name,
                                                            cid, start, end)
        if location_datas:
            for key, value in location_datas.items():
                if value["ad_type"] == "residual_current":
                    name = "漏电流(mA)"
                else:
                    name = f"{value.get('item')}温度(℃)"
                common_indexes.append(
                    ElecIndex(
                        stats_index=value["ad_type"],
                        name=name,
                        max=value.get("max_value") or '',
                        max_time=value.get("max_value_time") or '',
                        min=value.get("min_value") or '',
                        min_time=value.get("min_value_time") or '',
                        avg=value.get("mean_value") or '',
                    )
                )
    return ElecIndexResponse(
        ctnum=ctnum, common_indexes=common_indexes,
        elec_qual_indexes=elec_qual_indexes
    )

async def elec_current_service_new15(point_id):
    #  获取mtid
    meter_info = await get_meter_by_point_new15(point_id)
    if not meter_info:
        raise BusinessException(
            message="没有该监测点的monitor信息,请联系运维人员!")
    mtid = meter_info["mtid"]
    # 获取子表中的实时数据
    url = f"{SETTING.stb_url}db_electric?tz=Asia/Shanghai"
    sql = f"select last_row(*) from mt{mtid}_ele where pid={point_id}"
    is_succ, results = await get_td_engine_data(url, sql)
    if not is_succ:
        return '', {}
    head = parse_td_columns(results)
    if not results["data"]:
        results["data"] = ['' for i in range(len(head))]
    res = dict(zip(head, results["data"][0]))
    
    # 识电U只有一项有数据,返回具体的项
    ctnum = res.get("ctnum") or 3
    res = get_sdu_i_and_u(res, ctnum)
    
    if res.get("ts"):
        time_str = str(res["ts"])[0:19]
    else:
        time_str = time_format.get_datetime_str(0)
    return time_str,res


def get_sdu_i_and_u(res, ctnum):
    '''
        获取识电U的相序字段
    '''
    res["sdu_i"] = None
    res["sdu_u"] = None
    meter_n = res.get('meter_sn', '').lower()
    if meter_n == 'a':
        res["sdu_i"] = "ia"
        res["sdu_u"] = "ua" if ctnum == 3 else "uab"
    if meter_n == 'b':
        res["sdu_i"] = "ib"
        if ctnum == 3:
            res["sdu_u"] = "ub"
    if meter_n == 'c':
        res["sdu_i"] = "ic"
        res["sdu_u"] = "uc" if ctnum == 3 else "ucb"
    return res
