Commit 34b02de8 authored by Georgios Dagkakis's avatar Georgios Dagkakis

additions so that break interrupts the victim

parent 9b24d077
...@@ -17,13 +17,13 @@ ...@@ -17,13 +17,13 @@
# along with DREAM. If not, see <http://www.gnu.org/licenses/>. # along with DREAM. If not, see <http://www.gnu.org/licenses/>.
# =========================================================================== # ===========================================================================
''' '''
Created on 9 Nov 2012 Created on 19 Mar 2015
@author: George @author: George
''' '''
''' '''
models the failures that servers can have models the breaks that CoreObjects or ObjectResources can have
''' '''
# from SimPy.Simulation import now, Process, hold, request, release # from SimPy.Simulation import now, Process, hold, request, release
...@@ -41,7 +41,7 @@ class Break(ObjectInterruption): ...@@ -41,7 +41,7 @@ class Break(ObjectInterruption):
self.rngTTR=RandomNumberGenerator(self, distribution.get('TTR',{'Fixed':{'mean':10}})) self.rngTTR=RandomNumberGenerator(self, distribution.get('TTR',{'Fixed':{'mean':10}}))
self.type="Break" self.type="Break"
# shows how the time to failure is measured # shows how the time to break is measured
# 'constant' means it counts not matter the state of the victim # 'constant' means it counts not matter the state of the victim
self.deteriorationType=deteriorationType self.deteriorationType=deteriorationType
self.endUnfinished=endUnfinished self.endUnfinished=endUnfinished
...@@ -52,7 +52,7 @@ class Break(ObjectInterruption): ...@@ -52,7 +52,7 @@ class Break(ObjectInterruption):
self.victimEndsProcess=self.env.event() self.victimEndsProcess=self.env.event()
# ======================================================================= # =======================================================================
# The run method for the failure which has to served by a repairman # The run method for the break which has to served by a repairman
# ======================================================================= # =======================================================================
def run(self): def run(self):
from CoreObject import CoreObject from CoreObject import CoreObject
...@@ -62,25 +62,25 @@ class Break(ObjectInterruption): ...@@ -62,25 +62,25 @@ class Break(ObjectInterruption):
# if the time that the victim is off-shift should not be counted # if the time that the victim is off-shift should not be counted
timeToBreak=self.rngTTB.generateNumber() timeToBreak=self.rngTTB.generateNumber()
remainingTimeToBreak=timeToBreak remainingTimeToBreak=timeToBreak
failureNotTriggered=True breakNotTriggered=True
# if time to failure counts not matter the state of the victim # if time to break counts not matter the state of the victim
if self.deteriorationType=='constant': if self.deteriorationType=='constant':
yield self.env.timeout(remainingTimeToBreak) yield self.env.timeout(remainingTimeToBreak)
# # if time to failure counts only in onShift time # # if time to break counts only in onShift time
# elif self.deteriorationType=='onShift': # elif self.deteriorationType=='onShift':
# while failureNotTriggered: # while breakNotTriggered:
# timeRestartedCounting=self.env.now # timeRestartedCounting=self.env.now
# self.isWaitingForVictimOffShift=True # self.isWaitingForVictimOffShift=True
# #
# self.expectedSignals['victimOffShift']=1 # self.expectedSignals['victimOffShift']=1
# #
# receivedEvent=yield self.env.timeout(remainingTimeToFailure) | self.victimOffShift # receivedEvent=yield self.env.timeout(remainingTimeToBreak) | self.victimOffShift
# # the failure should receive a signal if there is a shift-off triggered # # the break should receive a signal if there is a shift-off triggered
# if self.victimOffShift in receivedEvent: # if self.victimOffShift in receivedEvent:
# assert self.victim.onShift==False, 'shiftFailure cannot recalculate TTB if the victim is onShift' # assert self.victim.onShift==False, 'break cannot recalculate TTB if the victim is onShift'
# self.victimOffShift=self.env.event() # self.victimOffShift=self.env.event()
# remainingTimeToFailure=remainingTimeToFailure-(self.env.now-timeRestartedCounting) # remainingTimeToBreak=remainingTimeToBreak-(self.env.now-timeRestartedCounting)
# # wait for the shift to start again # # wait for the shift to start again
# self.isWaitingForVictimOnShift=True # self.isWaitingForVictimOnShift=True
# #
...@@ -90,12 +90,12 @@ class Break(ObjectInterruption): ...@@ -90,12 +90,12 @@ class Break(ObjectInterruption):
# #
# self.isWaitingForVictimOnShift=False # self.isWaitingForVictimOnShift=False
# self.victimOnShift=self.env.event() # self.victimOnShift=self.env.event()
# assert self.victim.onShift==True, 'the victim of shiftFailure must be onShift to continue counting the TTB' # assert self.victim.onShift==True, 'the victim of break must be onShift to continue counting the TTB'
# else: # else:
# self.isWaitingForVictimOffShift=False # self.isWaitingForVictimOffShift=False
# failureNotTriggered=False # breakNotTriggered=False
# #
# # if time to failure counts only in working time # # if time to break counts only in working time
# elif self.deteriorationType=='working': # elif self.deteriorationType=='working':
# # wait for victim to start process # # wait for victim to start process
# #
...@@ -104,16 +104,16 @@ class Break(ObjectInterruption): ...@@ -104,16 +104,16 @@ class Break(ObjectInterruption):
# yield self.victimStartsProcess # yield self.victimStartsProcess
# #
# self.victimStartsProcess=self.env.event() # self.victimStartsProcess=self.env.event()
# while failureNotTriggered: # while breakNotTriggered:
# timeRestartedCounting=self.env.now # timeRestartedCounting=self.env.now
# #
# self.expectedSignals['victimEndsProcess']=1 # self.expectedSignals['victimEndsProcess']=1
# #
# # wait either for the failure or end of process # # wait either for the break or end of process
# receivedEvent=yield self.env.timeout(remainingTimeToFailure) | self.victimEndsProcess # receivedEvent=yield self.env.timeout(remainingTimeTobreak) | self.victimEndsProcess
# if self.victimEndsProcess in receivedEvent: # if self.victimEndsProcess in receivedEvent:
# self.victimEndsProcess=self.env.event() # self.victimEndsProcess=self.env.event()
# remainingTimeToFailure=remainingTimeToFailure-(self.env.now-timeRestartedCounting) # remainingTimeTobreak=remainingTimeTobreak-(self.env.now-timeRestartedCounting)
# #
# self.expectedSignals['victimStartsProcess']=1 # self.expectedSignals['victimStartsProcess']=1
# #
...@@ -122,15 +122,15 @@ class Break(ObjectInterruption): ...@@ -122,15 +122,15 @@ class Break(ObjectInterruption):
# # wait for victim to start again processing # # wait for victim to start again processing
# self.victimStartsProcess=self.env.event() # self.victimStartsProcess=self.env.event()
# else: # else:
# failureNotTriggered=False # breakNotTriggered=False
# interrupt the victim # interrupt the victim
# if the victim is station # if the victim is station
if issubclass(self.victim.__class__, CoreObject): if issubclass(self.victim.__class__, CoreObject):
# if the mode is to end current work before going off-shift and there is current work, # if the mode is to end current work before going to break and there is current work,
# wait for victimEndedLastProcessing or victimFailed # wait for victimEndedLastProcessing or victimFailed
# signal before going off-shift # signal before going into break
if self.endUnfinished and self.victim.isProcessing: if self.endUnfinished and self.victim.isProcessing:
self.victim.isWorkingOnTheLast=True self.victim.isWorkingOnTheLast=True
self.waitingSignal=True self.waitingSignal=True
...@@ -143,15 +143,6 @@ class Break(ObjectInterruption): ...@@ -143,15 +143,6 @@ class Break(ObjectInterruption):
elif self.victimFailed in receivedEvent: elif self.victimFailed in receivedEvent:
transmitter, eventTime=self.victimFailed.value transmitter, eventTime=self.victimFailed.value
self.victimFailed=self.env.event() self.victimFailed=self.env.event()
# sometimes the time to end the last process may overcome the time to restart theshift
# so off-shift should not happen at such a case
if len(self.remainingShiftPattern)>1:
if self.env.now>=self.remainingShiftPattern[1][0]:
self.remainingShiftPattern.pop(0)
# if there is no more shift data break the loop
if len(self.remainingShiftPattern)==0:
break
continue
self.interruptVictim() self.interruptVictim()
# if the victim is operator # if the victim is operator
elif issubclass(self.victim.__class__, ObjectResource): elif issubclass(self.victim.__class__, ObjectResource):
...@@ -165,31 +156,32 @@ class Break(ObjectInterruption): ...@@ -165,31 +156,32 @@ class Break(ObjectInterruption):
if self.victim.schedule: if self.victim.schedule:
if not self.victim.schedule[-1].get("exitTime", None): if not self.victim.schedule[-1].get("exitTime", None):
self.victim.schedule[-1]["exitTime"] = self.env.now self.victim.schedule[-1]["exitTime"] = self.env.now
self.victim.schedule.append({"station": {'id':'off-shift'}, self.victim.schedule.append({"station": {'id':'on-break'},
"entranceTime": self.env.now}) "entranceTime": self.env.now})
self.requestAllocation() self.requestAllocation()
self.victim.Up=False self.victim.Up=False
self.victim.timeBreakStarted=self.env.now self.victim.timeBreakStarted=self.env.now
self.outputTrace(self.victim.name,"starts breaj") self.victim.onBreak=True # get the victim on break
# update the failure time self.outputTrace(self.victim.name,"starts break")
# update the break time
breakTime=self.env.now breakTime=self.env.now
yield self.env.timeout(self.rngTTR.generateNumber()) # wait until the repairing process is over yield self.env.timeout(self.rngTTR.generateNumber()) # wait until the repairing process is over
# add the failure # add the break
# if victim is off shift add only the fail time before the shift ended # if victim is off shift add only the fail time before the shift ended
if not self.victim.onShift and breakTime < self.victim.timeLastShiftEnded: if not self.victim.onShift and breakTime < self.victim.timeLastShiftEnded:
self.victim.totalBreakTime+=self.victim.timeLastShiftEnded-breakTime self.victim.totalBreakTime+=self.victim.timeLastShiftEnded-breakTime
# if the victim was off shift since the start of the failure add nothing # if the victim was off shift since the start of the break add nothing
elif not self.victim.onShift and breakTime >= self.victim.timeLastShiftEnded: elif not self.victim.onShift and breakTime >= self.victim.timeLastShiftEnded:
pass pass
# if victim was off shift in the start of the fail time, add on # if victim was off shift in the start of the fail time, add on
elif self.victim.onShift and breakTime < self.victim.timeLastShiftStarted: elif self.victim.onShift and breakTime < self.victim.timeLastShiftStarted:
self.victim.totalBreakTime+=self.env.now-self.victim.timeLastShiftStarted self.victim.totalBreakTime+=self.env.now-self.victim.timeLastShiftStarted
# this can happen only if deteriorationType is constant # this can happen only if deteriorationType is constant
assert self.deteriorationType=='constant', 'object got failure while off-shift and deterioration type not constant' assert self.deteriorationType=='constant', 'object got break while off-shift and deterioration type not constant'
else: else:
self.victim.totalBreakTime+=self.env.now-breakTime self.victim.totalBreakTime+=self.env.now-breakTime
...@@ -201,4 +193,6 @@ class Break(ObjectInterruption): ...@@ -201,4 +193,6 @@ class Break(ObjectInterruption):
self.victim.schedule[-1]["exitTime"] = self.env.now self.victim.schedule[-1]["exitTime"] = self.env.now
self.requestAllocation() self.requestAllocation()
self.victim.timeBreakEnded=self.env.now
self.victim.onBreak=False # get the victim on break
self.outputTrace(self.victim.name,"returns from break") self.outputTrace(self.victim.name,"returns from break")
...@@ -47,6 +47,10 @@ class ObjectResource(ManPyObject): ...@@ -47,6 +47,10 @@ class ObjectResource(ManPyObject):
def initialize(self): def initialize(self):
from Globals import G from Globals import G
# flag that shows if the resource is on shift
self.onShift=True
# flag that shows if the resource is on break
self.onBreak=False
self.env=G.env self.env=G.env
self.timeLastOperationStarted=0 #holds the time that the last repair was started self.timeLastOperationStarted=0 #holds the time that the last repair was started
self.Res=simpy.Resource(self.env, capacity=self.capacity) self.Res=simpy.Resource(self.env, capacity=self.capacity)
...@@ -67,7 +71,7 @@ class ObjectResource(ManPyObject): ...@@ -67,7 +71,7 @@ class ObjectResource(ManPyObject):
# ======================================================================= # =======================================================================
def checkIfResourceIsAvailable(self,callerObject=None): def checkIfResourceIsAvailable(self,callerObject=None):
# return true if the operator is idle and on shift # return true if the operator is idle and on shift
return len(self.Res.users)<self.capacity and self.onShift and (not self.isLocked) return len(self.Res.users)<self.capacity and self.onShift and (not self.isLocked) and (not self.onBreak)
# ======================================================================= # =======================================================================
......
...@@ -97,8 +97,6 @@ class Operator(ObjectResource): ...@@ -97,8 +97,6 @@ class Operator(ObjectResource):
def initialize(self): def initialize(self):
ObjectResource.initialize(self) ObjectResource.initialize(self)
# flag that shows if the resource is on shift
self.onShift=True
self.totalWorkingTime=0 #holds the total working time self.totalWorkingTime=0 #holds the total working time
self.totalWaitingTime=0 #holds the total waiting time self.totalWaitingTime=0 #holds the total waiting time
self.totalOffShiftTime=0 #holds the total off-shift time self.totalOffShiftTime=0 #holds the total off-shift time
......
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