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
30 changes: 29 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,34 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- `PVSystem` enum inputs (`mounting`, `module_orientation`, `inverter_type`) accept case-insensitive strings,
at construction and on assignment.
- `PVSystem.with_defaults_applied()` returns a copy with all unset derived inputs resolved.

### Changed

- Derived `PVSystem` inputs (`mounting_height`, ohmic losses, bifacial parameters, transformer losses) are now
resolved when the payload is built; they read as `None` until set explicitly. Use `describe()` or
`with_defaults_applied()` to see effective values.
- `PVSystem.payload` is now an output-only snapshot (JSON string) and is no longer read back; it is omitted
from `to_file()` output.
- Building a payload no longer overwrites the plant's `dc_capacity_MW`, `ac_capacity_MW` or `gcr`.

### Fixed

- Payloads built after changing `mounting`, `bifacial`, `inverter_type` or `transformer_stages` now use the
corresponding derived defaults. Previously they were silently ignored, e.g. bifacial losses stayed 0
after `plant.bifacial = True`; results from workflows that assign these after construction will change.
- A stale cached payload could be sent after editing a plant (including via `make_copy()`).
- `PVSystem.set_inverter_from_rcl()` no longer multiplies the inverter efficiency by 100 in the
"Narrow your search" message (e.g. `eff=9860.0%` is now `eff=98.6%`).
- `PVSystem.payload_to_file()` now writes indented JSON instead of a single compact line, and keeps
non-ASCII characters (e.g. in module or inverter file names) instead of escaping them as `\uXXXX`.

## [0.7.0] - 2026-10-07

### Added
Expand All @@ -31,7 +59,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Flush-mount `PVSystem` tilt handling now preserves `plant.tilt` in mounting
specifications instead of forcing `0.0`, aligning flush-mount behaviour with
user-provided fixed-tilt inputs.
user-provided fixed-tilt inputs.

## [0.6.0] - 2026-09-24

Expand Down
9 changes: 9 additions & 0 deletions docs/getting-started/workflow-2-pvplant-builder.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ plant.bifacial_shade_loss = 0.15
plant.bifacial_mismatch_loss = 0.01
```

### Derived defaults

Unset mounting height, inverter and transformer losses, and bifacial parameters are derived when the
payload is built, using the final values of `mounting`, `bifacial`, `inverter_type` and
`transformer_stages`. You can assign these inputs in any order. Set an individual derived field to
override its default; explicit values including `0.0` are preserved. Read effective values with
`plant.with_defaults_applied()` or `plant.describe(verbose=True)`. Enum strings such as `"tracker"`
are accepted case-insensitively.

---

## Step 3: Add Module and Inverter Files
Expand Down
19 changes: 16 additions & 3 deletions solarfarmer/models/pvsystem/plant_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,34 @@
# ------------------------------------------------------------------------------


class InverterType(str, Enum):
class _CaseInsensitiveStrEnum(str, Enum):
"""String enum whose lookup by value ignores case (e.g. ``"fixed"`` -> ``FIXED``)."""

@classmethod
def _missing_(cls, value):
if isinstance(value, str):
folded = value.strip().casefold()
for member in cls:
if member.value.casefold() == folded:
return member
return None


class InverterType(_CaseInsensitiveStrEnum):
"""Enumeration for inverter types."""

STRING = "String"
CENTRAL = "Central"


class MountingType(str, Enum):
class MountingType(_CaseInsensitiveStrEnum):
"""Enumeration for mounting types."""

FIXED = "Fixed"
TRACKER = "Tracker"


class OrientationType(str, Enum):
class OrientationType(_CaseInsensitiveStrEnum):
"""Enumeration for module orientation types."""

PORTRAIT = "Portrait"
Expand Down
Loading
Loading