Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
dream
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
dream
Commits
3b194d7d
Commit
3b194d7d
authored
Oct 24, 2013
by
Ioannis Papagiannopoulos
Committed by
Sebastien Robin
Nov 06, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
in-line comments + cleanup in Machine.py
parent
236e141f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
224 additions
and
170 deletions
+224
-170
dream/simulation/Machine.py
dream/simulation/Machine.py
+224
-170
No files found.
dream/simulation/Machine.py
View file @
3b194d7d
...
@@ -34,22 +34,30 @@ from CoreObject import CoreObject
...
@@ -34,22 +34,30 @@ from CoreObject import CoreObject
from
RandomNumberGenerator
import
RandomNumberGenerator
from
RandomNumberGenerator
import
RandomNumberGenerator
import
scipy.stats
as
stat
import
scipy.stats
as
stat
#the Machine object
# ===========================================================================
# the Machine object
# ===========================================================================
class
Machine
(
CoreObject
):
class
Machine
(
CoreObject
):
#initialize the id the capacity, of the resource and the distribution
#initialize the id the capacity, of the resource and the distribution
def
__init__
(
self
,
id
,
name
,
capacity
=
1
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0
,
min
=
0
,
max
=
10
,
failureDistribution
=
'No'
,
MTTF
=
0
,
MTTR
=
0
,
availability
=
0
,
repairman
=
'None'
):
def
__init__
(
self
,
id
,
name
,
capacity
=
1
,
distribution
=
'Fixed'
,
mean
=
1
,
stdev
=
0
,
min
=
0
,
max
=
10
,
\
failureDistribution
=
'No'
,
MTTF
=
0
,
MTTR
=
0
,
availability
=
0
,
repairman
=
'None'
):
Process
.
__init__
(
self
)
Process
.
__init__
(
self
)
# used for the routing of the entities
self
.
predecessorIndex
=
0
#holds the index of the predecessor from which the Machine will take an entity next
self
.
predecessorIndex
=
0
#holds the index of the predecessor from which the Machine will take an entity next
self
.
successorIndex
=
0
#holds the index of the successor where the Machine will dispose an entity next
self
.
successorIndex
=
0
#holds the index of the successor where the Machine will dispose an entity next
# hold the id, name, and type of the Machine instance
self
.
id
=
id
self
.
id
=
id
self
.
objName
=
name
self
.
objName
=
name
self
.
type
=
"Machine"
#String that shows the type of object
# holds the capacity of the machine
self
.
capacity
=
capacity
self
.
capacity
=
capacity
# define the distribution types of the processing and failure times respectively
self
.
distType
=
distribution
#the distribution that the procTime follows
self
.
distType
=
distribution
#the distribution that the procTime follows
self
.
failureDistType
=
failureDistribution
#the distribution that the failure follows
self
.
failureDistType
=
failureDistribution
#the distribution that the failure follows
# sets the repairman resource of the Machine
self
.
repairman
=
repairman
self
.
repairman
=
repairman
# Sets the attributes of the processing (and failure) time(s)
self
.
rng
=
RandomNumberGenerator
(
self
,
self
.
distType
)
self
.
rng
=
RandomNumberGenerator
(
self
,
self
.
distType
)
self
.
rng
.
avg
=
mean
self
.
rng
.
avg
=
mean
self
.
rng
.
stdev
=
stdev
self
.
rng
.
stdev
=
stdev
...
@@ -58,243 +66,282 @@ class Machine(CoreObject):
...
@@ -58,243 +66,282 @@ class Machine(CoreObject):
self
.
MTTF
=
MTTF
self
.
MTTF
=
MTTF
self
.
MTTR
=
MTTR
self
.
MTTR
=
MTTR
self
.
availability
=
availability
self
.
availability
=
availability
# lists that hold the previous and next objects in the flow
self
.
next
=
[]
#list with the next objects in the flow
self
.
next
=
[]
#list with the next objects in the flow
self
.
previous
=
[]
#list with the previous objects in the flow
self
.
previous
=
[]
#list with the previous objects in the flow
self
.
nextIds
=
[]
#list with the ids of the next objects in the flow
self
.
nextIds
=
[]
#list with the ids of the next objects in the flow
self
.
previousIds
=
[]
#list with the ids of the previous objects in the flow
self
.
previousIds
=
[]
#list with the ids of the previous objects in the flow
self
.
type
=
"Machine"
#String that shows the type of object
# lists to hold statistics of multiple runs
#lists to hold statistics of multiple runs
self
.
Failure
=
[]
self
.
Failure
=
[]
self
.
Working
=
[]
self
.
Working
=
[]
self
.
Blockage
=
[]
self
.
Blockage
=
[]
self
.
Waiting
=
[]
self
.
Waiting
=
[]
# =======================================================================
# initialize the Machine object
# =======================================================================
def
initialize
(
self
):
def
initialize
(
self
):
Process
.
__init__
(
self
)
# using the Process __init__ and not the CoreObject __init__
self
.
Up
=
True
#Boolean that shows if the machine is in failure ("Down") or not ("up")
CoreObject
.
initialize
(
self
)
self
.
currentEntity
=
None
self
.
totalBlockageTime
=
0
#holds the total blockage time
self
.
totalFailureTime
=
0
#holds the total failure time
self
.
totalWaitingTime
=
0
#holds the total waiting time
self
.
totalWorkingTime
=
0
#holds the total working time
self
.
completedJobs
=
0
#holds the number of completed jobs
self
.
timeLastEntityEnded
=
0
#holds the last time that an entity ended processing in the object
self
.
nameLastEntityEnded
=
""
#holds the name of the last entity that ended processing in the object
self
.
timeLastEntityEntered
=
0
#holds the last time that an entity entered in the object
self
.
nameLastEntityEntered
=
""
#holds the name of the last entity that entered in the object
self
.
timeLastFailure
=
0
#holds the time that the last failure of the object started
self
.
timeLastFailureEnded
=
0
#holds the time that the last failure of the object Ended
self
.
downTimeProcessingCurrentEntity
=
0
#holds the time that the machine was down while processing the current entity
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
#holds the time that the object was down while trying
#to release the current entity
self
.
downTimeInCurrentEntity
=
0
#holds the total time that the object was down while holding current entity
self
.
timeLastEntityLeft
=
0
#holds the last time that an entity left the object
self
.
processingTimeOfCurrentEntity
=
0
#holds the total processing time that the current entity required
self
.
waitToDispose
=
False
#shows if the object waits to dispose an entity
#if the failure distribution for the object is fixed, activate the failure
#if the failure distribution for the object is fixed, activate the failure
if
(
self
.
failureDistType
==
"Fixed"
or
self
.
failureDistType
==
"Availability"
):
if
(
self
.
failureDistType
==
"Fixed"
or
self
.
failureDistType
==
"Availability"
):
MFailure
=
Failure
(
self
,
self
.
failureDistType
,
self
.
MTTF
,
self
.
MTTR
,
self
.
availability
,
self
.
id
,
self
.
repairman
)
MFailure
=
Failure
(
self
,
self
.
failureDistType
,
self
.
MTTF
,
self
.
MTTR
,
self
.
availability
,
self
.
id
,
self
.
repairman
)
activate
(
MFailure
,
MFailure
.
run
())
activate
(
MFailure
,
MFailure
.
run
())
# initialize the Queue (type Resource) of the Machine
self
.
Res
=
Resource
(
self
.
capacity
)
self
.
Res
=
Resource
(
self
.
capacity
)
self
.
predecessorIndex
=
0
#holds the index of the predecessor from which the Machine will take an entity next
# =======================================================================
self
.
successorIndex
=
0
#holds the index of the successor where the Machine will dispose an entity next
# the main process of the machine
# =======================================================================
#the main process of the machine
def
run
(
self
):
def
run
(
self
):
#execute all through simulation time
#execute all through simulation time
while
1
:
while
1
:
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
#wait until the machine can accept an entity
# wait until the machine can accept an entity and one predecessor requests it
#and one predecessor requests it
# canAcceptAndIsRequested is invoked to check when the machine requested to receive an entity
yield
waituntil
,
self
,
self
.
canAcceptAndIsRequested
self
.
getEntity
()
#get the entity from the predecessor
# get the entity from the predecessor
self
.
getEntity
()
# output to whenever an entity enters the Machine (self.objName)
self
.
outputTrace
(
"got into "
+
self
.
objName
)
self
.
outputTrace
(
"got into "
+
self
.
objName
)
self
.
currentEntity
=
self
.
getActiveObjectQueue
()[
0
]
#entity is the current entity processed in Machine
# set the currentEntity as the Entity just received and initialize the timer timeLastEntityEntered
self
.
currentEntity
=
self
.
getActiveObjectQueue
()[
0
]
# entity is the current entity processed in Machine
self
.
nameLastEntityEntered
=
self
.
currentEntity
.
name
# this holds the name of the last entity that got into Machine
self
.
timeLastEntityEntered
=
now
()
#this holds the last time that an entity got into Machine
self
.
timeLastEntityEntered
=
now
()
#this holds the last time that an entity got into Machine
self
.
nameLastEntityEntered
=
self
.
currentEntity
.
name
#this holds the name of the last entity that got into Machine
# variables dedicated to hold the processing times, the time when the Entity entered,
timeEntered
=
now
()
# and the processing time left
tinMStart
=
self
.
calculateProcessingTime
()
#get the processing time
timeEntered
=
now
()
# timeEntered dummy Timer that holds the time the last Entity Entered
tinM
=
tinMStart
tinMStart
=
self
.
calculateProcessingTime
()
# get the processing time, tinMStarts holds the processing time of the machine
self
.
processingTimeOfCurrentEntity
=
tinMStart
tinM
=
tinMStart
# timer to hold the processing time left
self
.
processingTimeOfCurrentEntity
=
tinMStart
# processing time of the machine
# variables used to flag any interruptions and the end of the processing
interruption
=
False
interruption
=
False
processingEndedFlag
=
True
processingEndedFlag
=
True
failureTime
=
0
# timers to follow up the failure time of the machine while on current Entity
self
.
downTimeInCurrentEntity
=
0
failureTime
=
0
# dummy variable keeping track of the failure time
# (why not avoid using it?)
#this loop is repeated until the processing time is expired with no failure
self
.
downTimeInCurrentEntity
=
0
#holds the total time that the
#object was down while holding current entity
# this loop is repeated until the processing time is expired with no failure
# check when the processingEndedFlag switched to false
while
processingEndedFlag
:
while
processingEndedFlag
:
# tBefore : dummy variable to keep track of the time that the processing starts after
# every interruption
tBefore
=
now
()
tBefore
=
now
()
yield
hold
,
self
,
tinM
#getting processed
# wait for the processing time left tinM, if no interruption occurs then change the
if
self
.
interrupted
():
#if a failure occurs while processing the machine is interrupted.
# processingEndedFlag and exit loop,
# else (if interrupted()) set interruption flag to true (only if tinM==0),
# and recalculate the processing time left tinM,
# passivate while waiting for repair.
yield
hold
,
self
,
tinM
# getting processed for remaining processing time tinM
if
self
.
interrupted
():
# if a failure occurs while processing the machine is interrupted.
# output to trace that the Machine (self.objName) got interrupted
self
.
outputTrace
(
"Interrupted at "
+
self
.
objName
)
self
.
outputTrace
(
"Interrupted at "
+
self
.
objName
)
# recalculate the processing time left tinM
tinM
=
tinM
-
(
now
()
-
tBefore
)
#the processing time left
tinM
=
tinM
-
(
now
()
-
tBefore
)
if
(
tinM
==
0
):
#sometimes the failure may happen exactly at the time that the processing would finish
if
(
tinM
==
0
):
# sometimes the failure may happen exactly at the time that the processing would finish
#this may produce ina ccordance to the simul8 because in both SimPy and Simul8
# this may produce disagreement with the simul8 because in both SimPy and Simul8
#it seems to be random which happens 1st
# it seems to be random which happens 1st
#this should not appear often to stochastic models though where times are random
# this should not appear often to stochastic models though where times are random
interruption
=
True
interruption
=
True
# passivate the Machine for as long as there is no repair
breakTime
=
now
()
# start counting the down time at breatTime dummy variable
yield
passivate
,
self
#if there is a failure in the machine it is passivated
breakTime
=
now
()
# dummy variable that the interruption happened
self
.
downTimeProcessingCurrentEntity
+=
now
()
-
breakTime
yield
passivate
,
self
# if there is a failure in the machine it is passivated
self
.
downTimeInCurrentEntity
+=
now
()
-
breakTime
# use the timers to count the time that Machine is down and related
self
.
timeLastFailureEnded
=
now
()
self
.
downTimeProcessingCurrentEntity
+=
now
()
-
breakTime
# count the time that Machine is down while processing this Entity
failureTime
+=
now
()
-
breakTime
self
.
downTimeInCurrentEntity
+=
now
()
-
breakTime
# count the time that Machine is down while on currentEntity
self
.
timeLastFailureEnded
=
now
()
# set the timeLastFailureEnded
failureTime
+=
now
()
-
breakTime
# dummy variable keeping track of the failure time
# output to trace that the Machine self.objName was passivated for the current failure time
self
.
outputTrace
(
"passivated in "
+
self
.
objName
+
" for "
+
str
(
now
()
-
breakTime
))
self
.
outputTrace
(
"passivated in "
+
self
.
objName
+
" for "
+
str
(
now
()
-
breakTime
))
# if no interruption occurred the processing in M1 is ended
else
:
else
:
processingEndedFlag
=
False
#if no interruption occurred the processing in M1 is ended
processingEndedFlag
=
False
# output to trace that the processing in the Machine self.objName ended
self
.
outputTrace
(
"ended processing in "
+
self
.
objName
)
self
.
outputTrace
(
"ended processing in "
+
self
.
objName
)
# set the variable that flags an Entity is ready to be disposed
self
.
waitToDispose
=
True
self
.
waitToDispose
=
True
self
.
totalWorkingTime
+=
tinMStart
#the total processing time for this entity is what the distribution initially gave
# update the total working time
self
.
timeLastEntityEnded
=
now
()
#this holds the last time that an entity ended processing in Machine
self
.
totalWorkingTime
+=
tinMStart
# the total processing time for this entity
self
.
nameLastEntityEnded
=
self
.
currentEntity
.
name
#this holds the name of the last entity that ended processing in Machine
# is what the distribution initially gave
self
.
completedJobs
+=
1
#Machine completed one more Job
# update the variables keeping track of Entity related attributes of the machine
self
.
timeLastEntityEnded
=
now
()
# this holds the time that the last entity ended processing in Machine
self
.
nameLastEntityEnded
=
self
.
currentEntity
.
name
# this holds the name of the last entity that ended processing in Machine
self
.
completedJobs
+=
1
# Machine completed one more Job
# re-initialize the downTimeProcessingCurrentEntity.
# a new machine is about to enter
self
.
downTimeProcessingCurrentEntity
=
0
self
.
downTimeProcessingCurrentEntity
=
0
reqTime
=
now
()
#entity has ended processing in Machine and requests for the next object
# dummy variable requests the successor object now
reqTime
=
now
()
# entity has ended processing in Machine and requests for the next object
# initialize the timer downTimeInTryingToReleaseCurrentEntity, we have to count how much time
# the Entity will wait for the next successor to be able to accept (canAccept)
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
self
.
downTimeInTryingToReleaseCurrentEntity
=
0
notBlockageTime
=
0
while
1
:
while
1
:
yield
waituntil
,
self
,
self
.
ifCanDisposeOrHaveFailure
#wait until the next Object #is available or machine has failure
# wait until the next Object is available or machine has failure
yield
waituntil
,
self
,
self
.
ifCanDisposeOrHaveFailure
if
self
.
Up
:
#if Next object available break
# if Next object available break
if
self
.
Up
:
break
break
else
:
#if M1 had failure, we want to wait until it is fixed and also count the failure time.
# if M1 had failure, we want to wait until it is fixed and also count the failure time.
failTime
=
now
()
else
:
failTime
=
now
()
# dummy variable holding the time failure happened
# passivate until machine is up
yield
waituntil
,
self
,
self
.
checkIfMachineIsUp
yield
waituntil
,
self
,
self
.
checkIfMachineIsUp
failureTime
+=
now
()
-
failTime
failureTime
+=
now
()
-
failTime
# count the failure while on current entity time with failureTime variable
# calculate the time the Machine was down while trying to dispose the current Entity,
# and the total down time while on current Entity
self
.
downTimeInTryingToReleaseCurrentEntity
+=
now
()
-
failTime
self
.
downTimeInTryingToReleaseCurrentEntity
+=
now
()
-
failTime
self
.
downTimeInCurrentEntity
+=
now
()
-
failTime
self
.
downTimeInCurrentEntity
+=
now
()
-
failTime
# already updated from failures during processing
# update the timeLastFailureEnded
self
.
timeLastFailureEnded
=
now
()
self
.
timeLastFailureEnded
=
now
()
totalTime
=
now
()
-
timeEntered
totalTime
=
now
()
-
timeEntered
# dummy variable holding the total time the Entity spent in the Machine
blockageTime
=
totalTime
-
(
tinMStart
+
failureTime
)
blockageTime
=
totalTime
-
(
tinMStart
+
failureTime
)
# count the time the Machine was blocked subtracting the failureTime
# and the processing time from the totalTime spent in the Machine
# ??? is the next equivalent to:
# self.totalBlockageTime+=blockageTime
self
.
totalBlockageTime
+=
totalTime
-
(
tinMStart
+
failureTime
)
#the time of blockage is derived from
self
.
totalBlockageTime
+=
totalTime
-
(
tinMStart
+
failureTime
)
#the time of blockage is derived from
#the whole time in the machine
#the whole time in the machine
#minus the processing time and the failure time
#minus the processing time and the failure time
#checks if the machine is Up
# =======================================================================
# checks if the machine is Up
# =======================================================================
def
checkIfMachineIsUp
(
self
):
def
checkIfMachineIsUp
(
self
):
return
self
.
Up
return
self
.
Up
#calculates the processing time
# =======================================================================
# calculates the processing time
# =======================================================================
def
calculateProcessingTime
(
self
):
def
calculateProcessingTime
(
self
):
return
self
.
rng
.
generateNumber
()
#
this is if we have a default processing time for all the entities
return
self
.
rng
.
generateNumber
()
#
this is if we have a default processing time for all the entities
#checks if the Machine can accept an entity
# =======================================================================
#it checks also who called it and returns TRUE only to the predecessor that will give the entity.
# checks if the Machine can accept an entity
# it checks also who called it and returns TRUE only to the predecessor
# that will give the entity.
# =======================================================================
def
canAccept
(
self
,
callerObject
=
None
):
def
canAccept
(
self
,
callerObject
=
None
):
# get active and giver objects
activeObject
=
self
.
getActiveObject
()
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
giverObject
=
self
.
getGiverObject
()
giverObject
=
self
.
getGiverObject
()
#if we have only one predecessor just check if there is a place and the machine is up
# if we have only one predecessor just check if there is a place and the machine is up
# this is done to achieve better (cpu) processing time
if
(
len
(
activeObject
.
previous
)
==
1
or
callerObject
==
None
):
if
(
len
(
activeObject
.
previous
)
==
1
or
callerObject
==
None
):
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
==
0
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
==
0
#
if the machine is busy return False immediately
# #
if the machine is busy return False immediately
if
len
(
activeObjectQueue
)
==
activeObject
.
capacity
:
#
if len(activeObjectQueue)==activeObject.capacity:
return
False
#
return False
thecaller
=
callerObject
thecaller
=
callerObject
# return True ONLY if the length of the activeOjbectQue is smaller than
return
len
(
activeObjectQueue
)
<
self
.
capacity
and
(
thecaller
is
giverObject
)
# the object capacity, and the callerObject is not None but the giverObject
return
len
(
activeObjectQueue
)
<
activeObject
.
capacity
and
(
thecaller
is
giverObject
)
#checks if the Machine can accept an entity and there is an entity in some predecessor waiting for it
#also updates the predecessorIndex to the one that is to be taken
# =======================================================================
# checks if the Machine can accept an entity and there is an entity in
# some predecessor waiting for it
# also updates the predecessorIndex to the one that is to be taken
# =======================================================================
def
canAcceptAndIsRequested
(
self
):
def
canAcceptAndIsRequested
(
self
):
# get active and giver objects
activeObject
=
self
.
getActiveObject
()
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
giverObject
=
self
.
getGiverObject
()
giverObject
=
self
.
getGiverObject
()
#if we have only one predecessor just check if there is a place, the machine is up and the predecessor has an entity to dispose
# if we have only one predecessor just check if there is a place,
# the machine is up and the predecessor has an entity to dispose
# this is done to achieve better (cpu) processing time
if
(
len
(
activeObject
.
previous
)
==
1
):
if
(
len
(
activeObject
.
previous
)
==
1
):
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
and
giverObject
.
haveToDispose
(
activeObject
)
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
\
and
giverObject
.
haveToDispose
(
activeObject
)
isRequested
=
False
# dummy variables that help prioritize the objects requesting to give objects to the Machine (activeObject)
maxTimeWaiting
=
0
isRequested
=
False
# is requested is dummyVariable checking if it is requested to accept an item
maxTimeWaiting
=
0
# dummy variable counting the time a predecessor is blocked
#loop through the predecessors to see which have to dispose and which is the one blocked for longer
#
loop through the predecessors to see which have to dispose and which is the one blocked for longer
i
=
0
i
=
0
# index used to set the predecessorIndex to the giver waiting the most
for
object
in
activeObject
.
previous
:
for
object
in
activeObject
.
previous
:
if
(
object
.
haveToDispose
(
activeObject
)):
if
(
object
.
haveToDispose
(
activeObject
)):
isRequested
=
True
isRequested
=
True
# if the predecessor objects have entities to dispose of
if
(
object
.
downTimeInTryingToReleaseCurrentEntity
>
0
):
if
(
object
.
downTimeInTryingToReleaseCurrentEntity
>
0
):
# and the predecessor has been down while trying to give away the Entity
timeWaiting
=
now
()
-
object
.
timeLastFailureEnded
timeWaiting
=
now
()
-
object
.
timeLastFailureEnded
# the timeWaiting dummy variable counts the time end of the last failure of the giver object
else
:
else
:
timeWaiting
=
now
()
-
object
.
timeLastEntityEnded
timeWaiting
=
now
()
-
object
.
timeLastEntityEnded
# in any other case, it holds the time since the end of the Entity processing
#if more than one predecessor have to dispose take the part from the one that is blocked longer
#if more than one predecessor have to dispose take the part from the one that is blocked longer
if
(
timeWaiting
>=
maxTimeWaiting
):
if
(
timeWaiting
>=
maxTimeWaiting
):
activeObject
.
predecessorIndex
=
i
activeObject
.
predecessorIndex
=
i
# the object to deliver the Entity to the activeObject is set to the ith member of the previous list
maxTimeWaiting
=
timeWaiting
maxTimeWaiting
=
timeWaiting
i
+=
1
i
+=
1
# in the next loops, check the other predecessors in the previous list
return
len
(
activeObjectQueue
)
<
activeObject
.
capacity
and
isRequested
and
activeObject
.
Up
return
activeObject
.
Up
and
len
(
activeObjectQueue
)
<
activeObject
.
capacity
and
isRequested
#checks if the machine down or it can dispose the object
# =======================================================================
# checks if the machine down or it can dispose the object
# =======================================================================
def
ifCanDisposeOrHaveFailure
(
self
):
def
ifCanDisposeOrHaveFailure
(
self
):
return
self
.
Up
==
False
or
self
.
next
[
0
].
canAccept
(
self
)
or
len
(
self
.
Res
.
activeQ
)
==
0
#the last part is added so that it is not removed and stack
# the last part is added so that it is not removed and stack gotta think of it again ??????????
#gotta think of it again
return
self
.
Up
==
False
or
self
.
next
[
0
].
canAccept
(
self
)
or
len
(
self
.
Res
.
activeQ
)
==
0
#removes an entity from the Machine
# =======================================================================
# removes an entity from the Machine
# =======================================================================
def
removeEntity
(
self
):
def
removeEntity
(
self
):
# get active and its queue
activeObject
=
self
.
getActiveObject
()
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObject
.
timeLastEntityLeft
=
now
()
activeObject
.
timeLastEntityLeft
=
now
()
# set the time that the last Entity was removed from this object
activeObject
.
outputTrace
(
"releases "
+
activeObject
.
objName
)
activeObject
.
outputTrace
(
"releases "
+
activeObject
.
objName
)
# output to trace that the Entity was released from the currentObject
activeObject
.
waitToDispose
=
False
activeObject
.
waitToDispose
=
False
# update the waitToDispose flag
activeObjectQueue
.
pop
(
0
)
#
remove the Entity from the activeQ
activeObjectQueue
.
pop
(
0
)
#
remove the Entity from the activeQ
activeObject
.
downTimeInTryingToReleaseCurrentEntity
=
0
activeObject
.
downTimeInTryingToReleaseCurrentEntity
=
0
# re-initialize the timer downTimeInTryingToReleaseCurrentEntity
# =======================================================================
#checks if the Machine can dispose an entity to the following object
# checks if the Machine can dispose an entity to the following object
# =======================================================================
def
haveToDispose
(
self
,
callerObject
=
None
):
def
haveToDispose
(
self
,
callerObject
=
None
):
# get active and the receiver object
activeObject
=
self
.
getActiveObject
()
activeObject
=
self
.
getActiveObject
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
activeObjectQueue
=
self
.
getActiveObjectQueue
()
receiverObject
=
activeObject
.
getReceiverObject
()
#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
if
(
len
(
activeObject
.
next
)
==
1
or
callerObject
==
None
):
if
(
len
(
activeObject
.
next
)
==
1
or
callerObject
==
None
):
return
len
(
activeObjectQueue
)
>
0
and
activeObject
.
waitToDispose
and
activeObject
.
Up
return
len
(
activeObjectQueue
)
>
0
and
activeObject
.
waitToDispose
and
activeObject
.
Up
#
if the Machine is empty it returns false right away
# #
if the Machine is empty it returns false right away
if
(
len
(
activeObjectQueue
)
==
0
):
#
if(len(activeObjectQueue)==0):
return
False
#
return False
thecaller
=
callerObject
thecaller
=
callerObject
# give the entity to the successor that is waiting for the most time.
#give the entity to the successor that is waiting for the most time.
# (plant simulation does not do this in every occasion!)
#(plant simulation does not do this in every occasion!)
maxTimeWaiting
=
0
# dummy variable counting the time a successor is waiting
maxTimeWaiting
=
0
i
=
0
# index used to set the successorIndex to the giver waiting the most
i
=
0
for
object
in
activeObject
.
next
:
for
object
in
activeObject
.
next
:
if
(
object
.
canAccept
(
activeObject
)):
if
(
object
.
canAccept
(
activeObject
)):
# if a successor can accept an object
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
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
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
# if the timeWaiting is the maximum among the ones of the successors
maxTimeWaiting
=
timeWaiting
maxTimeWaiting
=
timeWaiting
activeObject
.
successorIndex
=
i
activeObject
.
successorIndex
=
i
# set the successorIndex equal to the index of the longest waiting successor
i
+=
1
i
+=
1
# in the next loops, check the other successors in the previous list
return
len
(
activeObjectQueue
)
>
0
and
activeObject
.
waitToDispose
\
receiverObject
=
activeObject
.
getReceiverObject
()
and
activeObject
.
Up
and
(
thecaller
is
receiverObject
)
return
len
(
activeObjectQueue
)
>
0
and
activeObject
.
waitToDispose
and
activeObject
.
Up
and
(
thecaller
is
receiverObject
)
# =======================================================================
# 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
...
@@ -352,7 +399,10 @@ class Machine(CoreObject):
...
@@ -352,7 +399,10 @@ class Machine(CoreObject):
activeObject
.
Waiting
.
append
(
100
*
self
.
totalWaitingTime
/
MaxSimtime
)
activeObject
.
Waiting
.
append
(
100
*
self
.
totalWaitingTime
/
MaxSimtime
)
activeObject
.
Working
.
append
(
100
*
self
.
totalWorkingTime
/
MaxSimtime
)
activeObject
.
Working
.
append
(
100
*
self
.
totalWorkingTime
/
MaxSimtime
)
#outputs message to the trace.xls. Format is (Simulation Time | Entity Name | message)
# =======================================================================
# outputs message to the trace.xls.
# Format is (Simulation Time | Entity Name | message)
# =======================================================================
def
outputTrace
(
self
,
message
):
def
outputTrace
(
self
,
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
...
@@ -368,7 +418,9 @@ class Machine(CoreObject):
...
@@ -368,7 +418,9 @@ class Machine(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 the the "output.xls"
# =======================================================================
# outputs the the "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
:
...
@@ -438,7 +490,9 @@ class Machine(CoreObject):
...
@@ -438,7 +490,9 @@ class Machine(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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment