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 (LLM Integration)
The package includes an MCP server for use with Claude Desktop, ChatGPT, and other MCP-compatible LLM tools.
Installation
pip install site-calc-investment[mcp]
Claude Desktop Configuration
Add to claude_desktop_config.json:
{
"mcpServers": {
"site-calc-investment": {
"command": "uvx",
"args": ["--from", "site-calc-investment[mcp]", "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"
}
}
}
}
For local development against a source checkout, use uv run --directory instead:
{
"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"
}
}
}
}
ChatGPT Configuration
ChatGPT supports MCP via streaming HTTP or SSE (stdio is not supported). This requires:
- An eligible ChatGPT plan with Developer Mode access (Pro, Plus, Business, Enterprise, or Education). Business plan restricts Developer Mode to admins/owners; other plans may have similar admin gating.
- Developer Mode enabled (navigate to Settings -- the exact path may vary by account type)
Step 1 -- Start the MCP server in HTTP mode:
cd /path/to/client-investment
INVESTMENT_API_URL="http://your-api-url" \
INVESTMENT_API_KEY="inv_your_key_here" \
INVESTMENT_DATA_DIR="/path/to/data" \
uv run fastmcp run site_calc_investment.mcp.server:mcp --transport http --port 8000
Step 2 -- Expose to the internet (for local development):
ngrok http 8000
For production, deploy the server to a publicly accessible host instead.
Step 3 -- Add to ChatGPT:
- Open ChatGPT Settings > Apps & Connectors (or Connectors) > Advanced settings > Enable Developer Mode
- Click Create app
- Enter the ngrok HTTPS URL (e.g.
https://abc123.ngrok.io/mcp) as the server endpoint - Name: "Site-Calc Investment", Description: "Investment planning optimization tools"
- Click Refresh to load the tool list
Note: ChatGPT shows tool call details and may require manual confirmation for actions. The
save_data_filetool requires the server to have local filesystem access.
Tools (16)
| Tool | Description |
|---|---|
get_version |
Get server and package version info |
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.7.tar.gz.
File metadata
- Download URL: site_calc_investment-1.2.7.tar.gz
- Upload date:
- Size: 237.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9fd556fe6b11249dc1629181bdb1ab693c32fd3d4b8389aa721fbdc072e45e34
|
|
| MD5 |
f230e0a604f8a681f0258dd89233be10
|
|
| BLAKE2b-256 |
dba60b5797f10768378f1e14af2e3a8522e88fd74f3349d1533306e15dceecfb
|
Provenance
The following attestation bundles were made for site_calc_investment-1.2.7.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.7.tar.gz -
Subject digest:
9fd556fe6b11249dc1629181bdb1ab693c32fd3d4b8389aa721fbdc072e45e34 - Sigstore transparency entry: 919647845
- Sigstore integration time:
-
Permalink:
stranma/site-calc-investment@ff42248073a70bfbb5fd2ee56a921ad79caa4010 -
Branch / Tag:
- Owner: https://github.com/stranma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ff42248073a70bfbb5fd2ee56a921ad79caa4010 -
Trigger Event:
release
-
Statement type:
File details
Details for the file site_calc_investment-1.2.7-py3-none-any.whl.
File metadata
- Download URL: site_calc_investment-1.2.7-py3-none-any.whl
- Upload date:
- Size: 60.2 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 |
bdf810e2d47438fe5796692faf4fd344cac008d30698bd831790a9b60a3e52c6
|
|
| MD5 |
a9f762dbdb7cfe466dd9feada09dceb1
|
|
| BLAKE2b-256 |
28df8fa022b4ff5cb80d6d4dbe15615a8cf33cbdcf4c1b15bb26ae0b2ba121b2
|
Provenance
The following attestation bundles were made for site_calc_investment-1.2.7-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.7-py3-none-any.whl -
Subject digest:
bdf810e2d47438fe5796692faf4fd344cac008d30698bd831790a9b60a3e52c6 - Sigstore transparency entry: 919647847
- Sigstore integration time:
-
Permalink:
stranma/site-calc-investment@ff42248073a70bfbb5fd2ee56a921ad79caa4010 -
Branch / Tag:
- Owner: https://github.com/stranma
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@ff42248073a70bfbb5fd2ee56a921ad79caa4010 -
Trigger Event:
release
-
Statement type: