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 88 89 90 91 92 93 94
    """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" \
                f"'{start}' and '{now}' GROUP BY importance"
    alarm_sql = f"select importance, count(importance) doc_count from " \
                f"point_1min_event where cid=%s and event_datetime BETWEEN" \
                f"'{start}' and '{now}' and event_type in %s " \
                f"GROUP BY importance"
    first_score, second_score, third_score = 0, 0, 0
    async with MysqlUtil() as conn:
lcn's avatar
lcn committed
95
        score_datas = await conn.fetchall(score_sql, args=(cid,))
lcn's avatar
lcn committed
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
        alarm_datas = await conn.fetchall(alarm_sql, args=(cid, score_events))
    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
128
async def normal_rate_of_location(cid):
lcn's avatar
lcn committed
129
    """获取温度和漏电流达标率"""
ZZH's avatar
ZZH committed
130 131
    d_stats = {"residual_current": {"total": 0, "normal": 0},
               "temperature": {"total": 0, "normal": 0}, }
ZZH's avatar
ZZH committed
132
    sql = "select l.lid, l.ad_type type, s.threshold from " \
ZZH's avatar
ZZH committed
133 134 135
          "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
136
    async with MysqlUtil() as conn:
ZZH's avatar
ZZH committed
137 138 139
        locs = await conn.fetchall(sql, (cid,
                                         ("residual_current", "temperature"),
                                         ("overTemp", "overResidualCurrent")))
ZZH's avatar
ZZH committed
140 141 142 143
        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
144
        
ZZH's avatar
ZZH committed
145 146
        prefix = f"real_time:adio:{SETTING.mysql_db}"
        keys = [f"{prefix}:{lid}" for lid in lids]
ZZH's avatar
ZZH committed
147 148 149
        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
150
        
ZZH's avatar
ZZH committed
151 152 153 154
        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
155
                continue
lcn's avatar
lcn committed
156
            
ZZH's avatar
ZZH committed
157 158
            if not isinstance(d_loc["threshold"], (float, int)):
                continue
lcn's avatar
lcn committed
159
            
ZZH's avatar
ZZH committed
160 161 162 163 164
            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
165
                
ZZH's avatar
ZZH committed
166 167 168 169
                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
170
        
ZZH's avatar
ZZH committed
171 172 173 174 175 176
        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
177
        
ZZH's avatar
ZZH committed
178 179 180 181 182 183 184
        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
185 186


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


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


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


async def optimization_count_info(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
lcn's avatar
lcn committed
320
    
lcn's avatar
lcn committed
321 322 323 324
    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
325
    
lcn's avatar
lcn committed
326 327 328
    now = datetime.now()
    start_time = (
        pendulum.datetime(now.year, now.month, 1)
lcn's avatar
lcn committed
329 330
        .subtract(months=1)
        .strftime("%Y-%m-%d %H:%M:%S")
lcn's avatar
lcn committed
331 332 333
    )
    end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%d %H:%M:%S")
ZZH's avatar
ZZH committed
334 335
    power_use_info = await company_power_use_info(company_id, start_time,
                                                  end_time)
lcn's avatar
lcn committed
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
    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
354
    
lcn's avatar
lcn committed
355 356 357 358 359
    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
360
    last_month_str = datetime.strftime(last_month_dt, "%Y-%m-%d")
lcn's avatar
lcn committed
361 362 363 364 365 366
    # 功率因数
    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
367
            inline_ids, last_month_str))
lcn's avatar
lcn committed
368 369 370 371 372 373
        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
374
        
lcn's avatar
lcn committed
375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
        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
390
        
lcn's avatar
lcn committed
391 392 393 394 395
        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
396
    
lcn's avatar
lcn committed
397 398 399 400 401
    # 移峰填谷指数
    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
402
        
lcn's avatar
lcn committed
403 404 405 406 407 408 409
        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
410
        
lcn's avatar
lcn committed
411 412 413 414 415 416 417 418 419 420
        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
421
        
lcn's avatar
lcn committed
422 423 424 425 426 427
        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
428
    
lcn's avatar
lcn committed
429 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
    # 经济运行
    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
464
        
lcn's avatar
lcn committed
465 466 467 468 469
        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
470
    
lcn's avatar
lcn committed
471 472 473 474 475 476 477 478 479 480
    # 最大需量
    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
481
        
lcn's avatar
lcn committed
482 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
        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
510
    
lcn's avatar
lcn committed
511 512 513 514 515 516 517 518
    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
519
    
lcn's avatar
lcn committed
520 521 522 523
    # 计算最大需量
    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
524
    
lcn's avatar
lcn committed
525 526 527 528 529 530 531 532
    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
533
    
lcn's avatar
lcn committed
534 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
    # 经济运行最低负载率
    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
587 588
        results = await conn.fetchall(sql, args=(points, start, end,
                                                 SDU_ALARM_LIST))
lcn's avatar
lcn committed
589
    
lcn's avatar
lcn committed
590 591 592 593 594 595 596 597 598 599
    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
600
    
lcn's avatar
lcn committed
601 602
    alarm_score = (first_alarm_cnt * 2 + second_alarm_cnt * 1 +
                   third_alarm_cnt * 0.5) / len(points)
lcn's avatar
lcn committed
603
    
lcn's avatar
lcn committed
604 605
    if alarm_score >= 15:
        alarm_score = 15
lcn's avatar
lcn committed
606
    
lcn's avatar
lcn committed
607
    electric_use_score = get_electric_index(alarm_score)
lcn's avatar
lcn committed
608
    
lcn's avatar
lcn committed
609 610 611 612 613 614 615 616 617 618 619 620 621
    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,
    )

622

lcn's avatar
lcn committed
623 624 625 626 627 628
async def optimization_count_info_new(company_id: int):
    """
    首页用电经济指数和用电优化模块统计数据
    :param company_id:
    :return:
    """
lcn's avatar
lcn committed
629
    
lcn's avatar
lcn committed
630 631
    inlines = await get_inline_by_cid(company_id)
    inline_ids = [inline["inlid"] for inline in inlines]
lcn's avatar
lcn committed
632
    
lcn's avatar
lcn committed
633 634 635 636
    # 获取公司上月用电
    now = datetime.now()
    es_start_time = (
        pendulum.datetime(now.year, now.month, 1)
lcn's avatar
lcn committed
637 638
        .subtract(months=1)
        .strftime("%Y-%m-%dT%H:%M:%S+08:00")
lcn's avatar
lcn committed
639 640 641
    )
    es_end_time = pendulum.datetime(now.year, now.month, 1).strftime(
        "%Y-%m-%dT%H:%M:%S+08:00")
ZZH's avatar
ZZH committed
642 643 644
    power_use_info = await company_power_use_info(company_id,
                                                  es_start_time,
                                                  es_end_time)
lcn's avatar
lcn committed
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669
    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
670
    
lcn's avatar
lcn committed
671 672 673 674 675 676 677 678 679 680 681 682
    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
683
    
lcn's avatar
lcn committed
684 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
    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
718
    
lcn's avatar
lcn committed
719 720 721 722
    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
723
        
lcn's avatar
lcn committed
724 725 726 727 728 729 730 731 732 733 734 735 736
        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
737
    
lcn's avatar
lcn committed
738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
    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
755
    
lcn's avatar
lcn committed
756 757 758 759 760 761 762
    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
763
    
lcn's avatar
lcn committed
764 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
    # 经济运行
    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
824
    
lcn's avatar
lcn committed
825 826 827 828 829
    #  容量、需量价格
    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
    # 最大需量
830
    md_spaces = await get_md_space(inline_ids, last_month_dt)
lcn's avatar
lcn committed
831
    
lcn's avatar
lcn committed
832 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
    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
861
    
lcn's avatar
lcn committed
862 863 864 865 866
    if len(md_space_name):
        md_space_desc = f"若次月负荷无较大变动,建议{'、'.join(md_space_name)}" \
                        f"选择按最大需量计费"
    else:
        md_space_desc = "不存在容改需空间"
lcn's avatar
lcn committed
867
    
lcn's avatar
lcn committed
868 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
    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
907
    es_res = await sdu_alarm_importance_dao(start, end, point_list)
lcn's avatar
lcn committed
908
    es_res_key = {i["key"]: i for i in es_res}
lcn's avatar
lcn committed
909
    
lcn's avatar
lcn committed
910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
    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
925
        
lcn's avatar
lcn committed
926
        tmp_dic["alarm_count"] = tmp_dic["first"] + tmp_dic["second"] + \
ZZH's avatar
ZZH committed
927
                                 tmp_dic["third"]
lcn's avatar
lcn committed
928 929 930 931 932 933 934 935 936 937 938 939
        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:
940 941 942 943 944 945
        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
946 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
    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
1000 1001
    if not isinstance(score, int):
        return ""
lcn's avatar
lcn committed
1002 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
    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 ""