4. Equipment Maintenance Scheduling
4.1. Overview
This tutorial demonstrates how to model equipment maintenance and repairs in a project simulation. We’ll explore how preventive maintenance affects productivity and how to use priority-based resource allocation to ensure repairs take precedence over regular operations.
This walkthrough mirrors the runnable example in example/repair earthmoving.py
and shows how to implement realistic maintenance scheduling in discrete-event simulations.
The example includes an interactive dashboard for real-time visualization of the equipment maintenance and truck operations throughout the simulation.
4.2. Scenario
Model an earthmoving operation with preventive maintenance:
Two trucks (small and large) with different loading and hauling times.
A single loader shared between both trucks (the equipment requiring maintenance).
A repair person who monitors loader usage and performs preventive maintenance.
Priority-based scheduling: Repairs interrupt loading operations to ensure equipment reliability.
Dashboard visualization: Interactive dashboard showing real-time system dynamics.
4.2.1. Key Concepts
Worked Hours Tracking: The loader accumulates working hours that trigger maintenance when a threshold (10 hours) is reached.
Priority Resource: Uses
PriorityResourceto give repair requests higher priority than normal loading requests.Preventive Maintenance: Repairs are scheduled based on usage, not failures, preventing unexpected equipment breakdowns.
4.3. Full Example (from the examples folder)
"""
Earthmoving Operation with Equipment Repair Simulation
This simulation models an earthmoving project with equipment maintenance:
- 2 trucks (small and large) that load, haul, and dump dirt
- 1 loader shared between both trucks
- 1 repair person who services the loader based on usage hours
- Goal: Analyze impact of maintenance on project productivity
"""
import simpm
import simpm.des as d
import simpm.dist as dist
def truck_process(truck, loader, dumped_dirt, worked_hours):
"""
Truck operation cycle process.
Simulates the complete cycle of a truck in the earthmoving operation:
- Wait for loader availability
- Get loaded with dirt
- Haul to dump site
- Dump the load
- Return to pit for next load
"""
while True:
# LOADING PHASE: Wait for loader with normal priority (priority=2)
# Lower priority than repair (priority=-3) means trucks wait for repairs
yield truck.get(loader, 1, 2)
yield truck.do('load', truck.loading_dur)
# Track hours worked on the loader (for triggering repairs)
yield truck.add(worked_hours, truck.loading_dur)
# Release loader for other trucks or repair person
yield truck.put(loader, 1)
# HAULING PHASE: Transport loaded dirt to dump site
yield truck.do('haul', truck.hauling_dur)
# DUMPING PHASE: Unload dirt at dump site
yield truck.do('dump', truck.dumping_dur)
yield truck.add(dumped_dirt, truck.capacity)
# RETURN PHASE: Return to pit for next load
yield truck.do('return', 8)
def repair_process(repair_man, loader, worked_hours):
"""
Equipment repair process.
Simulates the repair person monitoring loader usage and performing
maintenance. When the loader reaches 10 accumulated working hours,
the repair person steps in with high priority to perform a 10-minute
repair, resetting the working hours counter.
"""
while True:
# Wait until 10 hours of work have been accumulated on the loader
yield repair_man.get(worked_hours, 10)
# Get the loader with HIGH PRIORITY (-3) to interrupt trucks
# Negative priority ensures repair takes precedence over normal loading
yield repair_man.get(loader, 1, -3)
# Perform the repair (10 minutes)
yield repair_man.do('repair', 10)
# Release the loader back to trucks
yield repair_man.put(loader, 1)
# Create the discrete event simulation environment
env = d.Environment()
# Create the PRIORITY LOADER resource
# PriorityResource allows requests with different priorities
loader = d.PriorityResource(env, 'loader', init=1, print_actions=False)
# Create counter for total dumped dirt
dumped_dirt = d.Resource(env, 'dirt', init=0, capacity=2000, print_actions=False)
# Create counter for loader working hours (triggers repairs when hits 10)
worked_hours = d.Resource(env, 'worked_hours', init=0, capacity=2000, print_actions=False)
# Create small truck entity with specific parameters
small_truck = d.Entity(env, 'small_truck', print_actions=False)
small_truck.loading_dur = dist.uniform(4, 5) # 4-5 minutes
small_truck.hauling_dur = dist.uniform(10, 14) # 10-14 minutes
small_truck.dumping_dur = 4 # 4 minutes
small_truck.capacity = 80 # 80 units per load
# Create large truck entity with specific parameters
large_truck = d.Entity(env, 'large_truck', print_actions=False)
large_truck.loading_dur = dist.uniform(4, 7) # 4-7 minutes
large_truck.hauling_dur = dist.uniform(12, 16) # 12-16 minutes
large_truck.dumping_dur = 5 # 5 minutes
large_truck.capacity = 100 # 100 units per load
# Create repair person entity
repair_man = d.Entity(env, 'repair_person', print_actions=False)
# Start truck processes for both small and large trucks
env.process(truck_process(small_truck, loader, dumped_dirt, worked_hours))
env.process(truck_process(large_truck, loader, dumped_dirt, worked_hours))
# Start repair process
env.process(repair_process(repair_man, loader, worked_hours))
# Run the simulation
simpm.run(env, dashboard=False)
# Print results
print(f"Simulation completed at t = {env.now:.2f} minutes")
print(f"Total dirt dumped: {dumped_dirt.level():.0f} units")
4.4. How It Works
1. Priority-Based Resource Allocation
The simulation uses PriorityResource instead of a regular Resource. This allows
multiple requests to be prioritized:
# Truck request (normal priority = 2)
yield truck.get(loader, 1, 2)
# Repair request (high priority = -3, more negative = higher priority)
yield repair_man.get(loader, 1, -3)
When the repair person requests the loader, they jump ahead of waiting trucks because their priority is higher (more negative).
2. Worked Hours Tracking
Every time a truck uses the loader, the working hours counter is incremented:
# Truck adds its loading duration to worked_hours
yield truck.add(worked_hours, truck.loading_dur)
The repair person monitors this counter and triggers maintenance when it reaches 10 hours:
# Repair triggered when worked_hours reaches 10
yield repair_man.get(worked_hours, 10)
3. Maintenance Process Flow
The repair process follows this cycle:
Wait for accumulation of 10 working hours
Request the loader with high priority
Perform 10-minute repair
Release the loader
Repeat
This simulates preventive maintenance that occurs regularly based on equipment usage.
4.5. Simulation Results
Running the simulation produces the following results:
======================================================================
EARTHMOVING PROJECT WITH REPAIRS - SIMULATION RESULTS
======================================================================
Simulation completed at t = 381.16 minutes
Approximately 6.35 hours
Total dirt dumped: 1960 units
Small Truck Statistics:
Total cycles completed: 51
Total dirt moved: 4080 units
Large Truck Statistics:
Total cycles completed: 43
Total dirt moved: 4300 units
Loader Queue Statistics:
Total requests: 34
Average wait time: 1.64 minutes
Maximum wait time: 7.57 minutes
Repair Statistics:
Total repairs performed: 10
Repair interval: Every 10 worked hours on loader
Repair time per service: 10 minutes
Sample repair schedule (first 5 repairs):
activity start_time finish_time
0 repair 33.360599 43.360599
1 repair 62.597502 72.597502
2 repair 118.888247 128.888247
3 repair 151.047873 161.047873
4 repair 182.777400 192.777400
Key Insights:
Project Duration: Approximately 6.35 hours to move 1,960 units of dirt with preventive maintenance.
Truck Efficiency: Small truck completes 51 cycles (4,080 units), large truck completes 43 cycles (4,300 units).
Maintenance Frequency: 10 repairs performed during the simulation, roughly one every 38 minutes of simulation time.
Queue Impact: Average wait time is only 1.64 minutes because repairs are scheduled regularly, preventing excessive queueing.
System Reliability: Regular maintenance prevents equipment failure and keeps the system running smoothly.
4.5.1. Comparison with No-Maintenance Scenario
Without preventive maintenance:
Trucks would run continuously without interruptions
Loader might fail or degrade unexpectedly
No scheduled downtime (but potential emergency breakdowns)
Short-term productivity higher, but long-term reliability lower
With preventive maintenance (this example):
Regular maintenance windows interrupt operations
Equipment reliability guaranteed through preventive care
Predictable downtime allows for planning
Longer project duration but more stable operations
4.6. Advanced Topics
1. Variable Repair Times
You can model different repair types with varying durations:
def repair_process_advanced(repair_man, loader, worked_hours):
"""Repair with variable duration based on equipment condition."""
while True:
yield repair_man.get(worked_hours, 10)
yield repair_man.get(loader, 1, -3)
# Different repair times based on hours accumulated
repair_duration = dist.uniform(8, 12) # 8-12 minutes
yield repair_man.do('repair', repair_duration)
yield repair_man.put(loader, 1)
2. Multiple Repair Persons
For complex equipment, add multiple repair specialists:
# Create 2 repair persons
repair_persons = env.create_entities("repair_person", 2)
for repair_person in repair_persons:
env.process(repair_process(repair_person, loader, worked_hours))
3. Stochastic Failures
Model unexpected equipment failures in addition to scheduled maintenance:
# Add emergency repair triggers for unexpected failures
def failure_process(repair_man, loader):
while True:
# Failure occurs randomly (e.g., exponential distribution)
yield repair_man.do('wait', dist.exponential(100))
# Emergency repair with highest priority
yield repair_man.get(loader, 1, -10) # Higher priority than scheduled repairs
yield repair_man.do('emergency_repair', 20) # Takes longer
yield repair_man.put(loader, 1)
4.7. Try It Yourself
Run the shipped example directly:
python example/repair earthmoving.py
The script includes:
Comprehensive docstrings for each process function
Detailed comments explaining priority levels and maintenance logic
Complete results reporting with truck and repair statistics
Sample schedules showing actual execution timeline
Performance metrics including wait times and repair frequency
Interactive Dashboard: Real-time visualization of equipment maintenance and truck operations (automatically opens in browser)
Expected Output:
The simulation will display:
Total simulation time in minutes and hours
Dirt moved by each truck and combined totals
Loader queue statistics (wait times, request counts)
Repair count and timing information
Sample activity schedules for trucks and repair person
Dashboard visualization showing:
Timeline of all activities (loading, hauling, dumping, repairs)
Truck cycles and how repairs interrupt operations
Resource utilization over time
Queue formation and resolution patterns
Entity status indicators (busy, waiting, idle)
4.7.1. Dashboard Features
When you run the simulation, the interactive dashboard displays:
Activity Timeline: Visual representation of each entity’s actions
Resource States: Real-time display of loader utilization and queue status
Statistics: Charts and graphs of waiting times, utilization rates, and throughput
Entity Details: Drill-down into individual truck and repair person schedules
Performance Metrics: Summary statistics for the entire simulation
The dashboard opens automatically in your default browser at http://127.0.0.1:8050.
4.7.2. Explore Further
To deepen your understanding:
Change the repair threshold: Modify the worked hours requirement from 10 to 5 or 15 to see how it affects productivity and repair frequency
Add more trucks: Increase fleet size to 3-5 trucks and observe how queueing patterns change
Variable truck types: Create additional truck types with different characteristics (capacity, speed, etc.)
Maintenance duration: Change repair time from 10 to 15 or 20 minutes and analyze the impact
Cost analysis: Add cost tracking for repairs vs. productivity loss
Sensitivity analysis: Systematically test different parameters using the dashboard to visualize impacts
Compare scenarios: Run without maintenance vs. with maintenance and compare dashboard results
This example demonstrates how SimPM can model realistic operational constraints like equipment maintenance and how the interactive dashboard provides insights into system dynamics, which is crucial for accurate project planning and resource management.