Commit fd670042 authored by Georgios Dagkakis's avatar Georgios Dagkakis

offer phase application and plugins added

parent 150dd66a
'''
Created on 1 Aug 2015
@author: Anna
'''
from copy import copy
import json
import time
import random
import operator
import datetime
from dream.plugins import plugin
class AddOfferPhaseGenerator(plugin.InputPreparationPlugin):
""" Input preparation
adds an EventGenerator that will call the Offer Phase model once
"""
def preprocess(self, data):
nodes=data['graph']['node']
data_uri_encoded_input_data = data['input'].get(self.configuration_dict['input_id_json'], {})
data_uri_encoded_workplan_data = data['input'].get(self.configuration_dict['input_id_workplan'], {})
algorithmAttributes=copy(data['general'])
nodes['OPG']={
"name": "OfferPhaseGenerator",
"prioritizeIfCanFinish": 1,
"interval": 1,
"start": 0,
"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}
}
return data
\ No newline at end of file
'''
Created on 1 Aug 2015
@author: Anna
'''
from dream.plugins import plugin
class PostProcessingOfferPhase(plugin.OutputPreparationPlugin):
""" Output the result of offer phase in a format compatible with
Output_viewDownloadFile
"""
def postprocess(self, data):
# XXX the event generator should store its result in data and not in global
# variable.
from dream.simulation.applications.FrozenSimulation.Globals import G
data['result']['result_list'][-1][self.configuration_dict['output_id']] = {
'name': 'Result.xlsx',
'mime_type': 'application/vnd.ms-excel',
'data': G.tabSchedule.xlsx.encode('base64')
}
return data
\ No newline at end of file
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
\ No newline at end of file
'''
Created on 4 Sep 2015
@author: Anna
'''
from dream.plugins import plugin
class projTabular(plugin.OutputPreparationPlugin):
""" Output the projection completion date in a tab
"""
def postprocess(self, data):
data['result']['result_list'][0]['exit_output'] = [['Project', 'Earliest Completion Date']]
from dream.simulation.applications.FrozenSimulation.Globals import G
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
'''
Created on 1 Aug 2015
@author: Anna
'''
from dream.plugins import plugin
class PostProcessingOfferPhase(plugin.OutputPreparationPlugin):
""" Output the result of offer phase in a format compatible with
Output_viewDownloadFile
"""
def postprocess(self, data):
# XXX the event generator should store its result in data and not in global
# variable.
from dream.simulation.applications.FrozenSimulation.Globals import G
data['result']['result_list'][-1][self.configuration_dict['output_id']] = {
'name': 'Result.xlsx',
'mime_type': 'application/vnd.ms-excel',
'data': G.tabSchedule.xlsx.encode('base64')
}
return data
\ No newline at end of file
'''
Created on 31 Aug 2015
@author: Anna
'''
import tablib
class G:
Schedule={}
seqPrjDone = None
resAvailability = None
MachPool = None
PMPool = None
Projects = None
xlreftime = None
reportResults = tablib.Databook()
tabSchedule = tablib.Dataset(title='Schedule')
tabSchedule.headers = (['Project', 'Part', 'Task ID', 'Station', 'Operator', 'Start Time', 'End Time'])
OrderDates = None
completionDate = None
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
\ No newline at end of file
This diff is collapsed.
'''
Created on 14 Aug 2015
@author: Anna
'''
from operator import itemgetter
from Globals import G
def findSequence(Projects, seqPrjDone, idDone):
opReady = []
print 'find sequence', Projects
print 'find sequence', seqPrjDone
for proj in seqPrjDone.keys():
for part in seqPrjDone[proj].keys():
if seqPrjDone[proj][part] < len(Projects[proj][part]):
possibleOp = True
print 'part', part, Projects[proj][part][seqPrjDone[proj][part]]['id']
if seqPrjDone[proj][part]==0 or Projects[proj][part][seqPrjDone[proj][part]-1]['id'] not in G.Schedule.keys():
minStartTime = max(G.xlreftime, G.OrderDates[proj])
else:
minStartTime = G.Schedule[Projects[proj][part][seqPrjDone[proj][part]-1]['id']]['endDate']
# verify whether the operation can be performed in terms of prerequisite operations
for preReq in Projects[proj][part][seqPrjDone[proj][part]]['preReq']:
if preReq not in idDone:
possibleOp = False
break
else:
if minStartTime < G.Schedule[preReq]['endDate']:
minStartTime = G.Schedule[preReq]['endDate']
if possibleOp:
newOp = Projects[proj][part][seqPrjDone[proj][part]]
print newOp['id'], 'possible'
newOp['minStartTime'] = minStartTime
newOp['project'] = proj
newOp['part'] = part
if 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']:
assert(seqPrjDone[proj][part] < len(Projects[proj][part]))
followOp = Projects[proj][part][seqPrjDone[proj][part]]
seqPrjDone[proj][part] += 1
# verify that the operation is the same
print followOp['operation'], newOp['operation']
assert (followOp['operation'].split('-')[0] in newOp['operation'])
# update operation (erase set)
newOp['operation'] = followOp['operation']
# update automatic time
newOp['autoTime'] = followOp['pt'] * followOp['qty']
# update opID, add followOp id
newOp['preID'] = newOp['id']
newOp['id'] = followOp['id']
else:
newOp['autoTime'] = 0
newOp['preID'] = None
if newOp['operation'] in ['INJM', 'MILL', 'EDM', 'TURN', 'DRILL']:
newOp['mode'] = 'MA'
elif newOp['operation'] == 'INJM-MAN':
newOp['mode'] = 'MM'
newOp['operation'] = 'INJM'
else:
newOp['mode'] = 'M'
opReady.append(newOp)
print 'pre', opReady
opReady = sorted(opReady, key=itemgetter('sequence', 'manualTime', 'autoTime'))
print 'seq', seqPrjDone, G.seqPrjDone
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
This diff is collapsed.
'''
Created on 6 Aug 2015
@author: Anna
'''
import datetime as dt
from copy import deepcopy
def shiftGenerator(startDate, noDays):
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 = 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)
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)
'''
Created on 6 Aug 2015
@author: Anna
'''
import datetime as dt
from copy import deepcopy
def availableTimeInterval_Manual(manualTime, tStart, availTime):
# suitable for manual operations...returns available time until the end
sortedTime = sorted(availTime.keys())
i = 0
while i<len(sortedTime) and sortedTime[i] <= tStart:
i += 1
i -= 1
if i < 0:
i = 0
# if i == 0 and tStart + manualTime < sortedTime[i]:
# return None
if availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i]) <= dt.timedelta(seconds=0):
i += 1
if i>=len(sortedTime):
print 'WARNING-not possible'
return None, 0
return sortedTime[i], availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i])
def availableTimeInterval_MM(manualTime, autoTime, tStart, availTime):
# suitable for MM operations...requires continuous availability over consecutive shifts
sortedTime = sorted(availTime.keys())
i = 0
while i<len(sortedTime) and sortedTime[i] <= tStart:
i += 1
i -= 1
if i < 0:
i = 0
# if i == 0 and tStart + autoTime + manualTime < sortedTime[i]:
# return None
tCumulative = dt.timedelta(seconds=0)
startSorted = sortedTime[i]
while i<len(sortedTime) and (tCumulative + availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i])) < manualTime+autoTime:
if availTime[sortedTime[i]]['endMode'] == 'EOS':
if i+1 < len(sortedTime) and availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and availTime[sortedTime[i+1]]['startMode'] == 'SOS':
tCumulative += availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i])
else:
tCumulative = dt.timedelta(seconds=0)
if i+1 < len(sortedTime):
startSorted = sortedTime[i+1]
i += 1
if i>=len(sortedTime):
return None, 0
return startSorted, manualTime+autoTime-tCumulative + max(tStart,sortedTime[i]) - max(tStart,startSorted)
def availableTimeInterval_MA(manualTime, autoTime, tStart, availTime):
sortedTime = sorted(availTime.keys())
print sortedTime
i = 0
while i<len(sortedTime) and sortedTime[i] <= tStart:
i += 1
i -= 1
if i < 0:
i = 0
# if i == 0 and tStart + autoTime + manualTime < sortedTime[i]:
# return None
print 'start', sortedTime[i]
while True:
tCumulative = dt.timedelta(seconds=0)
startSorted = sortedTime[i]
while i<len(sortedTime) and (tCumulative + availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i])) < manualTime:
if availTime[sortedTime[i]]['endMode'] == 'EOS':
if i+1 < len(sortedTime) and availTime[sortedTime[i+1]]['preDay'] == sortedTime[i].date() and availTime[sortedTime[i+1]]['startMode'] == 'SOS':
tCumulative += availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i])
else:
tCumulative = dt.timedelta(seconds=0)
if i+1 < len(sortedTime):
startSorted = sortedTime[i+1]
i += 1
if i>=len(sortedTime):
return None, 0
tManualEnd = max(tStart, sortedTime[i]) + manualTime - tCumulative
# while i<len(sortedTime) and availTime[sortedTime[i]]['end'] - max(tStart,sortedTime[i]) < manualTime:
# i += 1
if i>=len(sortedTime):
return None
# 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:
i += 1
else:
i += 1
else:
break
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
tempSave = deepcopy(availTime[keyStart])
if keyStart == tStart:
availTime.pop(keyStart,None)
else:
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']}
# case of interval ending after previous end (i.e. automatic operations)...check if goes into following available interval
elif tStart+reqTime > tempSave['end']:
sortedTime = sorted(availTime.keys())
i=0
while i<len(sortedTime) and sortedTime[i]<=keyStart:
i+=1
# if modeSim == 'avail':
# i -= 1
if i >= len(sortedTime):
print 'WARNING: beyond planning horizon'
return availTime
# print 'find next time', sortedTime[i], i
if tStart+reqTime > sortedTime[i]:
# repeat procedure
availTime = updateAvailTime(sortedTime[i], reqTime - (sortedTime[i]-tStart), sortedTime[i], availTime)
return availTime
def availableTime_Shift(tStart, tEnd, availTime):
sortedTime = sorted(availTime.keys())
i = 0
while i<len(sortedTime) and availTime[sortedTime[i]]['end'] <= tStart:
i += 1
# print i, sortedTime[i], availTime[sortedTime[i]]['end'], tStart, tEnd
if i>=len(sortedTime):
print 'WARNING: time interval not found'
return availTime
if availTime[sortedTime[i]]['end'] >= tEnd:
availTime = updateAvailTime(sortedTime[i], tEnd - max(tStart,sortedTime[i]), max(tStart,sortedTime[i]), availTime)
else:
if availTime[sortedTime[i]]['endMode'] == 'EOS':
if i==len(sortedTime)-1:
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:
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:
print 'beyond eos', max(tStart,sortedTime[i]), tEnd - max(tStart,sortedTime[i])
availTime = updateAvailTime(sortedTime[i], tEnd - max(tStart,sortedTime[i]), max(tStart,sortedTime[i]), availTime)
else:
return availTime
else:
return 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
'''
Created on 31 Aug 2015
@author: Anna
'''
import tablib
class G:
Schedule={}
seqPrjDone = None
resAvailability = None
MachPool = None
PMPool = None
Projects = None
xlreftime = None
reportResults = tablib.Databook()
tabSchedule = tablib.Dataset(title='Schedule')
tabSchedule.headers = (['Project', 'Part', 'Task ID', 'Station', 'Operator', 'Start Time', 'End Time'])
OrderDates = None
completionDate = None
jsonInput = None
excelInput = None
\ No newline at end of file
# ===========================================================================
# Copyright 2013 University of Limerick
#
# This file is part of DREAM.
#
# DREAM is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DREAM is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# ===========================================================================
# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
try:
__import__('pkg_resources').declare_namespace(__name__)
except ImportError:
from pkgutil import extend_path
__path__ = extend_path(__path__, __name__)
\ No newline at end of file
This diff is collapsed.
'''
Created on 14 Aug 2015
@author: Anna
'''
from operator import itemgetter
from Globals import G
def findSequence(Projects, seqPrjDone, idDone):
opReady = []
print 'find sequence', Projects
print 'find sequence', seqPrjDone
for proj in seqPrjDone.keys():
for part in seqPrjDone[proj].keys():
if seqPrjDone[proj][part] < len(Projects[proj][part]):
possibleOp = True
print 'part', part, Projects[proj][part][seqPrjDone[proj][part]]['id']
if seqPrjDone[proj][part]==0 or Projects[proj][part][seqPrjDone[proj][part]-1]['id'] not in G.Schedule.keys():
minStartTime = max(G.xlreftime, G.OrderDates[proj])
else:
minStartTime = G.Schedule[Projects[proj][part][seqPrjDone[proj][part]-1]['id']]['endDate']
# verify whether the operation can be performed in terms of prerequisite operations
for preReq in Projects[proj][part][seqPrjDone[proj][part]]['preReq']:
if preReq not in idDone:
possibleOp = False
break
else:
if minStartTime < G.Schedule[preReq]['endDate']:
minStartTime = G.Schedule[preReq]['endDate']
if possibleOp:
newOp = Projects[proj][part][seqPrjDone[proj][part]]
print newOp['id'], 'possible'
newOp['minStartTime'] = minStartTime
newOp['project'] = proj
newOp['part'] = part
if 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']:
assert(seqPrjDone[proj][part] < len(Projects[proj][part]))
followOp = Projects[proj][part][seqPrjDone[proj][part]]
seqPrjDone[proj][part] += 1
# verify that the operation is the same
print followOp['operation'], newOp['operation']
assert (followOp['operation'].split('-')[0] in newOp['operation'])
# update operation (erase set)
newOp['operation'] = followOp['operation']
# update automatic time
newOp['autoTime'] = followOp['pt'] * followOp['qty']
# update opID, add followOp id
newOp['preID'] = newOp['id']
newOp['id'] = followOp['id']
else:
newOp['autoTime'] = 0
newOp['preID'] = None
if newOp['operation'] in ['INJM', 'MILL', 'EDM', 'TURN', 'DRILL']:
newOp['mode'] = 'MA'
elif newOp['operation'] == 'INJM-MAN':
newOp['mode'] = 'MM'
newOp['operation'] = 'INJM'
else:
newOp['mode'] = 'M'
opReady.append(newOp)
print 'pre', opReady
opReady = sorted(opReady, key=itemgetter('sequence', 'manualTime', 'autoTime'))
print 'seq', seqPrjDone, G.seqPrjDone
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
This diff is collapsed.
'''
Created on 6 Aug 2015
@author: Anna
'''
import datetime as dt
from copy import deepcopy
def shiftGenerator(startDate, noDays):
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 = 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)
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)
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