Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b93b821
R2X Plugin Management System (#161)
micahpw Apr 16, 2025
3d789c9
fix: Fixing compatibility with plugin system (#192)
pesap May 18, 2025
cbd9edd
fix(plugins): File discovery V2.0.0 (#193)
micahpw Jun 13, 2025
0c51455
bug: PS ramp_limits and time_limits (#180)
jarry7 Jul 16, 2025
425fd13
Merge branch 'main' into v2.0.0
pesap Jul 16, 2025
e391f67
chore: update package dependencies. (#198)
pesap Jul 16, 2025
39fe01d
style: Fixing linting (#199)
pesap Jul 16, 2025
8a26bb5
feat: Adding new hydro structs from PSY 5 and add backward compatibil…
pesap Sep 9, 2025
0c4ff00
Merge plexos_exporter specific changes into R2X v2.0.0 branch (#200)
k1nshuk Sep 22, 2025
570c556
chore: Remove parser/exporter and update dependencies for plugin inte…
mcllerena Oct 21, 2025
1dcfc6f
Remove reeds referenced files (Plugins & Tests) (#217)
mcllerena Dec 13, 2025
cef8e82
fix: Removing test and adding lts version (#218)
pesap Dec 13, 2025
09405d8
feat: adding reeds to sienna. (#219)
pesap Dec 17, 2025
2401f6e
feat: add new components and update translations rules (#220)
mcllerena Dec 19, 2025
e636323
fix: fix bug on getters for duplicated arcs (#221)
mcllerena Dec 22, 2025
6f51064
refactor: update sienna to plexos translation components and properti…
mcllerena Dec 24, 2025
53de3ff
feature: initial approach to handle sienna-to-plexos translations (#223)
mcllerena Dec 29, 2025
9f372c1
refactor: updating code to match recent changes on translation (#224)
mcllerena Dec 29, 2025
9ccf99a
refactor: final restructure of reeds to plexos translation (#225)
mcllerena Jan 6, 2026
1906455
feat: include r2s translation plugin configuration (#226)
mcllerena Jan 6, 2026
bebb485
update entry point in pyproject.toml and plugin spec method (#227)
micahpw Jan 6, 2026
d20d925
fix: include reeds upgrader for translation runs
mcllerena Jan 6, 2026
2bcf6ab
feat: add missing translation and plugin configurations for cli integ…
mcllerena Jan 7, 2026
3259c50
fix: modify plugins and update p2s translation (#229)
mcllerena Jan 14, 2026
d9a735e
fix: reeds to sienna translation bug and add increase test coverage (…
mcllerena Jan 14, 2026
11008c9
fix: updates on tests and translations time series store (#231)
mcllerena Jan 15, 2026
2d6eb21
fix: update init file and run formatter on tests (#232)
mcllerena Jan 15, 2026
2ab32af
fix: update translation to match recent changes on plugins (#233)
mcllerena Feb 4, 2026
fd16564
feat: update translations and add tests for increased coverage (#234)
mcllerena Feb 13, 2026
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ coverage.xml
# Django stuff:
*.log
local_settings.py
_run_*_translations.py
db.sqlite3
db.sqlite3-journal

Expand Down
69 changes: 46 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,34 +1,57 @@
default_stages:
- pre-commit

default_install_hook_types:
- pre-commit
- commit-msg
- pre-push

repos:
- repo: local
hooks:
- id: ruff-format
name: ruff format
entry: uv run ruff format --verbose
language: system
types_or: [python, pyi]

- id: ruff-check
name: ruff check
entry: uv run ruff check --fix --config=pyproject.toml packages/
language: system
types_or: [python, pyi]

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0 # Use the ref you want to point at
rev: v6.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-added-large-files
args: ["--maxkb=10000"]
- id: check-json
- id: pretty-format-json
args: ["--autofix"]
- id: check-merge-conflict
- id: check-yaml
- id: check-toml
- id: check-json
- id: check-case-conflict
- id: check-xml
- id: end-of-file-fixer
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v4.0.0-alpha.8"
hooks:
- id: prettier
types_or: [yaml]
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.9.3

- repo: https://github.com/commitizen-tools/commitizen
rev: v4.10.0
hooks:
- id: ruff
args: [--fix, --config=pyproject.toml]
- id: ruff-format
args: [--verbose]
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.11.0"
- id: commitizen
stages:
- commit-msg
pass_filenames: false

- repo: local
hooks:
- id: mypy
- id: pytest
name: pytest (quick)
entry: uv run pytest -q -m "not slow" --maxfail=1 --disable-warnings
language: system
types: [python]
args: [--config-file=pyproject.toml, ./src/r2x]
pass_filenames: false
language: system
stages: [pre-push]

- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.9.4
hooks:
- id: uv-lock
File renamed without changes.
94 changes: 71 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
### R2X

> Model translation parsing tool (ReEDS to X)
>
> [![image](https://img.shields.io/pypi/v/r2x.svg)](https://pypi.python.org/pypi/r2x)
> [![image](https://img.shields.io/pypi/l/r2x.svg)](https://pypi.python.org/pypi/r2x)
> [![image](https://img.shields.io/pypi/pyversions/r2x.svg)](https://pypi.python.org/pypi/r2x)
> [![CI](https://github.com/NREL/r2x/actions/workflows/CI.yaml/badge.svg)](https://github.com/NREL/r2x/actions/workflows/CI.yaml)
> [![codecov](https://codecov.io/gh/NREL/r2x/branch/main/graph/badge.svg)](https://codecov.io/gh/NREL/r2x)
> [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
> [![Documentation](https://github.com/NREL/R2X/actions/workflows/docs-build.yaml/badge.svg?branch=main)](https://nrel.github.io/R2X/)

> [![image](https://img.shields.io/pypi/v/r2x.svg)](https://pypi.python.org/pypi/r2x) > [![image](https://img.shields.io/pypi/l/r2x.svg)](https://pypi.python.org/pypi/r2x) > [![image](https://img.shields.io/pypi/pyversions/r2x.svg)](https://pypi.python.org/pypi/r2x) > [![CI](https://github.com/NREL/r2x/actions/workflows/CI.yaml/badge.svg)](https://github.com/NREL/r2x/actions/workflows/CI.yaml) > [![codecov](https://codecov.io/gh/NREL/r2x/branch/main/graph/badge.svg)](https://codecov.io/gh/NREL/r2x) > [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) > [![Documentation](https://github.com/NREL/R2X/actions/workflows/docs-build.yaml/badge.svg?branch=main)](https://nrel.github.io/R2X/)

## Table of contents
* [Installation](#installation)
* [Features](#features)
* [Documentation](#documentation)
* [Roadmap](#roadmap)
* [Compatibility](#compatibility)

- [Installation](#installation)
- [Features](#features)
- [Documentation](#documentation)
- [Roadmap](#roadmap)
- [Compatibility](#compatibility)

## Installation

Expand All @@ -32,18 +26,73 @@ Or use it as standalone tool,
uvx r2x --help
```

## Quick Start

Use of Sienna parser.

```python
import json

from r2x_sienna.config import SiennaConfig
from r2x_sienna.parser import SiennaParser
from r2x_sienna.upgrader.data_upgrader import SiennaUpgrader
from r2x_core.logger import setup_logging
from r2x_core.store import DataStore
from r2x_core.upgrader_utils import run_upgrade_step

# Use for debugging and see parser/exporter progress
setup_logging(level="DEBUG")

# Use for level info and store logging results to file
setup_logging(level="INFO", log_file="debug.log")

path_to_sys = "path/to/sienna_sys.json"

# Required if upgrading a psy4 to psy5 system
upgrader = SiennaUpgrader(path=path_to_sys)
result = None
with open(path_to_sys) as f:
loaded_sys = json.load(f)

for step in upgrader.list_steps():
result = run_upgrade_step(step, data=loaded_sys, upgrader_context={"info": "value"})

config = SiennaConfig(
model_year=2029,
system_name="Sienna System",
json_path=path_to_sys,
scenario="Base",
system_base_power=100.0,
skip_validation=False,
)
data_store = DataStore()
parser = SiennaParser(
config=config,
data_store=data_store,
name=sys_name,
skip_validation=False,
)
stdin_payload = json.dumps(loaded_sys)
sienna_sys = parser.build_system(stdin_payload=stdin_payload)
```

See the `examples/` directory for more usage patterns including validation, dry-run previews, and custom configuration.

## Features

- Simple, functional API with Result[T, E] pattern
- Validation before translation with helpful error messages
- Dry-run mode to preview translations
- I/O helpers for stdin/stdout workflows
- [PowerSystem.jl](https://github.com/NREL-Sienna/PowerSystems.jl) model representations
- Translate [ReEDS](https://github.com/NREL/ReEDS-2.0) models to PCM models like [Sienna](https://github.com/NREL-Sienna) or PLEXOS,
- Translate from PLEXOS XML's to Sienna,
- Comprehensive PLEXOS XML parser,
- Translate [ReEDS](https://github.com/NREL/ReEDS-2.0) models to PCM models like [Sienna](https://github.com/NREL-Sienna) or PLEXOS
- Translate from PLEXOS XML's to Sienna
- Comprehensive PLEXOS XML parser

## Documentation

R2X documentation is available at [https://nrel.github.io/R2X/](https://nrel.github.io/R2X/)


## Roadmap

If you're curious about what we're working on, check out the roadmap:
Expand All @@ -53,14 +102,13 @@ If you're curious about what we're working on, check out the roadmap:
- [Nice-to-have](https://github.com/NREL/R2X/labels/Optional): Nice to have features or Issues to fix. Anyone can start working on (please let us know before you do).
- [Ideas](https://github.com/NREL/R2X/issues?q=is%3Aopen+is%3Aissue+label%3AIdea): Future work or ideas for R2X.


## Model compatibility

| R2X Version | Supported Input Model Versions | Supported Output Model Versions |
|--------------|----------------------------------------- |----------------------------------------- |
| 1.0 | ReEDS (v2024.8.0) | PLEXOS (9.0, 9.2, 10) |
| | Sienna (PSY 3.0) | Sienna (PSY 3.0, 4.0) |
| | PLEXOS (9.0, 9.2, 10) | |
| R2X Version | Supported Input Model Versions | Supported Output Model Versions |
| ----------- | ------------------------------ | ------------------------------- |
| 1.0 | ReEDS (v2024.8.0) | PLEXOS (9.0, 9.2, 10) |
| | Sienna (PSY 3.0) | Sienna (PSY 3.0, 4.0) |
| | PLEXOS (9.0, 9.2, 10) | |

### Licence

Expand Down
7 changes: 0 additions & 7 deletions environment.yml

This file was deleted.

43 changes: 43 additions & 0 deletions packages/r2x-plexos-to-sienna/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# R2X PLEXOS to Sienna Translator

This package provides translation capabilities from PLEXOS XML database files to Sienna PowerSystems format.

## Usage

### Basic Translation

```python
from r2x_plexos_to_sienna import PlexosToSiennaTranslation
from r2x_core.logger import setup_logging

# Advanced logging
# setup_logging(
# level="DEBUG",
# fmt="<green>{time:YYYY-MM-DD HH:mm:ss}</green> <level>{extra[short_level]:<4}</level> {message}",
# log_file="debug.log"
# )

# Define input file
xml_path = "/path/to/xml"

# Step to extract desired model name (important to locate time series, otherwise sets a default)
#
db = PlexosDB.from_xml(xml_path)
model_names = db.list_objects_by_class(ClassEnum.Model)

# Create translator instance
translator = PlexosToSiennaTranslation(
xml_path=xml_path,
model_name=model_names[1] if model_names else "Base", # model_2012
)
# Run the translation
translator.run()
```

## Configuration

The translator uses configuration rules defined in `config/rules.json` to map PLEXOS objects to Sienna PowerSystems components.

## Output

The translation produces Sienna PowerSystems-compatible JSON files in the specified output directory.
12 changes: 12 additions & 0 deletions packages/r2x-plexos-to-sienna/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[project]
name = "r2x-plexos-to-sienna"
version = "0.0.0"
description = "Translation helpers for PLEXOS-to-Sienna interoperability."
requires-python = ">=3.11, <3.14"
dependencies = ["r2x-plexos>=0.1.2,<1.0.0", "r2x-sienna>=0.1.0,<1.0.0"]

[project.entry-points."r2x_plugin"]
plexos-to-sienna = "r2x_plexos_to_sienna.plugin:manifest"

[tool.setuptools.package-data]
r2x_plexos_to_sienna = ["config/*.json"]
26 changes: 26 additions & 0 deletions packages/r2x-plexos-to-sienna/src/r2x_plexos_to_sienna/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
"""R2X PLEXOS to Sienna Translation Plugin.

A plugin for translating PLEXOS model systems to Sienna format within the R2X framework.
"""

from importlib.metadata import version

from loguru import logger

from .getters import * # noqa: F403
from .plugin_config import PlexosToSiennaConfig

__version__ = version("r2x_plexos_to_sienna")


logger.disable("r2x_plexos_to_sienna")


__all__ = [
"PlexosToSiennaConfig",
"__version__",
]


def hello() -> str:
return "Hello from r2x-plexos-to-sienna!"
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
{
"prime_mover_types": {
"battery": "BA",
"caes": "CE",
"coal": "ST",
"gas-cc": "CC",
"gas-ct": "GT",
"lfill-gas": "GT",
"nuclear": "ST",
"o-g-s": "ST",
"biopower": "ST",
"beccs": "ST",
"hyd": "HY",
"hydud": "HY",
"hydund": "HY",
"hyded": "HY",
"hydend": "HY",
"hydnd": "HY",
"hydnpnd": "HY",
"hydsnd": "HY",
"hydro-d": "HY",
"can-imports": "HY",
"hydro-and": "HY",
"hydro-dispatch": "HY",
"pumped-hydro": "PS",
"upv": "PVe",
"distpv": "PVe",
"dupv": "PVe",
"csp": "CP",
"pvb": "PVe",
"wind-ons": "WT",
"wind-ofs": "WS",
"geothermal": "BT",
"geohydro": "BT",
"egs": "BT",
"egs-nearfield": "BT",
"rtes": "BT",
"smr": "FC",
"h2-ct": "GT",
"h2-cc": "CC",
"electrolyzer": "OT"
}
}
Loading
Loading