count_info_pds.py 40 KB
Newer Older
1
# -*- coding:utf-8 -*-
lcn's avatar
lcn committed
2 3 4 5
import json
import time
from datetime import datetime, timedelta
import pendulum
lcn's avatar
lcn committed
6 7

from pot_libs.settings import SETTING
ZZH's avatar
ZZH committed
8
from unify_api.modules.electric.dao.electric_dao import load_add_to_compy_ids
lcn's avatar
lcn committed
9 10 11 12 13
from unify_api.utils.common_utils import round_2
from pot_libs.aredis_util.aredis_utils import RedisUtils
from pot_libs.logger import log
from pot_libs.mysql_util.mysql_util import MysqlUtil
from unify_api import constants
ZZH's avatar
ZZH committed
14
from unify_api.constants import Importance, SDU_ALARM_LIST
lcn's avatar
lcn committed
15
from unify_api.modules.alarm_manager.dao.list_static_dao import \
ZZH's avatar
ZZH committed
16 17
    alarm_aggs_importance, \
    sdu_alarm_importance_dao
ZZH's avatar
ZZH committed
18
from unify_api.modules.common.dao.common_dao import monitor_point_join
lcn's avatar
lcn committed
19
from unify_api.modules.common.procedures.common_utils import get_electric_index
ZZH's avatar
ZZH committed
20 21
from unify_api.modules.common.procedures.points import proxy_points, \
    get_points_num
ZZH's avatar
ZZH committed
22
from unify_api.modules.common.procedures.pttl_max import load_pttl_max
lcn's avatar
lcn committed
23 24 25 26
from unify_api.modules.home_page.components.count_info_cps import (
    MaxResidualCurrent,
    ElectricInfo,
)
ZZH's avatar
ZZH committed
27
from unify_api.utils.time_format import last30_day_range
lcn's avatar
lcn committed
28 29
from unify_api.modules.home_page.dao.count_info_dao import (
    get_inline_by_cid, get_power_factor_kpi, get_pcvf_kpi, get_economic_kpi,
ZZH's avatar
ZZH committed
30
    get_md_space, get_tc_runtime, compy_real_pf, compy_lst_month_pf
lcn's avatar
lcn committed
31 32 33 34
)
from unify_api.modules.electric_optimization.dao.power_index import (
    price_policy_by_cid
)
lcn's avatar
lcn committed
35 36
from unify_api.utils.taos_new import parse_td_columns, get_td_table_name, \
    td3_tbl_compate, get_td_engine_data
ZZH's avatar
ZZH committed
37
from unify_api.utils.time_format import CST
38 39 40 41
from unify_api.constants import PHASE_LINE_LANG
from unify_api.modules.common.dao.common_dao import (
    load_user_lang, load_monitor_names
)
lcn's avatar
lcn committed
42

lcn's avatar
lcn committed
43

ZZH's avatar
ZZH committed
44
async def other_info(cid):
lcn's avatar
lcn committed
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
    today_alarm_count, alarm_count, has_alarm_days = 0, 0, 0
    sql = "SELECT DATE_FORMAT(event_datetime,'%%Y-%%m-%%d') event_date, " \
          "count(id) doc_count FROM `point_1min_event` where cid=%s " \
          "and event_mode='alarm' GROUP BY event_date ORDER BY event_date desc"
    async with MysqlUtil() as conn:
        datas = await conn.fetchall(sql, args=(cid,))
    now_time = datetime.now()
    # 获取到工厂安装时间create_time
    async with MysqlUtil() as conn:
        company_sql = "select create_time from company where cid = %s"
    company = await conn.fetchone(company_sql, (cid,))
    create_time_timestamp = company["create_time"]
    create_time = datetime.fromtimestamp(create_time_timestamp)
    if not datas:
        # 1. 增加逻辑,新增工厂如果还没有事件产生
        # 系统安全运行天数: 当前时间 - 工厂安装时间 + 1
        safe_run_days = (now_time - create_time).days + 1
        return today_alarm_count, safe_run_days, alarm_count
    # 5. 构造返回
    # 如果每天都有报警, 防止安全运行天数-1天, 所以total_days +2
    total_days = (now_time - create_time).days + 2
    for data in datas:
        if data["event_date"] == str(now_time)[:10]:
            today_alarm_count = data["doc_count"]
        if data["doc_count"]:
            # 不安全运行的天数
            has_alarm_days += 1
        alarm_count += data["doc_count"]
    safe_run_days = total_days - has_alarm_days
    log.info(
        f"today_alarm_count={today_alarm_count} safe_run_days={safe_run_days}")
    return today_alarm_count, safe_run_days, alarm_count


def datetime_to_timestamp(dt):
    ans_time = time.mktime(dt.timetuple())
    return ans_time


ZZH's avatar
ZZH committed
84
async def electric_use_info(cid):
lcn's avatar
lcn committed
85 86 87 88 89 90 91 92
    """1.5用电安全指数"""
    now = str(datetime.now())
    start = str(datetime.now() - timedelta(30))
    score_events = ['overU', 'underTotalPF', 'underPhasePF', 'overTHDI',
                    'overTHDU', 'underU', 'unbalanceI', 'overPR',
                    'overResidualCurrent', 'unbalanceU', 'overI']
    score_sql = f"select importance, count(importance) doc_count from " \
                f"point_1min_event where cid=%s and event_datetime BETWEEN" \
lcn's avatar
lcn committed
93 94
                f"'{start}' and '{now}' and event_type in %s " \
                f"GROUP BY importance"
lcn's avatar
lcn committed
95 96
    alarm_sql = f"select importance, count(importance) doc_count from " \
                f"point_1min_event where cid=%s and event_datetime BETWEEN" \
lcn's avatar
lcn committed
97
                f"'{start}' and '{now}' " \
lcn's avatar
lcn committed
98 99 100
                f"GROUP BY importance"
    first_score, second_score, third_score = 0, 0, 0
    async with MysqlUtil() as conn:
lcn's avatar
lcn committed
101 102
        score_datas = await conn.fetchall(score_sql, args=(cid, score_events))
        alarm_datas = await conn.fetchall(alarm_sql, args=(cid,))
lcn's avatar
lcn committed
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
    for data in score_datas:
        if data["importance"] == Importance.First.value:
            first_score += data["doc_count"]
        elif data["importance"] == Importance.Second.value:
            second_score += data["doc_count"]
        elif data["importance"] == Importance.Third.value:
            third_score += data["doc_count"]
    point_len = await proxy_points([cid])
    alarm_score = (
        (first_score * 2 + second_score * 1 + third_score * 0.5) / point_len
        if point_len else 0
    )
    alarm_score = 15 if alarm_score >= 15 else alarm_score
    electric_use_score = get_electric_index(alarm_score)
    first_alarm, second_alarm, third_alarm = 0, 0, 0
    for data in alarm_datas:
        if data["importance"] == Importance.First.value:
            first_alarm += data["doc_count"]
        elif data["importance"] == Importance.Second.value:
            second_alarm += data["doc_count"]
        elif data["importance"] == Importance.Third.value:
            third_alarm += data["doc_count"]
    return ElectricInfo(
        first_alarm_cnt=first_alarm,
        second_alarm_cnt=second_alarm,
        third_alarm_cnt=third_alarm,
        alarm_score=alarm_score,
        electric_use_score=electric_use_score,
    )


ZZH's avatar
ZZH committed
134
async def normal_rate_of_location(cid):
lcn's avatar
lcn committed
135
    """获取温度和漏电流达标率"""
ZZH's avatar
ZZH committed
136 137
    d_stats = {"residual_current": {"total": 0, "normal": 0},
               "temperature": {"total": 0, "normal": 0}, }
ZZH's avatar
ZZH committed
138
    sql = "select l.lid, l.ad_type type, s.threshold from " \
ZZH's avatar
ZZH committed
139 140 141
          "location l left join soe_config_record s on l.lid=s.lid " \
          "where l.cid = %s and  s.enable=1 and l.ad_type in %s " \
          "and s.etype in %s;"
lcn's avatar
lcn committed
142
    async with MysqlUtil() as conn:
ZZH's avatar
ZZH committed
143 144 145
        locs = await conn.fetchall(sql, (cid,
                                         ("residual_current", "temperature"),
                                         ("overTemp", "overResidualCurrent")))
ZZH's avatar
ZZH committed
146 147 148 149
        loc_infos = {loc["lid"]: loc for loc in locs}
        lids = list(loc_infos.keys())
        if not lids:
            return "100%", "100%"
150

ZZH's avatar
ZZH committed
151 152
        prefix = f"real_time:adio:{SETTING.mysql_db}"
        keys = [f"{prefix}:{lid}" for lid in lids]
ZZH's avatar
ZZH committed
153 154 155
        rt_rlts = await RedisUtils().mget(keys)
        rt_adios = [json.loads(r) for r in rt_rlts if r]
        d_rt_adio = {adio["lid"]: adio for adio in rt_adios}
156

ZZH's avatar
ZZH committed
157 158 159 160
        now_ts = pendulum.now(tz=CST).int_timestamp
        for lid, d_loc in loc_infos.items():
            d_stats[d_loc["type"]]["total"] += 1
            if lid not in d_rt_adio:
lcn's avatar
lcn committed
161
                continue
162

ZZH's avatar
ZZH committed
163 164
            if not isinstance(d_loc["threshold"], (float, int)):
                continue
165

ZZH's avatar
ZZH committed
166 167 168 169 170
            try:
                d_adio = d_rt_adio[lid]
                if (now_ts - d_adio["ts"]) > constants.REAL_EXP_TIME:
                    log.warn(f"adio_current location_id={lid} has expire!")
                    continue
171

ZZH's avatar
ZZH committed
172 173 174 175
                if d_adio["v"] < d_loc["threshold"]:
                    d_stats[d_loc["type"]]["normal"] += 1
            except Exception as e:
                log.exception(f"parse real time adio:{d_adio} exc, e:{e}")
176

ZZH's avatar
ZZH committed
177 178 179 180 181 182
        if d_stats["temperature"]["total"] == 0:
            temp_qr = "100%"
        else:
            norm = d_stats["temperature"]["normal"]
            total = d_stats["temperature"]["total"]
            temp_qr = str(round((norm / total) * 100, )) + "%"
183

ZZH's avatar
ZZH committed
184 185 186 187 188 189 190
        if d_stats["residual_current"]["total"] == 0:
            rc_qr = "100%"
        else:
            norm = d_stats["residual_current"]["normal"]
            total = d_stats["residual_current"]["total"]
            rc_qr = str(round((norm / total) * 100)) + "%"
        return temp_qr, rc_qr
lcn's avatar
lcn committed
191 192


ZZH's avatar
ZZH committed
193
async def real_time_load(cid, end_dt=None):
lcn's avatar
lcn committed
194
    """实时负荷"""
ZZH's avatar
ZZH committed
195
    td_tbls = []
lcn's avatar
lcn committed
196 197 198 199
    add_to_compy_ids = await load_add_to_compy_ids(cid)
    if not add_to_compy_ids:
        return 0
    for item in add_to_compy_ids:
ZZH's avatar
ZZH committed
200 201 202 203
        mtid, sid = item["mtid"], item["sid"]
        tbl = get_td_table_name("electric", mtid)
        td_tbls.append(tbl)
        td_tbls.append(f"s_{sid.lower()}_e")
204

ZZH's avatar
ZZH committed
205
    td_mt_tables = td3_tbl_compate(td_tbls)
lcn's avatar
lcn committed
206
    if not end_dt:
ZZH's avatar
ZZH committed
207 208 209 210 211
        end_dt = pendulum.now(tz=CST)
    s_dt = end_dt.subtract(minutes=15)
    sql = f"SELECT last_row(mdptime, pttl) FROM electric_stb " \
          f"WHERE TBNAME IN {td_mt_tables} " \
          f"AND ts>='{str(s_dt)}' AND ts <='{str(end_dt)}' group by tbname;"
wang.wenrong's avatar
wang.wenrong committed
212
    url = f"{SETTING.stb_url}db_electric?tz=Asia/Shanghai"
lcn's avatar
lcn committed
213
    is_succ, results = await get_td_engine_data(url, sql)
lcn's avatar
lcn committed
214 215
    if not is_succ or not results:
        return 0
216

lcn's avatar
lcn committed
217 218 219 220 221 222 223 224 225 226
    head = parse_td_columns(results)
    datas = []
    for res in results["data"]:
        datas.append(dict(zip(head, res)))
    total = 0
    for item in datas:
        if not item:
            continue
        total += item["pttl"]
    return total
lcn's avatar
lcn committed
227 228


ZZH's avatar
ZZH committed
229
async def power_count_info(cid):
lcn's avatar
lcn committed
230 231 232 233
    """近30天負荷最大值"""
    now = datetime.now()
    start_time = (now - timedelta(30)).strftime("%Y-%m-%d 00:00:00")
    end_time = now.strftime("%Y-%m-%d %H:%M:%S")
234

ZZH's avatar
ZZH committed
235
    max_30d_load, _time = await load_pttl_max(cid, start_time, end_time, -1)
ZZH's avatar
ZZH committed
236
    cur_load = await real_time_load(cid)
lcn's avatar
lcn committed
237 238 239
    return round_2(cur_load), round_2(max_30d_load)


240
async def load_aiao_max(user_id, cid, s_dts, e_dts, filed):
ZZH's avatar
ZZH committed
241
    value_max, loc_name, occur_time = None, None, None
242
    sql = f"SELECT a.value_max,a.value_max_time,p.name,p.mtid,b.item FROM " \
lcn's avatar
lcn committed
243 244
          f"`location_15min_aiao` a LEFT JOIN location b on a.lid=b.lid " \
          f"LEFT JOIN point p on p.mtid=a.mtid where " \
245
          f"a.create_time BETWEEN '{s_dts}' and '{e_dts}' and a.cid=%s " \
lcn's avatar
lcn committed
246 247 248
          f" and a.ad_type=%s order by a.value_max desc limit 1"
    async with MysqlUtil() as conn:
        datas = await conn.fetchone(sql, args=(cid, filed))
249

lcn's avatar
lcn committed
250
    if datas:
251 252 253 254
        lang = await load_user_lang(user_id)
        mtid = datas["mtid"]
        if lang != "zh_CN":
            mtr_names = await load_monitor_names([mtid], lang)
ZZH's avatar
ZZH committed
255
            mtr_name = mtr_names.get(mtid) or datas["name"]
256 257 258
        else:
            mtr_name = datas["name"]

lcn's avatar
lcn committed
259
        value_max = round(datas["value_max"], 2)
260 261
        item_name = "漏电流" if datas['item'] == 'default' else datas['item']
        if lang != "zh_CN":
262
            item_name = PHASE_LINE_LANG.get(datas["item"], {}).get(lang, "")
263 264

        loc_name = f"{mtr_name}_{item_name}" if item_name else mtr_name
lcn's avatar
lcn committed
265 266
        occur_time = datas.get("value_max_time")
        occur_time = str(occur_time) if occur_time else None
267 268
    return MaxResidualCurrent(max=value_max, location_name=loc_name,
                              occur_time=occur_time)
lcn's avatar
lcn committed
269 270


ZZH's avatar
ZZH committed
271
async def company_power_use_info(company_id, start, end):
lcn's avatar
lcn committed
272 273 274 275 276 277 278 279 280
    async with MysqlUtil() as conn:
        sql = f"SELECT sum(kwh) kwh, sum(charge) charge FROM " \
              f"`company_15min_power` where create_time BETWEEN " \
              f"'{start}' and '{end}' AND cid=%s"
        datas = await conn.fetchone(sql, args=(company_id,))
    return datas


async def get_company_charge_price(company_id, es_time_start, es_time_end):
ZZH's avatar
ZZH committed
281 282
    power_use_info = await company_power_use_info(company_id, es_time_start,
                                                  es_time_end)
lcn's avatar
lcn committed
283 284 285 286 287 288 289
    if power_use_info["kwh"]:
        unit_price = power_use_info["charge"] / power_use_info["kwh"]
    else:
        unit_price = ""
    return unit_price


ZZH's avatar
ZZH committed
290
async def power_charge_price(cid):
lcn's avatar
lcn committed
291 292 293 294 295 296
    """ 首页获取昨日平均电价, 上月平均电价"""
    # 昨日平均电价
    now = datetime.now()
    yestday = now - timedelta(1)
    yestday_start = datetime(yestday.year, yestday.month, yestday.day, 0, 0, 0)
    yestday_end = yestday_start + timedelta(1)
ZZH's avatar
ZZH committed
297 298
    yestday_datas = await company_power_use_info(cid, str(yestday_start),
                                                 str(yestday_end))
lcn's avatar
lcn committed
299 300 301 302 303 304 305 306 307
    if yestday_datas["kwh"]:
        yestoday_price = yestday_datas["charge"] / yestday_datas["kwh"]
    else:
        yestoday_price = ""
    if now.month == 1:
        last_month = 12
        year = now.year - 1
        last_month_start = datetime(year=year, month=last_month, day=1)
    else:
lcn's avatar
lcn committed
308
        last_month_start = datetime(year=now.year, month=now.month - 1, day=1)
lcn's avatar
lcn committed
309
    last_month_end = datetime(year=now.year, month=now.month, day=1)
ZZH's avatar
ZZH committed
310 311 312
    last_month_datas = await company_power_use_info(cid, str(last_month_start),
                                                    str(last_month_end)
                                                    )
lcn's avatar
lcn committed
313 314 315 316 317 318 319
    if last_month_datas["kwh"]:
        last_month_price = last_month_datas["charge"] / last_month_datas["kwh"]
    else:
        last_month_price = ""
    return round_2(yestoday_price), round_2(last_month_price)


ZZH's avatar
ZZH committed
320
async def cal_power_factor(cid):
lcn's avatar
lcn committed
321
    """首页获取实时功率因数, 上月功率因数"""
ZZH's avatar
ZZH committed
322 323 324 325 326
    real_cos = await compy_real_pf(cid)
    lst_month_cos = await compy_lst_month_pf(cid)
    if lst_month_cos:
        lst_month_cos = round(lst_month_cos, 2)
    return real_cos, lst_month_cos
lcn's avatar
lcn committed
327 328 329 330 331 332 333 334


async def optimization_count_info(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
335

lcn's avatar
lcn committed
336 337 338 339
    async with MysqlUtil() as conn:
        sql = "SELECT inlid, `name` FROM inline WHERE cid=%s"
        inlines = await conn.fetchall(sql, args=(company_id,))
        inline_ids = [inline["inlid"] for inline in inlines]
340

lcn's avatar
lcn committed
341 342 343
    now = datetime.now()
    start_time = (
        pendulum.datetime(now.year, now.month, 1)
344 345
            .subtract(months=1)
            .strftime("%Y-%m-%d %H:%M:%S")
lcn's avatar
lcn committed
346 347 348
    )
    end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%d %H:%M:%S")
ZZH's avatar
ZZH committed
349 350
    power_use_info = await company_power_use_info(company_id, start_time,
                                                  end_time)
lcn's avatar
lcn committed
351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
    month_charge = power_use_info.get("charge")
    month_kwh = power_use_info.get("kwh")
    count_info_map = {
        "avg_price": month_charge / month_kwh if month_kwh else ""
    }
    if not inline_ids:
        count_info_map.update(
            {
                "power_factor": {"save_charge": "", "kpi_x": "", "desc": "", },
                "pcvf": {"save_charge": "", "kpi_x": "", "desc": "", },
                "power_save": {"save_charge": "", "kpi_x": "", "desc": "", },
                "md_space": {"save_charge": "", "kpi_x": "", "desc": "", },
                "save_percent": 0,
                "md_space_p": "",
                "mean_load_factor": "",
            }
        )
        return count_info_map
369

lcn's avatar
lcn committed
370 371 372 373 374
    now = datetime.now()
    if now.month == 1:
        last_month_dt = datetime(year=now.year - 1, month=12, day=1)
    else:
        last_month_dt = datetime(year=now.year, month=now.month - 1, day=1)
lcn's avatar
lcn committed
375
    last_month_str = datetime.strftime(last_month_dt, "%Y-%m-%d")
lcn's avatar
lcn committed
376 377 378 379 380 381
    # 功率因数
    async with MysqlUtil() as conn:
        sql = "SELECT inlid, `cos`, save_charge pf_cost, kpi_x, save_charge " \
              "FROM algo_power_factor_result WHERE inlid in %s " \
              "and month=%s"
        power_factor_results = await conn.fetchall(sql, args=(
lcn's avatar
lcn committed
382
            inline_ids, last_month_str))
lcn's avatar
lcn committed
383 384 385 386 387 388
        total_pf_save = round(
            sum([i["pf_cost"] for i in power_factor_results if
                 i["pf_cost"] and i["pf_cost"] >= 0]),
            2,
        )
        total_pf_save = 0 if total_pf_save <= 0 else total_pf_save
389

lcn's avatar
lcn committed
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
        pf_kpi_x_list = [
            i["kpi_x"] for i in power_factor_results if
            type(i["kpi_x"]) in [int, float]
        ]
        pf_kpi_x = min(pf_kpi_x_list) if len(pf_kpi_x_list) else ""
        if pf_kpi_x == "":
            pf_desc = ""
        elif pf_kpi_x >= 0.9:
            pf_desc = "无空间"
        elif 0.85 < pf_kpi_x < 0.9:
            pf_desc = "空间较小"
        elif 0.8 < pf_kpi_x <= 0.85:
            pf_desc = "空间适中"
        else:
            pf_desc = "空间较大"
405

lcn's avatar
lcn committed
406 407 408 409 410
        count_info_map["power_factor"] = {
            "save_charge": total_pf_save if pf_kpi_x != "" else "",
            "kpi_x": pf_kpi_x,
            "desc": pf_desc,
        }
411

lcn's avatar
lcn committed
412 413 414 415 416
    # 移峰填谷指数
    async with MysqlUtil() as conn:
        sql = "select `score`, `cost_save` from `algo_plsi_result` " \
              "where `inlid` in %s and `month` = %s"
        pcvfs = await conn.fetchall(sql, args=(inline_ids, last_month_str))
417

lcn's avatar
lcn committed
418 419 420 421 422 423 424
        pcvf_kpi_x_list = [i["score"] for i in pcvfs if
                           type(i["score"]) in [int, float]]
        pcvf_kpi_x = min(pcvf_kpi_x_list) if len(pcvf_kpi_x_list) else ""
        total_pcvf_save = round(
            sum([i["cost_save"] for i in pcvfs if
                 i["cost_save"] and i["cost_save"] >= 0]), 2
        )
425

lcn's avatar
lcn committed
426 427 428 429 430 431 432 433 434 435
        if pcvf_kpi_x == "":
            pcvf_desc = ""
        elif pcvf_kpi_x >= 90:
            pcvf_desc = "无空间"
        elif 80 < pcvf_kpi_x < 90:
            pcvf_desc = "空间较小"
        elif 70 < pcvf_kpi_x <= 80:
            pcvf_desc = "空间适中"
        else:
            pcvf_desc = "空间较大"
436

lcn's avatar
lcn committed
437 438 439 440 441 442
        total_pcvf_save = 0 if total_pcvf_save <= 0 else total_pcvf_save
        count_info_map["pcvf"] = {
            "save_charge": total_pcvf_save if pcvf_kpi_x != "" else "",
            "kpi_x": pcvf_kpi_x,
            "desc": pcvf_desc,
        }
443

lcn's avatar
lcn committed
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478
    # 经济运行
    async with MysqlUtil() as conn:
        sql = "select `kpi_x`, `save_charge`, `mean_load_factor` " \
              "from `algo_economic_operation_result` where " \
              "`inlid` in %s and `month` = %s"
        economic_operations = await conn.fetchall(sql, args=(
            inline_ids, last_month_str))
        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,
        )
        total_economic_save = 0 if total_economic_save <= 0 else \
            total_economic_save
        if economic_kpi_x == "":
            economic_desc = ""
        elif economic_kpi_x <= 0.6:
            economic_desc = "无空间"
        elif 0.6 < economic_kpi_x <= 0.7:
            economic_desc = "空间较小"
        elif 0.7 < economic_kpi_x <= 0.8:
            economic_desc = "空间适中"
        else:
            economic_desc = "空间较大"
479

lcn's avatar
lcn committed
480 481 482 483 484
        count_info_map["power_save"] = {
            "save_charge": total_economic_save if economic_kpi_x != "" else "",
            "kpi_x": economic_kpi_x,
            "desc": economic_desc,
        }
