#!E:\Pycharm Projects\Waytous
# -*- coding: utf-8 -*-
# @Time : 2021/8/24 11:28
# @Author : Opfer
# @Site :
# @File : dump.py    
# @Software: PyCharm

from para_config import *
from settings import *


# 卸载设备类
class DumpInfo(WalkManage):
    def __init__(self):
        # 卸载设备数量
        self.dynamic_dump_num = get_value("dynamic_dump_num")
        # 用于动态调度的卸载设备集合
        self.dynamic_dump_set = get_value("dynamic_dump_set")
        # 开始时间
        self.start_time = datetime.now()
        # 卸载时间
        self.unloading_time = np.zeros(self.dynamic_dump_num)
        # 入场时间
        self.entrance_time = np.zeros(self.dynamic_dump_num)
        # 出场时间
        self.exit_time = np.zeros(self.dynamic_dump_num)
        # 卸载点物料类型
        self.dump_material = {}
        # 卸点优先级
        self.dump_priority_coefficient = np.ones(self.dynamic_dump_num)
        # 卸点卸载能力
        self.dump_strength = np.zeros(self.dynamic_dump_num)

        # 日志器
        self.logger = get_logger("zxt.dump")

        # # 参数初始化
        # self.dump_para_period_update()

    def get_unloading_time(self):
        return self.unloading_time

    def get_dump_num(self):
        return self.dynamic_dump_num

    def get_dynamic_dump_set(self):
        return self.dynamic_dump_set

    def get_unloading_task_time(self):
        unloading_time = self.unloading_time

        dump_entrance_time = self.entrance_time

        dump_exit_time = self.exit_time

        unloading_task_time = unloading_time + dump_entrance_time + dump_exit_time

        return unloading_task_time

    # 更新卸载设备卸载时间
    def update_dump_unloadtime(self):
        self.unloading_time = np.zeros(self.dynamic_dump_num)

        for dump_id in self.dump_uuid_to_index_dict.keys():
            ave_unload_time = 0
            unload_count = 0
            # try:
            #     for query in (
            #         session_mysql.query(JobRecord.start_time, JobRecord.end_time)
            #         .join(Equipment, JobRecord.equipment_id == Equipment.equipment_id)
            #         .filter(Equipment.id == dump_id, JobRecord.end_time != None)
            #         .order_by(JobRecord.start_time.desc())
            #         .limit(10)
            #     ):
            #         ave_unload_time = ave_unload_time + float(
            #             (query.end_time - query.start_time)
            #             / timedelta(hours=0, minutes=1, seconds=0)
            #         )
            #         unload_count = unload_count + 1
            #     self.unloading_time[self.dump_uuid_to_index_dict[dump_id]] = (
            #         ave_unload_time / unload_count
            #     )
            # except Exception as es:
            #     self.logger.error(f"卸载设备 {dump_id} 卸载时间信息缺失, 已设为默认值(1min)")
            #     self.logger.error(es)
            self.unloading_time[self.dump_uuid_to_index_dict[dump_id]] = 2.00
        # print("average_unload_time: ", self.unloading_time[self.dump_uuid_to_index_dict[dump_id]])

    # 更新卸载设备出入时间
    def update_dump_entrance_exit_time(self):
        self.entrance_time = np.zeros(self.dynamic_dump_num)
        self.exit_time = np.zeros(self.dynamic_dump_num)
        now = datetime.now().strftime("%Y-%m-%d")

        for dump_id in self.dump_uuid_to_index_dict.keys():
            # try:
            #     for query in (
            #         session_mysql.query(WorkRecord)
            #         .filter(
            #             WorkRecord.equipment_id == dump_id, WorkRecord.work_day >= now
            #         )
            #         .first()
            #     ):
            #         self.entrance_time[self.dump_uuid_to_index_dict[dump_id]] = float(
            #             query.load_entrance_time / query.load_entrance_count
            #         )
            #         self.exit_time[self.dump_uuid_to_index_dict[dump_id]] = float(
            #             query.exit_entrance_time / query.exit_entrance_count
            #         )
            # except Exception as es:
            #     self.logger.error(f"卸载设备 {dump_id} 出入场时间信息缺失, 已设为默认值(1min)")
            #     self.logger.error(es)
            self.entrance_time[self.dump_uuid_to_index_dict[dump_id]] = 0.50
            self.exit_time[self.dump_uuid_to_index_dict[dump_id]] = 0.50

    def update_dump_material(self):
        self.dump_material = {}
        for dump_id in get_value("dynamic_dump_set"):
            try:
                unload_area_id = session_mysql.query(Dispatch).filter_by(dump_id=dump_id, isauto=1, isdeleted=0).first().unload_area_id
                dump_material_id = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().Material
                self.dump_material[dump_id] = dump_material_id
            except Exception as es:
                self.logger.error("卸点物料更新异常")
                self.logger.error(es)
                session_mysql.rollback()
                session_postgre.rollback()

    def update_dump_priority(self):
        unload_area_index_to_uuid_dict = get_value("unload_area_index_to_uuid_dict")
        self.dump_priority_coefficient = np.ones(self.dynamic_dump_num)
        for dump_id in self.dynamic_dump_set:
            try:
                unload_area_index = self.dump_index_to_unload_area_index_dict[self.dump_uuid_to_index_dict[dump_id]]
                unload_area_id = unload_area_index_to_uuid_dict[unload_area_index]
                self.logger.debug("update_dump_priority-unload_area_index")
                self.logger.debug(unload_area_index)
                self.logger.debug("update_dump_priority-unload_area_id")
                self.logger.debug(unload_area_id)
                item = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first()
                self.dump_priority_coefficient[self.dump_uuid_to_index_dict[dump_id]] += item.Priority
            except Exception as es:
                self.logger.error("卸点优先级更新异常")
                self.logger.error(es)
                session_postgre.rollback()

    def update_unload_ability(self):
        unload_area_index_to_uuid_dict = get_value("unload_area_index_to_uuid_dict")
        try:
            try:
                rule3 = session_mysql.query(DispatchRule).filter_by(id=3).first()
            except Exception as es:
                self.logger.error(es)
                session_mysql.rollback()
                session_postgre.rollback()
            if not rule3.disabled:
                for dump_index in range(self.dynamic_dump_num):
                    unload_area_id = unload_area_index_to_uuid_dict[self.dump_index_to_unload_area_index_dict[dump_index]]

                    try:
                        unload_ability = session_postgre.query(DumpArea).filter_by(Id=unload_area_id).first().UnloadAbililty
                    except Exception as es:
                        self.logger.error(es)
                        session_mysql.rollback()
                        session_postgre.rollback()
                    self.dump_strength[dump_index] = unload_ability  # 卸载设备最大卸载能力，单位吨/小时

                    if unload_ability < 200:
                        raise Exception("卸载点卸载能力异常")
            else:
                self.dump_strength = np.full(self.dynamic_dump_num, 5000)

        except Exception as es:
            self.logger.error(es)
            self.logger.error("卸载点卸载信息读取异常")

    def reset(self):
        # 卸载设备数量
        self.dynamic_dump_num = get_value("dynamic_dump_num")
        # 用于动态调度的卸载设备集合
        self.dynamic_dump_set = get_value("dynamic_dump_set")
        # 卸载时间
        self.unloading_time = np.zeros(self.dynamic_dump_num)
        # 入场时间
        self.entrance_time = np.zeros(self.dynamic_dump_num)
        # 出场时间
        self.exit_time = np.zeros(self.dynamic_dump_num)
        # 卸载点物料类型
        self.dump_material = {}
        # 卸点优先级
        self.dump_priority_coefficient = np.ones(self.dynamic_dump_num)
        # 卸点卸载能力
        self.dump_strength = np.zeros(self.dynamic_dump_num)

    def dump_para_period_update(self):

        self.reset()

        # print("Dump update!")

        self.logger.info("Dump update!")

        # 计算平均卸载时间
        self.update_dump_unloadtime()

        # 计算平均进出场时间
        self.update_dump_entrance_exit_time()

        # 更新卸点物料
        self.update_dump_material()

        # 更新设备优先级
        self.update_dump_priority()

        # 更新卸点卸载能力
        self.update_unload_ability()
        #
        # # 卸载目标产量
        # self.dump_target_mass = np.full(self.dynamic_dump_num, dump_target_mass)