JobShopObjects updated to handle events.

parent 087c5b76
...@@ -41,4 +41,25 @@ class ExitJobShop(Exit): ...@@ -41,4 +41,25 @@ class ExitJobShop(Exit):
from Globals import G from Globals import G
self.previous=G.ObjList self.previous=G.ObjList
Exit.initialize(self) #run default behaviour Exit.initialize(self) #run default behaviour
#===========================================================================
# method used to check whether the station is in the entity-to-be-received route
# TODO: consider giving the activeEntity as attribute
#===========================================================================
def isInRoute(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue()
thecaller=callerObject
# if the caller is not defined then return True. We are only interested in checking whether
# the station can accept whatever entity from whichever giver
if not thecaller:
return True
#check it the caller object holds an Entity that requests for current object
if len(thecaller.getActiveObjectQueue())>0:
# TODO: make sure that the first entity of the callerObject is to be disposed
activeEntity=thecaller.getActiveObjectQueue()[0]
# if the machine's Id is in the list of the entity's next stations
if activeObject.id in activeEntity.remainingRoute[0].get('stationIdsList',[]):
return True
return False
\ No newline at end of file
...@@ -49,6 +49,15 @@ class MachineJobShop(Machine): ...@@ -49,6 +49,15 @@ class MachineJobShop(Machine):
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue() activeObjectQueue=activeObject.getActiveObjectQueue()
activeEntity=activeObjectQueue[0] activeEntity=activeObjectQueue[0]
# reset the variables used to handle the interruptions timing
self.timeRestartingProcessing=0
self.breakTime=0
# output to trace that the processing in the Machine self.objName ended
try:
activeObject.outputTrace(activeObject.getActiveObjectQueue()[0].name,"ended processing in "+activeObject.objName)
except IndexError:
pass
import Globals import Globals
from Globals import G from Globals import G
# the entity that just got processed is cold again it will get # the entity that just got processed is cold again it will get
...@@ -71,6 +80,21 @@ class MachineJobShop(Machine): ...@@ -71,6 +80,21 @@ class MachineJobShop(Machine):
# the just processed entity is added to the list of entities # the just processed entity is added to the list of entities
# pending for the next processing # pending for the next processing
G.pendingEntities.append(activeObjectQueue[0]) G.pendingEntities.append(activeObjectQueue[0])
# set the variable that flags an Entity is ready to be disposed
activeObject.waitToDispose=True
#do this so that if it is overtime working it is not counted as off-shift time
if not activeObject.onShift:
activeObject.timeLastShiftEnded=now()
# update the total working time # the total processing time for this entity is what the distribution initially gave
activeObject.totalWorkingTime+=activeObject.totalProcessingTimeInCurrentEntity
# update the variables keeping track of Entity related attributes of the machine
activeObject.timeLastEntityEnded=now() # this holds the time that the last entity ended processing in Machine
activeObject.nameLastEntityEnded=activeObject.currentEntity.name # this holds the name of the last entity that ended processing in Machine
activeObject.completedJobs+=1 # Machine completed one more Job
# TODO: collapse that to Machine
# ======================================================================= # =======================================================================
# gets an entity from the predecessor that the predecessor index points to # gets an entity from the predecessor that the predecessor index points to
...@@ -130,23 +154,40 @@ class MachineJobShop(Machine): ...@@ -130,23 +154,40 @@ class MachineJobShop(Machine):
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue() activeObjectQueue=activeObject.getActiveObjectQueue()
thecaller=callerObject thecaller=callerObject
if (thecaller!=None): #return according to the state of the Queue
#check it the caller object holds an Entity that requests for current object # also check if (if the machine is to be operated) there are available operators
if len(thecaller.getActiveObjectQueue())>0: if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList)\
# TODO: make sure that the first entity of the callerObject is to be disposed or any(type=='Setup' for type in activeObject.multOperationTypeList))):
activeEntity=thecaller.getActiveObjectQueue()[0] return activeObject.operatorPool.checkIfResourceIsAvailable()\
# if the machine's Id is in the list of the entity's next stations and len(activeObject.getActiveObjectQueue())<activeObject.capacity\
if activeObject.id in activeEntity.remainingRoute[0].get('stationIdsList',[]): and activeObject.checkIfMachineIsUp()\
#return according to the state of the Queue and activeObject.isInRoute(thecaller)
# also check if (if the machine is to be operated) there are available operators else:
if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList)\ return len(activeObject.getActiveObjectQueue())<activeObject.capacity\
or any(type=='Setup' for type in activeObject.multOperationTypeList))): and activeObject.checkIfMachineIsUp()\
return activeObject.operatorPool.checkIfResourceIsAvailable()\ and activeObject.isInRoute(thecaller)
and len(activeObject.getActiveObjectQueue())<activeObject.capacity\
and activeObject.Up #===========================================================================
else: # method used to check whether the station is in the entity-to-be-received route
return len(activeObject.getActiveObjectQueue())<activeObject.capacity\ # TODO: consider giving the activeEntity as attribute
and activeObject.Up # TODO: consider the case when no caller is defined,
# postProcessing calls canAccept on next members with no arguments
#===========================================================================
def isInRoute(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue()
thecaller=callerObject
# if the caller is not defined then return True. We are only interested in checking whether
# the station can accept whatever entity from whichever giver
if not thecaller:
return True
#check it the caller object holds an Entity that requests for current object
if len(thecaller.getActiveObjectQueue())>0:
# TODO: make sure that the first entity of the callerObject is to be disposed
activeEntity=thecaller.getActiveObjectQueue()[0]
# if the machine's Id is in the list of the entity's next stations
if activeObject.id in activeEntity.remainingRoute[0].get('stationIdsList',[]):
return True
return False return False
# ======================================================================= # =======================================================================
...@@ -157,76 +198,65 @@ class MachineJobShop(Machine): ...@@ -157,76 +198,65 @@ class MachineJobShop(Machine):
# get active object and its queue # get active object and its queue
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
thecaller = callerObject thecaller=callerObject
#if we have only one successor just check if machine waits to dispose and also is up #if we have only one successor just check if machine waits to dispose and also is up
# this is done to achieve better (cpu) processing time # this is done to achieve better (cpu) processing time
if(len(activeObject.next)==1 or callerObject==None): if(callerObject==None):
activeObject.receiver=activeObject.next[0]
return len(activeObjectQueue)>0\ return len(activeObjectQueue)>0\
and activeObject.waitToDispose\ and activeObject.waitToDispose\
and activeObject.Up\ and activeObject.checkIfMachineIsUp()\
and thecaller==activeObject.receiver
thecaller=callerObject
# give the entity to the successor that is waiting for the most time.
# (plant simulation does not do this in every occasion!)
maxTimeWaiting=0 # dummy variable counting the time a successor is waiting
for object in activeObject.next:
if(object.canAccept(activeObject)): # if a successor can accept an object
timeWaiting=now()-object.timeLastEntityLeft # the time it has been waiting is updated and stored in dummy variable timeWaiting
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting=timeWaiting
activeObject.receiver=object # set the receiver as the longest waiting possible receiver
# in the next loops, check the other successors in the previous list
#return True if the Machine in the state of disposing and the caller is the receiver #return True if the Machine in the state of disposing and the caller is the receiver
return len(activeObjectQueue)>0\ return len(activeObjectQueue)>0\
and activeObject.waitToDispose\ and activeObject.waitToDispose\
and activeObject.Up\ and activeObject.checkIfMachineIsUp()\
and (thecaller is self.receiver) and (thecaller in activeObject.next)\
and thecaller.isInRoute(activeObject)
# ======================================================================= # # =======================================================================
# method to execute preemption # # method to execute preemption
# ======================================================================= # # =======================================================================
def preempt(self): # def preempt(self):
activeObject=self.getActiveObject() # activeObject=self.getActiveObject()
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
#if it is reset then set it as the original processing time # #if it is reset then set it as the original processing time
if self.resetOnPreemption: # if self.resetOnPreemption:
remainingProcessingTime=self.procTime # remainingProcessingTime=self.procTime
#else subtract the time that passed since the entity entered # #else subtract the time that passed since the entity entered
#(may need also failure time if there was. TO BE MELIORATED) # #(may need also failure time if there was. TO BE MELIORATED)
else: # else:
remainingProcessingTime=self.procTime-(now()-self.timeLastEntityEntered) # remainingProcessingTime=self.procTime-(now()-self.timeLastEntityEntered)
#update the remaining route of activeEntity # #update the remaining route of activeEntity
activeEntity.remainingRoute.insert(0, {'stationIdsList':[str(self.id)],\ # activeEntity.remainingRoute.insert(0, {'stationIdsList':[str(self.id)],\
'processingTime':\ # 'processingTime':\
{'distributionType':'Fixed',\ # {'distributionType':'Fixed',\
'mean':str(remainingProcessingTime)}}) # 'mean':str(remainingProcessingTime)}})
# activeEntity.remainingRoute.insert(0, [self.id, remainingProcessingTime]) # # activeEntity.remainingRoute.insert(0, [self.id, remainingProcessingTime])
activeEntity.remainingRoute.insert(0, {'stationIdsList':[str(self.lastGiver.id)],\ # activeEntity.remainingRoute.insert(0, {'stationIdsList':[str(self.lastGiver.id)],\
'processingTime':\ # 'processingTime':\
{'distributionType':'Fixed',\ # {'distributionType':'Fixed',\
'mean':'0'}}) # 'mean':'0'}})
# activeEntity.remainingRoute.insert(0, [self.lastGiver.id, 0]) # # activeEntity.remainingRoute.insert(0, [self.lastGiver.id, 0])
#set the receiver as the object where the active entity was preempted from # #set the receiver as the object where the active entity was preempted from
self.receiver=self.lastGiver # self.receiver=self.lastGiver
self.next=[self.receiver] # self.next=[self.receiver]
self.waitToDispose=True #set that I have to dispose # self.waitToDispose=True #set that I have to dispose
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
reactivate(self) # reactivate(self)
#=========================================================================== #===========================================================================
# just extend the default behaviour in order to read the load time # extend the default behaviour to check if whether the station
# from the Entity to be obtained # is in the route of the entity to be received
#=========================================================================== #===========================================================================
def canAcceptAndIsRequested(self): def canAcceptAndIsRequested(self):
if Machine.canAcceptAndIsRequested(self): activeObject=self.getActiveObject()
self.readLoadTime() giverObject=activeObject.getGiverObject()
return True if activeObject.isInRoute(giverObject):
if Machine.canAcceptAndIsRequested(self):
activeObject.readLoadTime()
return True
return False return False
#=========================================================================== #===========================================================================
...@@ -234,11 +264,12 @@ class MachineJobShop(Machine): ...@@ -234,11 +264,12 @@ class MachineJobShop(Machine):
# the load timeof the Entity must be read # the load timeof the Entity must be read
#=========================================================================== #===========================================================================
def readLoadTime(self): def readLoadTime(self):
self.giver.sortEntities() activeObject=self.getActiveObject()
activeEntity=self.giver.getActiveObjectQueue()[0] activeObject.giver.sortEntities()
activeEntity=activeObject.giver.getActiveObjectQueue()[0]
loadTime=activeEntity.remainingRoute[0].get('loadTime',{}) loadTime=activeEntity.remainingRoute[0].get('loadTime',{})
self.distType=loadTime.get('distributionType','Fixed') activeObject.distType=loadTime.get('distributionType','Fixed')
self.loadTime=float(loadTime.get('mean', 0)) activeObject.loadTime=float(loadTime.get('mean', 0))
# ======================================================================= # =======================================================================
# removes an entity from the Machine # removes an entity from the Machine
......
...@@ -135,7 +135,7 @@ class Broker(ObjectInterruption): ...@@ -135,7 +135,7 @@ class Broker(ObjectInterruption):
if candidateMachines: if candidateMachines:
maxTimeWaiting=0 maxTimeWaiting=0
receiver=None receiver=None
# choose the one that waits the most time and assign give it the chance to grasp the resource # choose the one that waits the most time and give it the chance to grasp the resource
for machine in candidateMachines: for machine in candidateMachines:
timeWaiting=now()-machine.broker.timeWaitForOperatorStarted timeWaiting=now()-machine.broker.timeWaitForOperatorStarted
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0): if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):
......
...@@ -160,7 +160,7 @@ class Queue(CoreObject): ...@@ -160,7 +160,7 @@ class Queue(CoreObject):
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
giverObject=self.getGiverObject() giverObject=self.getGiverObject()
return len(activeObjectQueue)<self.capacity and giverObject.haveToDispose(activeObject) return len(activeObjectQueue)<activeObject.capacity and giverObject.haveToDispose(activeObject)
# ======================================================================= # =======================================================================
......
...@@ -48,48 +48,67 @@ class QueueJobShop(Queue): ...@@ -48,48 +48,67 @@ class QueueJobShop(Queue):
# it checks also the next station of the Entity # it checks also the next station of the Entity
# and returns true only if the active object is the next station # and returns true only if the active object is the next station
# ======================================================================= # =======================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
if callerObject!=None: activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue()
thecaller=callerObject
#return according to the state of the Queue
#check it the caller object holds an Entity that requests for current object #check it the caller object holds an Entity that requests for current object
if len(callerObject.getActiveObjectQueue())>0: return len(self.getActiveObjectQueue())<activeObject.capacity\
activeEntity=callerObject.getActiveObjectQueue()[0] and activeObject.isInRoute(callerObject)
# check if the object in the active entity's route next step
if self.id in activeEntity.remainingRoute[0].get('stationIdsList',[]): #===========================================================================
# if activeEntity.remainingRoute[0][0]==self.id: # method used to check whether the station is in the entity-to-be-received route
return len(self.getActiveObjectQueue())<self.capacity #return according to the state of the Queue # TODO: consider giving the activeEntity as attribute
return False #===========================================================================
def isInRoute(self, callerObject=None):
activeObject=self.getActiveObject()
activeObjectQueue=activeObject.getActiveObjectQueue()
thecaller=callerObject
# if the caller is not defined then return True. We are only interested in checking whether
# the station can accept whatever entity from whichever giver
if not thecaller:
return True
#check it the caller object holds an Entity that requests for current object
if len(thecaller.getActiveObjectQueue())>0:
# TODO: make sure that the first entity of the callerObject is to be disposed
activeEntity=thecaller.getActiveObjectQueue()[0]
# if the machine's Id is in the list of the entity's next stations
if activeObject.id in activeEntity.remainingRoute[0].get('stationIdsList',[]):
return True
return False
# ======================================================================= # =======================================================================
# checks if the Queue can dispose an entity. # checks if the Queue can dispose an entity.
# Returns True only to the potential receiver # Returns True only to the potential receiver
# ======================================================================= # =======================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
# print self.id, 'htd',
# if callerObject:
# print callerObject.id
# get active object and its queue # get active object and its queue
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue() activeObjectQueue=self.getActiveObjectQueue()
thecaller = callerObject thecaller = callerObject
#if we have only one possible receiver just check if the Queue holds one or more entities #if we have only one possible receiver just check if the Queue holds one or more entities
if(len(activeObject.next)==1 or callerObject==None): if(callerObject==None):
activeObject.receiver=activeObject.next[0] return len(activeObjectQueue)>0
return len(activeObjectQueue)>0\
and thecaller==activeObject.receiver
#give the entity to the possible receiver that is waiting for the most time. #return True if the Queue has Entities and the caller is in the self.next list
#plant does not do this in every occasion! return len(activeObjectQueue)>0\
maxTimeWaiting=0 and (thecaller in activeObject.next)\
hasFreeReceiver=False and thecaller.isInRoute(activeObject)
# loop through the object in the successor list
for object in activeObject.next: #===========================================================================
if(object.canAccept(activeObject)): # if the object can accept # extend the default behaviour to check if whether the station
hasFreeReceiver=True # is in the route of the entity to be received
timeWaiting=now()-object.timeLastEntityLeft # compare the time that it has been waiting #===========================================================================
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):# with the others' def canAcceptAndIsRequested(self):
maxTimeWaiting=timeWaiting activeObject=self.getActiveObject()
self.receiver=object # and update the receiver to the index of this object giverObject=activeObject.getGiverObject()
if activeObject.isInRoute(giverObject):
#return True if the Queue has Entities and the caller is the receiver return Queue.canAcceptAndIsRequested(self)
return len(activeObjectQueue)>0 and (thecaller is self.receiver) and hasFreeReceiver
# ======================================================================= # =======================================================================
# gets an entity from the predecessor that the predecessor index points to # gets an entity from the predecessor that the predecessor index points to
...@@ -139,8 +158,9 @@ class QueueJobShop(Queue): ...@@ -139,8 +158,9 @@ class QueueJobShop(Queue):
# ======================================================================= # =======================================================================
def removeEntity(self, entity=None): def removeEntity(self, entity=None):
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
receiverObject=self.receiver receiverObject=activeObject.getReceiverObject()
activeEntity=Queue.removeEntity(self, entity) #run the default method #run the default method
activeEntity=Queue.removeEntity(self, entity)
removeReceiver=True removeReceiver=True
# search in the internalQ. If an entity has the same receiver do not remove # search in the internalQ. If an entity has the same receiver do not remove
for ent in self.getActiveObjectQueue(): for ent in self.getActiveObjectQueue():
......
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