I want to implement a discrete-event maintenance scheduling simulation in which some maintenance activities must happen whenever another one happens.
For example, if walls are repainted every 5 years, and dry-lining is replaced every 14 years, then walls must be repainted whenever the dry-lining is replaced and the clock restarted.
yr 5: paint walls
yr 10: paint walls
yr 14: replace dry-lining
yr 14: paint walls
yr 19: paint walls
...
I'm not sure whether I should implement each activity as a process which refers to the dependent process, or if "wall maintenance" should be a process with the logic handled internally, or some other way of.
The code I have has each activity as a process with the dependent process stored as an attribute but I feel like I'm probably missing the correct way of doing this as I'm seeing events happen twice in the same year.
This is the approach I took in the end:
import simpy
from simpy.events import Interrupt
class Construction(object):
def __init__(self, name, components):
self.name = name
self.components = components
self.link_components()
def link_components(self):
"""Link each component to the next outermost component
"""
for i, component in enumerate(self.components):
try:
component.dependent = self.components[i+1]
except IndexError:
component.dependent = None
class Component(object):
def __init__(self, env, name, lifespan):
"""Represents a component used in a construction.
"""
self.env = env
self.name = name
self.lifespan = lifespan
self.action = env.process(self.run())
def run(self):
while True:
try:
yield self.env.timeout(self.lifespan)
self.replace()
except Interrupt: # don't replace
pass
def replace(self):
print "yr %d: replace %s" % (env.now, self.name)
if self.dependent:
self.dependent.action.interrupt() # stop the dependent process
self.dependent.replace() # replace the dependent component
env = simpy.Environment()
components = [Component(env, 'structure', 60),
Component(env, 'dry-lining', 14),
Component(env, 'paint', 5)]
wall = Construction('wall', components)
env.run(until=65)