count_info_pds.py 39.7 KB
Newer Older
lcn's avatar
lcn committed
1 2 3 4
import json
import time
from datetime import datetime, timedelta
import pendulum
lcn's avatar
lcn committed
5 6

from pot_libs.settings import SETTING
ZZH's avatar
ZZH committed
7
from unify_api.modules.electric.dao.electric_dao import load_add_to_compy_ids
lcn's avatar
lcn committed
8 9 10 11 12
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
13
from unify_api.constants import Importance, SDU_ALARM_LIST
lcn's avatar
lcn committed
14
from unify_api.modules.alarm_manager.dao.list_static_dao import \
ZZH's avatar
ZZH committed
15 16
    alarm_aggs_importance, \
    sdu_alarm_importance_dao
ZZH's avatar
ZZH committed
17
from unify_api.modules.common.dao.common_dao import monitor_point_join
lcn's avatar
lcn committed
18
from unify_api.modules.common.procedures.common_utils import get_electric_index
ZZH's avatar
ZZH committed
19 20
from unify_api.modules.common.procedures.points import proxy_points, \
    get_points_num
ZZH's avatar
ZZH committed
21
from unify_api.modules.common.procedures.pttl_max import load_pttl_max
lcn's avatar
lcn committed
22 23 24 25
from unify_api.modules.home_page.components.count_info_cps import (
    MaxResidualCurrent,
    ElectricInfo,
)
ZZH's avatar
ZZH committed
26
from unify_api.utils.time_format import last30_day_range
lcn's avatar
lcn committed
27 28
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
29
    get_md_space, get_tc_runtime, compy_real_pf, compy_lst_month_pf
lcn's avatar
lcn committed
30 31 32 33
)
from unify_api.modules.electric_optimization.dao.power_index import (
    price_policy_by_cid
)
lcn's avatar
lcn committed
34 35
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
36
from unify_api.utils.time_format import CST
lcn's avatar
lcn committed
37

lcn's avatar
lcn committed
38

ZZH's avatar
ZZH committed
39
async def other_info(cid):
lcn's avatar
lcn committed
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
    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
79
async def electric_use_info(cid):
lcn's avatar
lcn committed
80 81 82 83 84 85 86 87
    """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
88 89
                f"'{start}' and '{now}' and event_type in %s " \
                f"GROUP BY importance"
lcn's avatar
lcn committed
90 91
    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
92
                f"'{start}' and '{now}' " \
lcn's avatar
lcn committed
93 94 95
                f"GROUP BY importance"
    first_score, second_score, third_score = 0, 0, 0
    async with MysqlUtil() as conn:
lcn's avatar
lcn committed
96 97
        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
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
    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
129
async def normal_rate_of_location(cid):
lcn's avatar
lcn committed
130
    """获取温度和漏电流达标率"""
ZZH's avatar
ZZH committed
131 132
    d_stats = {"residual_current": {"total": 0, "normal": 0},
               "temperature": {"total": 0, "normal": 0}, }
ZZH's avatar
ZZH committed
133
    sql = "select l.lid, l.ad_type type, s.threshold from " \
ZZH's avatar
ZZH committed
134 135 136
          "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
137
    async with MysqlUtil() as conn:
ZZH's avatar
ZZH committed
138 139 140
        locs = await conn.fetchall(sql, (cid,
                                         ("residual_current", "temperature"),
                                         ("overTemp", "overResidualCurrent")))
ZZH's avatar
ZZH committed
141 142 143 144
        loc_infos = {loc["lid"]: loc for loc in locs}
        lids = list(loc_infos.keys())
        if not lids:
            return "100%", "100%"
lcn's avatar
lcn committed
145
        
ZZH's avatar
ZZH committed
146 147
        prefix = f"real_time:adio:{SETTING.mysql_db}"
        keys = [f"{prefix}:{lid}" for lid in lids]
ZZH's avatar
ZZH committed
148 149 150
        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}
lcn's avatar
lcn committed
151
        
ZZH's avatar
ZZH committed
152 153 154 155
        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
156
                continue
lcn's avatar
lcn committed
157
            
ZZH's avatar
ZZH committed
158 159
            if not isinstance(d_loc["threshold"], (float, int)):
                continue
lcn's avatar
lcn committed
160
            
ZZH's avatar
ZZH committed
161 162 163 164 165
            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
lcn's avatar
lcn committed
166
                
ZZH's avatar
ZZH committed
167 168 169 170
                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}")
lcn's avatar
lcn committed
171
        
ZZH's avatar
ZZH committed
172 173 174 175 176 177
        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, )) + "%"
lcn's avatar
lcn committed
178
        
ZZH's avatar
ZZH committed
179 180 181 182 183 184 185
        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
186 187


ZZH's avatar
ZZH committed
188
async def real_time_load(cid, end_dt=None):
lcn's avatar
lcn committed
189
    """实时负荷"""
ZZH's avatar
ZZH committed
190
    td_tbls = []
lcn's avatar
lcn committed
191 192 193 194
    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
195 196 197 198
        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")
lcn's avatar
lcn committed
199
    
ZZH's avatar
ZZH committed
200
    td_mt_tables = td3_tbl_compate(td_tbls)
lcn's avatar
lcn committed
201
    if not end_dt:
ZZH's avatar
ZZH committed
202 203 204 205 206
        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
207
    url = f"{SETTING.stb_url}db_electric?tz=Asia/Shanghai"
lcn's avatar
lcn committed
208
    is_succ, results = await get_td_engine_data(url, sql)
lcn's avatar
lcn committed
209 210
    if not is_succ or not results:
        return 0
lcn's avatar
lcn committed
211
    
lcn's avatar
lcn committed
212 213 214 215 216 217 218 219 220 221
    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
222 223


ZZH's avatar
ZZH committed
224
async def power_count_info(cid):
lcn's avatar
lcn committed
225 226 227 228
    """近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")
