power_index.py 8.58 KB
Newer Older
lcn's avatar
lcn committed
1 2 3 4 5 6 7 8 9 10 11
import pendulum
from datetime import datetime, date
from unify_api.modules.electric_optimization.dao.power_index import \
    tc_by_inline_id, price_policy_by_cid, pids_by_cid, get_economic_operations
from unify_api.modules.electric_optimization.components.optimization_cps import (
    PowerSaveResp, PeakCutValleyFillResp, MdSpaceResp, PowerFactorResp,
)
from unify_api.modules.electric_optimization.procedures.optimization_pds import (
    month_md_space
)
from unify_api.modules.electric_optimization.procedures.optimization_pds import (
ZZH's avatar
ZZH committed
12 13
    month_power_pcvf, month_power_factors, month_power_loadrate,
    load_inline_power
lcn's avatar
lcn committed
14 15 16
)
from unify_api.constants import ADD_ELE_PRICE
from unify_api.modules.elec_charge.dao.elec_charge_dao import (
ZZH's avatar
ZZH committed
17
    point_kwh_charge
lcn's avatar
lcn committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
)


# 需量管理
async def md_space_service(inline_id):
    dt = pendulum.now(tz="Asia/Shanghai")
    this_month_start_dt = pendulum.date(year=dt.year, month=dt.month, day=1)
    latest_12_months = [this_month_start_dt.subtract(months=i) for i in
                        range(1, 13)]
    latest_12_months.sort()

    monthstr_list = [str(date(i.year, i.month, day=1))[:10] for i in
                     latest_12_months]
    md_space_map = await month_md_space(inline_id, monthstr_list)
    inline = await tc_by_inline_id(inline_id)
wang.wenrong's avatar
wang.wenrong committed
33
    price_policy = await price_policy_by_cid(inline["cid"])
lcn's avatar
lcn committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

    last_month = monthstr_list[-1]
    return MdSpaceResp(
        time_slots=[f"{str(i.year)[2:]}年{i.month}月" for i in latest_12_months],
        md_charge_values=[
            round(md_space_map.get(i, {}).get("inline_md_charge"), 2)
            if type(md_space_map.get(i, {}).get("inline_md_charge")) in [int,
                                                                         float]
            else ""
            for i in monthstr_list
        ],
        tc_charge_values=[
            round(md_space_map.get(i, {}).get("inline_tc_charge"), 2)
            if type(md_space_map.get(i, {}).get("inline_md_charge")) in [int,
                                                                         float]
            else ""
            for i in monthstr_list
        ],
        inline_md_predict=round(
            md_space_map.get(last_month, {}).get("inline_md_predict"), 2)
        if type(md_space_map.get(last_month, {}).get("inline_md_predict")) in [
            int, float]
        else "",
        tc_runtime=inline["tc_runtime"] if inline else "",
        price_md=price_policy["price_md"] if price_policy else "",
        price_tc=price_policy["price_tc"] if price_policy else "",
    )


# 功率因素
async def power_factor_service(inline_id):
    dt = pendulum.now(tz="Asia/Shanghai")
    this_month_start_dt = pendulum.date(year=dt.year, month=dt.month, day=1)
    latest_12_months = [this_month_start_dt.subtract(months=i) for i in
                        range(1, 13)]
    latest_12_months.sort()

    latest_12_months = [date(i.year, i.month, i.day) for i in latest_12_months]
    power_factors_map = await month_power_factors(inline_id, latest_12_months)

    last_month = latest_12_months[-1]
    save_charge = power_factors_map.get(last_month, {}).get("save_charge")
    last_month_pf = (
        power_factors_map.get(last_month, {}).get("cos")
        if power_factors_map.get(last_month, {}).get("cos")
        else ""
    )
    save_charge = save_charge if isinstance(save_charge, (int, float)) else ""
    if last_month_pf != "" and last_month_pf > 0.9:
        # 功率因数大于0.9不返回save_charge
        save_charge = None
    inline = await tc_by_inline_id(inline_id)
wang.wenrong's avatar
wang.wenrong committed
86
    point_list = await pids_by_cid(inline.get("cid"))
ZZH's avatar
ZZH committed
87
    charge_res = await point_kwh_charge(point_list)
lcn's avatar
lcn committed
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    # total_charge = charge_res["aggregations"]["charge"]["value"]
    total_charge = charge_res.get("charge") or 0
    if last_month_pf and 0.9 > last_month_pf >= 0:
        punish_money = total_charge * ADD_ELE_PRICE[last_month_pf] / 100
    else:
        punish_money = 0.0
    return PowerFactorResp(
        time_slots=[f"{str(i.year)[2:]}年{i.month}月" for i in latest_12_months],
        power_factor_values=[
            power_factors_map.get(i, {}).get("cos")
            if power_factors_map.get(i, {}).get("cos")
            else ""
            for i in latest_12_months
        ],
        power_factor=last_month_pf,
        save_charge=save_charge,
        punish_money=round(punish_money, 2)
    )


# 移峰填谷
async def power_peakcut_service(inline_id):
    dt = pendulum.now(tz="Asia/Shanghai")
    this_month_start_dt = pendulum.date(year=dt.year, month=dt.month, day=1)
    latest_12_months = [this_month_start_dt.subtract(months=i) for i in
                        range(1, 13)]
    latest_12_months.sort()

    monthstr_list = [str(date(i.year, i.month, day=1))[:10] for i in
                     latest_12_months]
    power_pcvf_map = await month_power_pcvf(inline_id, monthstr_list)
    pcvf_indexs = []
    for i in monthstr_list:
        score = power_pcvf_map.get(str(i), {}).get("score", "")
        if type(score) in [int, float]:
            pass
        else:
            score = ""
        pcvf_indexs.append(score)

    # now = datetime.now()
    # es_start_time = (
    #     pendulum.datetime(now.year, now.month, 1)
    #         .subtract(months=1)
    #         .strftime("%Y-%m-%dT%H:%M:%S+08:00")
    # )
    # es_end_time = pendulum.datetime(now.year, now.month, 1).strftime(
    #     "%Y-%m-%dT%H:%M:%S+08:00")
    # power_use_info = await inline_power_use_info(inline_id, es_start_time,
    #                                              es_end_time)
    now = datetime.now()
    start_time = (
        pendulum.datetime(now.year, now.month, 1)
            .subtract(months=1).strftime("%Y-%m-%d %H:%M:%S")
    )
    end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%d %H:%M:%S")
ZZH's avatar
ZZH committed
145
    power_use_info = await load_inline_power(inline_id, start_time, end_time)
lcn's avatar
lcn committed
146 147 148 149 150 151 152 153
    month_kwh = power_use_info.get("kwh") or 0
    month_charge = power_use_info.get("charge") or 0
    avg_price = month_kwh / month_charge if month_charge else ""

    last_month = monthstr_list[-1]
    save_charge = power_pcvf_map.get(str(last_month), {}).get("cost_save")

    inline = await tc_by_inline_id(inline_id)
wang.wenrong's avatar
wang.wenrong committed
154
    price_policy = await price_policy_by_cid(inline["cid"])
lcn's avatar
lcn committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
    if avg_price and price_policy["price_f"]:
        growth_percentage = round(
            (
                    (round(avg_price, 2) - round(price_policy["price_f"], 2))
                    / round(price_policy["price_f"], 2)
            )
            * 100,
            2,
        )
    else:
        growth_percentage = ""

    return PeakCutValleyFillResp(
        time_slots=[f"{str(i.year)[2:]}年{i.month}月" for i in latest_12_months],
        pcvf_indexs=pcvf_indexs,
        avg_price=avg_price,
        save_charge=save_charge,
        pcvf_index=power_pcvf_map.get(str(last_month), {}).get("score", ""),
        price_f=price_policy["price_f"],
        growth_percentage=growth_percentage,
    )


# 经济运行
async def power_save_service(inline_id):
    dt = pendulum.now(tz="Asia/Shanghai")
    this_month_start_dt = pendulum.date(year=dt.year, month=dt.month, day=1)
    latest_12_months = [this_month_start_dt.subtract(months=i) for i in
                        range(1, 13)]
    latest_12_months.sort()

    monthstr_list = [str(date(i.year, i.month, day=1))[:10] for i in
                     latest_12_months]
    power_loadrate_map = await month_power_loadrate(inline_id, monthstr_list)
    load_rates = []
    for i in monthstr_list:
        load_rate = power_loadrate_map.get(str(i), {}).get("mean_load_factor",
                                                           "")
        if type(load_rate) in [int, float]:
            load_rate = round(load_rate / 0.01, 2)
        else:
            load_rate = ""
        load_rates.append(load_rate)
    economic_operations = await get_economic_operations(inline_id,
                                                        monthstr_list[-1])
    economic_kpi_x_list = [
        i["kpi_x"] for i in economic_operations if
        type(i["kpi_x"]) in [int, float]
    ]
    economic_kpi_x = max(economic_kpi_x_list) if economic_kpi_x_list else ""
    total_economic_save = round(
        sum(
            [
                i["save_charge"]
                for i in economic_operations
                if i["save_charge"] and i["save_charge"] >= 0
            ]
        ),
        2,
    )
    save_charge = 0 if total_economic_save <= 0 else total_economic_save
    return PowerSaveResp(
        time_slots=[f"{str(i.year)[2:]}年{i.month}月" for i in latest_12_months],
        load_rates=load_rates,
        avg_load_rate=load_rates[-1],
        save_charge=save_charge if economic_kpi_x != "" else "",
    )