485

lcn's avatar
lcn committed
486 487 488 489 490 491 492 493 494 495
    # 最大需量
    async with MysqlUtil() as conn:
        sql = (
            "select a.inline_md_charge, a.kpi_x, a.save_charge "
            "from `algo_md_space_analysis_result` a "
            "inner join`algo_md_space_analysis_unit` b "
            " on a.space_analysis_id=b.id "
            "where b.inlid in %s and a.month = %s and b.valid=1;"
        )
        md_spaces = await conn.fetchall(sql, args=(inline_ids, last_month_str))
496

lcn's avatar
lcn committed
497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
        md_space_kpi_x_list = [i["kpi_x"] for i in md_spaces if
                               type(i["kpi_x"]) in [int, float]]
        md_space_kpi_x = max(md_space_kpi_x_list) if len(
            md_space_kpi_x_list) else ""
        total_md_space_save = round(
            sum(
                [i["save_charge"] for i in md_spaces if
                 i["save_charge"] and i["save_charge"] >= 0]
            ),
            2,
        )
        total_md_space_save = 0 if total_md_space_save <= 0 else \
            total_md_space_save
        if md_space_kpi_x == "":
            md_space_desc = ""
        elif md_space_kpi_x <= 0:
            md_space_desc = "无空间"
        elif 0 < md_space_kpi_x <= 0.1:
            md_space_desc = "空间较小"
        elif 0.1 < md_space_kpi_x <= 0.2:
            md_space_desc = "空间适中"
        else:
            md_space_desc = "空间较大"
        count_info_map["md_space"] = {
            "save_charge": total_md_space_save if md_space_kpi_x != "" else "",
            "kpi_x": md_space_kpi_x,
            "desc": md_space_desc,
        }
525

lcn's avatar
lcn committed
526 527 528 529 530 531 532 533
    total_save_cost = 0
    for _, item in count_info_map.items():
        total_save_cost += (
            item["save_charge"] if isinstance(item, dict) and item[
                "save_charge"] else 0
        )
    save_percent = total_save_cost / month_charge if month_charge else ""
    count_info_map["save_percent"] = save_percent
534

lcn's avatar
lcn committed
535 536 537 538
    # 计算最大需量
    async with MysqlUtil() as conn:
        sql = "select `price_md`,`price_tc` from `price_policy` where `cid`=%s"
        price_policy = await conn.fetchone(sql, args=(company_id,))
539

lcn's avatar
lcn committed
540 541 542 543 544 545 546 547
    total_md_space_charge = sum(
        [i["inline_md_charge"] for i in md_spaces if i["inline_md_charge"]])
    total_md_space_p = (
        total_md_space_charge / price_policy["price_md"]
        if price_policy and price_policy["price_md"]
        else ""
    )
    count_info_map["md_space_p"] = total_md_space_p
548

lcn's avatar
lcn committed
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
    # 经济运行最低负载率
    mean_load_factors = [
        i["mean_load_factor"] for i in economic_operations if
        i["mean_load_factor"]
    ]
    count_info_map["mean_load_factor"] = ""
    if mean_load_factors:
        count_info_map["mean_load_factor"] = min(mean_load_factors)
    return count_info_map


async def electric_use_info_sdu(cid):
    start, end = last30_day_range()
    first_alarm_cnt = 0
    second_alarm_cnt = 0
    third_alarm_cnt = 0
    sql = f"select importance,count(1) doc_count from point_1min_event " \
          f"where cid={cid} and event_datetime BETWEEN '{start}' and '{end}' " \
          f"and event_type in {tuple(SDU_ALARM_LIST)} GROUP BY importance"
    log.info(f"sql:{sql}")
    async with MysqlUtil() as conn:
        datas = await conn.fetchall(sql)
    for data in datas:
        if data["importance"] == Importance.First.value:
            first_alarm_cnt += data["doc_count"]
        elif data["importance"] == Importance.Second.value:
            second_alarm_cnt += data["doc_count"]
        elif data["importance"] == Importance.Third.value:
            third_alarm_cnt += data["doc_count"]
    point_len = await get_points_num(cid)
    alarm_score = (
        (
                first_alarm_cnt * 2 + second_alarm_cnt * 1 + third_alarm_cnt * 0.5) / point_len
        if point_len
        else 0
    )
    alarm_score = 15 if alarm_score >= 15 else alarm_score
    electric_use_score = get_electric_index(alarm_score)
    return ElectricInfo(
        first_alarm_cnt=first_alarm_cnt,
        second_alarm_cnt=second_alarm_cnt,
        third_alarm_cnt=third_alarm_cnt,
        alarm_score=alarm_score,
        electric_use_score=electric_use_score,
    )


async def electric_use_info_points_sdu(start, end, points):
    """用电安全指数, 识电u, 根据points来计算"""
    sql = f"select importance,count(*) as doc_count from  point_1min_event " \
          f"where  pid in %s and  event_datetime BETWEEN %s and %s " \
          f"and event_type in %s group by importance"
    async with MysqlUtil() as conn:
lcn's avatar
lcn committed
602 603
        results = await conn.fetchall(sql, args=(points, start, end,
                                                 SDU_ALARM_LIST))
604

lcn's avatar
lcn committed
605 606 607 608 609 610 611 612 613 614
    first_alarm_cnt = 0
    second_alarm_cnt = 0
    third_alarm_cnt = 0
    for result in results:
        if result["importance"] == Importance.First.value:
            first_alarm_cnt += result["doc_count"]
        elif result["importance"] == Importance.Second.value:
            second_alarm_cnt += result["doc_count"]
        elif result["importance"] == Importance.Third.value:
            third_alarm_cnt += result["doc_count"]
615

lcn's avatar
lcn committed
616 617
    alarm_score = (first_alarm_cnt * 2 + second_alarm_cnt * 1 +
                   third_alarm_cnt * 0.5) / len(points)
618

lcn's avatar
lcn committed
619 620
    if alarm_score >= 15:
        alarm_score = 15
621

lcn's avatar
lcn committed
622
    electric_use_score = get_electric_index(alarm_score)
623