lcn's avatar
lcn committed
229
    
ZZH's avatar
ZZH committed
230
    max_30d_load, _time = await load_pttl_max(cid, start_time, end_time, -1)
ZZH's avatar
ZZH committed
231
    cur_load = await real_time_load(cid)
lcn's avatar
lcn committed
232 233 234
    return round_2(cur_load), round_2(max_30d_load)


ZZH's avatar
ZZH committed
235
async def get_max_aiao_of_filed(cid, start, end, filed="temperature"):
lcn's avatar
lcn committed
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
    value_max, location_name, occur_time = None, None, None
    sql = f"SELECT a.value_max,a.value_max_time,p.name,b.item FROM " \
          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 " \
          f"a.create_time BETWEEN '{start}' and '{end}' and a.cid=%s " \
          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))
    if datas:
        value_max = round(datas["value_max"], 2)
        item_name = '漏电流' if datas['item'] == 'default' else datas['item']
        location_name = f"{datas['name']}_{item_name}"
        occur_time = datas.get("value_max_time")
        occur_time = str(occur_time) if occur_time else None
    return MaxResidualCurrent(
        max=value_max,
        location_name=location_name,
        occur_time=occur_time,
    )


ZZH's avatar
ZZH committed
257
async def company_power_use_info(company_id, start, end):
lcn's avatar
lcn committed
258 259 260 261 262 263 264 265 266
    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
267 268
    power_use_info = await company_power_use_info(company_id, es_time_start,
                                                  es_time_end)
lcn's avatar
lcn committed
269 270 271 272 273 274 275
    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
276
async def power_charge_price(cid):
lcn's avatar
lcn committed
277 278 279 280 281 282
    """ 首页获取昨日平均电价, 上月平均电价"""
    # 昨日平均电价
    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
283 284
    yestday_datas = await company_power_use_info(cid, str(yestday_start),
                                                 str(yestday_end))
lcn's avatar
lcn committed
285 286 287 288 289 290 291 292 293
    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
294
        last_month_start = datetime(year=now.year, month=now.month - 1, day=1)
lcn's avatar
lcn committed
295
    last_month_end = datetime(year=now.year, month=now.month, day=1)
ZZH's avatar
ZZH committed
296 297 298
    last_month_datas = await company_power_use_info(cid, str(last_month_start),
                                                    str(last_month_end)
                                                    )
lcn's avatar
lcn committed
299 300 301 302 303 304 305
    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
