Python client for Site-Calc investment planning (capacity sizing, ROI analysis)
Project description
Site-Calc Investment Client
Python client for Site-Calc investment planning API - long-term capacity planning and ROI analysis.
Installation
pip install site-calc-investment
Quick Start
from datetime import datetime
from zoneinfo import ZoneInfo
from site_calc_investment import InvestmentClient
from site_calc_investment.models import (
Resolution, Site, Battery, ElectricityImport, ElectricityExport,
InvestmentPlanningRequest, InvestmentParameters, OptimizationConfig
)
from site_calc_investment.models.requests import TimeSpanInvestment
# Initialize client
client = InvestmentClient(
base_url="https://api.site-calc.example.com",
api_key="inv_your_api_key_here"
)
# Create 1-week planning horizon (1-hour resolution)
timespan = TimeSpanInvestment(
start=datetime(2025, 1, 1, tzinfo=ZoneInfo("Europe/Prague")),
intervals=168, # 1 week = 7 days × 24 hours
resolution=Resolution.HOUR_1
)
# Generate hourly prices (example: day/night pattern)
prices = [30.0 if h % 24 < 6 else 80.0 if 8 <= h % 24 < 20 else 50.0 for h in range(168)]
# Define devices (NO ancillary_services field)
battery = Battery(
name="Battery1",
properties={
"capacity": 10.0,
"max_power": 5.0,
"efficiency": 0.90,
"initial_soc": 0.5
}
)
grid_import = ElectricityImport(
name="GridImport",
properties={"price": prices, "max_import": 10.0}
)
grid_export = ElectricityExport(
name="GridExport",
properties={"price": prices, "max_export": 10.0}
)
site = Site(site_id="investment_site", devices=[battery, grid_import, grid_export])
# Investment parameters
inv_params = InvestmentParameters(
discount_rate=0.05,
project_lifetime_years=10, # Required field
device_capital_costs={"Battery1": 500000}, # €500k CAPEX
device_annual_opex={"Battery1": 5000} # €5k/year O&M
)
# Create and submit optimization request
request = InvestmentPlanningRequest(
sites=[site],
timespan=timespan,
investment_parameters=inv_params,
optimization_config=OptimizationConfig(
objective="maximize_profit", # Options: maximize_profit, minimize_cost, maximize_self_consumption
time_limit_seconds=300 # Max 900 seconds (15 min)
)
)
job = client.create_planning_job(request)
result = client.wait_for_completion(job.job_id, poll_interval=5, timeout=600)
print(f"Status: {result.status}")
print(f"Solver: {result.summary.solver_status}")
print(f"Profit: €{result.summary.expected_profit:,.2f}")
Features
- ✅ Long-term capacity planning (1-10 years)
- ✅ Investment ROI analysis (NPV, IRR, payback)
- ✅ Scenario comparison utilities
- ✅ Financial analysis helpers
- ✅ 1-hour resolution optimization
- ✅ Multi-site optimization
- ✅ Type-safe Pydantic models
- ✅ Automatic retry and error handling
- ✅ Job management (cancel single or all jobs)
Capabilities
| Feature | Value |
|---|---|
| Max Horizon | 100,000 intervals (~11 years at 1-hour) |
| Resolution | 1-hour only |
| ANS Support | No |
| Binary Variables | Relaxed to continuous |
| Timeout | 900 seconds (15 minutes) max |
Supported Devices
- Battery (NO ANS)
- CHP - Combined Heat and Power (continuous operation)
- Heat Accumulator
- Photovoltaic
- Heat Demand
- Electricity Demand
- Electricity Import/Export (market interface)
- Gas Import (market interface)
- Heat Export (market interface)
Job Management
The client provides methods for managing optimization jobs:
# Create a job
job = client.create_planning_job(request)
print(f"Job ID: {job.job_id}")
# Check job status
status = client.get_job_status(job.job_id)
print(f"Status: {status.status}, Progress: {status.progress}%")
# Wait for completion
result = client.wait_for_completion(job.job_id, poll_interval=30, timeout=7200)
# Cancel a single job
cancelled = client.cancel_job(job.job_id)
# Cancel all pending/running jobs (bulk cancel)
result = client.cancel_all_jobs()
print(f"Cancelled {result['cancelled_count']} jobs")
Financial Analysis
from site_calc_investment.analysis import (
calculate_npv,
calculate_irr,
calculate_payback_period,
compare_scenarios
)
# NPV calculation
npv = calculate_npv(
cash_flows=annual_revenues,
discount_rate=0.05,
initial_investment=-1500000
)
# IRR calculation
irr = calculate_irr([-1500000] + annual_revenues)
# Scenario comparison
comparison = compare_scenarios(
[result_5mw, result_10mw, result_15mw],
names=["5 MW", "10 MW", "15 MW"]
)
print(comparison) # DataFrame with NPV, IRR, costs, revenues
MCP Server (Claude Desktop Integration)
The package includes an MCP server for use with Claude Desktop and other LLM tools.
Installation
pip install site-calc-investment[mcp]
Claude Desktop Configuration
Add to claude_desktop_config.json:
{
"mcpServers": {
"site-calc-investment": {
"command": "uv",
"args": ["run", "--directory", "/path/to/client-investment", "site-calc-investment-mcp"],
"env": {
"INVESTMENT_API_URL": "http://your-api-url",
"INVESTMENT_API_KEY": "inv_your_key_here",
"INVESTMENT_DATA_DIR": "/path/to/data/directory"
}
}
}
}
Tools (15)
| Tool | Description |
|---|---|
create_scenario |
Create a new draft scenario |
add_device |
Add a device (battery, CHP, PV, etc.) |
set_timespan |
Set optimization time horizon |
set_investment_params |
Set financial parameters (NPV, IRR) |
review_scenario |
Review scenario before submission |
remove_device |
Remove a device |
delete_scenario |
Delete a scenario |
list_scenarios |
List all draft scenarios |
submit_scenario |
Submit for optimization |
get_job_status |
Check job progress |
get_job_result |
Get optimization results |
cancel_job |
Cancel a job |
list_jobs |
List all jobs |
get_device_schema |
Get device property schema |
save_data_file |
Save generated data as CSV |
save_data_file lets the LLM write generated data (price arrays, demand profiles) to local CSV files, which can then be referenced in add_device properties.
See docs/MCP_SERVER_SPEC.md for full specification.
Documentation
Full documentation available at: https://github.com/stranma/site-calc-investment#readme
Examples
See examples/ directory for complete examples:
capacity_planning.py- 10-year capacity planning workflowroi_analysis.py- Investment ROI calculationscenario_comparison.py- Compare device configurations
Requirements
- Python ≥ 3.10
- API key with
inv_prefix (investment client)
Key Differences from Operational Client
- ❌ No
/optimal-biddingendpoint - ❌ No
ancillary_serviceson devices - ❌ No 15-minute resolution (1-hour only)
- ✅ Up to 100,000 intervals (vs. 296)
- ✅ Investment metrics (NPV, IRR, payback)
- ✅ Financial analysis helpers
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Format code
ruff format .
# Type check
mypy site_calc_investment
License
MIT License
Support
- Issues: https://github.com/stranma/site-calc-investment/issues
- Documentation: https://github.com/stranma/site-calc-investment#readme
Part of the Site-Calc platform.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file site_calc_investment-1.2.4.tar.gz.
File metadata
- Download URL: site_calc_investment-1.2.4.tar.gz
- Upload date:
- Size: 210.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ba448d1f770e1320c4d317e72cae2e3676c3de378d220b4ed8f58544d8527076
|
|
| MD5 |
84c4dcfef5d1777651cf57bc58f2ee98
|
|
| BLAKE2b-256 |
de57713c5b08ce973ea199d94bd71d4c0f65fe417d4e2fe64f1aaf567257b36f
|
Provenance
The following attestation bundles were made for site_calc_investment-1.2.4.tar.gz:
Publisher:
publish.yml on stranma/site-calc-investment
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
site_calc_investment-1.2.4.tar.gz -
Subject digest:
ba448d1f770e1320c4d317e72cae2e3676c3de378d220b4ed8f58544d8527076 - Sigstore transparency entry: 911379602
- Sigstore integration time:
-
Permalink:
stranma/site-calc-investment@a9c12b2b36a18bed286e0ade5ea41639fb987a32 -
Branch / Tag:
refs/tags/v1.2.4 - Owner: https://github.com/stranma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9c12b2b36a18bed286e0ade5ea41639fb987a32 -
Trigger Event:
release
-
Statement type:
File details
Details for the file site_calc_investment-1.2.4-py3-none-any.whl.
File metadata
- Download URL: site_calc_investment-1.2.4-py3-none-any.whl
- Upload date:
- Size: 40.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80aaf5215cb2f73ddd36ff2dac63c48ec560d2db03e319c58c71cfe262364cd7
|
|
| MD5 |
2d2c0d49e4de0aa5638c2f86823a8634
|
|
| BLAKE2b-256 |
8654f9bfa078278c5e0c82de275411a3d89cd8a46e3d3db767ed7185157c4303
|
Provenance
The following attestation bundles were made for site_calc_investment-1.2.4-py3-none-any.whl:
Publisher:
publish.yml on stranma/site-calc-investment
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
site_calc_investment-1.2.4-py3-none-any.whl -
Subject digest:
80aaf5215cb2f73ddd36ff2dac63c48ec560d2db03e319c58c71cfe262364cd7 - Sigstore transparency entry: 911379755
- Sigstore integration time:
-
Permalink:
stranma/site-calc-investment@a9c12b2b36a18bed286e0ade5ea41639fb987a32 -
Branch / Tag:
refs/tags/v1.2.4 - Owner: https://github.com/stranma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a9c12b2b36a18bed286e0ade5ea41639fb987a32 -
Trigger Event:
release
-
Statement type: