Untitled

 avatar
unknown
plain_text
2 years ago
8.9 kB
4
Indexable
import json
import pandas as pd
from datetime import datetime, timedelta
import time
import plotly
import plotly.express as px
import plotly.graph_objects as go
from operation import Operation
from machine import Machine
import holidays
# import inventory
input_path='.'
india_holidays = holidays.India(years=[2021, 2022, 2023, 2024, 2025, 2026, 2027])

input_file = input_path+'/inputs/Process_schedule.xlsx'
input_file=pd.ExcelFile(input_file)

components={}
components_list=input_file.sheet_names
for sheet_name in components_list:
    components[sheet_name]=pd.read_excel(input_file, sheet_name=sheet_name,skiprows=1,header=None,engine="openpyxl")
    components[sheet_name].fillna("",inplace=True)
    
for key in components.keys():
    for i in range(0,len(components[key])):
        if components[key][1][i]=='' and i!=1:
            components[key].drop(i,inplace=True)
            
op={}
for sheet_name in components_list:
    op[sheet_name]={}
for key in components.keys():
    for i in range(2,len(components[key])):
        total_machines=components[key][2][i].split(',')
        op[key][components[key][1][i]]={
            "machine" : total_machines,
            "transit time" : timedelta(minutes=(float(components[key][4][i] or 0)*60)),
            "loading time" : timedelta(minutes=(float(components[key][5][i] or 0)*60)),
            "unloading time" : timedelta(minutes=(float(components[key][6][i] or 0)*60)),
            "machining time" : timedelta(minutes=(float(components[key][7][i] or 0)*60)),
            "inspection time" : timedelta(minutes=(float(components[key][8][i] or 0)*60)),
            "total time": timedelta(minutes=(float(components[key][4][i] or 0)*60))+timedelta(minutes=(float(components[key][5][i] or 0)*60))+timedelta(minutes=(float(components[key][6][i] or 0)*60))+timedelta(minutes=(float(components[key][7][i] or 0)*60))+timedelta(minutes=(float(components[key][8][i] or 0)*60))
        }

inventory={}
for sheet_name in components_list:
    inventory[sheet_name]={
        "quantity" : 0,
    }
    
machines={}
for key in components.keys():
    for i in range(2,len(components[key])):
        machine_list=components[key][2][i].split(',')
        for machine in machine_list:
            if machine not in machines.keys():
                machines[machine]={
                    "operations" : [],
                }
            machines[machine]["operations"].append(components[key][1][i])
        
def getEarliestStartDate(orders_given):
    earliest_start_date = ""
    for order in orders_given:
        if order["start_date"] == "":
            continue
        if earliest_start_date == "":
            earliest_start_date = order["start_date"]
        elif order["start_date"] < earliest_start_date:
            earliest_start_date = order["start_date"]
    return earliest_start_date

def generateSchedule(orders_given):
    earliest_start_date = getEarliestStartDate(orders_given)
    # inventory = []
    operation_list = []
    
    for order in orders_given:
        for i in range(order["quantity"]):
            for operation in op[order["variant"]]:
                operation_list.append(Operation(order["priority"],
                                                op[order["variant"]][operation]["total time"],
                                                operation,
                                                datetime.strptime(order["start_date"],"%Y-%m-%d"),
                                                order["variant"],
                                                op[order["variant"]][operation]["machine"]))
    operation_list=sorted(operation_list,key=lambda x: x.priority)

    machine_class = []
    for machine in machines:
         machine_class.append(Machine(machine))
    
    curr_operations={}
    for order in orders_given:
        for variant in order.keys():
            curr_operations[variant]={}

    logs = []
    working = []
    current_datetime = datetime.strptime(earliest_start_date, "%Y-%m-%d")

    while len(operation_list):
        found=False
        for operation in operation_list:
            if operation.start_date<=current_datetime:
                if len(curr_operations[operation.variant])==0:
                
                    machine = operation.findMachine(machine_class)
                    if machine!=None:
                        freeat=machine.startMachine(inventory,working,operation,current_datetime)
                        curr_operations[operation.variant]={
                        "operation":operation.name,
                        "time":freeat
                        }
                        operation_list.remove(operation)
                        found=True
                        logs.append([operation.name,current_datetime, freeat,operation.variant,machine.name])

        if not found:
            next_start_date = None
            for op in operation_list:
                if op.start_date>=current_datetime:
                    if next_start_date==None:
                        next_start_date = op.start_date
                    elif op.start_date<next_start_date:
                        next_start_date = op.start_date
            earliest_stopping_machine=None
            for machine in working:
                if earliest_stopping_machine==None:
                    earliest_stopping_machine = machine
                elif machine.freeat<earliest_stopping_machine.freeat:
                    earliest_stopping_machine = machine
            if next_start_date!=None:
                if earliest_stopping_machine.freeat>next_start_date:
                    current_datetime = next_start_date
                else:
                    current_datetime = earliest_stopping_machine.freeat
                    earliest_stopping_machine.freeMachine(inventory,working)
            else:
                current_datetime = earliest_stopping_machine.freeat
                earliest_stopping_machine.freeMachine(inventory,working)
            if len(working)!=0:
                for machine in working:
                    if machine.freeat<=current_datetime:
                        machine.freeMachine(inventory,working)
        else:
            current_datetime+=timedelta(minutes=1)
            
        for key in curr_operations.keys():
            if len(curr_operations[key])>0:
                if curr_operations[key]["time"]<=current_datetime:
                    curr_operations[key]={}

    for i, log in enumerate(logs):
        if log[1].weekday() == 6 or log[1] in india_holidays:
            for j in range(i, len(logs)):
                logs[j][1] += timedelta(days=1)
                logs[j][2] += timedelta(days=1)

    logs1 = pd.DataFrame(
        logs, columns=["Operation", "Start Time", "End Time", "Variant", "Machine"]
    )
    fig = px.timeline(
        logs1, x_start="Start Time", x_end="End Time", y="Operation", color="Variant"
    )
    fig.update_layout(height=600, width=1500)
    fig.update_yaxes(
        autorange="reversed",
        categoryorder="array"
        # categoryarray=list(datasheet["Operation"]),
    )
    fig.write_html("./templates/ganttChart.html")
    ganttGraphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    fig2 = px.timeline(
        logs1, x_start="Start Time", x_end="End Time", y="Machine", color="Variant"
    )
    fig2.update_layout(height=600, width=1500)
    fig2.update_yaxes(
        autorange="reversed",
        categoryorder="array"
    )
    fig2.write_html("./templates/machineLoading.html")
    machineLoadingGraphJson = json.dumps(fig2, cls=plotly.utils.PlotlyJSONEncoder)
    machine_utilization = {}

    for log in logs:
        if log[4] not in machine_utilization:
            machine_utilization[log[4]] = log[2] - log[1]
        else:
            machine_utilization[log[4]] += log[2] - log[1]
    mu = []

    for machine in machine_utilization:
        mu.append([machine, machine_utilization[machine]])
    mu = pd.DataFrame(mu, columns=["Machine", "Utilization"])
    mu.sort_values(by="Machine", inplace=True)
    mu["Utilization"] = mu["Utilization"].apply(
        lambda x: x
        / (current_datetime - datetime.strptime(earliest_start_date, "%Y-%m-%d"))
        * 100
    )
    fig = go.Figure([go.Bar(x=mu["Machine"], y=mu["Utilization"])])
    fig.update_layout(
        title="Machine Utilization",
        xaxis_title="Machine",
        yaxis_title="Utilization",
        height=600,
        width=1500,
    )
    fig.write_html("./templates/machineUtilization.html")
    MachineUtilGraphJSON = json.dumps(fig, cls=plotly.utils.PlotlyJSONEncoder)
    return logs, ganttGraphJSON, MachineUtilGraphJSON, machineLoadingGraphJson
Editor is loading...