306
async def cal_power_factor(cid):
lcn's avatar
lcn committed
307
    """首页获取实时功率因数, 上月功率因数"""
ZZH's avatar
ZZH committed
308 309 310 311 312
    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
313 314 315 316 317 318 319 320


async def optimization_count_info(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
lcn's avatar
lcn committed
321
    
lcn's avatar
lcn committed
322 323 324 325
    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]
lcn's avatar
lcn committed
326
    
lcn's avatar
lcn committed
327 328 329
    now = datetime.now()
    start_time = (
        pendulum.datetime(now.year, now.month, 1)
lcn's avatar
lcn committed
330 331
        .subtract(months=1)
        .strftime("%Y-%m-%d %H:%M:%S")
lcn's avatar
lcn committed
332 333 334
    )
    end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%d %H:%M:%S")
ZZH's avatar
ZZH committed
335 336
    power_use_info = await company_power_use_info(company_id, start_time,
                                                  end_time)
lcn's avatar
lcn committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
    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
lcn's avatar
lcn committed
355
    
lcn's avatar
lcn committed
356 357 358 359 360
    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
361
    last_month_str = datetime.strftime(last_month_dt, "%Y-%m-%d")
lcn's avatar
lcn committed
362 363 364 365 366 367
    # 功率因数
    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
368
            inline_ids, last_month_str))
lcn's avatar
lcn committed
369 370 371 372 373 374
        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
lcn's avatar
lcn committed
375
        
lcn's avatar
lcn committed
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390
        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 = "空间较大"
lcn's avatar
lcn committed
391
        
lcn's avatar
lcn committed
392 393 394 395 396
        count_info_map["power_factor"] = {
            "save_charge": total_pf_save if pf_kpi_x != "" else "",
            "kpi_x": pf_kpi_x,
            "desc": pf_desc,
        }
lcn's avatar
lcn committed
397
    
lcn's avatar
lcn committed
398 399 400 401 402
    # 移峰填谷指数
    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))
lcn's avatar
lcn committed
403
        
lcn's avatar
lcn committed
404 405 406 407 408 409 410
        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
        )
lcn's avatar
lcn committed
411
        
lcn's avatar
lcn committed
412 413 414 415 416 417 418 419 420 421
        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 = "空间较大"
lcn's avatar
lcn committed
422
        
lcn's avatar
lcn committed
423 424 425 426 427 428
        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,
        }
lcn's avatar
lcn committed
429
    
lcn's avatar
lcn committed
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
    # 经济运行
    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 = "空间较大"
lcn's avatar
lcn committed
465
        
lcn's avatar
lcn committed
466 467 468 469 470
        count_info_map["power_save"] = {
            "save_charge": total_economic_save if economic_kpi_x != "" else "",
            "kpi_x": economic_kpi_x,
            "desc": economic_desc,
        }
lcn's avatar
lcn committed
471
    
lcn's avatar
lcn committed
472 473 474 475 476 477 478 479 480 481
    # 最大需量
    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))
lcn's avatar
lcn committed
482
        
lcn's avatar
lcn committed
483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
        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,
        }
lcn's avatar
lcn committed
511
    
lcn's avatar
lcn committed
512 513 514 515 516 517 518 519
    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
lcn's avatar
lcn committed
520
    
lcn's avatar
lcn committed
521 522 523 524
    # 计算最大需量
    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,))
lcn's avatar
lcn committed
525
    
lcn's avatar
lcn committed
526 527 528 529 530 531 532 533
    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
lcn's avatar
lcn committed
534
    
lcn's avatar
lcn committed
535 536 537 538 539 540 541 542 543 544 545 546 547 548 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
    # 经济运行最低负载率
    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
588 589
        results = await conn.fetchall(sql, args=(points, start, end,
                                                 SDU_ALARM_LIST))
lcn's avatar
lcn committed
590
    
lcn's avatar
lcn committed
591 592 593 594 595 596 597 598 599 600
    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"]
lcn's avatar
lcn committed
601
    
lcn's avatar
lcn committed
602 603
    alarm_score = (first_alarm_cnt * 2 + second_alarm_cnt * 1 +
                   third_alarm_cnt * 0.5) / len(points)
lcn's avatar
lcn committed
604
    