lcn's avatar
lcn committed
624 625 626 627 628 629 630 631 632 633 634 635 636
    log.info(
        "point_len={} alarm_score={} electric_use_score={}".format(
            len(points), alarm_score, electric_use_score
        )
    )
    return ElectricInfo(
        first_alarm_cnt=first_alarm_cnt,
        second_alarm_cnt=second_alarm_cnt,
        third_alarm_cnt=third_alarm_cnt,
        alarm_score=alarm_score,
        electric_use_score=electric_use_score,
    )

637

lcn's avatar
lcn committed
638 639 640 641 642 643
async def optimization_count_info_new(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
644

lcn's avatar
lcn committed
645 646
    inlines = await get_inline_by_cid(company_id)
    inline_ids = [inline["inlid"] for inline in inlines]
647

lcn's avatar
lcn committed
648 649 650 651
    # 获取公司上月用电
    now = datetime.now()
    es_start_time = (
        pendulum.datetime(now.year, now.month, 1)
652 653
            .subtract(months=1)
            .strftime("%Y-%m-%dT%H:%M:%S+08:00")
lcn's avatar
lcn committed
654 655 656
    )
    es_end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%dT%H:%M:%S+08:00")
ZZH's avatar
ZZH committed
657 658 659
    power_use_info = await company_power_use_info(company_id,
                                                  es_start_time,
                                                  es_end_time)
lcn's avatar
lcn committed
660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684
    month_charge = power_use_info["charge"]
    count_info_map = {
        "avg_price": power_use_info["charge"] / power_use_info["kwh"]
        if power_use_info["kwh"]
        else ""
    }
    if not inline_ids:
        count_info_map.update(
            {
                "power_factor": {"save_charge": "", "kpi_x": "", "desc": "", },
                "pcvf": {"save_charge": "", "kpi_x": "", "desc": "", },
                "power_save": {"save_charge": "", "kpi_x": "", "desc": "", },
                "md_space": {"save_charge": "", "kpi_x": "", "desc": "", },
                "save_percent": 0,
                "md_space_p": "",
                "mean_load_factor": "",
            }
        )
        return count_info_map
    if now.month == 1:
        last_month_dt = datetime(year=now.year - 1, month=12, day=1)
    else:
        last_month_dt = datetime(year=now.year, month=now.month - 1, day=1)
    last_month_str = datetime.strftime(last_month_dt, "%Y-%m")
    # 功率因数
685

lcn's avatar
lcn committed
686 687 688 689 690 691 692 693 694 695 696 697
    power_factor_results = await get_power_factor_kpi(inline_ids,
                                                      last_month_dt)
    total_pf_save = round(
        sum([i["pf_cost"] for i in power_factor_results if
             i["pf_cost"] and i["pf_cost"] >= 0]),
        2,
    )
    total_pf_save = 0 if total_pf_save <= 0 else total_pf_save
    pf_kpi_x_list = [
        (i["name"], i["kpi_x"]) for i in power_factor_results if
        type(i["kpi_x"]) in [int, float]
    ]
698

lcn's avatar
lcn committed
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732
    if len(pf_kpi_x_list):
        pf_kpi_x_num = [pf_kpi[1] for pf_kpi in pf_kpi_x_list]
        pf_kpi_x = min(pf_kpi_x_num)
        if pf_kpi_x >= 0.9:
            pf_desc = "上月功率因数比较合理,请继续保持"
        else:
            pf_kpi_x_name = []
            for index, kpi_num in enumerate(pf_kpi_x_num):
                if kpi_num < 0.9:
                    pf_kpi_x_name.append(pf_kpi_x_list[index][0])
            pf_desc = f"{'、'.join(pf_kpi_x_name)}可以进行无功补偿"
    else:
        pf_kpi_x = ""
        pf_desc = ""
    if pf_kpi_x == "":
        pf_space = ""
    elif pf_kpi_x >= 0.9:
        pf_space = "无空间"
    elif 0.85 < pf_kpi_x < 0.9:
        pf_space = "空间较小"
    elif 0.8 < pf_kpi_x <= 0.85:
        pf_space = "空间适中"
    else:
        pf_space = "空间较大"
    count_info_map["power_factor"] = {
        "save_charge": total_pf_save if pf_kpi_x != "" else "",
        "kpi_x": pf_kpi_x,
        "desc": pf_desc,
        "space": pf_space
    }
    # 移峰填谷指数
    pcvfs = await get_pcvf_kpi(inline_ids, last_month_str)
    pcvf_kpi_x_list = [(i["name"], i["score"]) for i in pcvfs if
                       type(i["score"]) in [int, float]]
733

lcn's avatar
lcn committed
734 735 736 737
    if len(pcvf_kpi_x_list):
        pcvf_kpi_x_num = [pcvf_kpi[1] for pcvf_kpi in pcvf_kpi_x_list]
        pcvf_kpi_x = min(pcvf_kpi_x_num)
        pcvf_kpi_x_name = []
738

lcn's avatar
lcn committed
739 740 741 742 743 744 745 746 747 748 749 750 751
        if pcvf_kpi_x < 70:
            for index, kpi_num in enumerate(pcvf_kpi_x_num):
                if kpi_num < 70:
                    pcvf_kpi_x_name.append(pcvf_kpi_x_list[index][0])
            pcvf_desc = f"{'、'.join(pcvf_kpi_x_name)}可以进行无功补偿"
        elif pcvf_kpi_x < 90:
            for index, kpi_num in enumerate(pcvf_kpi_x_num):
                if kpi_num < 90:
                    pcvf_kpi_x_name.append(pcvf_kpi_x_list[index][0])
            pcvf_desc = f"请合理调整{'、'.join(pcvf_kpi_x_name)}用电时间或" \
                        f"引入新能源,转移高峰电量至低谷"
        else:
            pcvf_desc = "平均电价处于较低水平,请继续保持"
752

lcn's avatar
lcn committed
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
    else:
        pcvf_kpi_x = ""
        pcvf_desc = ""
    if pcvf_kpi_x == "":
        pcvf_space = ""
    elif pcvf_kpi_x >= 90:
        pcvf_space = "无空间"
    elif 80 < pcvf_kpi_x < 90:
        pcvf_space = "空间较小"
    elif 70 < pcvf_kpi_x <= 80:
        pcvf_space = "空间适中"
    else:
        pcvf_space = "空间较大"
    total_pcvf_save = round(
        sum([i["cost_save"] for i in pcvfs if
             i["cost_save"] and i["cost_save"] >= 0]), 2
    )
770

lcn's avatar
lcn committed
771 772 773 774 775 776 777
    total_pcvf_save = 0 if total_pcvf_save <= 0 else total_pcvf_save
    count_info_map["pcvf"] = {
        "save_charge": total_pcvf_save if pcvf_kpi_x != "" else "",
        "kpi_x": pcvf_kpi_x,
        "desc": pcvf_desc,
        "space": pcvf_space
    }
778

lcn's avatar
lcn committed
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
    # 经济运行
    economic_operations = await get_economic_kpi(inline_ids, last_month_str)
    economic_kpi_x_list = [
        (i["name"], i["kpi_x"]) for i in economic_operations if
        type(i["kpi_x"]) in [int, float]
    ]
    total_economic_save = round(
        sum(
            [
                i["save_charge"]
                for i in economic_operations
                if i["save_charge"] and i["save_charge"] >= 0
            ]
        ),
        2,
    )
    if len(economic_kpi_x_list):
        econ_kpi_x_num = [econ_kpi[1] for econ_kpi in economic_kpi_x_list]
        econ_kpi_x = max(econ_kpi_x_num)
        econ_kpi_x_min = min(econ_kpi_x_num)
        econ_kpi_x_name = []
        if econ_kpi_x >= 0.9:
            for index, kpi_max in enumerate(econ_kpi_x_num):
                if kpi_max >= 0.9:
                    econ_kpi_x_name.append(economic_kpi_x_list[index][0])
            economic_desc = f"{'、'.join(econ_kpi_x_name)}负载率超过" \
                            f"安全阈值,应考虑扩容"
        elif econ_kpi_x >= 0.7:
            for index, kpi_max in enumerate(econ_kpi_x_num):
                if kpi_max >= 0.7:
                    econ_kpi_x_name.append(economic_kpi_x_list[index][0])
            economic_desc = f"{'、'.join(econ_kpi_x_name)}负载率较高," \
                            f"可考虑调整负荷或扩容"
        elif econ_kpi_x_min < 0.6 and econ_kpi_x < 0.9:
            for index, kpi_max in enumerate(econ_kpi_x_num):
                if kpi_max < 0.6:
                    econ_kpi_x_name.append(economic_kpi_x_list[index][0])
            economic_desc = f"{'、'.join(econ_kpi_x_name)}负载率较低," \
                            f"请考虑容改需或更换小容量变压器"
        else:
            economic_desc = "进线负载率比较经济,请继续保持"
    else:
        econ_kpi_x = ""
        economic_desc = ""
    if econ_kpi_x == "":
        econ_space = ""
    elif econ_kpi_x <= 0.6:
        econ_space = "无空间"
    elif 0.6 < econ_kpi_x <= 0.7:
        econ_space = "空间较小"
    elif 0.7 < econ_kpi_x <= 0.8:
        econ_space = "空间适中"
    else:
        econ_space = "空间较大"
    count_info_map["power_save"] = {
        "save_charge": total_economic_save if econ_kpi_x != "" else "",
        "kpi_x": econ_kpi_x,
        "desc": economic_desc,
        "space": econ_space
    }
839

lcn's avatar
lcn committed
840 841 842 843 844
    #  容量、需量价格
    price_policy = await price_policy_by_cid(company_id)
    price_md = price_policy["price_md"] if price_policy["price_md"] else 0
    price_tc = price_policy["price_tc"] if price_policy["price_tc"] else 0
    # 最大需量
845
    md_spaces = await get_md_space(inline_ids, last_month_dt)
846

lcn's avatar
lcn committed
847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
    md_space_kpi_x_list = [i["kpi_x"] for i in md_spaces if
                           type(i["kpi_x"]) in [int, float]]
    md_space_kpi_x = max(md_space_kpi_x_list) if len(
        md_space_kpi_x_list) else ""
    total_md_space_save = round(
        sum(
            [i["save_charge"] for i in md_spaces if
             i["save_charge"] and i["save_charge"] >= 0]
        ),
        2,
    )
    total_md_space_save = 0 if total_md_space_save <= 0 else total_md_space_save
    if md_space_kpi_x == "":
        md_space_space = ""
    elif md_space_kpi_x <= 0:
        md_space_space = "无空间"
    elif 0 < md_space_kpi_x <= 0.1:
        md_space_space = "空间较小"
    elif 0.1 < md_space_kpi_x <= 0.2:
        md_space_space = "空间适中"
    else:
        md_space_space = "空间较大"
    md_space_tc_runtimes = await get_tc_runtime(inline_ids)
    md_space_name = []
    for index, item in enumerate(md_spaces):
        if type(item["inline_md_predict"]) in [int, float] and \
                md_space_tc_runtimes[index]["tc_runtime"] * price_tc >= \
                price_md * item["inline_md_predict"]:
            md_space_name.append(md_space_tc_runtimes[index]["name"])
876

lcn's avatar
lcn committed
877 878 879 880 881
    if len(md_space_name):
        md_space_desc = f"若次月负荷无较大变动,建议{'、'.join(md_space_name)}" \
                        f"选择按最大需量计费"
    else:
        md_space_desc = "不存在容改需空间"
882

lcn's avatar
lcn committed
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921
    count_info_map["md_space"] = {
        "save_charge": total_md_space_save if md_space_kpi_x != "" else "",
        "kpi_x": md_space_kpi_x,
        "desc": md_space_desc,
        "space": md_space_space
    }
    # 节费率
    total_save_cost = 0
    for _, item in count_info_map.items():
        total_save_cost += (
            item["save_charge"] if isinstance(item, dict) and item[
                "save_charge"] else 0
        )
    save_percent = total_save_cost / month_charge if month_charge else ""
    count_info_map["save_percent"] = save_percent
    # 计算最大需量
    total_md_space_charge = sum(
        [i["inline_md_charge"] for i in md_spaces if i["inline_md_charge"]])
    total_md_space_p = (
        total_md_space_charge / price_policy["price_md"]
        if price_policy and price_policy["price_md"]
        else ""
    )
    count_info_map["md_space_p"] = total_md_space_p
    # 经济运行最低负载率
    mean_load_factors = [
        i["mean_load_factor"] for i in economic_operations if
        i["mean_load_factor"]
    ]
    count_info_map["mean_load_factor"] = ""
    if mean_load_factors:
        count_info_map["mean_load_factor"] = min(mean_load_factors)
    return count_info_map


async def cid_alarm_importance_count(cid, start, end):
    """计算工厂报警数, 按报警等级"""
    monitor_point_list = await monitor_point_join(cid)
    point_list = [i["pid"] for i in monitor_point_list]
ZZH's avatar
ZZH committed
922
    es_res = await sdu_alarm_importance_dao(start, end, point_list)
lcn's avatar
lcn committed
923
    es_res_key = {i["key"]: i for i in es_res}
924

lcn's avatar
lcn committed
925 926 927 928 929 930 931 932 933 934 935 936 937 938 939
    res_list = []
    for info in monitor_point_list:
        name = info.get("name")
        point_id = info.get("pid")
        tmp_dic = {"name": name, "alarm_count": 0,
                   "first": 0, "second": 0, "third": 0}
        if point_id in es_res_key:
            inner_bucket = es_res_key[point_id]["importance"]["buckets"]
            for b in inner_bucket:
                if b["key"] == Importance.First.value:
                    tmp_dic["first"] += b["doc_count"]
                elif b["key"] == Importance.Second.value:
                    tmp_dic["second"] += b["doc_count"]
                elif b["key"] == Importance.Third.value:
                    tmp_dic["third"] += b["doc_count"]
940

lcn's avatar
lcn committed
941
        tmp_dic["alarm_count"] = tmp_dic["first"] + tmp_dic["second"] + \
ZZH's avatar
ZZH committed
942
                                 tmp_dic["third"]
lcn's avatar
lcn committed
943 944 945 946 947 948 949 950 951 952 953 954
        res_list.append(tmp_dic)
    # 按照报警数, 排top5
    res_list_sort = sorted(res_list, key=lambda i: i["alarm_count"],
                           reverse=True)[:5]
    return res_list_sort


async def alarm_importance_count_total(cid, start, end):
    """计算工厂报警数, 按报警等级"""
    es_res = await alarm_aggs_importance(cid, start, end)
    first_cnt, second_cnt, third_cnt = 0, 0, 0
    for buckets in es_res:
955 956 957 958 959 960
        if buckets["importance"] == Importance.First.value:
            first_cnt += buckets["alarm_count"]
        elif buckets["importance"] == Importance.Second.value:
            second_cnt += buckets["alarm_count"]
        elif buckets["importance"] == Importance.Third.value:
            third_cnt += buckets["alarm_count"]
lcn's avatar
lcn committed
961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
    return {
        "first_cnt": first_cnt,
        "second_cnt": second_cnt,
        "third_cnt": third_cnt,
        "total_cnt": first_cnt + second_cnt + third_cnt
    }


def safety_ratio_res(score, client_name):
    """根据安全指数, 求安全风险系数"""
    # wechat和web共用
    if 90 <= score <= 100:
        return "风险较低" if client_name == "wechat" else "当前安全状况良好,请继续保持!"
    elif 80 <= score < 90:
        return "低风险" if client_name == "wechat" else "当前安全状况较好,请关注报警信息!"
    elif 60 <= score < 80:
        return "中风险" if client_name == "wechat" else "当前安全状况一般,请密切关注报警信息!"
    elif 40 <= score < 60:
        return "风险较高" if client_name == "wechat" else "当前安全状况较差,请重视报警信息!"
    elif 0 <= score < 40:
        return "高风险" if client_name == "wechat" else "当前安全状况很差,请重视报警信息并处理!"
    else:
        log.error(f"score:{score}, 安全指数不在0-100范围内")
        return ""


def health_status_res(score, client_name):
    """根据健康指数, 求健康状态"""
    if 90 <= score <= 100:
        return "状态优" if client_name == "wechat" else "当前健康状况良好,请继续保持!"
    elif 75 <= score < 90:
        return "状态较好" if client_name == "wechat" else "当前健康状况较好,请关注电能质量信息!"
    elif 60 <= score < 75:
        return "状况一般" if client_name == "wechat" else "当前健康状况一般,请密切关注电能质量信息!"
    elif 0 <= score < 60:
        return "状态差" if client_name == "wechat" else "当前健康状况差,请重视电能质量信息并改善!"
    else:
        log.error(f"score:{score}, 健康指数不在0-100范围内")
        return ""


def carbon_status_res(score):
    """根据碳排指数, 求达标情况, wechat使用"""
    if 80 <= score <= 100:
        return "达标"
    elif 0 <= score < 80:
        return "不达标"
    else:
        log.error(f"score:{score}, 碳排指数不在0-100范围内")
        return ""


def carbon_status_res_web(score):
    """根据碳排指数, 求达标情况, web使用"""
wang.wenrong's avatar
wang.wenrong committed
1015 1016
    if not isinstance(score, int):
        return ""
lcn's avatar
lcn committed
1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042
    if 90 <= score <= 100:
        return "当前能耗达标且水平很低,请继续保持!"
    elif 80 <= score < 90:
        return "当前能耗达标且水平较低,请继续保持!"
    elif 60 <= score < 80:
        return "当前能耗不达标,请关注能耗控制!"
    elif 0 <= score < 60:
        return "当前能耗不达标且水平较高,请重视能耗控制!"
    else:
        log.error(f"score:{score}, 碳排指数不在0-100范围内")
        return ""


def economic_index_desc(score, client_name):
    """经济指数, 返回文字说明"""
    if 90 <= score <= 100:
        return "状态良好" if client_name == "wechat" else "当前经济性良好,请继续保持"
    elif 75 <= score < 90:
        return "存在空间" if client_name == "wechat" else "存在空间,建议关注优化措施"
    elif 60 <= score < 75:
        return "空间较大" if client_name == "wechat" else "空间较大,建议尝试优化措施!"
    elif 0 <= score < 60:
        return "空间很大" if client_name == "wechat" else "空间很大,建议采取优化措施!"
    else:
        log.error(f"score:{score}, 经济指数不在0-100范围内")
        return ""