Commit 9cd884a0 authored by Ioannis Papagiannopoulos's avatar Ioannis Papagiannopoulos Committed by Jérome Perrin

Comments added

parent 9c33bce8
This diff is collapsed.
...@@ -34,10 +34,13 @@ from RandomNumberGenerator import RandomNumberGenerator ...@@ -34,10 +34,13 @@ from RandomNumberGenerator import RandomNumberGenerator
import scipy.stats as stat import scipy.stats as stat
from CoreObject import CoreObject from CoreObject import CoreObject
#the Dismantle object # ===========================================================================
# the Dismantle object
# ===========================================================================
class Dismantle(CoreObject): class Dismantle(CoreObject):
# =======================================================================
#initialize the object # initialize the object
# =======================================================================
def __init__(self, id, name, distribution='Fixed', mean=1, stdev=0.1, min=0, max=5): def __init__(self, id, name, distribution='Fixed', mean=1, stdev=0.1, min=0, max=5):
CoreObject.__init__(self) CoreObject.__init__(self)
self.id=id self.id=id
...@@ -63,13 +66,15 @@ class Dismantle(CoreObject): ...@@ -63,13 +66,15 @@ class Dismantle(CoreObject):
self.Working=[] self.Working=[]
self.Blockage=[] self.Blockage=[]
# ============================== variable that is used for the loading of machines ============= # variable that is used for the loading of machines
self.exitAssignedToReceiver = False # by default the objects are not blocked self.exitAssignedToReceiver = False # by default the objects are not blocked
# when the entities have to be loaded to operatedMachines # when the entities have to be loaded to operatedMachines
# then the giverObjects have to be blocked for the time # then the giverObjects have to be blocked for the time
# that the machine is being loaded # that the machine is being loaded
# =======================================================================
# the initialize method
# =======================================================================
def initialize(self): def initialize(self):
Process.__init__(self) Process.__init__(self)
CoreObject.initialize(self) CoreObject.initialize(self)
...@@ -91,8 +96,6 @@ class Dismantle(CoreObject): ...@@ -91,8 +96,6 @@ class Dismantle(CoreObject):
self.processingTimeOfCurrentEntity=0 #holds the total processing time that the current entity required self.processingTimeOfCurrentEntity=0 #holds the total processing time that the current entity required
self.totalBlockageTime=0 #holds the total blockage time self.totalBlockageTime=0 #holds the total blockage time
self.totalWaitingTime=0 #holds the total waiting time self.totalWaitingTime=0 #holds the total waiting time
self.totalWorkingTime=0 #holds the total working time self.totalWorkingTime=0 #holds the total working time
...@@ -108,7 +111,9 @@ class Dismantle(CoreObject): ...@@ -108,7 +111,9 @@ class Dismantle(CoreObject):
self.Res.activeQ=[] self.Res.activeQ=[]
self.Res.waitQ=[] self.Res.waitQ=[]
# =======================================================================
# the run method
# =======================================================================
def run(self): def run(self):
while 1: while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Assembly can accept a frame yield waituntil, self, self.canAcceptAndIsRequested #wait until the Assembly can accept a frame
...@@ -136,21 +141,30 @@ class Dismantle(CoreObject): ...@@ -136,21 +141,30 @@ class Dismantle(CoreObject):
self.waitToDisposeFrame=False #the Dismantle has no Frame to dispose now self.waitToDisposeFrame=False #the Dismantle has no Frame to dispose now
#self.totalBlockageTime+=now()-startBlockageTime #add the blockage time #self.totalBlockageTime+=now()-startBlockageTime #add the blockage time
# =======================================================================
#checks if the Dismantle can accept an entity and there is a Frame waiting for it # checks if the Dismantle can accept an entity and there is a Frame
# waiting for it
# =======================================================================
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
return len(self.getActiveObjectQueue())==0 and self.getGiverObject().haveToDispose(self) return len(self.getActiveObjectQueue())==0 and self.getGiverObject().haveToDispose(self)
#checks if the Dismantle can accept an entity # =======================================================================
# checks if the Dismantle can accept an entity
# =======================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
return len(self.getActiveObjectQueue())==0 return len(self.getActiveObjectQueue())==0
#defines where parts and frames go after they leave the object # =======================================================================
# defines where parts and frames go after they leave the object
# =======================================================================
def definePartFrameRouting(self, successorPartList=[], successorFrameList=[]): def definePartFrameRouting(self, successorPartList=[], successorFrameList=[]):
self.nextPart=successorPartList self.nextPart=successorPartList
self.nextFrame=successorFrameList self.nextFrame=successorFrameList
#checks if the caller waits for a part or a frame and if the Dismantle is in the state of disposing one it returnse true # =======================================================================
# checks if the caller waits for a part or a frame and if the Dismantle
# is in the state of disposing one it returnse true
# =======================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
thecaller=callerObject thecaller=callerObject
...@@ -166,15 +180,21 @@ class Dismantle(CoreObject): ...@@ -166,15 +180,21 @@ class Dismantle(CoreObject):
return True return True
return False return False
#checks if the frame is emptied # =======================================================================
# checks if the frame is emptied
# =======================================================================
def frameIsEmpty(self): def frameIsEmpty(self):
return len(self.getActiveObjectQueue())==1 return len(self.getActiveObjectQueue())==1
#checks if Dismantle is emptied # =======================================================================
# checks if Dismantle is emptied
# =======================================================================
def isEmpty(self): def isEmpty(self):
return len(self.getActiveObjectQueue())==0 return len(self.getActiveObjectQueue())==0
#gets a frame from the giver # =======================================================================
# gets a frame from the giver
# =======================================================================
def getEntity(self): def getEntity(self):
activeEntity=CoreObject.getEntity(self) #run the default method activeEntity=CoreObject.getEntity(self) #run the default method
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
...@@ -189,7 +209,9 @@ class Dismantle(CoreObject): ...@@ -189,7 +209,9 @@ class Dismantle(CoreObject):
activeObjectQueue.pop(0) activeObjectQueue.pop(0)
return activeEntity return activeEntity
#removes an entity from the Dismantle # =======================================================================
# removes an entity from the Dismantle
# =======================================================================
def removeEntity(self): def removeEntity(self):
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
activeEntity=CoreObject.removeEntity(self) #run the default method activeEntity=CoreObject.removeEntity(self) #run the default method
...@@ -202,7 +224,9 @@ class Dismantle(CoreObject): ...@@ -202,7 +224,9 @@ class Dismantle(CoreObject):
self.waitToDisposePart=False self.waitToDisposePart=False
return activeEntity return activeEntity
#add the blockage only if the very last Entity (Frame) is to depart # =======================================================================
# add the blockage only if the very last Entity (Frame) is to depart
# =======================================================================
def addBlockage(self): def addBlockage(self):
if len(self.getActiveObjectQueue())==1: if len(self.getActiveObjectQueue())==1:
self.totalTimeInCurrentEntity=now()-self.timeLastEntityEntered self.totalTimeInCurrentEntity=now()-self.timeLastEntityEntered
...@@ -210,8 +234,9 @@ class Dismantle(CoreObject): ...@@ -210,8 +234,9 @@ class Dismantle(CoreObject):
blockage=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity) blockage=now()-(self.timeLastEntityEnded+self.downTimeInTryingToReleaseCurrentEntity)
self.totalBlockageTime+=blockage self.totalBlockageTime+=blockage
# =======================================================================
#actions to be taken after the simulation ends # actions to be taken after the simulation ends
# =======================================================================
def postProcessing(self, MaxSimtime=None): def postProcessing(self, MaxSimtime=None):
if MaxSimtime==None: if MaxSimtime==None:
from Globals import G from Globals import G
...@@ -234,8 +259,10 @@ class Dismantle(CoreObject): ...@@ -234,8 +259,10 @@ class Dismantle(CoreObject):
self.Working.append(100*self.totalWorkingTime/MaxSimtime) self.Working.append(100*self.totalWorkingTime/MaxSimtime)
self.Blockage.append(100*self.totalBlockageTime/MaxSimtime) self.Blockage.append(100*self.totalBlockageTime/MaxSimtime)
# =======================================================================
#outputs message to the trace.xls. Format is (Simulation Time | Entity or Frame Name | message) # outputs message to the trace.xls.
# Format is (Simulation Time | Entity or Frame Name | message)
# =======================================================================
def outputTrace(self, name, message): def outputTrace(self, name, message):
from Globals import G from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to if(G.trace=="Yes"): #output only if the user has selected to
...@@ -250,8 +277,9 @@ class Dismantle(CoreObject): ...@@ -250,8 +277,9 @@ class Dismantle(CoreObject):
G.sheetIndex+=1 G.sheetIndex+=1
G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True) G.traceSheet=G.traceFile.add_sheet('sheet '+str(G.sheetIndex), cell_overwrite_ok=True)
# =======================================================================
#outputs data to "output.xls" # outputs data to "output.xls"
# =======================================================================
def outputResultsXL(self, MaxSimtime=None): def outputResultsXL(self, MaxSimtime=None):
from Globals import G from Globals import G
if MaxSimtime==None: if MaxSimtime==None:
...@@ -303,7 +331,9 @@ class Dismantle(CoreObject): ...@@ -303,7 +331,9 @@ class Dismantle(CoreObject):
G.outputIndex+=1 G.outputIndex+=1
G.outputIndex+=1 G.outputIndex+=1
#outputs results to JSON File # =======================================================================
# outputs results to JSON File
# =======================================================================
def outputResultsJSON(self): def outputResultsJSON(self):
from Globals import G from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel if(G.numberOfReplications==1): #if we had just one replication output the results to excel
......
...@@ -34,7 +34,9 @@ import xlrd ...@@ -34,7 +34,9 @@ import xlrd
from random import Random, expovariate, gammavariate, normalvariate from random import Random, expovariate, gammavariate, normalvariate
from SimPy.Simulation import now from SimPy.Simulation import now
# ===========================================================================
# globals # globals
# ===========================================================================
class G: class G:
seed=1450 #the seed of the random number generator seed=1450 #the seed of the random number generator
Rnd = Random(seed) #random number generator Rnd = Random(seed) #random number generator
...@@ -49,7 +51,7 @@ class G: ...@@ -49,7 +51,7 @@ class G:
maxSimTime=0 #the total simulation time maxSimTime=0 #the total simulation time
# data for the trace output in excel # data for the trace output in excel
# ======================================================================= # -----------------------------------------------------------------------
trace="" #this is written from input. If it is "Yes" then you write to trace, else we do not trace="" #this is written from input. If it is "Yes" then you write to trace, else we do not
traceIndex=0 #index that shows in what row we are traceIndex=0 #index that shows in what row we are
sheetIndex=1 #index that shows in what sheet we are sheetIndex=1 #index that shows in what sheet we are
...@@ -58,19 +60,22 @@ class G: ...@@ -58,19 +60,22 @@ class G:
# variables for excel output # variables for excel output
# ======================================================================= # -----------------------------------------------------------------------
outputIndex=0 #index that shows in what row we are outputIndex=0 #index that shows in what row we are
sheetIndex=1 #index that shows in what sheet we are sheetIndex=1 #index that shows in what sheet we are
outputFile = xlwt.Workbook() #create excel file outputFile = xlwt.Workbook() #create excel file
outputSheet = outputFile.add_sheet('sheet '+str(sheetIndex), cell_overwrite_ok=True) #create excel sheet outputSheet = outputFile.add_sheet('sheet '+str(sheetIndex), cell_overwrite_ok=True) #create excel sheet
#variables for json output #variables for json output
# ======================================================================= # -----------------------------------------------------------------------
outputJSON={} outputJSON={}
outputJSONFile=None outputJSONFile=None
numberOfEntities = 0 numberOfEntities = 0
# =======================================================================
# method to move entities exceeding a certain safety stock
# =======================================================================
def moveExcess(argumentDict={}): def moveExcess(argumentDict={}):
giver=findObjectById(argumentDict.get('from', None)) giver=findObjectById(argumentDict.get('from', None))
receiver=findObjectById(argumentDict.get('to', None)) receiver=findObjectById(argumentDict.get('to', None))
...@@ -87,20 +92,29 @@ def moveExcess(argumentDict={}): ...@@ -87,20 +92,29 @@ def moveExcess(argumentDict={}):
else: else:
print "Giver and/or Receiver not defined" print "Giver and/or Receiver not defined"
# =======================================================================
# method finding objects by ID
# =======================================================================
def findObjectById(id): def findObjectById(id):
for obj in G.ObjList: for obj in G.ObjList:
if obj.id==id: if obj.id==id:
return obj return obj
return None return None
# =======================================================================
# method to set-up the entities in the current stations
# as Work In Progress
# =======================================================================
def setWIP(entityList): def setWIP(entityList):
for entity in entityList: for entity in entityList:
# if the entity is of type Part
if entity.type=='Part': if entity.type=='Part':
object=entity.currentStation #identify the object object=entity.currentStation #identify the object
object.getActiveObjectQueue().append(entity) #append the entity to its Queue object.getActiveObjectQueue().append(entity) #append the entity to its Queue
entity.schedule.append([object,now()]) #append the time to schedule so that it can be read in the result entity.schedule.append([object,now()]) #append the time to schedule so that it can be read in the result
# if the entity is of type Job/OrderComponent/Order
elif entity.type=='Job' or 'OrderComponent' or 'Order': elif entity.type=='Job' or 'OrderComponent' or 'Order':
object=findObjectById(entity.remainingRoute[0][0]) # find the object in the 'G.ObjList object=findObjectById(entity.remainingRoute[0][0]) # find the object in the 'G.ObjList'
object.getActiveObjectQueue().append(entity) # append the entity to its Queue object.getActiveObjectQueue().append(entity) # append the entity to its Queue
object.receiver=findObjectById(entity.remainingRoute[1][0]) object.receiver=findObjectById(entity.remainingRoute[1][0])
entity.remainingRoute.pop(0) # remove data from the remaining route. entity.remainingRoute.pop(0) # remove data from the remaining route.
......
...@@ -29,7 +29,9 @@ in the system and also in the processing times at each station ...@@ -29,7 +29,9 @@ in the system and also in the processing times at each station
from Globals import G from Globals import G
from Entity import Entity from Entity import Entity
# ============================ The job object ============================== # =======================================================================
# The job object
# =======================================================================
class Job(Entity): # inherits from the Entity class class Job(Entity): # inherits from the Entity class
type="Job" type="Job"
...@@ -43,11 +45,13 @@ class Job(Entity): # inherits from the Entity c ...@@ -43,11 +45,13 @@ class Job(Entity): # inherits from the Entity c
self.remainingRoute=list(route) # the remaining route. in the beginning self.remainingRoute=list(route) # the remaining route. in the beginning
# this should be the same as the full route # this should be the same as the full route
# the scheduling of the entity as resolved by the simulation # the scheduling of the entity as resolved by the simulation
self.schedule=[] # keeps the result of the simulation. # self.schedule=[] # keeps the result of the simulation.
# A list with the stations and time of entrance # # A list with the stations and time of entrance
self.extraPropertyDict = extraPropertyDict self.extraPropertyDict = extraPropertyDict
#==================== outputs results to JSON File ====================== # =======================================================================
# outputs results to JSON File
# =======================================================================
def outputResultsJSON(self): def outputResultsJSON(self):
from Globals import G from Globals import G
if(G.numberOfReplications==1): #if we had just one replication output the results to excel if(G.numberOfReplications==1): #if we had just one replication output the results to excel
...@@ -74,13 +78,15 @@ class Job(Entity): # inherits from the Entity c ...@@ -74,13 +78,15 @@ class Job(Entity): # inherits from the Entity c
i=0 i=0
for record in self.schedule: for record in self.schedule:
json['results']['schedule'].append({}) # dictionary holding time and json['results']['schedule'].append({}) # dictionary holding time and
json['results']['schedule'][i]['stepNumber']=i #the step number json['results']['schedule'][i]['stepNumber']=i # the step number
json['results']['schedule'][i]['stationId']=record[0].id # id of the Object json['results']['schedule'][i]['stationId']=record[0].id # id of the Object
json['results']['schedule'][i]['entranceTime']=record[1] # time entering the Object json['results']['schedule'][i]['entranceTime']=record[1] # time entering the Object
i+=1 i+=1
G.outputJSON['elementList'].append(json) G.outputJSON['elementList'].append(json)
# ==== initializes all the Entity for a new simulation replication ====== # =======================================================================
# initializes all the Entity for a new simulation replication
# =======================================================================
def initialize(self): def initialize(self):
# has to be re-initialized each time a new Job is added # has to be re-initialized each time a new Job is added
self.remainingRoute=list(self.route) self.remainingRoute=list(self.route)
......
...@@ -691,7 +691,6 @@ def createObjects(): ...@@ -691,7 +691,6 @@ def createObjects():
if possible_successor.id==nextId: if possible_successor.id==nextId:
possible_successor.previousIds.append(element.id) possible_successor.previousIds.append(element.id)
# =========================================================================== # ===========================================================================
# defines the topology (predecessors and successors for all the objects) # defines the topology (predecessors and successors for all the objects)
# =========================================================================== # ===========================================================================
...@@ -914,7 +913,10 @@ def createWIP(): ...@@ -914,7 +913,10 @@ def createWIP():
orderDate=float(entity.get('orderDate', '0')) orderDate=float(entity.get('orderDate', '0'))
isCritical=bool(int(entity.get('isCritical', '0'))) isCritical=bool(int(entity.get('isCritical', '0')))
basicsEnded=bool(int(entity.get('basicsEnded', '0'))) basicsEnded=bool(int(entity.get('basicsEnded', '0')))
# read the manager ID
manager=entity.get('manager', None) manager=entity.get('manager', None)
# if a manager ID is assigned then search for the operator with the corresponding ID
# and assign it as the manager of the order
if manager: if manager:
for operator in G.OperatorsList: for operator in G.OperatorsList:
if manager==operator.id: if manager==operator.id:
...@@ -968,7 +970,6 @@ def createWIP(): ...@@ -968,7 +970,6 @@ def createWIP():
G.WipList.append(O) G.WipList.append(O)
G.EntityList.append(O) G.EntityList.append(O)
# =========================================================================== # ===========================================================================
# reads the interruptions of the stations # reads the interruptions of the stations
# =========================================================================== # ===========================================================================
...@@ -980,9 +981,12 @@ def createObjectInterruptions(): ...@@ -980,9 +981,12 @@ def createObjectInterruptions():
json_data = G.JSONData json_data = G.JSONData
#Read the json data #Read the json data
nodes = json_data['nodes'] # read from the dictionary the dicts with key 'nodes' nodes = json_data['nodes'] # read from the dictionary the dicts with key 'nodes'
# for the elements in the nodes dict
for (element_id, element) in nodes.iteritems(): for (element_id, element) in nodes.iteritems():
element['id'] = element_id element['id'] = element_id
scheduledMaintenance=element.get('scheduledMaintenance', {}) scheduledMaintenance=element.get('scheduledMaintenance', {})
# if there is a scheduled maintenance initiate it and append it
# to the interruptions- and scheduled maintenances- list
if len(scheduledMaintenance): if len(scheduledMaintenance):
start=float(scheduledMaintenance.get('start', 0)) start=float(scheduledMaintenance.get('start', 0))
duration=float(scheduledMaintenance.get('duration', 1)) duration=float(scheduledMaintenance.get('duration', 1))
...@@ -991,6 +995,8 @@ def createObjectInterruptions(): ...@@ -991,6 +995,8 @@ def createObjectInterruptions():
G.ObjectInterruptionList.append(SM) G.ObjectInterruptionList.append(SM)
G.ScheduledMaintenanceList.append(SM) G.ScheduledMaintenanceList.append(SM)
failure=element.get('failures', {}) failure=element.get('failures', {})
# if there are failures assigned
# initiate them
if len(failure): if len(failure):
distributionType=failure.get('failureDistribution', 'No') distributionType=failure.get('failureDistribution', 'No')
if distributionType=='No': if distributionType=='No':
...@@ -1004,15 +1010,12 @@ def createObjectInterruptions(): ...@@ -1004,15 +1010,12 @@ def createObjectInterruptions():
G.ObjectInterruptionList.append(F) G.ObjectInterruptionList.append(F)
G.FailureList.append(F) G.FailureList.append(F)
# =========================================================================== # ===========================================================================
# used to convert a string read from the input to object type # used to convert a string read from the input to object type
# =========================================================================== # ===========================================================================
def str_to_class(str): def str_to_class(str):
return getattr(sys.modules[__name__], str) return getattr(sys.modules[__name__], str)
# =========================================================================== # ===========================================================================
# the main script that is ran # the main script that is ran
# =========================================================================== # ===========================================================================
......
...@@ -27,7 +27,9 @@ inherits from MachineJobShop it can preempt the currently processed Entity if ne ...@@ -27,7 +27,9 @@ inherits from MachineJobShop it can preempt the currently processed Entity if ne
from MachineJobShop import MachineJobShop from MachineJobShop import MachineJobShop
from SimPy.Simulation import reactivate, now from SimPy.Simulation import reactivate, now
#the MachineJobShop object # ===========================================================================
# the MachineJobShop object
# ===========================================================================
class MachinePreemptive(MachineJobShop): class MachinePreemptive(MachineJobShop):
def __init__(self, id, name, capacity=1, distribution='Fixed', mean=1, stdev=0, min=0, max=10,\ def __init__(self, id, name, capacity=1, distribution='Fixed', mean=1, stdev=0, min=0, max=10,\
...@@ -41,7 +43,9 @@ class MachinePreemptive(MachineJobShop): ...@@ -41,7 +43,9 @@ class MachinePreemptive(MachineJobShop):
self.lastGiver=self.giver self.lastGiver=self.giver
return activeEntity return activeEntity
#method to execute the preemption # =======================================================================
# method to execute the preemption
# =======================================================================
def preempt(self): def preempt(self):
activeEntity=self.getActiveObjectQueue()[0] #get the active Entity activeEntity=self.getActiveObjectQueue()[0] #get the active Entity
#calculate the remaining processing time #calculate the remaining processing time
......
...@@ -28,7 +28,9 @@ Order is an Entity that can have its design, get broken to sub-components ...@@ -28,7 +28,9 @@ Order is an Entity that can have its design, get broken to sub-components
from Globals import G from Globals import G
from Job import Job from Job import Job
# ============================ The Order object ============================== # =======================================================================
# The Order object
# =======================================================================
class Order(Job): class Order(Job):
type="Order" type="Order"
...@@ -36,10 +38,10 @@ class Order(Job): ...@@ -36,10 +38,10 @@ class Order(Job):
componentsList=[], manager=None, basicsEnded=False, extraPropertyDict=None): componentsList=[], manager=None, basicsEnded=False, extraPropertyDict=None):
Job. __init__(self, id=id, name=name, route=route, priority=priority, dueDate=dueDate, orderDate=orderDate, Job. __init__(self, id=id, name=name, route=route, priority=priority, dueDate=dueDate, orderDate=orderDate,
extraPropertyDict=extraPropertyDict) extraPropertyDict=extraPropertyDict)
self.isCritical=isCritical self.isCritical=isCritical # flag to inform weather the order is critical -> preemption
self.componentsList=componentsList self.componentsList=componentsList # list of components that the order will be broken into
self.manager=manager self.manager=manager # the manager responsible to handle the order
self.basicsEnded=basicsEnded self.basicsEnded=basicsEnded # flag that informs that the basic components of the order are finished
...@@ -35,6 +35,6 @@ class OrderComponent(Job): # inherits from the ...@@ -35,6 +35,6 @@ class OrderComponent(Job): # inherits from the
def __init__(self, id=None, name=None, route=[], priority=0, dueDate=None, orderDate=None, extraPropertyDict=None, def __init__(self, id=None, name=None, route=[], priority=0, dueDate=None, orderDate=None, extraPropertyDict=None,
componentType='Basic', order=None, isCritical=False): componentType='Basic', order=None, isCritical=False):
Job.__init__(self, id, name, route, priority, dueDate, orderDate, extraPropertyDict) Job.__init__(self, id, name, route, priority, dueDate, orderDate, extraPropertyDict)
self.auxiliaryList=[] self.auxiliaryList=[] # Holds the auxiliary components that the component needs for a certain processing
self.order=order self.order=order # parent order of the order component
self.isCritical=isCritical #this should be self.order.isCritical. Added now for testing self.isCritical=isCritical # this should be self.order.isCritical. Added now for testing
...@@ -47,6 +47,9 @@ class OrderDecomposition(CoreObject): ...@@ -47,6 +47,9 @@ class OrderDecomposition(CoreObject):
self.objName=name self.objName=name
self.type='OrderDecomposition' self.type='OrderDecomposition'
# =======================================================================
# the initialize method
# =======================================================================
def initialize(self): def initialize(self):
self.previous=G.ObjList self.previous=G.ObjList
self.next=G.ObjList self.next=G.ObjList
...@@ -56,7 +59,9 @@ class OrderDecomposition(CoreObject): ...@@ -56,7 +59,9 @@ class OrderDecomposition(CoreObject):
self.newlyCreatedComponents=[] # a list to hold components just after decomposition self.newlyCreatedComponents=[] # a list to hold components just after decomposition
self.orderToBeDecomposed=None self.orderToBeDecomposed=None
#run just waits until there is something to get and gets it # =======================================================================
# run just waits until there is something to get and gets it
# =======================================================================
def run(self): def run(self):
while 1: while 1:
yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity yield waituntil, self, self.canAcceptAndIsRequested #wait until the Queue can accept an entity
...@@ -64,12 +69,15 @@ class OrderDecomposition(CoreObject): ...@@ -64,12 +69,15 @@ class OrderDecomposition(CoreObject):
self.getEntity() self.getEntity()
self.decompose() self.decompose()
# =======================================================================
# as a dummy object can always accept
# =======================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
return True return True
# ======================================================================= # =======================================================================
# checks if the OrderDecomposition can accept an entity and there is an entity in # checks if the OrderDecomposition can accept an entity
# some possible giver waiting for it # and there is an entity in some possible giver waiting for it
# also updates the giver to the one that is to be taken # also updates the giver to the one that is to be taken
# ======================================================================= # =======================================================================
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
...@@ -104,7 +112,8 @@ class OrderDecomposition(CoreObject): ...@@ -104,7 +112,8 @@ class OrderDecomposition(CoreObject):
return activeObject.Up and isRequested return activeObject.Up and isRequested
# ======================================================================= # =======================================================================
# checks if the OrderDecomposition can dispose an entity to the following object # checks if the OrderDecomposition can dispose
# an entity to the following object
# ======================================================================= # =======================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
...@@ -118,7 +127,9 @@ class OrderDecomposition(CoreObject): ...@@ -118,7 +127,9 @@ class OrderDecomposition(CoreObject):
#return True if the OrderDecomposition in the state of disposing and the caller is the receiver #return True if the OrderDecomposition in the state of disposing and the caller is the receiver
return self.Up and (callerObject is self.receiver) return self.Up and (callerObject is self.receiver)
#decomposes the order to its components # =======================================================================
# decomposes the order to its components
# =======================================================================
def decompose(self): def decompose(self):
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
#loop in the internal Queue. Decompose only if an Entity is of type order #loop in the internal Queue. Decompose only if an Entity is of type order
...@@ -137,7 +148,9 @@ class OrderDecomposition(CoreObject): ...@@ -137,7 +148,9 @@ class OrderDecomposition(CoreObject):
self.orderToBeDecomposed=None self.orderToBeDecomposed=None
self.newlyCreatedComponents=[] self.newlyCreatedComponents=[]
#creates the components # =======================================================================
# creates the components
# =======================================================================
def createOrderComponent(self, component): def createOrderComponent(self, component):
#read attributes fromthe json or from the orderToBeDecomposed #read attributes fromthe json or from the orderToBeDecomposed
id=component.get('id', 'not found') id=component.get('id', 'not found')
......
...@@ -28,10 +28,13 @@ Inherits from QueueJobShop. If it gets an isCritical Entity it can interrupt the ...@@ -28,10 +28,13 @@ Inherits from QueueJobShop. If it gets an isCritical Entity it can interrupt the
from QueueJobShop import QueueJobShop from QueueJobShop import QueueJobShop
from SimPy.Simulation import now from SimPy.Simulation import now
#the QueuePreemptive object # ===========================================================================
# the QueuePreemptive object
# ===========================================================================
class QueuePreemptive(QueueJobShop): class QueuePreemptive(QueueJobShop):
# =======================================================================
#extend he default so that it can interrupt the receiver if need be # extend he default so that it can interrupt the receiver if need be
# =======================================================================
def getEntity(self): def getEntity(self):
activeEntity=QueueJobShop.getEntity(self) #execute default behaviour activeEntity=QueueJobShop.getEntity(self) #execute default behaviour
#if the obtained Entity is critical #if the obtained Entity is critical
...@@ -44,7 +47,9 @@ class QueuePreemptive(QueueJobShop): ...@@ -44,7 +47,9 @@ class QueuePreemptive(QueueJobShop):
self.receiver.preempt() self.receiver.preempt()
self.receiver.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station self.receiver.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station
#for future use # =======================================================================
# for future use
# =======================================================================
def sortEntities(self): def sortEntities(self):
QueueJobShop.sortEntities(self) QueueJobShop.sortEntities(self)
......
...@@ -30,13 +30,23 @@ from SimPy.Simulation import now, Process, hold, request, release, infinity ...@@ -30,13 +30,23 @@ from SimPy.Simulation import now, Process, hold, request, release, infinity
from RandomNumberGenerator import RandomNumberGenerator from RandomNumberGenerator import RandomNumberGenerator
from ObjectInterruption import ObjectInterruption from ObjectInterruption import ObjectInterruption
# ===========================================================================
# the scheduled maintenance class
# ===========================================================================
class ScheduledMaintenance(ObjectInterruption): class ScheduledMaintenance(ObjectInterruption):
# =======================================================================
# the __init__() method of the class
# =======================================================================
def __init__(self, victim=None, start=0, duration=1): def __init__(self, victim=None, start=0, duration=1):
ObjectInterruption.__init__(self,victim) ObjectInterruption.__init__(self,victim)
self.start=start self.start=start
self.duration=duration self.duration=duration
# =======================================================================
# the run method
# holds till the defined start time, interrupts the victim,
# holds for the maintenance duration, and finally reactivates the victim
# =======================================================================
def run(self): def run(self):
yield hold,self,self.start #wait until the start time yield hold,self,self.start #wait until the start time
try: try:
...@@ -48,7 +58,7 @@ class ScheduledMaintenance(ObjectInterruption): ...@@ -48,7 +58,7 @@ class ScheduledMaintenance(ObjectInterruption):
except AttributeError: except AttributeError:
print "AttributeError1" print "AttributeError1"
yield hold,self,self.duration #wait until the start time yield hold,self,self.duration # wait for the defined duration of the interruption
self.victim.totalFailureTime+=self.duration self.victim.totalFailureTime+=self.duration
try: try:
......
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