lcn's avatar
lcn committed
605 606
    if alarm_score >= 15:
        alarm_score = 15
lcn's avatar
lcn committed
607
    
lcn's avatar
lcn committed
608
    electric_use_score = get_electric_index(alarm_score)
lcn's avatar
lcn committed
609
    
lcn's avatar
lcn committed
610 611 612 613 614 615 616 617 618 619 620 621 622
    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,
    )

623

lcn's avatar
lcn committed
624 625 626 627 628 629
async def optimization_count_info_new(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
lcn's avatar
lcn committed
630
    
lcn's avatar
lcn committed
631 632
    inlines = await get_inline_by_cid(company_id)
    inline_ids = [inline["inlid"] for inline in inlines]
lcn's avatar
lcn committed
633
    
lcn's avatar
lcn committed
634 635 636 637
    # 获取公司上月用电
    now = datetime.now()
    es_start_time = (
        pendulum.datetime(now.year, now.month, 1)
lcn's avatar
lcn committed
638 639
        .subtract(months=1)
        .strftime("%Y-%m-%dT%H:%M:%S+08:00")
lcn's avatar
lcn committed
640 641 642
    )
    es_end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%dT%H:%M:%S+08:00")
ZZH's avatar
ZZH committed
643 644 645
    power_use_info = await company_power_use_info(company_id,
                                                  es_start_time,
                                                  es_end_time)
lcn's avatar
lcn committed
646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
    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")
    # 功率因数
lcn's avatar
lcn committed
671
    
lcn's avatar
lcn committed
672 673 674 675 676 677 678 679 680 681 682 683
    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]
    ]
lcn's avatar
lcn committed
684
    
lcn's avatar
lcn committed
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
    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]]
lcn's avatar
lcn committed
719
    
lcn's avatar
lcn committed
720 721 722 723
    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 = []
lcn's avatar
lcn committed
724
        
lcn's avatar
lcn committed
725 726 727 728 729 730 731 732 733 734 735 736 737
        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 = "平均电价处于较低水平,请继续保持"
lcn's avatar
lcn committed
738
    
lcn's avatar
lcn committed
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755
    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
    )
lcn's avatar
lcn committed
756
    
lcn's avatar
lcn committed
757 758 759 760 761 762 763
    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
    }
lcn's avatar
lcn committed
764
    
lcn's avatar
lcn committed
765 766 767 768 769 770 771 772 773 774 775 776 777 778 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
    # 经济运行
    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
    }
lcn's avatar
lcn committed
825
    
lcn's avatar
lcn committed
826 827 828 829 830
    #  容量、需量价格
    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
    # 最大需量
831
    md_spaces = await get_md_space(inline_ids, last_month_dt)
lcn's avatar
lcn committed
832
    
lcn's avatar
lcn committed
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861
    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"])
lcn's avatar
lcn committed
862
    
lcn's avatar
lcn committed
863 864 865 866 867
    if len(md_space_name):
        md_space_desc = f"若次月负荷无较大变动,建议{'、'.join(md_space_name)}" \
                        f"选择按最大需量计费"
    else:
        md_space_desc = "不存在容改需空间"
lcn's avatar
lcn committed
868
    
lcn's avatar
lcn committed
869 870 871 872 873 874 875 876 877 878 879 880 881 882 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
    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
908
    es_res = await sdu_alarm_importance_dao(start, end, point_list)
lcn's avatar
lcn committed
909
    es_res_key = {i["key"]: i for i in es_res}
lcn's avatar
lcn committed
910
    
lcn's avatar
lcn committed
911 912 913 914 915 916 917 918 919 920 921 922 923 924 925
    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"]
lcn's avatar
lcn committed
926
        
lcn's avatar
lcn committed
927
        tmp_dic["alarm_count"] = tmp_dic["first"] + tmp_dic["second"] + \
ZZH's avatar
ZZH committed
928
                                 tmp_dic["third"]
lcn's avatar
lcn committed
929 930 931 932 933 934 935 936 937 938 939 940
        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:
941 942 943 944 945 946
        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
947 948 949 950 951 952 953 954 955 956 957 958 959 960 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
    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
1001 1002
    if not isinstance(score, int):
        return ""
lcn's avatar
lcn committed
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028
    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 ""