Cost Optimization and ROI for Utility ML Projects
What You’ll Learn
By the end of this chapter, you will understand how ROI works in the context of utility machine learning projects. You’ll learn to calculate costs across the full ML lifecycle, from development through deployment and maintenance. You’ll see how to quantify value from efficiency gains, risk reduction, and operational improvements. You’ll master financial metrics like NPV, IRR, and payback period for ML investments, and you’ll build business cases that justify ML initiatives to stakeholders. Finally, you’ll recognize common pitfalls that undermine ROI and learn how to avoid them.
The Business Problem: Justifying ML Investments in a Regulated Industry
Utilities operate in a unique environment: long planning horizons, regulated investments, and complex stakeholder relationships. When proposing machine learning initiatives, data science teams face a critical challenge: how do we prove that ML creates value? Business leaders, regulators, and boards need clear financial justification. Yet ML projects often involve long development cycles, probabilistic outcomes, and value that may be indirect or delayed.
I learned this the hard way. I did a project for the ExxonMobil board of directors trying to forecast corporate earnings given different situations like oil price changes. What would that do to ExxonMobil’s stock price? I got this wrong—I don’t know if you saw the stock price, but it’s not doing well right now. At the time, I was using regressions to try and forecast corporate earnings, and I needed to use upper and lower bounds to give a sense of the uncertainty. Corporate earnings could be five billion, but that could be as low as 3.5 billion or as high as eight billion. That’s using these upper and lower bounds to get a sense of what the actual earnings could be. Well, you know you’re precise when you’re talking about between eight and 3 billion—very, very close. The point is, I had the technical model right, but I didn’t frame the uncertainty in a way that helped decision-making. The model worked, but the ROI story didn’t.
Consider a predictive maintenance project. The model might reduce unplanned outages by 15 percent, but quantifying the value requires understanding the cost of each outage hour, the avoided capital spending from extended asset life, and the regulatory penalties avoided. These benefits accrue over years, not months. Meanwhile, costs include not just model development, but also data infrastructure, monitoring, retraining, and integration with operational systems.
Many utilities pursue ML without a clear plan for measuring impact. Projects get stuck in “pilot purgatory”—technically sound but unable to demonstrate value. Others deliver real gains but fail to track them, leaving stakeholders uncertain about whether to scale or invest further. I’ve seen this pattern over and over: the model works, but nobody can prove it.
The Analytics Solution: Structured ROI Measurement
Return on Investment (ROI) measurement for utility ML requires going beyond traditional financial accounting. You need frameworks that connect model performance to business outcomes, account for the full lifecycle of ML projects, and handle the uncertainty inherent in probabilistic systems.
This chapter introduces a structured approach to ROI measurement aligned with the CPMAI (Cognitive Project Management for AI) framework. CPMAI provides six phases for managing analytics initiatives, each offering natural checkpoints to plan, monitor, and reevaluate ROI. By aligning financial thinking with project structure, you avoid the trap of trying to justify ROI only after deployment.
The approach rests on several key principles. Start with business value, not technology. Define success in operational terms like hours saved, dollars avoided, or reliability improved. Account for full lifecycle costs, including development, deployment, monitoring, retraining, and decommissioning. Measure continuously, tracking ROI at each project phase rather than waiting until the end. And translate technical metrics to business outcomes, recognizing that model accuracy matters only if it changes decisions and improves operations.
Here’s what I’ve learned: ROI isn’t a final report you write at the end. It’s a design discipline you apply throughout the project. If you wait until deployment to figure out if the project was worth it, you’re too late.
Understanding ROI in the Context of Utility AI
Return on Investment (ROI) traditionally compares the net financial benefit of a project to its cost. You subtract the cost from the benefit, divide by the cost, and express it as a percentage. For most capital projects, that’s enough. For AI in utilities, it isn’t.
Utility ML projects incur different kinds of costs and yield different types of value. Some benefits are direct and measurable, like reducing unplanned transformer failures by 20 percent. Others are indirect, like making dispatch decisions faster or catching voltage excursions earlier. You may need to project value over time and account for risks, adoption hurdles, and delays in impact.
AI costs fall into several categories. Data costs include acquiring, cleaning, storing, and annotating data such as SCADA historical data, maintenance logs, and weather feeds. Infrastructure costs cover GPUs for training, cloud compute, MLOps tooling, and data storage. Talent costs encompass data scientists, ML engineers, domain experts, and change management specialists. Process costs include compliance reviews, regulatory documentation, change management, and retraining cycles. Integration costs involve APIs, ETL pipelines, SCADA integration, and dashboard development.
You must include the full lifecycle—not just model development, but also monitoring, retraining, and decommissioning. A model deployed in six months may cost more in maintenance over three years than in initial development.
Value comes in four forms for utilities. Efficiency gains include automation like automated inspection analysis, faster processing such as real-time outage prediction, and fewer errors like reduced manual data entry. Operational improvements encompass reduced O&M costs from predictive maintenance, deferred capital spending from extended asset life, and improved resource utilization through optimized crew dispatch. Risk reduction includes outage avoidance, regulatory compliance such as meeting SAIDI/SAIFI targets, and safety improvements like early fire detection. Revenue opportunities involve better market participation through improved load forecasting, new services like customer analytics, and demand response optimization.
These must be translated into measurable outcomes. Instead of “better forecasting,” aim for “15 percent more accurate day-ahead forecasts that reduce imbalance costs by $500K annually.”
I’ve seen utilities quantify ROI in different ways. Alabama Power’s SPEAR system can predict storm impact within a 10% margin of error. For a 10-day storm with 500 customer outages, improving from 20% to 10% margin of error saves about $2.8M per storm event. That’s direct cost savings. Their RAMP system enables real-time monitoring of assets, and with 70,000 annual outages, even a targeted 5% reduction could save $17.5M in crew costs alone. Customer outage history retrieval went from four hours to four seconds—that’s a 3600X efficiency gain. Those are the kinds of numbers that get executive attention.
Pipeline predictive maintenance shows another ROI pattern. According to industry data, unplanned pipeline downtime can cost around $5 million per incident. I’ve seen companies report $36 million a year due to unplanned downtime. According to the US Department of Energy, predictive maintenance saves roughly 8 to 12% of operational costs when compared against preventative maintenance. That’s avoided downtime costs.
Time-to-value ROI is another dimension. A production engineer analyzing 200 wells, understanding decline curves, and recommending actions before a production meeting might traditionally take days waiting for data science support, with multiple handoffs and uncertain results. With AI agents, that workflow provides analysis in minutes, reliable and reproducible methodology, scalable across business units. That’s transforming a multi-day process into minutes.
These examples show different ROI dimensions: direct cost savings, operational efficiency, avoided downtime costs, and time-to-insight acceleration. Each demonstrates how utilities can quantify value when they align technical capabilities with business outcomes.
CPMAI Phases and ROI Alignment
The CPMAI framework breaks AI and analytics projects into six structured phases. Each phase offers a natural point to plan, monitor, or reevaluate ROI. By aligning financial thinking with project structure, you avoid the trap of trying to justify ROI only after the fact.
Phase I focuses on business understanding and ROI definition. This is where ROI starts—not with models, but with business needs. In Phase I, you define the business objective in clear, quantifiable terms. What is the problem? What decisions will the AI model support? What outcomes will change, and how will we measure them?
For utilities, this might mean reducing unplanned transformer failures by 20 percent, saving $2M annually in avoided outages and deferred replacements. Or it might mean improving day-ahead load forecast accuracy by 15 percent, reducing imbalance costs by $500K per year.
You also define initial ROI hypotheses. If we reduce outage duration by 10 percent, how much money do we save? What’s the current cost of unplanned maintenance? ROI isn’t a single number—it’s a range you refine through the project. But without a baseline, there’s no way to measure impact later.
Phase II centers on data understanding and cost-benefit framing. This phase surfaces costs and risks. You audit data availability, quality, bias, and relevance. You might find that critical features are missing, or that historical data doesn’t reflect current operations. Each data gap has a cost—either financial or analytical.
For utilities, this often means discovering that SCADA data has gaps, maintenance logs are incomplete, or weather data needs to be purchased. At this point, refine the ROI estimate. Account for data acquisition costs. Identify effort needed to integrate and clean data. Forecast whether the expected benefits still justify moving forward.
Phase III involves data preparation and resource allocation. You now build training and test datasets. Labeling, normalization, feature engineering, and integration take time and money. ROI models should track these hours and infrastructure use as sunk costs.
This is also when model architecture decisions affect compute costs. A deep learning model might deliver 3 percent higher accuracy but cost 5x more to train and deploy. Is the marginal lift worth it? You don’t need to answer in abstract—you refer back to your ROI assumptions from Phase I.
Phase IV covers modeling and value projection. Now you build models. But you also run simulations to test value scenarios. What if the model hits 80 percent precision instead of 90? What if adoption is 50 percent in year one? Build a few ROI projection curves based on business impact per accuracy level.
If your project automates outage prediction, simulate cost savings per avoided outage based on model performance. Build sensitivity models. ROI is no longer a static number—it becomes a curve with confidence bands.
Phase V focuses on evaluation and ROI simulation. You now evaluate the model’s business utility. Don’t just report metrics like F1 or AUC. Translate them into business terms. If your model flags transformer failures with 92 percent precision, how many false positives occur? What’s the operational cost of investigating false alarms?
This is when the pre-project ROI forecast meets real-world performance. You update the ROI model and decide whether to proceed, revise, or pause. CPMAI treats this phase as a business checkpoint—not just a technical one.
Phase VI addresses deployment and realized value tracking. Once deployed, monitor realized value against projections. Did the model reduce costs or time as expected? Did adoption lag? Did external factors shift the outcome?
Track post-deployment costs: support, retraining, integration updates. These often go unmeasured but shrink long-term ROI if ignored. You now have a closed feedback loop. Use this data not just for reporting but to refine ROI estimates in future CPMAI projects.
Metrics and Methods for ROI Measurement
Quantifying ROI in utility analytics requires going beyond traditional financial accounting. You need to define metrics that connect business outcomes with model performance. These must be practical, measurable, and traceable across the lifecycle of a CPMAI project.
Direct value metrics tie immediately to financial performance. These are easiest to track and communicate. Cost savings include reduced O&M through fewer unplanned maintenance calls, lower imbalance costs from better load forecasting, and deferred capital spending from extended asset life. Operational efficiency encompasses reduced outage duration through faster restoration, improved resource utilization via optimized crew dispatch, and headcount deferral through automated inspections.
When possible, express gains in annualized or marginal terms. For example, a predictive maintenance model reduced unplanned transformer failures by 20 percent, saving $2M annually in avoided outages and deferred replacements.
Indirect value metrics don’t produce immediate financial returns but create conditions for better performance. Reliability improvements include SAIDI/SAIFI reductions through fewer and shorter outages, and improved voltage quality through better voltage control. Regulatory compliance involves meeting reliability targets to avoid penalties, and audit readiness through complete model documentation. Customer satisfaction improvements include faster service restoration, more accurate billing, and personalized programs.
Translate these into financial estimates when feasible. For example, improved SAIDI may reduce regulatory penalties or improve customer retention.
Time-based metrics reflect that AI investments carry a time horizon. The payback period is the time it takes for net benefits to exceed costs. The breakeven point occurs when cumulative savings match initial investment. Time to impact measures months from deployment to first measurable benefit. Value decay or drift happens when model performance—and value—starts to drop.
In CPMAI, track these over time. Use them to schedule model retraining and stakeholder reviews.
Financial tools used for capital projects include Net Present Value (NPV), which calculates total expected value of project benefits minus costs, discounted to present value. Internal Rate of Return (IRR) estimates the effective annual return rate.
To apply these, project benefits and costs across time and apply a discount rate, typically 8-12% for utilities. This makes AI projects comparable to other capital expenditures and strengthens budget justification.
Common Pitfalls and How to Avoid Them
Utility ML projects fail to deliver ROI not because the models are wrong, but because the process around them is weak. Many projects launch with vague goals, shallow metrics, or blind optimism about adoption. CPMAI anticipates these risks by emphasizing structured checkpoints, but teams still need to watch for recurring pitfalls.
I’ve seen all of these kill projects. Let me tell you about the ones that show up most often.
The first common pitfall is vague or overstated expectations. It’s tempting to declare that AI will revolutionize operations. But vague ambitions prevent measurable outcomes. If a project aims to improve reliability, what does success look like? A 5 percent SAIDI reduction? A 20 percent reduction in unplanned outages? Overstated or ill-defined expectations inflate the denominator of ROI and lead to disappointment, even when the project delivers real gains.
The fix is straightforward. In CPMAI Phase I, define success as a concrete metric tied to revenue, cost, or risk. Use scenarios—best case, expected case, worst case. Set thresholds for go/no-go decisions early.
The second pitfall is technical success without business impact. A model with high accuracy does not guarantee ROI. If no one uses the model, or if it feeds into a decision process that ignores it, the value is zero. Many models die in proof-of-concept purgatory—technically sound, but disconnected from operations.
The fix requires linking technical metrics to business action in Phase IV and V. Ask what people will do differently if this model works. What decisions will change? Evaluate the model not just on AUC, but on how it moves the dial on KPIs.
The third pitfall is ignoring lifecycle costs. Projects often focus on development costs and ignore what happens next: integration, monitoring, retraining, support, and governance. These costs accumulate. An AI solution may be deployed in six months but cost more in maintenance than in development.
The fix involves including end-to-end costs in Phase III and VI. Budget for MLOps, retraining cycles, and compliance reviews. Build a cost model that extends through decommissioning or model retirement. That gives you a true ROI picture, not just a launch-phase snapshot.
The fourth pitfall is failing to track post-deployment value. Even successful models decay. Behavior changes. Data distributions shift. Initial ROI projections become outdated. If no one tracks performance against assumptions, the ROI silently erodes while leadership still believes the project is a success.
The fix is to use Phase VI to install monitoring processes. Set review intervals to compare actual versus expected impact. Build dashboards that track business metrics alongside model metrics. This lets you intervene when value declines—and improve the model or retire it with full awareness.
The fifth pitfall is underestimating adoption challenges. Even perfect models can fail if users don’t trust or understand them. AI often challenges intuition or legacy practices. If end users aren’t trained, incentivized, or included in the loop, usage stalls. The project delivers no ROI—not because of math, but because of behavior.
The fix is to bake adoption planning into Phase I and V. Include change management costs in your ROI model. Treat usage as a required outcome, not an optional extra.
These pitfalls are avoidable. CPMAI helps by forcing ROI thinking into each project checkpoint. When you treat ROI not as a final report, but as a live design constraint, you deliver projects that work—and keep working.
Case Example: Predictive Maintenance for Transformers
To bring ROI measurement to life, let’s walk through a real-world case: a predictive maintenance initiative for distribution transformers. The goal was to reduce unplanned transformer failures by using AI to predict failures and schedule maintenance before breakdowns occurred.
The business context involved a utility managing 5,000 distribution transformers across its service territory. Each unplanned failure caused an average outage affecting 200 customers for 4 hours. The utility estimated that each outage hour cost $10,000 in customer impact, regulatory penalties, and restoration costs. Transformers failed unexpectedly about 50 times per year, totaling $2M in avoidable costs annually. The goal was to cut this by 30 percent.
The initial ROI hypothesis in Phase I projected expected annual savings of $600,000, representing 30 percent of the $2M in avoidable costs. The estimated project cost was $450,000, covering personnel, sensors, compute, and integration. The break-even target was 9 months, with a minimum viable ROI of 20% NPV within 3 years.
During Phase II data understanding, SCADA data was available but noisy and inconsistent. Labeling failure events required manual review of maintenance logs. It took two engineers four weeks to clean and align the data. Revised costs added $25,000 for data preparation labor and $5,000 for data quality tools. The team re-ran the ROI model, keeping the same benefit assumptions. The project remained viable, but the breakeven point shifted to 10 months.
In Phase III data preparation, the data pipeline was stabilized, and feature engineering revealed useful indicators: temperature spikes and vibration anomalies 3-6 hours before failures. They built and tested a training set with 24 months of historical data. Additional costs included $8,000 for cloud compute for model training and storage, and $3,000 for an internal security review for cloud compliance. At this stage, model lift was still unknown, but the updated total project cost reached $491,000.
During Phase IV modeling, the final model was a gradient boosting classifier with 88 percent precision and 75 percent recall. Simulation showed the model could correctly predict 30 of the 50 annual failures, with only 5 false positives. The business translation showed avoided outages of 120 hours at $10,000 per hour, totaling $1,200,000. False positive maintenance costs were 5 incidents at $2,000 each, totaling $10,000. The net projected benefit was $1,190,000.
The ROI projection in Phase V showed NPV at 10% discount over 3 years of approximately $1,850,000, with an IRR of approximately 85% and a payback period of 5 months. Before deployment, the model underwent final business evaluation. The operations manager validated the value assumptions. Finance verified the projected cost structure. The team ran Monte Carlo simulations of failure rate variability. Even in pessimistic scenarios where 20 failures were detected instead of 30, the model still cleared the ROI threshold.
The model was approved for phased rollout across 1,000 high-risk transformers.
In Phase VI post-deployment, the first 12 months showed the model detected 28 of 35 actual failures. Outage duration was reduced by 90 hours. Realized savings were approximately $900,000. Maintenance response time dropped from 6 hours to 1.5 hours.
Unexpected costs included $5,000 for retraining the model after a firmware upgrade, $8,000 for additional staff training, and $12,000 for enhanced monitoring infrastructure. The team adjusted the ROI dashboard and extended model monitoring to include explainability tracking and confidence score thresholds.
The lessons learned were clear. Early ROI framing created clear decision points. Tracking costs across the full lifecycle avoided surprises. Framing value in operational terms like hours saved and dollars avoided gained business trust. The CPMAI structure enabled fast re-scoping when assumptions changed.
This case shows that ROI isn’t a final number—it’s a design discipline. By using CPMAI to shape how decisions were made, the project avoided technical overreach and delivered measurable business impact.
Building ROI Analysis into Utility ML Projects
Let’s walk through how to calculate ROI for a predictive maintenance project. This code shows how to model costs, benefits, and financial metrics (NPV, IRR, payback period) across the project lifecycle. I’m showing you this because I’ve seen too many projects that had great models but couldn’t prove the value.
First, we define project costs and benefits:
costs = {
"development": {
"data_preparation": config["costs"]["data_prep"],
"model_development": config["costs"]["model_dev"],
"infrastructure": config["costs"]["infrastructure"],
"personnel": config["costs"]["personnel"],
},
"deployment": {
"integration": config["costs"]["integration"],
"training": config["costs"]["training"],
"compliance": config["costs"]["compliance"],
},
"maintenance": {
"monitoring": config["costs"]["monitoring_annual"],
"retraining": config["costs"]["retraining_annual"],
"support": config["costs"]["support_annual"],
}
}
total_development = sum(costs["development"].values())
total_deployment = sum(costs["deployment"].values())
total_maintenance_annual = sum(costs["maintenance"].values())
return {
"costs": costs,
"total_development": total_development,This sets up the cost structure (development, infrastructure, personnel) and benefit assumptions (outage reduction, cost per outage hour). In practice, these would come from business analysis and historical data. The key is being honest about costs—I’ve seen projects underestimate maintenance costs by 50% or more.
Next, we calculate financial metrics:
"total_deployment": total_deployment,
"total_maintenance_annual": total_maintenance_annual,
}
def calculate_benefits():
"""Calculate annual benefits from ML project."""
# Base metrics
annual_outages = config["benefits"]["annual_outages"]
outage_reduction_pct = config["benefits"]["outage_reduction_pct"]
cost_per_outage_hour = config["benefits"]["cost_per_outage_hour"]
avg_outage_hours = config["benefits"]["avg_outage_hours"]
# Calculate avoided outages
avoided_outages = annual_outages * (outage_reduction_pct / 100)
avoided_hours = avoided_outages * avg_outage_hours
# Calculate savings
outage_savings = avoided_hours * cost_per_outage_hour
# Other benefits
o_m_savings = config["benefits"]["o_m_savings_annual"]
capital_deferral = config["benefits"]["capital_deferral_annual"]
total_annual_benefits = outage_savings + o_m_savings + capital_deferral
return {
"avoided_outages": avoided_outages,
"avoided_hours": avoided_hours,
"outage_savings": outage_savings,This calculates NPV, IRR, and payback period using standard financial formulas. The code handles time-based cash flows and discounting. These are the same metrics utilities use for capital projects, which makes it easier to compare ML investments to other initiatives.
Finally, we visualize the ROI analysis:
"o_m_savings": o_m_savings,
"capital_deferral": capital_deferral,
"total_annual_benefits": total_annual_benefits,
}
def calculate_npv(cash_flows, discount_rate):
"""Calculate Net Present Value."""
npv = 0
for i, cf in enumerate(cash_flows):
npv += cf / ((1 + discount_rate) ** i)
return npv
def calculate_irr(cash_flows, tolerance=1e-6, max_iterations=100):
"""Calculate Internal Rate of Return using binary search."""
def npv_at_rate(rate):
return sum(cf / ((1 + rate) ** i) for i, cf in enumerate(cash_flows))
# Initial bounds
low = -0.99 # Can't have rate < -100%
high = 10.0 # Upper bound (1000%)
# Check if NPV is positive at high rate (no solution)
if npv_at_rate(high) > 0:
return None
# Binary search for IRR
for _ in range(max_iterations):
mid = (low + high) / 2This creates a dashboard showing cumulative costs and benefits over time, helping stakeholders understand when the project breaks even and how value accrues. I’ve found that visualizations like this are essential for getting buy-in—people need to see when they’ll get their money back.
The complete, runnable script is at content/c16/roi_analysis.py. Modify the assumptions and see how sensitive your ROI is to different scenarios.
What I Want You to Remember
ROI measurement starts with business value, not technology. Define success in operational terms like hours saved, dollars avoided, or reliability improved before building models. Account for full lifecycle costs, including development, deployment, monitoring, retraining, and decommissioning. A model deployed in six months may cost more in maintenance over three years. I’ve seen this happen—teams celebrate deployment, then realize they didn’t budget for ongoing costs.
Measure continuously, not just at the end. Track ROI at each CPMAI phase. This enables course correction and builds stakeholder confidence. Translate technical metrics to business outcomes. Model accuracy matters, but only if it changes decisions and improves operations. Link F1 scores to operational KPIs. I learned this from my ExxonMobil project: the model was technically correct, but I didn’t frame it in business terms that mattered.
Avoid common pitfalls. Vague expectations, ignoring lifecycle costs, failing to track post-deployment value, and underestimating adoption challenges all undermine ROI. Remember that ROI is a design discipline, not a final report. By treating ROI as a live constraint throughout the project, you deliver solutions that work—and keep working.
Here’s the bottom line: if you can’t prove the value, you won’t get the budget. It’s that simple. Do the ROI work upfront, track it continuously, and be honest about what’s working and what isn’t.
What’s Next
In Chapter 20, we’ll step back and take a strategic view—exploring how to build AI roadmaps for utilities and projecting the long-term impact of AI adoption on operational performance and customer outcomes. This is where strategy meets execution.
Code
"""Chapter 19: Cost Optimization and ROI for Utility ML Projects."""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import yaml
from pathlib import Path
from datetime import datetime, timedelta
# Load config
config_path = Path(__file__).parent / "config.yaml"
with open(config_path) as f:
config = yaml.safe_load(f)
np.random.seed(config["model"]["random_state"])
def calculate_project_costs():
"""Calculate total project costs across lifecycle."""
costs = {
"development": {
"data_preparation": config["costs"]["data_prep"],
"model_development": config["costs"]["model_dev"],
"infrastructure": config["costs"]["infrastructure"],
"personnel": config["costs"]["personnel"],
},
"deployment": {
"integration": config["costs"]["integration"],
"training": config["costs"]["training"],
"compliance": config["costs"]["compliance"],
},
"maintenance": {
"monitoring": config["costs"]["monitoring_annual"],
"retraining": config["costs"]["retraining_annual"],
"support": config["costs"]["support_annual"],
}
}
total_development = sum(costs["development"].values())
total_deployment = sum(costs["deployment"].values())
total_maintenance_annual = sum(costs["maintenance"].values())
return {
"costs": costs,
"total_development": total_development,
"total_deployment": total_deployment,
"total_maintenance_annual": total_maintenance_annual,
}
def calculate_benefits():
"""Calculate annual benefits from ML project."""
# Base metrics
annual_outages = config["benefits"]["annual_outages"]
outage_reduction_pct = config["benefits"]["outage_reduction_pct"]
cost_per_outage_hour = config["benefits"]["cost_per_outage_hour"]
avg_outage_hours = config["benefits"]["avg_outage_hours"]
# Calculate avoided outages
avoided_outages = annual_outages * (outage_reduction_pct / 100)
avoided_hours = avoided_outages * avg_outage_hours
# Calculate savings
outage_savings = avoided_hours * cost_per_outage_hour
# Other benefits
o_m_savings = config["benefits"]["o_m_savings_annual"]
capital_deferral = config["benefits"]["capital_deferral_annual"]
total_annual_benefits = outage_savings + o_m_savings + capital_deferral
return {
"avoided_outages": avoided_outages,
"avoided_hours": avoided_hours,
"outage_savings": outage_savings,
"o_m_savings": o_m_savings,
"capital_deferral": capital_deferral,
"total_annual_benefits": total_annual_benefits,
}
def calculate_npv(cash_flows, discount_rate):
"""Calculate Net Present Value."""
npv = 0
for i, cf in enumerate(cash_flows):
npv += cf / ((1 + discount_rate) ** i)
return npv
def calculate_irr(cash_flows, tolerance=1e-6, max_iterations=100):
"""Calculate Internal Rate of Return using binary search."""
def npv_at_rate(rate):
return sum(cf / ((1 + rate) ** i) for i, cf in enumerate(cash_flows))
# Initial bounds
low = -0.99 # Can't have rate < -100%
high = 10.0 # Upper bound (1000%)
# Check if NPV is positive at high rate (no solution)
if npv_at_rate(high) > 0:
return None
# Binary search for IRR
for _ in range(max_iterations):
mid = (low + high) / 2
npv = npv_at_rate(mid)
if abs(npv) < tolerance:
return mid
if npv > 0:
low = mid
else:
high = mid
if high - low < tolerance:
break
return (low + high) / 2
def calculate_payback_period(cash_flows):
"""Calculate payback period in months."""
cumulative = 0
for i, cf in enumerate(cash_flows):
cumulative += cf
if cumulative > 0:
# Interpolate to get exact month
if i == 0:
return 0
prev_cumulative = sum(cash_flows[:i])
months = i - 1 + abs(prev_cumulative) / abs(cf)
return months
return None
def build_roi_model():
"""Build complete ROI model with costs and benefits over time."""
cost_data = calculate_project_costs()
benefit_data = calculate_benefits()
years = config["roi"]["analysis_years"]
discount_rate = config["roi"]["discount_rate"]
# Build cash flow timeline
cash_flows = []
cost_timeline = []
benefit_timeline = []
cumulative_net = []
# Year 0: Development and deployment costs
year_0_costs = (cost_data["total_development"] +
cost_data["total_deployment"])
cash_flows.append(-year_0_costs)
cost_timeline.append(year_0_costs)
benefit_timeline.append(0)
cumulative_net.append(-year_0_costs)
# Years 1-N: Maintenance costs and benefits
for year in range(1, years + 1):
year_costs = cost_data["total_maintenance_annual"]
year_benefits = benefit_data["total_annual_benefits"]
net_cash_flow = year_benefits - year_costs
cash_flows.append(net_cash_flow)
cost_timeline.append(year_costs)
benefit_timeline.append(year_benefits)
cumulative_net.append(cumulative_net[-1] + net_cash_flow)
# Calculate financial metrics
npv = calculate_npv(cash_flows, discount_rate)
irr = calculate_irr(cash_flows)
payback_months = calculate_payback_period(cash_flows)
return {
"cash_flows": cash_flows,
"cost_timeline": cost_timeline,
"benefit_timeline": benefit_timeline,
"cumulative_net": cumulative_net,
"npv": npv,
"irr": irr,
"payback_months": payback_months,
"cost_data": cost_data,
"benefit_data": benefit_data,
}
def plot_roi_analysis(roi_model):
"""Visualize ROI analysis."""
years = config["roi"]["analysis_years"]
time_points = list(range(years + 1))
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=config["plotting"]["figsize"])
# Plot 1: Cumulative costs and benefits
ax1.plot(time_points,
[sum(roi_model["cost_timeline"][:i+1]) for i in range(len(time_points))],
label="Cumulative Costs",
color=config["plotting"]["colors"]["costs"],
linewidth=2)
ax1.plot(time_points,
[sum(roi_model["benefit_timeline"][:i+1]) for i in range(len(time_points))],
label="Cumulative Benefits",
color=config["plotting"]["colors"]["benefits"],
linewidth=2)
ax1.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax1.set_xlabel("Year")
ax1.set_ylabel("Cumulative Value ($)")
ax1.set_title("ROI Timeline: Costs vs. Benefits")
ax1.legend()
ax1.grid(True, alpha=0.3)
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
# Plot 2: Net cash flow
ax2.bar(time_points, roi_model["cumulative_net"],
color=[config["plotting"]["colors"]["positive"] if x > 0
else config["plotting"]["colors"]["negative"]
for x in roi_model["cumulative_net"]],
alpha=0.7)
ax2.axhline(y=0, color='gray', linestyle='--', alpha=0.5)
ax2.set_xlabel("Year")
ax2.set_ylabel("Cumulative Net Value ($)")
ax2.set_title("Cumulative Net ROI")
ax2.grid(True, alpha=0.3, axis='y')
ax2.spines['top'].set_visible(False)
ax2.spines['right'].set_visible(False)
plt.tight_layout()
plt.savefig(config["plotting"]["output_file"])
plt.close()
def print_roi_summary(roi_model):
"""Print ROI summary report."""
print("\n" + "="*60)
print("ROI ANALYSIS SUMMARY")
print("="*60)
print("\n--- COSTS ---")
print(f"Development & Deployment: ${roi_model['cost_data']['total_development'] + roi_model['cost_data']['total_deployment']:,.0f}")
print(f"Annual Maintenance: ${roi_model['cost_data']['total_maintenance_annual']:,.0f}")
print("\n--- BENEFITS (Annual) ---")
print(f"Outage Savings: ${roi_model['benefit_data']['outage_savings']:,.0f}")
print(f"O&M Savings: ${roi_model['benefit_data']['o_m_savings']:,.0f}")
print(f"Capital Deferral: ${roi_model['benefit_data']['capital_deferral']:,.0f}")
print(f"Total Annual Benefits: ${roi_model['benefit_data']['total_annual_benefits']:,.0f}")
print("\n--- FINANCIAL METRICS ---")
print(f"NPV (10% discount): ${roi_model['npv']:,.0f}")
if roi_model['irr']:
print(f"IRR: {roi_model['irr']*100:.1f}%")
if roi_model['payback_months']:
print(f"Payback Period: {roi_model['payback_months']:.1f} months")
print("\n" + "="*60)
if __name__ == "__main__":
print("\n--- Building ROI Model ---")
roi_model = build_roi_model()
print_roi_summary(roi_model)
print("\n--- Generating ROI Visualization ---")
plot_roi_analysis(roi_model)
print(f"Plot saved to: {config['plotting']['output_file']}")