Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ These are the primary functions for interacting with the SolarFarmer API.

### `TSV_COLUMNS`

Data dictionary describing the SolarFarmer TSV weather file format required and optional columns, units, valid ranges, aliases, and the missing-value sentinel. See the [`weather` module docstring](../api.md) for full details.
Data dictionary describing the SolarFarmer TSV weather file format: required and optional columns, units, valid ranges, aliases, and the missing-value sentinel. See the [`weather` module docstring](../api.md) for full details.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/faq.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,6 @@ The core SDK (payload construction, API calls, annual/monthly summary data) work

## My TMY weather file gives a 400 error with no useful message. What's wrong?

TMY (Typical Meteorological Year) datasets from NSRDB, PVGIS, or similar sources contain timestamps from multiple source years. SolarFarmer requires all timestamps in a TSV file to belong to a single calendar year.
TMY (Typical Meteorological Year) datasets from NSRDB, PVGIS, or similar sources contain timestamps drawn from different source years, causing them to go backwards in time when sorted as a full year. SolarFarmer requires timestamps in a TSV file to be chronologically ordered (non-decreasing years). Multi-year and sub-year files with continuous, ordered timestamps are fully supported; only shuffled years are rejected.

Use [`sf.from_pvlib()`](api.md#from_pvlib) or [`sf.from_dataframe(year=1990)`](api.md#from_dataframe) to remap timestamps automatically. The SDK also calls [`check_sequential_year_timestamps()`](api.md#check_sequential_year_timestamps) before upload to catch this early.
Use [`sf.from_pvlib()`](api.md#from_pvlib) or [`sf.from_dataframe(year=1990)`](api.md#from_dataframe) to remap all timestamps to a single year before export. The SDK also calls [`check_sequential_year_timestamps()`](api.md#check_sequential_year_timestamps) before upload to catch this early.
2 changes: 1 addition & 1 deletion docs/getting-started/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ The SolarFarmer SDK supports three distinct user workflows. Choose the one that
Specify your plant: location (lat/lon), DC and AC capacities, inverter type, mounting configuration.
`PVSystem` handles the payload construction and you run the calculation.

Results from `PVSystem` are approximations based on simplified layout assumptions — see [FAQ](../faq.md) for details.
Results from `PVSystem` are approximations based on simplified layout assumptions. See [FAQ](../faq.md) for details.

---

Expand Down
4 changes: 2 additions & 2 deletions docs/getting-started/quick-start-examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ print(f"Net Energy: {net_energy:.1f} MWh")
print(f"Performance Ratio: {performance_ratio:.1%}")

# Get loss tree time-series results
loss_tree_timeseries = results.loss_tree_timeseries
loss_tree_timeseries = results.loss_tree_timeseries()

# Print summary
results.print_annual_results()
Expand Down Expand Up @@ -466,7 +466,7 @@ for project in projects:
with open(output_file, 'w') as f:
f.write(payload_json)

print(f"Generated payload for {project['name']}")
print(f"Generated payload for {project['name']}")

print(f"\nGenerated {len(projects)} payloads for batch submission")
```
Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started/workflow-1-existing-api-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This workflow involves three steps:

```mermaid
graph TB
A["📁 Existing API Files<br/>(JSON, PAN, OND, weather)"]
A["Existing API Files<br/>(JSON, PAN, OND, weather)"]
B["run_energy_calculation()"]
C["ModelChainResponse"]
D["CalculationResults<br/>(Time-series, losses, metrics)"]
Expand Down Expand Up @@ -180,15 +180,15 @@ For detailed documentation on loss tree time-series results, refer to the [Loss

```python
# Get loss tree timeseries results
loss_tree_timeseries = results.loss_tree_timeseries
loss_tree_timeseries = results.loss_tree_timeseries()

```

For detailed documentation on PVsyst-format time-series results, refer to the [PVsyst Results Format Reference](https://mysoftware.dnv.com/download/public/renewables/solarfarmer/manuals/latest/CalcRef/OutputFiles/CloudTestingFiles.html#pvsystformatresultstxt){ target="_blank" .external }.

```python
# Get pvsyst-format time-series results
timeseries_data = results.pvsyst_timeseries
timeseries_data = results.pvsyst_timeseries()

```

Expand Down
12 changes: 6 additions & 6 deletions docs/getting-started/workflow-2-pvplant-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ description: Create plant configurations and automatically build API payloads
## Overview

!!! info "Approximated Design"
`PVSystem` constructs a plant layout from high-level inputs (location, capacity, equipment files) using simplified assumptionsincluding uniform mid-row shading for all strings and inferred string sizing. This is well-suited for early-stage yield screening and scenario comparison. For full design fidelity, use [Workflow 1](workflow-1-existing-api-files.md) with a SolarFarmer Desktopexported payload or [Workflow 3](workflow-3-plantbuilder-advanced.md) for direct data model mapping.
`PVSystem` constructs a plant layout from high-level inputs (location, capacity, equipment files) using simplified assumptions, including uniform mid-row shading for all strings and inferred string sizing. This is well-suited for early-stage yield screening and scenario comparison. For full design fidelity, use [Workflow 1](workflow-1-existing-api-files.md) with a SolarFarmer Desktop-exported payload or [Workflow 3](workflow-3-plantbuilder-advanced.md) for direct data model mapping.

This workflow involves four steps:

Expand All @@ -27,7 +27,7 @@ This workflow involves four steps:

```mermaid
graph TB
A["📋 Define PVSystem<br/>(location, capacity, equipment)"]
A["Define PVSystem<br/>(location, capacity, equipment)"]
B["PVSystem Payload<br/>(automatic payload construction)"]
C["run_energy_calculation()<br/>(submit to API)"]
D["CalculationResults<br/>(analyze performance)"]
Expand Down Expand Up @@ -126,7 +126,7 @@ plant.bifacial_mismatch_loss = 0.01
## Step 3: Add Module and Inverter Files

The SDK uses PAN (module) and OND (inverter) files for detailed specifications.
Dict keys are user-facing labels only the spec ID sent to the API is derived from the filename (everything before the last `.`).
Dict keys are user-facing labels only; the spec ID sent to the API is derived from the filename (everything before the last `.`).

```python
from pathlib import Path
Expand Down Expand Up @@ -165,7 +165,7 @@ plant.horizon_file = Path(r"path/to/horizon_data.hor")

# Or specify horizon angles directly
plant.horizon(
elevation_angles=[0, 5, 10, 15, 20, 25, 30],
elevation_angles=[0, 5, 10, 15, 10, 5, 0, 0],
azimuth_angles=[0, 45, 90, 135, 180, 225, 270, 315]
)
```
Expand Down Expand Up @@ -256,8 +256,8 @@ annual_data = plant.results.AnnualData[0]
net_energy = annual_data['energyYieldResults']['netEnergy']
performance_ratio = annual_data['energyYieldResults']['performanceRatio']

print(f"Net Annual Energy: {net_energy} MWh")
print(f"Performance Ratio: {performance_ratio}%")
print(f"Net Annual Energy: {net_energy:.1f} MWh")
print(f"Performance Ratio: {performance_ratio:.1%}")
```

---
Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started/workflow-3-plantbuilder-advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This workflow gives you complete control over API object construction:

```mermaid
graph TB
A["🗄️ Your Data Model<br/>(database, file, API, etc.)"]
A["Your Data Model<br/>(database, file, API, etc.)"]
B["Mapper/Builder"]
C["EnergyCalculationInputs + PVPlant<br/>+ Component Classes<br/>(Inverter, Layout, Location, etc.)"]
D["SolarFarmer API"]
Expand Down Expand Up @@ -390,7 +390,7 @@ design = workflow.design_and_optimize(base_config={...})

## Debugging and Validation

All SDK component classes are Pydantic models, so invalid field types, out-of-range values, and missing required fields raise a `ValidationError` at construction time before any serialization or API call occurs.
All SDK component classes are Pydantic models, so invalid field types, out-of-range values, and missing required fields raise a `ValidationError` at construction time, before any serialization or API call occurs.

```python
from pydantic import ValidationError
Expand All @@ -408,7 +408,7 @@ except ValidationError as e:
This means that if construction of your `EnergyCalculationInputs` object completes without raising, the required structure and field constraints are already satisfied.

!!! warning
Unknown keyword arguments are silently ignored Pydantic does not enforce `extra='forbid'` on these models. A misspelled field name will not raise locally; the value will simply be absent from the serialized payload. The server-side validation service is the safeguard for those cases.
Unknown keyword arguments are silently ignored; Pydantic does not enforce `extra='forbid'` on these models. A misspelled field name will not raise locally; the value will simply be absent from the serialized payload. The server-side validation service is the safeguard for those cases.

!!! note
All energy calculation API calls are validated upon receipt by the [SolarFarmer API Validation Service](https://mysoftware.dnv.com/download/public/renewables/solarfarmer/manuals/latest/WebApi/Troubleshooting/ValidationService.html){ target="_blank" .external }. This provides an additional layer of error detection and reporting.
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: SolarFarmer Python SDK
---

# Welcome to SolarFarmer API
A Python SDK that wraps the [DNV SolarFarmer API](https://mysoftware.dnv.com/download/public/renewables/solarfarmer/manuals/latest/WebApi/Introduction/introduction.html) to help you run cloud-based energy calculations and manage API payloads in a user-friendly way.
A Python SDK that wraps the [DNV SolarFarmer API](https://mysoftware.dnv.com/download/public/renewables/solarfarmer/manuals/latest/WebApi/Introduction/introduction.html) to run cloud-based energy calculations and manage API payloads.

[New to SolarFarmer? Discover it here!](https://www.dnv.com/software/services/solarfarmer/){ .md-button .md-button-primary target="_blank" .external }

Expand Down
Loading
Loading