Commit bb2092c7 authored by Georgios Dagkakis's avatar Georgios Dagkakis

updates in frozen simulation approach

parent 5d81ba21
......@@ -32,6 +32,6 @@ class AddOfferPhaseGenerator(plugin.InputPreparationPlugin):
"stop": 0.5,
"_class": "dream.simulation.EventGenerator.EventGenerator",
"method": "dream.simulation.applications.FrozenSimulation.exeSim.exeSim",
"argumentDict": {'jsonInput':data_uri_encoded_input_data, 'workplanInput':data_uri_encoded_workplan_data}
"argumentDict": {'jsonInput':data_uri_encoded_input_data, 'workplanInput':data_uri_encoded_workplan_data, 'algorithmAttributes':algorithmAttributes}
}
return data
\ No newline at end of file
......@@ -3,7 +3,6 @@ Created on 4 Sep 2015
@author: Anna
'''
from dream.plugins import plugin
class projTabular(plugin.OutputPreparationPlugin):
......@@ -16,4 +15,6 @@ class projTabular(plugin.OutputPreparationPlugin):
for proj in G.completionDate.keys():
data['result']['result_list'][0]['exit_output'].append([proj, G.completionDate[proj]])
return data
\ No newline at end of file
return data
from dream.plugins import plugin
from operator import itemgetter
class schedTabular(plugin.OutputPreparationPlugin):
""" Output the schedule in a tab
"""
def postprocess(self, data):
data['result']['result_list'][0]['schedule_output'] = [['Project', 'Part', 'Task ID', 'Station', 'Operator', 'Start Time', 'End Time']]
from dream.simulation.applications.FrozenSimulation.Globals import G
# sort schedule items in start time ascending order
sList = []
for entry in G.tabSchedule:
if 'End Time' not in entry:
sList.append([x for x in entry])
sList = sorted(sList, key=itemgetter(5))
for item in sList:
data['result']['result_list'][0]['schedule_output'].append(item)
return data
\ No newline at end of file
......@@ -179,7 +179,7 @@ def MAM_allocation(currentOp):
print G.resAvailability[sorted_startTimeOp[0]['pm']]
def exeSim(jsonInput, workplanInput):
def exeSim(jsonInput, workplanInput, algorithmAttributes):
mime_type, attachement_data = jsonInput[len('data:'):].split(';base64,', 1)
attachement_data = attachement_data.decode('base64')
......@@ -190,7 +190,7 @@ def exeSim(jsonInput, workplanInput):
excelInput = attachement_data
# read input data
importInput(jInput, excelInput)
importInput(jInput, excelInput, algorithmAttributes)
# find initial operation
opDone = []
......
......@@ -46,11 +46,10 @@ def findSequence(Projects, seqPrjDone, idDone):
newOp['minStartTime'] = minStartTime
newOp['project'] = proj
newOp['part'] = part
if newOp['personnel'].lower() != 'automatic':
if newOp['operation'] not in ['INJM', 'MILL', 'EDM','INJM-MAN']: #newOp['personnel'].lower() != 'automatic':
newOp['manualTime'] = newOp['pt'] * newOp['qty']
seqPrjDone[proj][part] += 1
# newOp['manualTime']
# if it is a setup operation add the following operation
if 'SET' in newOp['operation']:
......@@ -78,7 +77,7 @@ def findSequence(Projects, seqPrjDone, idDone):
newOp['autoTime'] = 0
newOp['preID'] = None
if newOp['operation'] in ['INJM', 'MILL', 'EDM', 'TURN', 'DRILL']:
if newOp['operation'] in ['INJM', 'MILL', 'EDM']: #, 'TURN', 'DRILL']:
newOp['mode'] = 'MA'
elif newOp['operation'] == 'INJM-MAN':
......@@ -88,6 +87,8 @@ def findSequence(Projects, seqPrjDone, idDone):
else:
newOp['mode'] = 'M'
newOp['sequence'] = seqPrjDone[proj][part]
opReady.append(newOp)
print 'pre', opReady
......@@ -97,16 +98,3 @@ def findSequence(Projects, seqPrjDone, idDone):
return opReady
if __name__ == '__main__':
import jsonReader as jR
seq = jR.seqPrjDone
seq['Order 1']['Order 1 - Mould'] = 2
seq['Order 1']['Order 1 - Part 01'] = 3
seq['Order 1']['Order 1 - Part 02'] = 3
seq['Order 1']['Order 1 - Part 03'] = 1
op = findSequence(jR.Projects, jR.seqPrjDone, ['ID-00001','ID-00002','ID-00003','ID-00004','ID-00005', 'ID-00006', 'ID-00007', 'ID-00008', 'ID-00009'])
print 'op', op
\ No newline at end of file
......@@ -8,6 +8,7 @@ import json
import tablib
import datetime as dt
import xlrd
from operator import itemgetter
from copy import deepcopy
from shiftGeneration import shiftGenerator
from timeCalculations import availableTime_Shift
......@@ -76,25 +77,27 @@ def combSchedules(bothSchedList,combData):
h.write(combData.xlsx)
def importInput(jInput, excelInput):
def importInput(jInput, excelInput, algorithmAttributes):
#===========================================================
# Import workstations and operators schedule from json file
#===========================================================
dataJSON = json.loads(jInput)
print 'in import'
wb = xlrd.open_workbook(file_contents = excelInput)
frozen ={}
takenPeriods = {}
startSimDate = dateToOrdinal(dataJSON['general']['currentDate'], '%Y/%m/%d %H:%M')
startUserDate = dateToOrdinal(algorithmAttributes.get('currentDate',startSimDate), '%Y/%m/%d %H:%M')
forzenOpsData=tablib.Dataset()
forzenOpsData.headers = ['Date','Part','Order Name','WP-ID','Personnel','WorkStation','Time In','Time Out','Date Out','Frozen']
schedule = dataJSON['result']['result_list'][0]['component_schedule']
selSol = 0
if 'reference_solution' in dataJSON['input']:
selSol = dataJSON['input']['reference_solution']
schedule = dataJSON['result']['result_list'][selSol]['component_schedule']
for item in schedule:
if "Job ID" in item:
......@@ -121,7 +124,7 @@ def importInput(jInput, excelInput):
takenPeriods[station][startDate] = {'endDate': dateOut, 'taskID':item[3]}
PMschedule = dataJSON['result']['result_list'][0]['operator_gantt']['task_list']
PMschedule = dataJSON['result']['result_list'][selSol]['operator_gantt']['task_list']
for item in PMschedule:
......@@ -131,7 +134,6 @@ def importInput(jInput, excelInput):
stopDate = dateToOrdinal(item['stop_date'], "%d-%m-%Y %H:%M")
ordinalOutDate = excel_date(stopDate.date())
taskID = item['text'].split()[0]
print pm, taskID
pt = float((stopDate-startDate).seconds)/3600
if taskID == 'off-shift':
......@@ -154,70 +156,61 @@ def importInput(jInput, excelInput):
global numParts
#scenario = 'SIMPLE_2.xlsx'
WorkPlan = wb.sheet_by_index(0)
Projects = {}
OrderDates = {}
DueDates = {}
Shift = {}
seqPrjDone = {}
# FIXME: importare data riferimento
td = dt.datetime(2015,07,23)
xlreftime = excel_date(td)
for i in range(WorkPlan.nrows):
i += 1
if i < WorkPlan.nrows: #for the first line of the project name
if WorkPlan.cell_value(i,2) != '' and WorkPlan.cell_value(i,6) != '':
Projects[WorkPlan.cell_value(i,2)] = {}
print 'order date', xlrd.xldate_as_tuple(WorkPlan.cell_value(i,3), wb.datemode)
oyear, omonth, oday, ohour, ominute, osecond = xlrd.xldate_as_tuple(WorkPlan.cell_value(i,3), wb.datemode)
if WorkPlan.cell_value(i,0) != '' and WorkPlan.cell_value(i,2) != '':
Projects[WorkPlan.cell_value(i,0)] = {}
oyear, omonth, oday, ohour, ominute, osecond = xlrd.xldate_as_tuple(WorkPlan.cell_value(i,1), wb.datemode)
if ohour < 8:
ohour = 8
OrderDates[WorkPlan.cell_value(i,2)] = dt.datetime(oyear, omonth, oday, ohour, ominute, osecond) #FIXME: perche cosi?
DueDates[WorkPlan.cell_value(i,2)] = (xlreftime + WorkPlan.cell_value(i,4))
OrderDates[WorkPlan.cell_value(i,0)] = dt.datetime(oyear, omonth, oday, ohour, ominute, osecond)
header = i
current = WorkPlan.cell_value(header,2)
current = WorkPlan.cell_value(header,0)
seqPrjDone[current] = {}
#for a part whose name is not in the first line
if str(WorkPlan.cell_value(i,13)).split(';'+' ')[0].upper() == 'ALL':
if str(WorkPlan.cell_value(i,6)).split(';'+' ')[0].upper() == 'ALL':
prerq = []
for wpid in range(header,i):
prerq.append(str(WorkPlan.cell_value(wpid,14)))
prerq.append(str(WorkPlan.cell_value(wpid,7)))
else:
prerq = str(WorkPlan.cell_value(i,13)).split(';'+' ')
prerq = str(WorkPlan.cell_value(i,6)).split(';'+' ')
if len(prerq) == 1 and prerq[0]=='':
prerq=[]
if WorkPlan.cell_value(i,6) == '':
if WorkPlan.cell_value(i,2) == '':
continue
Projects[current].setdefault(WorkPlan.cell_value(i,6),[]).append({'id':str(WorkPlan.cell_value(i,14)), 'personnel':str(WorkPlan.cell_value(i,10)),
'pt': WorkPlan.cell_value(i,12), 'qty':WorkPlan.cell_value(i,11), 'preReq': prerq,
'operation': str(WorkPlan.cell_value(i,8)), 'sequence':WorkPlan.cell_value(i,9),
'project':current, 'part':WorkPlan.cell_value(i,6)})
seqPrjDone[current].setdefault(WorkPlan.cell_value(i,6),0)
print 'workplan', Projects
print 'sequence', seqPrjDone
Projects[current].setdefault(WorkPlan.cell_value(i,2),[]).append({'id':str(WorkPlan.cell_value(i,7)),
'pt': WorkPlan.cell_value(i,5), 'qty':WorkPlan.cell_value(i,4), 'preReq': prerq,
'operation': str(WorkPlan.cell_value(i,3)),
'project':current, 'part':WorkPlan.cell_value(i,2)}) #'personnel':str(WorkPlan.cell_value(i,10)), 'sequence':WorkPlan.cell_value(i,9),
seqPrjDone[current].setdefault(WorkPlan.cell_value(i,2),0)
maxODate = max(OrderDates.iteritems(), key=itemgetter(1))[1]
#==================================
# Import shift data from json file
#==================================
offShiftTimes = {}
stRtstOp = {}
unitTime = 'Hours'
# default shift times are hard coded as there is no correspondence with json file
# 7:00 - 18:00 are standard shift times
# 8:00 - 18:00 are standard shift times
defaultStartShift = 8.0/24
defaultEndShift = 18.0/24
defaultStartShift = dt.datetime(year=2014,month=1,day=1,hour=8,minute=0)
defaultEndShift = dt.datetime(year=2014,month=1,day=1,hour=18,minute=0)
stRtstOp['Default'] = [defaultStartShift,defaultEndShift]
shiftData = dataJSON['input']["shift_spreadsheet"]
......@@ -229,10 +222,12 @@ def importInput(jInput, excelInput):
if item[1] == '' or item[1]== None:
continue
currDate = excel_date(dateToOrdinal(item[1], "%Y/%m/%d").date())
if item[0] != '':#the first line for an operator
currResc = item[0]
cDate = dateToOrdinal(item[1], "%Y/%m/%d").date()
print item[2], item[3]
# set shift exceptions
if item[2] == '' or item[2]== None:
shiftStart = defaultStartShift
else:
......@@ -241,54 +236,20 @@ def importInput(jInput, excelInput):
shiftEnd = defaultEndShift
else:
shiftEnd = dt.datetime.strptime(item[3],'%H:%M')
# read off-shift periods
if item[4] == '' or item[4]== None:
offshiftPeriods = {}
else:
offshiftPeriods = offShiftFormat_2(item[4],cDate)
if item[0] != '':#the first line for an operator
currResc = item[0]
if currResc not in offShiftTimes:#no previous entry for the operator
offShiftTimes[currResc] = {}
offShiftTimes[currResc] = offshiftPeriods
stRtstOp[currResc] = {}
stRtstOp[currResc][cDate] = [shiftStart.time(),shiftEnd.time()]
else:
offShiftTimes[currResc] = offshiftPeriods
else:
offShiftTimes[currResc][cDate] = offshiftPeriods
stRtstOp[currResc][cDate] = [shiftStart,shiftEnd]
print 'off shift time', offShiftTimes
offShifts = dict((k,{}) for k in offShiftTimes.keys() + takenPeriods.keys())
for rsce in offShifts.keys():
if rsce in takenPeriods:
offShifts[rsce] = takenPeriods[rsce] #directly copy everything from the extracted dict
if rsce in offShiftTimes:#if that resource is present in the directly specified
for dte in offShiftTimes[rsce]:
if dte not in offShifts[rsce]:#if this date was not originally specified
offShifts[rsce][dte] = offShiftTimes[rsce][dte]
else:
starts = offShifts[rsce][dte]['Start']
stops = offShifts[rsce][dte]['Stop']
starts.extend(offShiftTimes[rsce][dte]['Start'])
stops.extend(offShiftTimes[rsce][dte]['Stop'])
u = list(set(starts))
v = list(set(stops))
offShifts[rsce][dte]['Start'] = u
offShifts[rsce][dte]['Stop'] = v
offShifts[rsce][dte]['Start'].sort()
offShifts[rsce][dte]['Stop'].sort()
print 'stRtstOp', stRtstOp
print 'off shift', offShifts
offShiftTimes.setdefault(currResc,{})
for offS in offshiftPeriods.keys():
offShiftTimes[currResc][offS] = offshiftPeriods[offS]
stRtstOp.setdefault(currResc,{})[cDate] = [shiftStart.time(),shiftEnd.time()]
#==================================================
# Import machine and pm information from json file
#==================================================
......@@ -298,6 +259,7 @@ def importInput(jInput, excelInput):
PMInfo = []
PMPool = {}
# static information on applicable technologies
stationTechnologies = {"CAD1": ["ENG", "CAD"], # XXX CAD1 is considered different than CAD2, they are not equivalent
"CAD2": ["CAD"],
"CAM": ["CAM"],
......@@ -309,6 +271,7 @@ def importInput(jInput, excelInput):
"ASSM": ["ASSM"],
"INJM": ["INJM"]}
# import machines information
possMachines = dataJSON['graph']['node']
for mach in possMachines.keys():
......@@ -326,9 +289,7 @@ def importInput(jInput, excelInput):
for tec in pool:
MachPool.setdefault(tec,[]).append(mach)
print MachInfo
print 'mach pool', MachPool
# import PM information
PMskills = dataJSON['input']['operator_skills_spreadsheet']
for item in range(1,len(PMskills)):
......@@ -344,36 +305,44 @@ def importInput(jInput, excelInput):
PMInfo.append({'name':PMskills[item][0], 'skills': skills, 'sched':'FIFO', 'status':''})
for sk in skills:
PMPool.setdefault(sk,[]).append(PMskills[item][0])
print PMInfo
print 'pm pool', PMPool
print '======================',offShifts
# set start simulation date as maximum betweeen the current date (json) and the order date
G.xlreftime = max(startSimDate,maxODate,startUserDate)
shiftRes = {}
resAvailability = {}
# define shifts for PMs
for item in PMInfo:
pm = item['name']
shiftRes[pm] = shiftGenerator(startSimDate,7)
if pm in stRtstOp:
exceptions = stRtstOp[pm]
else:
exceptions = {}
shiftRes[pm] = shiftGenerator(G.xlreftime,30,exceptions)
resAvailability[pm] = deepcopy(shiftRes[pm])
if pm in offShifts:
for unavailDate in offShifts[pm].keys():
print pm, unavailDate, offShifts[pm][unavailDate]['endDate']-unavailDate
resAvailability[pm] = availableTime_Shift(unavailDate,offShifts[pm][unavailDate]['endDate'],resAvailability[pm])
if pm in offShiftTimes:
for unavailDate in offShiftTimes[pm].keys():
resAvailability[pm] = availableTime_Shift(unavailDate,offShiftTimes[pm][unavailDate]['endDate'],resAvailability[pm])
if pm in takenPeriods:
for unavailDate in takenPeriods[pm].keys():
resAvailability[pm] = availableTime_Shift(unavailDate,takenPeriods[pm][unavailDate]['endDate'],resAvailability[pm])
print 'shift', pm, shiftRes[pm]
print 'shift', pm, resAvailability[pm]
# define shifts for machines
for item in MachInfo:
mach = item['name']
shiftRes[mach] = shiftGenerator(startSimDate,7)
if mach in stRtstOp:
exceptions = stRtstOp[mach]
else:
exceptions = {}
shiftRes[mach] = shiftGenerator(G.xlreftime,30,exceptions)
resAvailability[mach] = deepcopy(shiftRes[mach])
if mach in offShifts:
for unavailDate in offShifts[mach].keys():
print mach, unavailDate, offShifts[mach][unavailDate]['endDate']-unavailDate
resAvailability[mach] = availableTime_Shift(unavailDate,offShifts[mach][unavailDate]['endDate'],resAvailability[mach])
print 'shift', mach, shiftRes[mach]
print 'shift', mach, resAvailability[mach]
if mach in offShiftTimes:
for unavailDate in offShiftTimes[mach].keys():
resAvailability[mach] = availableTime_Shift(unavailDate,offShiftTimes[mach][unavailDate]['endDate'],resAvailability[mach])
if mach in takenPeriods:
for unavailDate in takenPeriods[mach].keys():
resAvailability[mach] = availableTime_Shift(unavailDate,takenPeriods[mach][unavailDate]['endDate'],resAvailability[mach])
# set global variables
G.resAvailability = deepcopy(resAvailability)
......@@ -382,6 +351,5 @@ def importInput(jInput, excelInput):
G.MachPool = deepcopy(MachPool)
G.PMPool = deepcopy(PMPool)
G.Projects = deepcopy(Projects)
G.xlreftime = td
G.OrderDates = deepcopy(OrderDates)
G.completionDate = deepcopy(OrderDates)
......@@ -7,28 +7,29 @@ Created on 6 Aug 2015
import datetime as dt
from copy import deepcopy
def shiftGenerator(startDate, noDays):
def shiftGenerator(startDate, noDays, exceptions):
shift = {}
day = 0
actualDays = 0
preDay = deepcopy(startDate.date())
while actualDays < noDays:
st = deepcopy(startDate)
if day:
dateStart = st.date()
dateStart += dt.timedelta(days=day)
st = deepcopy(startDate)
dateStart = st.date()
dateStart += dt.timedelta(days=day)
if dateStart in exceptions:
st = dt.datetime(dateStart.year,dateStart.month, dateStart.day, exceptions[dateStart][0].hour, exceptions[dateStart][0].minute)
fin = dt.datetime(st.year, st.month, st.day, exceptions[st.date()][1].hour, exceptions[st.date()][1].minute)
else:
st = dt.datetime(dateStart.year,dateStart.month, dateStart.day, 8,0)
if st.weekday() < 5:
fin = dt.datetime(st.year, st.month, st.day, 18,0)
if st.weekday() < 5 or st.date() in exceptions:
shift[st] = {'end':fin, 'startMode':'SOS', 'endMode':'EOS', 'preDay':preDay}
preDay = st.date()
actualDays += 1
day += 1
return shift
if __name__ == '__main__':
shift = shiftGenerator(dt.datetime(2015,8,4,12,00),10)
......@@ -127,13 +127,11 @@ def availableTimeInterval_MA(manualTime, autoTime, tStart, availTime):
# print 'end manual', sortedTime[i]
if autoTime:
# if availTime[sortedTime[i]]['end']- max(tStart,sortedTime[i]) <= (manualTime+autoTime):
if availTime[sortedTime[i]]['end']- max(tManualEnd,sortedTime[i]) <= autoTime:
if availTime[sortedTime[i]]['endMode'] == 'EOS':
if i==len(sortedTime)-1:
break
# if availTime[sortedTime[i+1]]['startMode']=='SOS' and availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and availTime[sortedTime[i+1]]['end'] - max(tStart,sortedTime[i]) >= (manualTime+autoTime):
if availTime[sortedTime[i+1]]['startMode']=='SOS' and availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and availTime[sortedTime[i+1]]['end'] - max(tManualEnd,sortedTime[i]) >= autoTime:
break
else:
......@@ -146,14 +144,12 @@ def availableTimeInterval_MA(manualTime, autoTime, tStart, availTime):
else:
break
# return sortedTime[i]
return startSorted, tManualEnd - max(tStart,startSorted)
def updateAvailTime(keyStart, reqTime, tStart, availTime):
# tStart e` tempo effettivo di inizio calcolato in precedenza come max(tStart,keyStart)
# print 'update', keyStart, reqTime, tStart
if reqTime <= dt.timedelta(seconds=0):
return availTime
......@@ -166,8 +162,7 @@ def updateAvailTime(keyStart, reqTime, tStart, availTime):
availTime[keyStart]['end'] = tStart
availTime[keyStart]['endMode'] = 'IS'
# print 'inizio', keyStart, availTime[keyStart]
# case of interval ending before previous end
if tStart+reqTime < tempSave['end']:
availTime[tStart+reqTime] = {'end':tempSave['end'], 'startMode':'IS', 'endMode':tempSave['endMode'], 'preDay':tempSave['preDay']}
......@@ -220,7 +215,7 @@ def availableTime_Shift(tStart, tEnd, availTime):
print 'WARNING: beyond last interval'
availTime= updateAvailTime(sortedTime[i], tEnd - max(tStart,sortedTime[i]), max(tStart,sortedTime[i]), availTime)
if availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and sortedTime[i+1] >= tEnd:
elif availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and sortedTime[i+1] >= tEnd:
availTime = updateAvailTime(sortedTime[i], tEnd - max(tStart,sortedTime[i]), max(tStart,sortedTime[i]), availTime)
elif availTime[sortedTime[i+1]]['startMode']=='SOS' and availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and availTime[sortedTime[i+1]]['end'] >= tEnd:
......@@ -234,28 +229,3 @@ def availableTime_Shift(tStart, tEnd, availTime):
return availTime
if __name__ == '__main__':
availTime = {dt.datetime(2015, 7, 23, 8, 0): {'end': dt.datetime(2015, 7, 23, 18, 0), 'startMode': 'SOS', 'endMode': 'EOS'},
dt.datetime(2015, 7, 24, 8, 0): {'end': dt.datetime(2015, 7, 24, 18, 0), 'startMode': 'SOS', 'endMode': 'EOS'},
dt.datetime(2015, 7, 25, 8, 0): {'end': dt.datetime(2015, 7, 27, 18, 0), 'startMode': 'SOS', 'endMode': 'EOS'}}
tStart = dt.datetime(2015,7,23,12,00)
tEnd = dt.datetime(2015,7,25,14,0)
autoTime = dt.timedelta(hours=20)
manualTime = dt.timedelta(hours=4)
print tStart
keyStart, pt = availableTimeInterval_MM(manualTime, autoTime, tStart, availTime)
print keyStart
# pt = manualTime + autoTime
print 'pt', pt
if keyStart:
availTime = updateAvailTime(keyStart, pt, max(tStart,keyStart), availTime)
else:
print 'WARNING: operation cannot be performed'
#availTime = availableTime_Shift(tStart, tEnd, availTime)
print 'updated time', availTime
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment