[
  {
    "path": ".claude/Sienna.md",
    "content": "# Sienna Programming Practices\n\nThis document describes general programming practices and conventions that apply across all Sienna packages (PowerSystems.jl, PowerSimulations.jl, PowerFlows.jl, PowerNetworkMatrices.jl, InfrastructureSystems.jl, etc.).\n\n## Performance Requirements\n\n**Priority:** Critical. See the [Julia Performance Tips](https://docs.julialang.org/en/v1/manual/performance-tips/).\n\n### Anti-Patterns to Avoid\n\n#### Type instability\n\nFunctions must return consistent concrete types. Check with `@code_warntype`.\n\n- Bad: `f(x) = x > 0 ? 1 : 1.0`\n- Good: `f(x) = x > 0 ? 1.0 : 1.0`\n\n#### Abstract field types\n\nStruct fields must have concrete types or be parameterized.\n\n- Bad: `struct Foo; data::AbstractVector; end`\n- Good: `struct Foo{T<:AbstractVector}; data::T; end`\n\n#### Untyped containers\n\n- Bad: `Vector{Any}()`, `Vector{Real}()`\n- Good: `Vector{Float64}()`, `Vector{Int}()`\n\n#### Non-const globals\n\n- Bad: `THRESHOLD = 0.5`\n- Good: `const THRESHOLD = 0.5`\n\n#### Unnecessary allocations\n\n- Use views instead of copies (`@view`, `@views`)\n- Pre-allocate arrays instead of `push!` in loops\n- Use in-place operations (functions ending with `!`)\n\n#### Captured variables\n\nAvoid closures that capture variables causing boxing. Pass variables as function arguments instead.\n\n#### Splatting penalty\n\nAvoid splatting (`...`) in performance-critical code.\n\n#### Abstract return types\n\nAvoid returning `Union` types or abstract types.\n\n#### Using `isa` in function logic\n\n**ABSOLUTELY FORBIDDEN unless the user explicitly asks for it.** Never write code that uses `isa` checks for type-based branching. This is always wrong — use multiple dispatch instead.\n\n- Bad: `if x isa Float64 ... elseif x isa Int ... end`\n- Good: Use multiple dispatch with specific type signatures\n- Bad: `function f(x); if x isa AbstractVector return sum(x) else return x end; end`\n- Good: `f(x::AbstractVector) = sum(x); f(x::Number) = x`\n\n**Why this matters:** `isa` checks force the compiler to handle multiple code paths at runtime, losing type information and preventing specialization. Multiple dispatch allows the compiler to generate optimized code for each type. Using `isa` is an anti-pattern that defeats Julia's core design.\n\n### Best Practices\n\n- Use `@inbounds` when bounds are verified\n- Use broadcasting (dot syntax) for element-wise operations\n- Avoid `try-catch` in hot paths\n- Use function barriers to isolate type instability\n\n> Apply these guidelines with judgment. Not every function is performance-critical. Focus optimization efforts on hot paths and frequently called code.\n\n## Code Conventions\n\nStyle guide: <https://sienna-platform.github.io/InfrastructureSystems.jl/stable/style/>\n\nFormatter (JuliaFormatter): Use the formatter script provided in each package.\n\nKey rules:\n\n- Constructors: use `function Foo()` not `Foo() = ...`\n- Asserts: prefer `InfrastructureSystems.@assert_op` over `@assert`\n- Globals: `UPPER_CASE` for constants\n- Exports: all exports in main module file\n- Comments: complete sentences, describe why not how\n\n## Documentation Practices and Requirements\n\nFramework: [Diataxis](https://diataxis.fr/)\n\nSienna guide: <https://sienna-platform.github.io/InfrastructureSystems.jl/stable/docs_best_practices/explanation/>\n\nDocstring requirements:\n\n- Scope: all elements of public interface (IS is selective about exports)\n- Include: function signatures and arguments list\n- Automation: `DocStringExtensions.TYPEDSIGNATURES` (`TYPEDFIELDS` used sparingly in IS)\n- See also: add links for functions with same name (multiple dispatch)\n\nAPI docs:\n\n- Public: typically in `docs/src/api/public.md` using `@autodocs` with `Public=true, Private=false`\n- Internals: typically in `docs/src/api/internals.md`\n\n## Design Principles\n\n- Elegance and concision in both interface and implementation\n- Fail fast with actionable error messages rather than hiding problems\n- Validate invariants explicitly in subtle cases\n- Avoid over-adherence to backwards compatibility for internal helpers\n\n## Contribution Workflow\n\nBranch naming: `feature/description` or `fix/description`\n\n1. Create feature branch\n2. Follow style guide and run formatter\n3. Ensure tests pass\n4. Submit pull request\n\n## AI Agent Guidance\n\n**Key priorities:** Read existing patterns first, maintain consistency, use concrete types in hot paths, run formatter, add docstrings to public API, ensure tests pass.\n\n**Critical rules:**\n- Always use `julia --project=<env>` (never bare `julia`)\n- **NEVER use `isa` in function logic** — use multiple dispatch instead. This is absolutely forbidden unless the user explicitly asks for it.\n- Never edit auto-generated files directly\n- Verify type stability with `@code_warntype` for performance-critical code\n- Consider downstream package impact\n\n## Julia Environment Best Practices\n\n**CRITICAL:** Always use `julia --project=<env>` when running Julia code in Sienna repositories. **NEVER** use bare `julia` or `julia --project` without specifying the environment. Each package typically defines dependencies in `test/Project.toml` for testing.\n\nCommon patterns:\n\n```sh\n# Run tests (using test environment)\njulia --project=test test/runtests.jl\n\n# Run specific test\njulia --project=test test/runtests.jl test_file_name\n\n# Run expression\njulia --project=test -e 'using PackageName; ...'\n\n# Instantiate environment\njulia --project=test -e 'using Pkg; Pkg.instantiate()'\n\n# Build docs (using docs environment)\njulia --project=docs docs/make.jl\n```\n\n**Why this matters:** Running without `--project=<env>` will fail because required packages won't be available in the default environment. The test/docs environments contain all necessary dependencies for their respective tasks.\n\n## Troubleshooting\n\n**Type instability**\n- Symptom: Poor performance, many allocations\n- Diagnosis: `@code_warntype` on suspect function\n- Solution: See performance anti-patterns above\n\n**Formatter fails**\n- Symptom: Formatter command returns error\n- Solution: Run the formatter script provided in the package (e.g., `julia -e 'include(\"scripts/formatter/formatter_code.jl\")'`)\n\n**Test failures**\n- Symptom: Tests fail unexpectedly\n- Solution: `julia --project=test -e 'using Pkg; Pkg.instantiate()'`\n"
  },
  {
    "path": ".claude/claude.md",
    "content": "# PowerSystems.jl\n\nData model library for power system simulation and optimization. Julia compat: `^1.10`.\n\n> **General Sienna Programming Practices:** For information on performance requirements, code conventions, documentation practices, and contribution workflows that apply across all Sienna packages, see [Sienna.md](Sienna.md).\n\n## Design Objectives\n\n**Primary goal:** Performance and expressiveness.\n\nComprehensive data model library for power system simulation, optimization, and dynamics analysis. Provides the `System` container and all component types (generators, loads, branches, storage, dynamic models). Consumed by PowerSimulations.jl, PowerFlows.jl, PowerNetworkMatrices.jl, and other Sienna packages. All code must be written with performance in mind.\n\n## File Structure\n\n### `src/`\n\nKey files:\n\n- `PowerSystems.jl` -- main module, exports, and includes\n- `base.jl` -- `System` type definition and core methods\n- `definitions.jl` -- core type definitions and enums\n- `deprecated.jl` -- deprecated function warnings\n- `subsystems.jl` -- subsystem management\n- `contingencies.jl` -- contingency definitions\n- `outages.jl` -- outage modeling\n- `component_selector.jl` -- component selection utilities\n- `data_format_conversions.jl` -- format conversion methods\n\n#### `models/`\n\nCore component models and definitions:\n\n- `components.jl` -- base component methods\n- `devices.jl` -- device implementations\n- `branches.jl` -- branch/transmission line definitions\n- `topological_elements.jl` -- buses and topology\n- `generation.jl` -- generation component definitions\n- `storage.jl` -- storage/battery definitions\n- `loads.jl` -- load component definitions\n- `reserves.jl` -- reserve ancillary services\n- `services.jl` -- all kinds of ancillary services (supertype to reserves)\n- `static_models.jl` -- static component definitions\n- `dynamic_generator.jl` -- dynamic generator models\n- `dynamic_inverter.jl` -- dynamic inverter models\n- `dynamic_branch.jl` -- dynamic branch models\n- `dynamic_loads.jl` -- dynamic load models\n- `HybridSystem.jl` -- hybrid renewable + storage systems\n- `serialization.jl` -- component serialization\n- `supplemental_constructors.jl` -- additional constructors\n- `supplemental_accessors.jl` -- getter methods\n- `supplemental_setters.jl` -- setter methods\n- `generated/` -- auto-generated component type files (**DO NOT EDIT directly**)\n- `cost_functions/` -- operational cost types (ThermalGenerationCost, StorageCost, etc.)\n\n#### `parsers/`\n\nData parsing and import functionality:\n\n- `common.jl` -- shared parsing utilities\n- `power_system_table_data.jl` -- CSV/table-based data parsing\n- `power_models_data.jl` -- PowerModels.jl format support\n- `psse_dynamic_data.jl` -- PSS/E dynamic data parsing\n- `pm_io/` -- PowerModels I/O (matpower.jl, psse.jl, pti.jl)\n- `im_io/` -- InteractiveModels I/O (matlab.jl)\n\n#### `utils/`\n\nUtility functions:\n\n- `print.jl` -- enhanced console display\n- `generate_struct_files.jl` -- generate component definitions\n- `logging.jl` -- logging configuration\n- `conversion.jl` -- unit and format conversions\n- `IO/` -- data validation (system_checks.jl, branchdata_checks.jl, base_checks.jl)\n\n#### `descriptors/`\n\nJSON schema and metadata:\n\n- `power_system_structs.json` -- component structure definitions\n- `power_system_inputs.json` -- input specifications\n\n### Other top-level directories\n\n- `test/` -- test suite\n- `docs/` -- documentation source\n- `scripts/` -- utility scripts (formatter)\n\n## Auto-Generation\n\nComponent structs are auto-generated from JSON descriptors (`src/descriptors/power_system_structs.json`). Generated files are in `src/models/generated/` and should **NOT** be edited directly. Over 140 component types are auto-generated.\n\nGenerator: `src/utils/generate_struct_files.jl`\n\nWorkflow:\n\n1. Edit `src/descriptors/power_system_structs.json` to define/modify struct fields\n2. Run the generation script\n3. Generated files include docstrings, constructors, and accessors automatically\n\n## Downstream Packages\n\n- **PowerSimulations.jl** -- production cost modeling and unit commitment\n- **PowerFlows.jl** -- power flow analysis\n- **PowerNetworkMatrices.jl** -- network matrix calculations\n- **PowerSystemsInvestmentsPortfolios.jl** -- capacity expansion portfolios\n\n## Dependencies\n\n- **InfrastructureSystems.jl** -- base types, system data management, time series\n- **PowerFlowData.jl** -- power flow data handling\n- **DataFrames.jl** -- tabular data processing\n- **TimeSeries.jl** -- time series data management\n- **PrettyTables.jl** -- enhanced console output\n\n## Core Abstractions\n\n### System\n\nMain container for power system data. Defined in `src/base.jl`.\n\nFields:\n\n- `data` -- `IS.SystemData` for storing components and time series\n- `frequency` -- system frequency (Hz)\n- `bus_numbers` -- set of bus numbers for validation\n- `runchecks` -- flag for data validation\n- `units_settings` -- unit system settings (`SYSTEM_BASE`, `DEVICE_BASE`, `NATURAL_UNITS`)\n\nKey methods: `add_component!`, `remove_component!`, `get_component`, `get_components`, `get_bus`, `set_units_base_system!`\n\n### Component\n\nAbstract base type for all power system elements.\n\nHierarchy:\n\n- **Topology** -- network topology elements: `Bus` (`ACBus`, `DCBus`), `Arc`, `Area`, `LoadZone`\n- **Device** -- physical equipment: `StaticInjection` (generators, loads, storage), `Branch` (lines, transformers)\n- **Service** -- ancillary services (reserves, AGC)\n- **DynamicComponent** -- dynamic models for stability analysis\n\n### StaticInjection\n\nStatic injection devices (generators, loads, storage).\n\n- **Generator:** `ThermalStandard`, `ThermalMultiStart`, `HydroDispatch`, `RenewableDispatch`, `RenewableNonDispatch`\n- **Storage:** `EnergyReservoirStorage`, `HybridSystem`\n- **ElectricLoad:** `PowerLoad`, `StandardLoad`, `InterruptiblePowerLoad`, `ControllableLoad`\n- **StaticInjectionSubsystem:** grouped injection components\n\n### Branch\n\nTransmission elements connecting buses. Branches that contain Arcs with ACBuses are AC Branches and branches with DCBuses are DC Branches.\n\n- **ACBranch:** `Line`, `TwoWindingTransformer`, `PhaseShiftingTransformer`, `TapTransformer`, `TwoTerminalHVDCLine`, `MonitoredLine`\n- **DCBranch:** `TModelHVDCLine`\n- **ControlledBranch:** `DiscreteControlledACBranch`\n\n### DynamicInjection\n\nDynamic models for transient stability.\n\n- **DynamicGenerator** -- synchronous machines with AVR, PSS, TurbineGovernor\n- **DynamicInverter** -- inverter-based resources with converter, filter, controls\n\n### Service\n\nAncillary services and system requirements.\n\n- **Reserve:** `ConstantReserve`, `VariableReserve`, `ReserveDemandCurve`\n- **AGC** -- automatic generation control\n- **TransmissionInterface** -- interface flow limits\n\n### OperationalCost\n\nCost structures for component operations.\n\n- **ThermalGenerationCost** -- thermal unit costs with fuel, startup, variable O&M\n- **HydroGenerationCost** -- hydro unit costs\n- **RenewableGenerationCost** -- renewable unit costs\n- **StorageCost** -- storage operation costs\n- **MarketBidCost** -- market bid/offer curves\n\n### TimeSeriesData\n\nTime-varying data attached to components.\n\n- **SingleTimeSeries** -- single scenario time series\n- **Deterministic** -- deterministic forecast\n- **Probabilistic** -- probabilistic forecast with scenarios\n\n## Common Tasks\n\n```sh\n# Dev local copy\njulia --project=test -e 'using Pkg; Pkg.develop(path = \".\")'\n\n# Run all tests\njulia --project=test test/runtests.jl\n\n# Run specific tests (without extension)\njulia --project=test test/runtests.jl <test_file_name_without_extension>\n# Example:\njulia --project=test test/runtests.jl test_plant_attributes\n\n# Build docs\njulia --project=docs docs/make.jl\n\n# Format code\njulia -e 'include(\"scripts/formatter/formatter_code.jl\")'\n\n# Check formatting\ngit diff --exit-code\n\n# Instantiate test environment\njulia --project=test -e 'using Pkg; Pkg.instantiate()'\n\n# Generate structs\njulia --project=test -e \"using InfrastructureSystems; InfrastructureSystems.generate_structs(\\\"./src/descriptors/power_system_structs.json\\\", \\\"./src/models/generated\\\")\"\n```\n\n## PowerSystems.jl Specific Guidelines\n\n### Julia Environment\n\n**Always use `julia --project=test`** when running Julia code in this repository. See [Sienna.md](Sienna.md) for general Julia environment best practices. The `test/Project.toml` defines all required dependencies including PowerSystems, PowerSystemCaseBuilder, and InfrastructureSystems.\n\n### Working with Auto-Generated Code\n\nComponent structs are auto-generated from `src/descriptors/power_system_structs.json`. Over 140 component types are auto-generated.\n\n**DO NOT** edit files in `src/models/generated/` directly. Instead:\n\n1. Edit `src/descriptors/power_system_structs.json` to define/modify struct fields\n2. Run the generation script: `julia --project=test -e \"using InfrastructureSystems; InfrastructureSystems.generate_structs(\\\"./src/descriptors/power_system_structs.json\\\", \\\"./src/models/generated\\\")\"`\n3. Generated files include docstrings, constructors, and accessors automatically\n\n### PowerSystems-Specific Patterns\n\n- **Component addition:** Use `add_component!(sys, component)` not direct insertion\n- **Component retrieval:** Use `get_component(Type, sys, name)` or `get_components(Type, sys)`\n- **Time series:** Always attach to components, never store standalone\n- **Units:** Be mindful of `SYSTEM_BASE`, `DEVICE_BASE`, `NATURAL_UNITS` settings\n- **Validation:** Use `runchecks=true` during development to catch issues early\n- **Bus numbers:** Must be unique across system; validated on add\n"
  },
  {
    "path": ".devcontainer/devcontainer.json",
    "content": "{\n    \"extensions\": [\n        \"julialang.language-julia\"\n    ],\n    \"image\": \"ghcr.io/julia-vscode/julia-devcontainer\"\n}\n"
  },
  {
    "path": ".editorconfig",
    "content": "# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\ninsert_final_newline = true\n\n# Julia files\n[*.jl]\nindent_style = space\nindent_size = 4\ntrim_trailing_whitespace = true\n"
  },
  {
    "path": ".github/copilot-setup-steps.yml",
    "content": "name: \"Copilot Setup Steps\"\n\non: workflow_dispatch\n\njobs:\n  copilot-setup:\n    runs-on: ubuntu-latest\n    steps:\n      - name: Checkout repository\n        uses: actions/checkout@v4\n\n      - name: Set up Julia\n        uses: julia-actions/setup-julia@v2\n        with:\n          version: \"1\"\n\n      - name: Install documentation dependencies\n        run: |\n          julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "Thanks for opening a PR to PowerSystems.jl, please take note of the following when making a PR:\n\nCheck the [contributor guidelines](https://sienna-platform.github.io/PowerSystems.jl/stable/api/developer_guidelines/)\n\n1. Add a description of the changes proposed in the pull request.\n2. Is my PR fixing an open issue? Add the reference to the related issue\n3. If you are contributing a new struct: please refer to the [testing requirements for new structs](https://sienna-platform.github.io/PowerSystems.jl/stable/how_to/add_new_types/#Testing-the-addition-of-new-struct-to-the-code-base)\n"
  },
  {
    "path": ".github/workflows/TagBot.yml",
    "content": "name: TagBot\non:\n  issue_comment:\n    types:\n      - created\n  workflow_dispatch:\njobs:\n  TagBot:\n    if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot'\n    runs-on: ubuntu-latest\n    steps:\n      - uses: JuliaRegistries/TagBot@v1\n        with:\n          token: ${{ secrets.GITHUB_TOKEN }}\n          ssh: ${{ secrets.DOCUMENTER_KEY }}\n"
  },
  {
    "path": ".github/workflows/cross-package-test.yml",
    "content": "name: CrossPackageTest\n\non:\n  push:\n    branches: [main]\n    tags: [v*]\n  pull_request:\n\njobs:\n  test:\n    name: Julia v${{ matrix.julia-version }} - ${{ matrix.package_name }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        julia-version: [1]\n        os: [ubuntu-latest]\n        package_name: [PowerSimulations, PowerSystemCaseBuilder, PowerNetworkMatrices, PowerFlows]\n    continue-on-error: true\n    steps:\n      - uses: actions/checkout@v2\n      - uses: julia-actions/setup-julia@v2\n        with:\n          version: ${{ matrix.julia-version }}\n          arch: x64\n      - uses: julia-actions/julia-buildpkg@latest\n      - name: Clone ${{matrix.package_name}}\n        uses: actions/checkout@v2\n        with:\n          repository: Sienna-Platform/${{matrix.package_name}}.jl\n          path: downstream\n      - name: Run the tests\n        shell: julia --project=downstream {0}\n        run: |\n          using Pkg\n          try\n            # Force it to use this PR's version of the package\n            Pkg.develop(PackageSpec(path=\".\"))  # resolver may fail with main deps\n            Pkg.update()\n            Pkg.test()  # resolver may fail with test time deps\n          catch err\n            err isa Pkg.Resolve.ResolverError || rethrow()\n            # If we can't resolve that means this is incompatible by SemVer, and this is fine.\n            # It means we marked this as a breaking change, so we don't need to worry about\n            # mistakenly introducing a breaking change as we have intentionally made one.\n            @info \"Not compatible with this release. No problem.\" exception=err\n            exit(0)  # Exit immediately, as a success\n          end\n"
  },
  {
    "path": ".github/workflows/doc-preview-cleanup.yml",
    "content": "name: Doc Preview Cleanup\n\non:\n  pull_request:\n    types: [closed]\n\n# Ensure that only one \"Doc Preview Cleanup\" workflow is force pushing at a time\nconcurrency:\n  group: doc-preview-cleanup\n  cancel-in-progress: false\n\njobs:\n  doc-preview-cleanup:\n    runs-on: ubuntu-latest\n    if: github.event.pull_request.head.repo.fork == false\n    # This workflow pushes to gh-pages; permissions are per-job and independent of docs.yml\n    permissions:\n      contents: write\n    steps:\n      - name: Checkout gh-pages branch\n        uses: actions/checkout@v4\n        with:\n          ref: gh-pages\n      - name: Delete preview and history + push changes\n        run: |\n          if [ -d \"${preview_dir}\" ]; then\n              git config user.name \"Documenter.jl\"\n              git config user.email \"documenter@juliadocs.github.io\"\n              git rm -rf \"${preview_dir}\"\n              git commit -m \"delete preview\"\n              git branch gh-pages-new \"$(echo \"delete history\" | git commit-tree \"HEAD^{tree}\")\"\n              git push --force origin gh-pages-new:gh-pages\n          fi\n        env:\n          preview_dir: previews/PR${{ github.event.number }}\n"
  },
  {
    "path": ".github/workflows/docs.yml",
    "content": "name: Documentation\n\non:\n  push:\n    branches:\n      - main\n      - 'release-'\n    tags: '*'\n  pull_request:\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - uses: julia-actions/setup-julia@v2\n        with:\n          version: '1'\n      - name: Install dependencies\n        run: julia --project=docs/ -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'\n\n      - name: Set DOCUMENTER_CURRENT_VERSION for tutorial download links\n        run: |\n          if [[ \"${{ github.event_name }}\" == \"pull_request\" ]]; then\n            echo \"DOCUMENTER_CURRENT_VERSION=previews/PR${{ github.event.pull_request.number }}\" >> \"$GITHUB_ENV\"\n          elif [[ \"${{ github.ref }}\" == refs/tags/* ]]; then\n            echo \"DOCUMENTER_CURRENT_VERSION=${GITHUB_REF_NAME}\" >> \"$GITHUB_ENV\"\n          elif [[ \"${{ github.ref }}\" == \"refs/heads/main\" ]] || [[ \"${{ github.ref }}\" =~ ^refs/heads/release- ]]; then\n            echo \"DOCUMENTER_CURRENT_VERSION=dev\" >> \"$GITHUB_ENV\"\n          fi\n      - name: Build and deploy\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}\n        run: julia --project=docs --color=yes docs/make.jl\n"
  },
  {
    "path": ".github/workflows/fix-docs-on-failure.yml",
    "content": "name: Auto-fix Documentation Failures\n\non:\n  workflow_run:\n    workflows: [\"Documentation\"]\n    types:\n      - completed\n    branches:\n      - main\n\npermissions:\n  issues: write\n  actions: read\n  pull-requests: read\n\njobs:\n  open-copilot-issue:\n    runs-on: ubuntu-latest\n    if: ${{ github.event.workflow_run.conclusion == 'failure' }}\n    steps:\n      - name: Create or update Copilot issue for docs failure\n        uses: actions/github-script@v7\n        with:\n          script: |\n            const runId = context.payload.workflow_run.id;\n            const runUrl = context.payload.workflow_run.html_url;\n            const headSha = context.payload.workflow_run.head_sha;\n            const owner = context.repo.owner;\n            const repo = context.repo.repo;\n\n            // --- Gather failure logs ---\n            const { data: jobsData } = await github.rest.actions.listJobsForWorkflowRun({\n              owner, repo, run_id: runId, filter: 'latest',\n            });\n\n            let failureSummary = '';\n            for (const job of jobsData.jobs) {\n              if (job.conclusion === 'failure') {\n                failureSummary += `### Job: ${job.name}\\n`;\n                failureSummary += `- **Status:** ${job.conclusion}\\n`;\n                failureSummary += `- **URL:** ${job.html_url}\\n\\n`;\n\n                try {\n                  const logResponse = await github.rest.actions.downloadJobLogsForWorkflowRun({\n                    owner, repo, job_id: job.id,\n                  });\n                  const logLines = logResponse.data.split('\\n');\n                  const tail = logLines.slice(-200).join('\\n');\n                  failureSummary += '<details><summary>Log tail (last 200 lines)</summary>\\n\\n```\\n' + tail + '\\n```\\n</details>\\n\\n';\n                } catch (e) {\n                  failureSummary += `_Could not fetch logs: ${e.message}_\\n\\n`;\n                }\n              }\n            }\n\n            // --- Check for an existing open issue ---\n            const { data: issues } = await github.rest.issues.listForRepo({\n              owner, repo,\n              labels: 'documentation,copilot',\n              state: 'open',\n              per_page: 5,\n            });\n            const existingIssue = issues.find(i =>\n              i.title.startsWith('[Copilot] Fix documentation build failure')\n            );\n\n            // --- Check for open PRs (including drafts) already addressing docs failures ---\n            const { data: openPRs } = await github.rest.pulls.list({\n              owner, repo,\n              state: 'open',\n              per_page: 30,\n            });\n            const docFixPRs = openPRs.filter(pr => {\n              const title = pr.title.toLowerCase();\n              const body = (pr.body || '').toLowerCase();\n              const labels = pr.labels.map(l => l.name.toLowerCase());\n              return (\n                labels.includes('documentation') ||\n                title.includes('documentation') ||\n                /\\bdocs?\\b/.test(title) ||\n                body.includes('documentation build failure') ||\n                body.includes('docs/make.jl')\n              );\n            });\n\n            let prSection = '';\n            if (docFixPRs.length > 0) {\n              prSection = '### Existing PRs that may address this failure\\n\\n';\n              prSection += 'Check these open PRs (including drafts) before starting work — they may already fix some or all of the errors:\\n\\n';\n              for (const pr of docFixPRs) {\n                const draft = pr.draft ? ' (draft)' : '';\n                prSection += `- #${pr.number}${draft}: ${pr.title}\\n`;\n              }\n              prSection += '\\nIf an existing PR already resolves the failure, close this issue. Otherwise, coordinate with or build on the existing PR.\\n\\n';\n            }\n\n            // --- Build issue body ---\n            const body = [\n              '## Documentation build failed on `main`',\n              '',\n              `The [Documentation workflow run](${runUrl}) (run ID: \\`${runId}\\`) failed at commit \\`${headSha}\\`.`,\n              '',\n              prSection,\n              '### Task',\n              'Please investigate the documentation build failure and open a PR to fix it.',\n              \"The documentation is built with Julia's Documenter.jl package. The build script is at `docs/make.jl`.\",\n              '',\n              '### Cross-repo documentation context',\n              '',\n              'PowerSystems.jl docs are linked to other Sienna packages via [DocumenterInterLinks.jl](https://github.com/JuliaDocumenter/DocumenterInterLinks.jl).',\n              'The `docs/make.jl` file configures `InterLinks` to resolve `@extref` cross-references to other repos in the **Sienna-Platform** (and **NLR-Sienna**) GitHub orgs.',\n              '',\n              '**Common cross-repo causes of documentation failures:**',\n              '- Missing or renamed docstrings in a dependency (e.g., `InfrastructureSystems.jl`) that are referenced via `@extref`',\n              '- Ambiguous docstrings that are imported from another package and re-exported by PowerSystems.jl — these need disambiguation in the `@autodocs` or `@docs` blocks',\n              '- Broken `InterLinks` URLs when a dependency has reorganized or redeployed its documentation',\n              '- `ExternalFallbacks` in `docs/make.jl` that reference symbols no longer present in the upstream package',\n              '',\n              '**If the fix belongs in another repository:**',\n              '- Open a PR in the appropriate **Sienna-Platform/** or **NLR-Sienna/** repo (e.g., `InfrastructureSystems.jl`) to fix the upstream docstring or export',\n              '- Link the upstream PR in this issue and in any PowerSystems.jl PR',\n              '- If a temporary workaround is possible in PowerSystems.jl (e.g., updating `ExternalFallbacks`), include it and note the upstream PR that provides the permanent fix',\n              '',\n              '### Other common causes',\n              '- Docstring errors or missing exports in this repo',\n              '- Broken cross-references or links',\n              '- Literate.jl script errors in `docs/src/`',\n              '- Dependency issues in `docs/Project.toml`',\n              '',\n              '### Documentation guidelines',\n              '',\n              'Follow these guidelines when making documentation changes:',\n              '- [Sienna documentation practices](https://github.com/Sienna-Platform/InfrastructureSystems.jl/blob/main/.claude/Sienna.md) (see \"Documentation Practices and Requirements\")',\n              '- [Sienna docs best practices](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/docs_best_practices/explanation/)',\n              '- [Diataxis framework](https://diataxis.fr/)',\n              '',\n              '### Failure Details',\n              failureSummary,\n            ].join('\\n');\n\n            if (existingIssue) {\n              // Update the existing issue with new failure info\n              const comment = [\n                '## New documentation build failure',\n                '',\n                `A new failure occurred at commit \\`${headSha}\\`.`,\n                '',\n                `[Workflow run](${runUrl})`,\n                '',\n                prSection,\n                failureSummary,\n              ].join('\\n');\n\n              await github.rest.issues.createComment({\n                owner, repo,\n                issue_number: existingIssue.number,\n                body: comment,\n              });\n              console.log(`Updated existing issue #${existingIssue.number}`);\n            } else if (docFixPRs.length > 0) {\n              // There are already open PRs that may fix this — don't create a duplicate issue,\n              // just add a comment on the most recent relevant PR\n              const targetPR = docFixPRs[0];\n              await github.rest.issues.createComment({\n                owner, repo,\n                issue_number: targetPR.number,\n                body: [\n                  '## Documentation build still failing on `main`',\n                  '',\n                  `The [Documentation workflow](${runUrl}) failed at commit \\`${headSha}\\`.`,\n                  'This PR may already address the failure — please verify.',\n                  '',\n                  failureSummary,\n                ].join('\\n'),\n              });\n              console.log(`Commented on existing docs PR #${targetPR.number}`);\n            } else {\n              // Ensure labels exist\n              for (const label of ['documentation', 'copilot']) {\n                try {\n                  await github.rest.issues.getLabel({ owner, repo, name: label });\n                } catch {\n                  const colors = { documentation: '0075ca', copilot: 'c2e0c6' };\n                  const descriptions = {\n                    documentation: 'Improvements or additions to documentation',\n                    copilot: 'Copilot agent task',\n                  };\n                  await github.rest.issues.createLabel({\n                    owner, repo, name: label,\n                    color: colors[label],\n                    description: descriptions[label],\n                  });\n                }\n              }\n\n              // Create a new issue\n              const { data: issue } = await github.rest.issues.create({\n                owner, repo,\n                title: `[Copilot] Fix documentation build failure (${headSha.slice(0, 7)})`,\n                body: body,\n                labels: ['documentation', 'copilot'],\n              });\n\n              // Assign the issue to Copilot to trigger the coding agent\n              try {\n                await github.rest.issues.addAssignees({\n                  owner, repo,\n                  issue_number: issue.number,\n                  assignees: ['copilot'],\n                });\n                console.log(`Created issue #${issue.number} and assigned to Copilot`);\n              } catch (e) {\n                // If assigning fails, mention @copilot in a comment as fallback\n                console.log(`Could not assign to copilot: ${e.message}`);\n                await github.rest.issues.createComment({\n                  owner, repo,\n                  issue_number: issue.number,\n                  body: '@copilot',\n                });\n                console.log(`Created issue #${issue.number} and mentioned @copilot in comment`);\n              }\n            }\n"
  },
  {
    "path": ".github/workflows/format-check.yml",
    "content": "name: Format Check\n\non:\n  push:\n    branches:\n      - 'main'\n      - 'release-'\n    tags: '*'\n  pull_request:\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        julia-version: [1]\n        julia-arch: [x86]\n        os: [ubuntu-latest]\n    steps:\n      - uses: julia-actions/setup-julia@latest\n        with:\n          version: ${{ matrix.julia-version }}\n\n      - uses: actions/checkout@v4\n      - name: Install JuliaFormatter and format\n        run: |\n          julia  -e 'include(\"scripts/formatter/formatter_code.jl\")'\n      - uses: reviewdog/action-suggester@v1\n        if: github.event_name == 'pull_request'\n        with:\n          tool_name: JuliaFormatter\n          fail_on_error: true\n      - name: Format check\n        run: |\n          julia -e '\n          out = Cmd(`git diff --name-only`) |> read |> String\n          if out == \"\"\n              exit(0)\n          else\n              @error \"Some files have not been formatted !!!\"\n              write(stdout, out)\n              exit(1)\n          end'\n"
  },
  {
    "path": ".github/workflows/main-tests.yml",
    "content": "name: Main - CI\n\non:\n  schedule:\n  - cron: \"0 0 * * 1-5\"\n  push:\n    branches:\n      - main\n\njobs:\n  test:\n    name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        julia-version: ['1', 'nightly']\n        julia-arch: [x64]\n        os: [ubuntu-latest, windows-latest, macOS-latest]\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: julia-actions/setup-julia@latest\n        with:\n          version: ${{ matrix.julia-version }}\n          arch: ${{ matrix.julia-arch }}\n      - uses: julia-actions/julia-buildpkg@latest\n        env:\n          PYTHON: \"\"\n      - uses: julia-actions/julia-runtest@latest\n        continue-on-error: ${{ matrix.julia-version == 'nightly' }}\n        env:\n          PYTHON: \"\"\n      - uses: julia-actions/julia-processcoverage@v1\n      - uses: codecov/codecov-action@v1\n        with:\n          file: ./lcov.info\n          flags: unittests\n          name: codecov-umbrella\n          fail_ci_if_error: false\n          token: ${{ secrets.CODECOV_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/pr_testing.yml",
    "content": "name: Test-CI\n\non:\n  pull_request:\n    types: [opened, synchronize, reopened]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  test:\n    name: Julia ${{ matrix.julia-version }} - ${{ matrix.os }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        julia-version: ['1']\n        julia-arch: [x64]\n        os: [ubuntu-latest, windows-latest, macOS-latest]\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: julia-actions/setup-julia@latest\n        with:\n          version: ${{ matrix.julia-version }}\n          arch: ${{ matrix.julia-arch }}\n      - uses: julia-actions/julia-buildpkg@latest\n        env:\n          PYTHON: \"\"\n      - uses: julia-actions/julia-runtest@latest\n        env:\n          PYTHON: \"\"\n      - uses: julia-actions/julia-processcoverage@v1\n      - uses: codecov/codecov-action@v4\n        with:\n          file: ./lcov.info\n          flags: unittests\n          name: codecov-umbrella\n          fail_ci_if_error: false\n          token: ${{ secrets.CODECOV_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "#Files generated by invoking Julia with --code-coverage\n*.jl.cov\n*.jl.*.cov\n*.log\n_*.jl\n# Files generated by invoking Julia with --track-allocation\n*.jl.mem\n\n## Autogenerated code during the documentation process\ngenerated*.md\ndocs/src/tutorials/generated/\n\n*.raw\n\n# Test data\ndata\n\n# System-specific files and directories generated by the BinaryProvider and BinDeps packages\n# They contain absolute paths specific to the host computer, and so should not be committed\ndeps/deps.jl\ndeps/build.log\ndeps/downloads/\ndeps/usr/\ndeps/src/\n\n# Build artifacts for creating documentation generated by the Documenter package\ndocs/build/\ndocs/site/\n\n#Jupyter Ignores\n.ipynb_checkpoints/\n.ipynb_checkpoints\n\n#Mac temp ignores\n.DS_Store\n\n#Figures\n*.pdf\n*.ipynb\n\nManifest.toml\n.vscode\n*.h5\n\n################################################################################\n#                              Operating systems                               #\n################################################################################\n\n########################################\n#                Linux                 #\n########################################\n\n*~\n\n# temporary files which can be created if a process still has a handle open of\n# a deleted file\n.fuse_hidden*\n\n# KDE directory preferences\n.directory\n\n# Linux trash folder which might appear on any partition or disk\n.Trash-*\n\n# .nfs files are created when an open file is removed but is still being accessed\n.nfs*\n\n########################################\n#                macOS                 #\n########################################\n\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n########################################\n#               Windows                #\n########################################\n\n# Windows thumbnail cache files\nThumbs.db\nehthumbs.db\nehthumbs_vista.db\n\n# Dump file\n*.stackdump\n\n# Folder config file\n[Dd]esktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Windows Installer files\n*.cab\n*.msi\n*.msix\n*.msm\n*.msp\n\n# Windows shortcuts\n*.lnk\n\n## Acknowledgements\n# Many thanks to `https://gitignore.io/`, written and maintained by Joe Blau, which contributed much material to this gitignore file.\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "repos:\n  - repo: local\n    hooks:\n      - id: julia-formatter\n        name: Run Julia formatter\n        entry: julia scripts/formatter/formatter_code.jl\n        language: system\n        types: [file]\n        pass_filenames: false\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# PowerSystems Change Log\n\n## 1.0.0 Announcement\n\nAfter 1.0.0 release, the manual Changelog will no longer be maintained. Please refer to the [releases page](https://github.com/Sienna-Platform/PowerSystems.jl/releases) to follow up with the changes.\n\n## 0.28.0\n\n- Export additional methods\n- Change System constructor that takes iterable arguments\n\n## 0.27.0\n\n- Change errors to warnings when validating impedance values in AC Branches\n- Add Support for non-spinning reserve (Thanks @andrewrosemberg)\n- Add costs to reserve products (Thanks @andrewrosemberg)\n- Improvements to documentation\n- Extend parsing of PSS/e dyr files\n- Modifications to dynamic structs to support (min, max) tuples\n\n\n## 0.26.0\n\n- Add conversion field to HydroStorage\n- Bug fix in add_component for RegulationDevice\n- Add StaticReserveGroup object (Thanks @andrewrosemberg)\n\n\n## 0.25.0\n\n- Bug fix in units settings when parsing TableData\n- Add defaults for ThermalStandard Fuel and Prime Mover (Thanks @raphaelsaavedra)\n- Bug Fix cost data in TableData Parsing\n- Bump IS version and remove type inputs to setter functions\n\n## 0.24.1\n\n- Add pss/e .dyr file parsing support\n- Bug fixes in staturation data GENROU and GENROE\n- Bug fixes in TableData parsing\n\n## 0.24.0\n\n- Change the use of @forward macros to avoid world of age errors\n- Change DynamicMachines constructors to avoid de-serialization errors\n- Change implementation of DynamicBranches\n- Change implementation of RegulatioDevices\n\n## 0.23.3\n\n- Bug fixes in TableDataParsing\n- Improvements in RegulationDevice getter functions\n- Addition of get_max_reactive_power for RenewableDispatch\n\n## 0.23.2\n\n- Bug fixes in TableDataParsing\n- Add get_max_reactive_power for RenewableGeneration with PowerFactor\n\n## 0.23.1\n\n- Fix bug in DynamicGenerator constructor\n- Add additional get_value methods for ThermalStandard ramps\n- Improve testing\n\n## 0.23.0\n\n- Addition of get_max_active_power, get_max_reactive_power accessor functions\n- Enable serialization of DynamicLines\n- Islanding detection in PTDF, LODF and Ybus calculations\n- Remove MVABase field from DynamicInverter\n\n## 0.22.0\n\n- Addition of DynamicLines Struct\n- Renames of Fields in Structs to match code guidelines\n- Store RAW Electric Source Data (Z) in Thermal Generators\n- Implement UnitsInfo to return data in different bases accordingly\n- Update Autogeneration of structs.\n\n## 0.21.0\n\n- Improvements to Power Flow solve: Add Jacobian Function, add a method that modifies the system and one that returns results\n- Improvements to TableData Parsing\n- Add new methods to get admittance from branches\n- Add Monitored Line to PTDF\n\n## 0.20.1\n\n- Add AC1A, ST1A, GasTG structs for dynamic modeling.\n- Implement heuristic in pwl data to avoid NaN\n- Bug fixes with Regulation Devices\n- Improved testing.\n\n## 0.20.0\n\n- Add Support for MultiStart Thermal Generation (a.k.a. PGLIB Model)\n- Performance updates to Power Flow.\n- Remove Make PF function.\n- Fixin forecast handling of composed structs\n- Update to IS v0.11\n- Add SalientPoleGenerator and RoundRotorGenerator with saturation variants\n- Add regulation device composed with generators\n- Add Basepower field to InjectionDevices in system's per unit\n- Add readonly option for seralization of time series\n\n## 0.19.0\n\n- Update for IS 0.9\n- Change behaviour of get_component\n\n## 0.18.5\n\n- Bug fix for serialization\n\n## 0.18.4\n\n- Add deepcopy method for system\n\n## 0.18.3\n\n- Bug fix in serialization to folder\n\n## 0.18.2\n\n- Fix potential miscalculation of PWL upper bound limits\n\n## 0.18.1\n\n- Remove warning PWL get_slope function\n\n## 0.18.0\n\n- Add functions to to get breakpoints and slopes from PWL cost functions\n- Add getter function support for generated structs\n- Enable addition of DynamicInjections to StaticInjection components and associated methods\n\n## 0.17.2\n\n- Add DemandCurveReserve\n- Add functions to manipilate pwl cost functions\n\n## 0.17.1\n\n- Fix bug with frequency de-serialization\n\n## 0.17.0\n\n- Fix Serialization of DynamicInverter\n- Fix remove_component for Area\n- Add available fields for Reserves\n\n## 0.16.0\n\n- Changes to DynamicInverter and DynamicGenerator structs\n- Bugfix in solve_powerflow!\n- add option to set store location of hdf5 file\n\n## v0.15.2\n\n- add get_available_components method\n\n## v0.15.1\n\n- add has_forecasts method\n\n## v0.15.0\n- Add filtering function to get_components\n- Add Parser for Texas A&M models\n- Add tiime_at_status field in ThermalStandard\n\n## v0.14.1\n\n- Update InfrastructureSystems dependency\n\n## v0.14.0\n\n- Update names and contents of Dynamic Structs, RenewableGen, HydroGen and ThermalGen\n\n## v0.13.1\n\n- Update CSV dependency to v0.6\n\n## v0.13.0\n\n- Change uses of Load Zone and Area\n- Add AGC service\n- Remove unnecessary fields in transfer service\n- Add participation factor field in TechThermal\n\n## v0.12.0\n\n- Make LoadZone and Area optional Bus Inputs\n\n## v0.11.2\n\n- Reduce warning print for unsupported columns outs when parsing data\n\n## v0.11.1\n\n- Change device internal forecasts field name\n\n## v0.11.0\n\n- Add support for Load Zones and Areas\n- Add return status for power flows\n- Change behavior of Matpower and PTI files parsing\n\n## v0.10.0\n\n- Update PTI parsing code from PM and IM\n- Modify the user's interface for enums\n\n## v0.9.1\n\n- Update Struct autogeneration code\n\n## v0.9.0\n\n- Update Hydropower structs naming\n\n## v0.8.6\n\n- Add missing getter functions for DynamicInverter and DynamicGenerator\n- Add missing getter functions for System fields.\n- Add frequency field to System and DEFAULT_SYSTEM_FREQUENCY\n\n## v0.8.5\n\n- Add functions to handle DynamicInjection components\n\n## v0.8.4\n\n- Fix 7z error in Julia 1.3 and Windows\n- Bugfix in pu conversion in HVDC Table Data\n- Improve testing\n\n## v0.8.3\n\n- Update DynamicGenerator and DynamicInverter to comply with PSY\n- Change get_components to support parametrized structs\n- Improve testing of dynamic structs\n\n## v0.8.2\n\n- Update package dependencies compatibility\n- Add range to struct docstrings\n- Hydropower data parsing improvements\n\n## v0.8.1\n\n- Bugfix TableData HydroStorage\n\n## v0.8.0\n\n- Updated HydroDispatch and removed HydroStorage\n\n## v0.7.1\n\n- Bugfix services removal\n\n## v0.7.0\n\n- Make codebase consistent with the style guides.\n- Add Dynamic Data capabilities.\n- Change the use of services and store them inside of devices.\n- Add ext field to devices\n- Add ext field to the system\n\n## v0.6.2\n\n- Downgrade compatible version of CSV to 0.5.13 to avoid tab-complete hang.\n- Bug Fix in docstrings autogeneration code\n- Contiguous forecasts function added\n\n## v0.6.1\n\n- Remove bin from auto-generation code\n- Updated docstrings\n\n## v0.6.0\n\n- Use accessor functions instead of labels to get forecasts\n- Bug Fix in code autogeneration\n\n## v0.5.2\n\n- Enforce unique bus numbers\n- Set min version of IS to 0.2.4\n\n## v0.5.1\n\n- Bugfix in generate_initial_times\n- Bug fixes on SystemTable Data\n\n## v0.5.0\n\n- Store and access forecast data from Disk\n\n## v0.4.3\n\n- Fix Parsing bug in Table data #362\n- Enable custom validation descriptors when parsing PSS/e and MATPOWER files\n- Enable multiple loads per bus when parsing PSS/e and MATPOWER files\n- Support multiple generators per bus and non-sequential bus indexing in power flow\n\n## v0.4.2\n\n- Fix printing of forecasts #350 fixing #343\n\n## v0.1.1\n\n- Update to Julia-v0.7\n\n## v0.1.0\n\n- Initial implementation\n"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n- family-names: \"Lara\"\n  given-names: \"José Daniel\"\n- family-names: \"Barrows\"\n  given-names: \"Clayton\"\n- family-names: \"Thom\"\n  given-names: \"Daniel\"\n- family-names: \"Krishnamurthy\"\n  given-names: \"Dheepak\"\n- family-names: \"Callaway\"\n  given-names: \"Duncan\"\ntitle: \"PowerSystems.jl — A power system data management package for large scale modeling\"\nversion: 1.0.0\ndoi: 10.5281/zenodo.1234\ndate-released: 2021-09-21\nurl: \"https://github.com/Sienna-Platform/PowerSystems.jl\"\npreferred-citation:\n  type: article\n  authors:\n  - family-names: \"Lara\"\n    given-names: \"José Daniel\"\n  - family-names: \"Barrows\"\n    given-names: \"Clayton\"\n  - family-names: \"Thom\"\n    given-names: \"Daniel\"\n  - family-names: \"Krishnamurthy\"\n    given-names: \"Dheepak\"\n  - family-names: \"Callaway\"\n    given-names: \"Duncan\"\n  title: \"PowerSystems.jl — A power system data management package for large scale modeling\"\n  journal: \"SoftwareX\"\n  volume: 15\n  month: 7\n  doi: \"https://doi.org/10.1016/j.softx.2021.100747\"\n  url: \"https://www.sciencedirect.com/science/article/pii/S2352711021000765\"\n  year: 2021\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nCommunity driven development of this package is encouraged. To maintain code quality standards, please adhere to the following guidlines when contributing:\n - To get started, <a href=\"https://www.clahub.com/agreements/NREL/PowerSystems.jl\">sign the Contributor License Agreement</a>.\n - Please do your best to adhere to our [coding style guide](https://sienna-platform.github.io/InfrastructureSystems.jl/latest/style).\n - To submit code contributions, [fork](https://help.github.com/articles/fork-a-repo/) the repository, commit your changes, and [submit a pull request](https://help.github.com/articles/creating-a-pull-request-from-a-fork/).\n"
  },
  {
    "path": "LICENSE",
    "content": "BSD 3-Clause License\n\nCopyright (c) 2018, 2023 Alliance for Sustainable Energy, LLC and The Regents of the University of California\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n  list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from\n  this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "Project.toml",
    "content": "name = \"PowerSystems\"\nuuid = \"bcd98974-b02a-5e2f-9ee0-a103f5c450dd\"\nauthors = [\"Jose Daniel Lara\", \"Daniel Thom\", \"Rodrigo Henriquez-Auba\", \"Gabriel Konar-Steenberg\", \"Clayton Barrows\"]\nversion = \"5.9.1\"\n\n[deps]\nCSV = \"336ed68f-0bac-5ca0-87d4-7b16caf5d00b\"\nDataFrames = \"a93c6f00-e57d-5684-b7b6-d8193f3e46c0\"\nDataStructures = \"864edb3b-99cc-5e75-8d2d-829cb0a9cfe8\"\nDates = \"ade2ca70-3891-5945-98fb-dc099432e06a\"\nDocStringExtensions = \"ffbed154-4ef7-542d-bbb7-c09d3a79fcae\"\nInfrastructureSystems = \"2cd47ed4-ca9b-11e9-27f2-ab636a7671f1\"\nInteractiveUtils = \"b77e0a4c-d291-57a0-90e8-8db25a27a240\"\nJSON3 = \"0f8b85d8-7281-11e9-16c2-39a750bddbf1\"\nLinearAlgebra = \"37e2e46d-f89d-539d-b4ee-838fcccc9c8e\"\nLogging = \"56ddb016-857b-54e1-b83d-db4d58db5568\"\nPowerFlowData = \"dd99e9e3-7471-40fc-b48d-a10501125371\"\nPrettyTables = \"08abe8d2-0d0c-5749-adfa-8a2ac140af0d\"\nTimeSeries = \"9e3dc215-6440-5c97-bce1-76c03772f85e\"\nUUIDs = \"cf7118a7-6976-5b1a-9a39-7adc72f591a4\"\nUnicode = \"4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5\"\nYAML = \"ddb6d928-2868-570f-bddf-ab3f9cf99eb6\"\n\n[compat]\nCSV = \"~0.10\"\nDataFrames = \"1\"\nDataStructures = \"^0.19\"\nDates = \"1\"\nDocStringExtensions = \"0.8, 0.9.2\"\nInfrastructureSystems = \"^3.5\"\nInteractiveUtils = \"1\"\nJSON3 = \"1\"\nLinearAlgebra = \"1\"\nLogging = \"1\"\nPowerFlowData = \"^1.5\"\nPrettyTables = \"2.4, 3.1\"\nTimeSeries = \"0.25\"\nUUIDs = \"1\"\nUnicode = \"1\"\nYAML = \"~0.4\"\njulia = \"^1.10\"\n"
  },
  {
    "path": "README.md",
    "content": "# PowerSystems.jl\n\n[![Main - CI](https://github.com/Sienna-Platform/PowerSystems.jl/workflows/Main%20-%20CI/badge.svg)](https://github.com/Sienna-Platform/PowerSystems.jl/actions/workflows/main-tests.yml)\n[![codecov](https://codecov.io/gh/Sienna-Platform/PowerSystems.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/Sienna-Platform/PowerSystems.jl)\n[![Documentation](https://github.com/Sienna-Platform/PowerSystems.jl/actions/workflows/docs.yml/badge.svg)](https://github.com/Sienna-Platform/PowerSystems.jl/actions/workflows/docs.yml)\n[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.17703517.svg)](https://doi.org/10.5281/zenodo.17703517)\n[<img src=\"https://img.shields.io/badge/slack-@Sienna/PSY-sienna.svg?logo=slack\">](https://join.slack.com/t/core-sienna/shared_invite/zt-glam9vdu-o8A9TwZTZqqNTKHa7q3BpQ)\n[![PowerSystems.jl Downloads](https://img.shields.io/badge/dynamic/json?url=http%3A%2F%2Fjuliapkgstats.com%2Fapi%2Fv1%2Ftotal_downloads%2FPowerSystems&query=total_requests&label=Downloads)](http://juliapkgstats.com/pkg/PowerSystems)\n\n\nThe `PowerSystems.jl` package provides a rigorous data model using Julia structures to enable power systems analysis and modeling. In addition to stand-alone system analysis tools and data model building, the `PowerSystems.jl` package is used as the foundational data container for the [PowerSimulations.jl](https://github.com/Sienna-Platform/PowerSimulations.jl) and [PowerSimulationsDynamics.jl](https://github.com/Sienna-Platform/PowerSimulationsDynamics.jl) packages. `PowerSystems.jl` supports a limited number of data file formats for parsing.\n\n## Version Advisory\n\n- PowerSystems will work with Julia v1.6+.\n\n## Device data enabled in PowerSystems\n\n- Generators (Thermal, Renewable and Hydro)\n- Transmission (Lines, and Transformers)\n- Active Flow control devices (DC Lines and Phase Shifting Transformers)\n- TwoTerminal and Multiterminal HVDC\n- Topological elements (Buses, Arcs, Areas)\n- Storage (Batteries)\n- Load (Static, and Curtailable)\n- Services (Reserves, Transfers)\n- TimeSeries (Deterministic, Scenarios, Probabilistic)\n- Dynamic Generators Models\n- Dynamic Inverter Models\n\nFor information on using the package and a more extensive list of device data enabled, see the [stable documentation](https://sienna-platform.github.io/PowerSystems.jl/stable/). Use the [in-development documentation](https://sienna-platform.github.io/PowerSystems.jl/dev/) for the version of the documentation which contains the unreleased features.\n\n## Parsing capabilities in PowerSystems\n\n- MATPOWER CaseFormat\n- PSS/e - PTI Format v30 (partial support), v33, v35 (.raw and .dyr files)\n- [RTS-GMLC](https://github.com/GridMod/RTS-GMLC/tree/master/RTS_Data/SourceData) table data format\n\n## Development\n\nContributions to the development and enhancement of PowerSystems are welcome. Please see\n[CONTRIBUTING.md](https://github.com/NREL/PowerSystems.jl/blob/main/CONTRIBUTING.md) for\ncode contribution guidelines.\n\n## Citing PowerSystems.jl\n\n[Paper describing `PowerSystems.jl`](https://www.sciencedirect.com/science/article/pii/S2352711021000765)\n\n```bibtex\n@article{LARA2021100747,\n  title = {PowerSystems.jl — A power system data management package for large scale modeling},\n  journal = {SoftwareX},\n  volume = {15},\n  pages = {100747},\n  year = {2021},\n  issn = {2352-7110},\n  doi = {https://doi.org/10.1016/j.softx.2021.100747},\n  url = {https://www.sciencedirect.com/science/article/pii/S2352711021000765},\n  author = {José Daniel Lara and Clayton Barrows and Daniel Thom and Dheepak Krishnamurthy and Duncan Callaway},\n  keywords = {Power Systems, Julia, Energy}\n}\n```\n\n## License\n\nPowerSystems is released under a BSD [license](https://github.com/NREL/PowerSystems.jl/blob/main/LICENSE).\nPowerSystems has been developed as part of the Scalable Integrated Infrastructure Planning (SIIP)\ninitiative at the U.S. Department of Energy's National Laboratory of the Rockies ([NLR](https://www.nlr.gov/), formerly NREL) Software Record SWR-23-105.\n"
  },
  {
    "path": "codecov.yml",
    "content": "codecov:\n  require_ci_to_pass: yes\n\ncoverage:\n  precision: 2\n  round: down\n  range: \"70...100\"\n\n  status:\n    project:                   # measuring the overall project coverage\n      default:                 # context, you can create multiple ones with custom titles\n        enabled: yes           # must be yes|true to enable this status\n        target: auto           # specify the target coverage for each commit status\n                               #   option: \"auto\" (must increase from parent commit or pull request base)\n                               #   option: \"X%\" a static target percentage to hit\n        threshold: 5        # allowed to drop X% and still result in a \"success\" commit status\n        if_not_found: success  # if parent is not found report status as success, error, or failure\n        if_ci_failed: error    # if ci fails report status as success, error, or failure\n    patch:\n      default:\n        target: 70\n\nparsers:\n  gcov:\n    branch_detection:\n      conditional: yes\n      loop: yes\n      method: no\n      macro: no\n\ncomment:\n  layout: \"reach,diff,flags,tree\"\n  behavior: default\n  require_changes: no\n\nignore:\n  - \"src/parsers/pm_io/\"\n  - \"src/parsers/im_io/\"\n"
  },
  {
    "path": "docs/Makefile",
    "content": "BRANCH := $(shell git rev-parse --abbrev-ref HEAD)\n\nhtml:\n\tjulia make.jl\n\ngithub: html\n\t-git branch -D gh-pages\n\t-git push origin --delete gh-pages\n\tghp-import -n -b gh-pages -m \"Update documentation\" ./build\n\tgit checkout gh-pages\n\tgit push --set-upstream origin gh-pages\n\tgit checkout ${BRANCH}\n\nall: github\n"
  },
  {
    "path": "docs/Project.toml",
    "content": "[deps]\nCSV = \"336ed68f-0bac-5ca0-87d4-7b16caf5d00b\"\nDataFrames = \"a93c6f00-e57d-5684-b7b6-d8193f3e46c0\"\nDataStructures = \"864edb3b-99cc-5e75-8d2d-829cb0a9cfe8\"\nDates = \"ade2ca70-3891-5945-98fb-dc099432e06a\"\nDocumenter = \"e30172f5-a6a5-5a46-863b-614d45cd2de4\"\nDocumenterInterLinks = \"d12716ef-a0f6-4df4-a9f1-a5a34e75c656\"\nDocumenterMermaid = \"a078cd44-4d9c-4618-b545-3ab9d77f9177\"\nInfrastructureSystems = \"2cd47ed4-ca9b-11e9-27f2-ab636a7671f1\"\nIpopt = \"b6b21f68-93f8-5de0-b562-5493be1d77c9\"\nJSON3 = \"0f8b85d8-7281-11e9-16c2-39a750bddbf1\"\nJuMP = \"4076af6c-e467-56ae-b986-b466b2749572\"\nLiterate = \"98b081ad-f1c9-55d3-8b20-4c87d4299306\"\nPowerSystemCaseBuilder = \"f00506e0-b84f-492a-93c2-c0a9afc4364e\"\nPowerSystems = \"bcd98974-b02a-5e2f-9ee0-a103f5c450dd\"\nPrettyTables = \"08abe8d2-0d0c-5749-adfa-8a2ac140af0d\"\nTimeSeries = \"9e3dc215-6440-5c97-bce1-76c03772f85e\"\nTypeTree = \"04da0e3b-1cad-4b2c-a963-fc1602baf1af\"\n\n[compat]\nCSV = \"~0.10\"\nDocumenter = \"=1.15.0\"\njulia = \"^1.10\"\n"
  },
  {
    "path": "docs/make.jl",
    "content": "using Documenter, PowerSystems\nimport DataStructures: OrderedDict\nusing Literate\nusing DocumenterInterLinks\nusing DocumenterMermaid\n\n\nlinks = InterLinks(\n    \"InfrastructureSystems\" => \"https://sienna-platform.github.io/InfrastructureSystems.jl/stable/\",\n    # Sometimes IS docstrings @extref to PSY, and sometimes those IS docstrings are included\n    # in the PSY reference, so we can have PSY @extref-ing to itself:\n    \"PowerSystems\" => \"https://sienna-platform.github.io/PowerSystems.jl/stable/\",\n)\n\n# This is a fallback for the docstrings that are referenced within IS docstrings\nfallbacks = ExternalFallbacks(\n    \"ComponentContainer\" => \"@extref InfrastructureSystems.ComponentContainer\",\n    \"InfrastructureSystemsComponent\" => \"@extref InfrastructureSystems.InfrastructureSystemsComponent\"\n)\n\n# This is commented out because the output is not user-friendly. Deliberation on how to best\n# communicate this information to users is ongoing.\n#include(joinpath(@__DIR__, \"src\", \"generate_validation_table.jl\"))\ninclude(joinpath(@__DIR__, \"make_model_library.jl\"))\ninclude(joinpath(@__DIR__, \"make_tutorials.jl\"))\n\npages = OrderedDict(\n        \"Welcome Page\" => \"index.md\",\n        \"Tutorials\" =>  Any[\n            \"Create and Explore a Power `System`\" => \"tutorials/generated_creating_system.md\",\n            \"Manipulating Data Sets\" => \"tutorials/generated_manipulating_datasets.md\",\n            \"Working with Time Series\" => \"tutorials/generated_working_with_time_series.md\",\n            \"Adding Data for Dynamic Simulations\" => \"tutorials/generated_add_dynamic_data.md\",\n        ],\n        \"How to...\" =>  Any[\n            \"...import data\" => Any[\n                \"Parse a MATPOWER or PSS/e file\" => \"how_to/parse_matpower_psse.md\",\n                \"Parse PSS/e dynamic data\" => \"how_to/parse_dynamic_data.md\",\n                \"Build a `System` using .csv files\" => \"how_to/build_system_with_files.md\",\n                \"Save and read data with a JSON\" => \"how_to/serialize_data.md\",\n            ],\n            \"...add a component using natural units (MW)\" => \"how_to/add_component_natural_units.md\",\n            \"...use context managers for bulk operations\" => \"how_to/use_context_managers.md\",\n            \"...add additional data to a component\" => \"how_to/adding_additional_fields.md\",\n            \"...add time-series data\" => Any[\n                \"Parse time series data from .csv files\" => \"how_to/parse_ts_from_csvs.md\",\n                \"Improve performance with time series data\" => \"how_to/improve_ts_performance.md\",\n            ],\n            \"...add cost data\" => Any[\n                \"Add an Operating Cost\" => \"how_to/add_cost_curve.md\",\n                \"Add a market bid\" => \"how_to/market_bid_cost.md\",\n                \"Add costs for imported/exported power\" => \"how_to/create_system_with_source_import_export_cost.md\",\n                \"Add time series fuel costs\" => \"how_to/add_fuel_curve_timeseries.md\",\n\n            ],\n            \"...customize or add a new Type\" => \"how_to/add_new_types.md\",\n            \"...define hydro generators with reservoirs\" => \"how_to/create_hydro_datasets.md\",\n            \"...handle 3-Winding Transformers\" => \"how_to/handle_3W_transformers.md\",\n            \"...use PowerSystems.jl with JuMP.jl\" => \"how_to/jump.md\",\n            \"...reduce REPL printing\" => \"how_to/reduce_repl_printing.md\",\n            \"...update to a new `PowerSystems.jl` version\" => Any[\n                \"Migrate from version 4.0 to 5.0\" => \"how_to/migrating_to_psy5.md\",\n            ],\n        ],\n        \"Explanation\" =>\n            Any[\n            \"explanation/system.md\",\n            \"explanation/type_structure.md\",\n            \"explanation/buses_type_explanation.md\",\n            \"explanation/per_unit.md\",\n            \"explanation/power_concepts.md\",\n            \"explanation/conforming_and_non_conforming_loads.md\",\n            \"explanation/transformer_per_unit_models.md\",\n            \"explanation/time_series.md\",\n            \"explanation/dynamic_data.md\",\n            \"explanation/supplemental_attributes.md\",\n            \"explanation/plant_attributes.md\",\n            ],\n        \"Model Library\" => Any[],\n        \"Reference\" =>\n            Any[\"Public API\" => \"api/public.md\",\n            \"Glossary and Acronyms\" => \"api/glossary.md\",\n            \"Type Tree\" => \"api/type_tree.md\",\n            \"`ValueCurve` Options\" => \"api/valuecurve_options.md\",\n            \"Specifying the category of...\" => \"api/enumerated_types.md\",\n            \"Supported PSS/e Models\" => \"api/psse_models.md\",\n            \"Comparison of Load, Generator, and Storage Types\" => \"api/static_injection_subtypes.md\",\n            \"Citation\" => \"api/citation.md\",\n            \"Developers\" => [\"Developer Guidelines\" => \"api/developer_guidelines.md\",\n            \"Internals\" => \"api/internal.md\"]\n            ]\n)\n\npages[\"Model Library\"] = make_model_library(\n     categories = [\n        Topology,\n        StaticInjection,\n        Service,\n        Branch,\n        DynamicInjection,\n    ],\n    exceptions = [PSY.DynamicComponent,\n                  PSY.ActivePowerControl,\n                  PSY.ReactivePowerControl,\n                  PSY.DynamicBranch,\n                  PSY.HybridSystem,\n                  PSY.OperationalCost,\n                  PSY.DynamicInverter,\n                  PSY.DynamicGenerator,\n                  ],\n    manual_additions =\n        Dict(\"Service\" => [\"Reserves\" => \"model_library/reserves.md\"],\n        \"StaticInjection\" => [\"HybridSystem\" => \"model_library/hybrid_system.md\"],\n        \"DynamicInjection\" => [\"Dynamic Inverter\" => \"model_library/dynamic_inverter.md\",\n        \"Dynamic Generator\" => \"model_library/dynamic_generator.md\",\n        ],\n        \"Branch\" => [\"Dynamic Lines\" => \"model_library/dynamic_branch.md\"],\n        \"Operating Costs\" => [\"ThermalGenerationCost\" =>\"model_library/thermal_generation_cost.md\",\n        \"HydroGenerationCost\" =>\"model_library/hydro_generation_cost.md\",\n        \"HydroReservoirCost\" =>\"model_library/hydro_reservoir_cost.md\",\n        \"RenewableGenerationCost\" =>\"model_library/renewable_generation_cost.md\",\n        \"StorageCost\" =>\"model_library/storage_cost.md\",\n        \"LoadCost\" =>\"model_library/load_cost.md\",\n        \"MarketBidCost\" =>\"model_library/market_bid_cost.md\",\n        \"ImportExportCost\" =>\"model_library/import_export_cost.md\",\n        \"OfferCurveCost\" =>\"model_library/offer_curve_cost.md\"],\n        \"HydroReservoir\" => \"model_library/hydro_reservoir.md\",\n        )\n)\n\n# clean_old_generated_files and insert_md are now defined in make_tutorials.jl\n# They are used here for other sections (Model Library, Explanation, How to...)\n\n# This code performs the automated addition of Literate - Generated Markdowns. The desired\n# section name should be the name of the file for instance network_matrices.jl -> Network Matrices\njulia_file_filter = x -> occursin(\".jl\", x)\nfolders = Dict(\n    \"Model Library\" => filter(julia_file_filter, readdir(\"docs/src/model_library\")),\n    \"Explanation\" => filter(julia_file_filter, readdir(\"docs/src/explanation\")),\n    \"How to...\" => filter(julia_file_filter, readdir(\"docs/src/how_to\")),\n)\n\n# Clean up old generated files in folders before Literate generates new ones\n# Note: model_library is cleaned by make_model_library.jl before it generates files,\n# so we only clean explanation and how_to directories here\nfor (section, folder) in folders\n    # Skip model_library as it's already cleaned by make_model_library()\n    section == \"Model Library\" && continue\n    section_folder_name = lowercase(replace(section, \" \" => \"_\"))\n    outputdir = joinpath(pwd(), \"docs\", \"src\", \"$section_folder_name\")\n    clean_old_generated_files(outputdir)\nend\n\n\n# Process other sections (Model Library, Explanation, How to...)\nfor (section, folder) in folders\n    for file in folder\n        @show file\n        section_folder_name = lowercase(replace(section, \" \" => \"_\"))\n        inputfile = joinpath(\"$section_folder_name\", \"$file\")\n        infile_path = joinpath(pwd(), \"docs\", \"src\", inputfile)\n        execute = occursin(\"EXECUTE = TRUE\", uppercase(readline(infile_path))) ? true : false\n        execute && include(infile_path)\n        \n        outputdir = joinpath(pwd(), \"docs\", \"src\", \"$section_folder_name\")\n        outputfile = string(\"generated_\", replace(\"$file\", \".jl\" => \"\"))\n        \n        # Generate markdown\n        Literate.markdown(infile_path,\n                          outputdir;\n                          name = outputfile,\n                          credit = false,\n                          flavor = Literate.DocumenterFlavor(),\n                          documenter = true,\n                          postprocess = insert_md,\n                          execute = execute)\n        \n        subsection = titlecase(replace(split(file, \".\")[1], \"_\" => \" \"))\n        push!(pages[section], (\"$subsection\" =>  joinpath(\"$section_folder_name\", \"$(outputfile).md\")))\n    end\nend\n\n# Process tutorials separately with Literate\nmake_tutorials()\n\nmakedocs(\n    modules = [PowerSystems],\n    format = Documenter.HTML(\n        prettyurls = haskey(ENV, \"GITHUB_ACTIONS\"),\n        size_threshold = nothing,),\n    sitename = \"PowerSystems.jl\",\n    authors = \"Jose Daniel Lara, Daniel Thom, Kate Doubleday, Rodrigo Henriquez-Auba, and Clayton Barrows\",\n    pages = Any[p for p in pages],\n    draft = false,\n    plugins = [links, fallbacks],\n)\n\ndeploydocs(\n    repo = \"github.com/Sienna-Platform/PowerSystems.jl.git\",\n    target = \"build\",\n    branch = \"gh-pages\",\n    devbranch = \"main\",\n    devurl = \"dev\",\n    push_preview=true,\n    versions = [\"stable\" => \"v^\", \"v#.#\"],\n)\n"
  },
  {
    "path": "docs/make_model_library.jl",
    "content": "using InteractiveUtils\nimport InfrastructureSystems as IS\nimport PowerSystems as PSY\n\nfunction _clean_old_generated_files(dir::String)\n    # Remove old generated_*.md files before creating new ones\n    if !isdir(dir)\n        @warn \"Directory does not exist: $dir\"\n        return\n    end\n    generated_files = filter(f -> startswith(f, \"generated_\") && endswith(f, \".md\"), readdir(dir))\n    for file in generated_files\n        rm(joinpath(dir, file), force=true)\n        @info \"Removed old generated file: $file\"\n    end\nend\n\nfunction _check_exception(T, exceptions::Vector)\n    for type_exception in exceptions\n        if T <: type_exception\n            return true\n        end\n    end\n    return false\nend\n\nfunction _write_first_level_markdown(c::String)\n    file_name = \"model_library/generated_$(c).md\"\n            open(joinpath(\"docs/src\", file_name), \"w\") do io\n                print(\n                    io,\n                    \"\"\"\n                    # $(c)\n\n                    ```@autodocs\n                    Modules = [PowerSystems]\n                    Pages   = [\"generated/$(c).jl\"]\n                    Order = [:type, :function]\n                    Public = true\n                    Private = false\n                    ```\n                    \"\"\",\n                )\n            end\n    return file_name\nend\n\nfunction _write_second_level_markdown(input::DataType, subtypes::Vector{DataType}, exceptions)\n    c = string(nameof(input))\n    file_name = \"model_library/generated_$(c).md\"\n            open(joinpath(\"docs/src\", file_name), \"w\") do io\n                print(io, \"# $input\\n\\n\")\n                for T_ in subtypes\n                    _check_exception(T_, exceptions) && continue\n                    T = string(nameof(T_))\n                    print(\n                        io,\n                        \"\"\"\n                        ## $(T)\n\n                        ```@autodocs\n                        Modules = [PowerSystems]\n                        Pages   = [\"/$(T).jl\"]\n                        Order = [:type, :function]\n                        Public = true\n                        Private = false\n                        ```\n\n                        \"\"\",\n                    )\n                end\n            end\n    return file_name\nend\n\nfunction make_dynamics_library!(model_library;\ndyn_categories =[\n    PSY.DynamicGeneratorComponent,\n    PSY.DynamicInverterComponent,\n],\nexceptions = [PSY.OuterControl,\n              PSY.ActivePowerControl,\n              PSY.ReactivePowerControl,],\n\nmanual_additions = Dict{String, Any}(\"DynamicInverterComponent\" => Any[\"OuterControl\" => \"model_library/outer_control.md\"])\n)\n    for abstract_type in dyn_categories\n        @info \"Making entries for subtypes of $abstract_type\"\n        abstract_type_string = string(nameof(abstract_type))\n        addition = Dict{String, Any}()\n        internal_index = Any[]\n        for c_ in subtypes(abstract_type)\n            c_string = string(nameof(c_))\n            _check_exception(c_, exceptions) && continue\n            concretes = IS.get_all_concrete_subtypes(c_)\n            file_name = _write_second_level_markdown(c_,\n            concretes, exceptions)\n            push!(internal_index, c_string => file_name)\n        end\n        push!(model_library, abstract_type_string => internal_index)\n        if haskey(manual_additions, abstract_type_string)\n            addition = get(manual_additions, abstract_type_string, nothing)\n            push!(model_library[abstract_type_string], addition...)\n        end\n    end\nend\n\nfunction make_model_library(;\n    categories = [],\n    exceptions = [],\n    manual_additions = Dict{String, Any}()\n)\n    # Clean up old generated files before creating new ones\n    _clean_old_generated_files(joinpath(\"docs\", \"src\", \"model_library\"))\n\n    model_library = Dict{String, Any}()\n\n    for abstract_type in categories\n        @info \"Making entries for subtypes of $abstract_type\"\n        internal_index = Any[]\n        concrete = IS.get_all_concrete_subtypes(abstract_type)\n        for c_ in concrete\n            _check_exception(c_, exceptions) && continue\n            c = string(nameof(c_))\n            file_name = _write_first_level_markdown(c)\n            push!(internal_index, c => file_name)\n        end\n        isempty(internal_index) && continue\n        model_library[string(nameof(abstract_type))] = internal_index\n    end\n\n    make_dynamics_library!(model_library)\n\n    for (k, v) in manual_additions\n        if haskey(model_library, k)\n            push!(model_library[k], v...)\n        else\n            model_library[k] = v\n        end\n    end\n\n    return Any[p for p in model_library]\nend\n"
  },
  {
    "path": "docs/make_tutorials.jl",
    "content": "using Pkg\nusing Literate\nusing DataFrames\nusing PrettyTables\n\n# Limit DataFrame rendering during docs generation to avoid huge literal outputs.\n# Notes:\n# - Environment-variable approaches tested (`DATAFRAMES_ROWS`, `DATAFRAMES_COLUMNS`,\n#   `LINES`, `COLUMNS`) did not constrain DataFrames output in this pipeline.\n# - We keep a docs-local Base.show override as a fallback and accept `kwargs...`\n#   so explicit show(...; kwargs) calls do not error on unsupported keywords.\nfunction _env_int(name::String, default::Int)\n    parsed = tryparse(Int, get(ENV, name, string(default)))\n    return something(parsed, default)\nend\n\nconst _DF_MAX_ROWS = _env_int(\"SIENNA_DOCS_DF_MAX_ROWS\", 10)\nconst _DF_MAX_COLS = _env_int(\"SIENNA_DOCS_DF_MAX_COLS\", 80)\n\nfunction Base.show(io::IO, mime::MIME\"text/plain\", df::DataFrame; kwargs...)\n    # Keep docs output bounded while allowing explicit caller kwargs.\n    PrettyTables.pretty_table(io, df;\n        backend = :text,\n        maximum_number_of_rows = _DF_MAX_ROWS,\n        maximum_number_of_columns = _DF_MAX_COLS,\n        show_omitted_cell_summary = true,\n        compact_printing = false,\n        limit_printing = true,\n        kwargs...)\nend\n\nfunction Base.show(io::IO, mime::MIME\"text/html\", df::DataFrame; kwargs...)\n    PrettyTables.pretty_table(io, df;\n        backend = :html,\n        maximum_number_of_rows = _DF_MAX_ROWS,\n        maximum_number_of_columns = _DF_MAX_COLS,\n        show_omitted_cell_summary = true,\n        compact_printing = false,\n        limit_printing = true,\n        kwargs...)\nend\n\n# Remove previously generated tutorial artifacts so a docs build only reflects\n# current source tutorials.\n#\n# Input:\n# - dir: tutorial output directory that can contain generated_*.md/ipynb.\n# Output:\n# - Deletes matching files in-place and logs each deletion.\nfunction clean_old_generated_files(dir::String)\n    if !isdir(dir)\n        @warn \"Directory does not exist: $dir\"\n        return\n    end\n    generated_files = filter(\n        f ->\n            startswith(f, \"generated_\") &&\n                (endswith(f, \".md\") || endswith(f, \".ipynb\")),\n        readdir(dir),\n    )\n    for file in generated_files\n        rm(joinpath(dir, file); force = true)\n        @info \"Removed old generated file: $file\"\n    end\nend\n\n#########################################################\n# Literate post-processing functions for tutorial generation\n#########################################################\n\n# Compute docs base URL from Documenter deploy context.\n#\n# Behavior:\n# - previews/PR123 -> .../previews/PR123\n# - dev (or custom DOCUMENTER_DEVURL) -> .../dev\n# - tagged versions like v0.9 -> .../v0.9\n# - fallback -> .../stable\n#\n# This keeps generated download/view-online links correct across preview, dev,\n# tagged, and stable deployments.\nfunction _compute_docs_base_url()\n    base = \"https://sienna-platform.github.io/PowerSystems.jl\"\n\n    current_version = get(ENV, \"DOCUMENTER_CURRENT_VERSION\", \"\")\n\n    # Preview builds (e.g. \"previews/PR123\")\n    if startswith(current_version, \"previews/PR\")\n        return \"$base/$current_version\"\n    end\n\n    # Dev builds\n    if current_version == \"dev\"\n        dev_suffix = get(ENV, \"DOCUMENTER_DEVURL\", \"dev\")\n        return \"$base/$dev_suffix\"\n    end\n\n    # Tagged/versioned builds (e.g. \"v0.9\", \"v1.2.3\")\n    if !isempty(current_version) && current_version != \"stable\"\n        return \"$base/$current_version\"\n    end\n\n    # Default to stable\n    return \"$base/stable\"\nend\n\nconst _DOCS_BASE_URL = _compute_docs_base_url()\n\n\"\"\"\nChoose how tutorial download links are written in generated markdown.\n\n- **Absolute** (under `_DOCS_BASE_URL/tutorials/`): CI / Documenter context (`GITHUB_ACTIONS` or\n  non-empty `DOCUMENTER_CURRENT_VERSION`) so previews, `dev`, and versioned URLs match\n  `_compute_docs_base_url()`.\n- **Relative** (bare filenames): local/offline builds; files sit next to `generated_*.md`\n  under `docs/src/tutorials/`.\n\nOverride: `SIENNA_DOCS_DOWNLOAD_LINKS`=`absolute` or `relative`.\n\"\"\"\nfunction _downloads_use_absolute_urls()\n    o = get(ENV, \"SIENNA_DOCS_DOWNLOAD_LINKS\", \"\")\n    o == \"absolute\" && return true\n    o == \"relative\" && return false\n    haskey(ENV, \"GITHUB_ACTIONS\") && return true\n    !isempty(get(ENV, \"DOCUMENTER_CURRENT_VERSION\", \"\")) && return true\n    return false\nend\n\n# Replace APPEND_MARKDOWN(\"path/to/file.md\") placeholders with file contents.\n#\n# Sample input:\n#   \"Before\\nAPPEND_MARKDOWN(\\\"docs/src/tutorials/_snippet.md\\\")\\nAfter\"\n# Sample output:\n#   \"Before\\n<contents of _snippet.md>\\nAfter\"\n#\n# Notes:\n# - Uses a non-greedy-safe capture (`[^\\\"]*`) so multiple placeholders can be\n#   replaced independently.\nfunction insert_md(content)\n    pattern = r\"APPEND_MARKDOWN\\(\\\"([^\\\"]*)\\\"\\)\"\n    if occursin(pattern, content)\n        content = replace(content, pattern => m -> read(m.captures[1], String))\n    end\n    return content\nend\n\n# Default display titles for Documenter admonition types when no custom title is given.\n# See https://documenter.juliadocs.org/stable/showcase/#Admonitions\nconst _ADMONITION_DISPLAY_NAMES = Dict{String, String}(\n    \"note\" => \"Note\",\n    \"info\" => \"Info\",\n    \"tip\" => \"Tip\",\n    \"warning\" => \"Warning\",\n    \"danger\" => \"Danger\",\n    \"compat\" => \"Compat\",\n    \"todo\" => \"TODO\",\n    \"details\" => \"Details\",\n)\n\n# Preprocess Literate source to convert Documenter-style admonitions into Jupyter-friendly\n# blockquotes. Used only for notebook output; markdown keeps `!!! type` and is rendered by\n# Documenter. Admonitions are not recognized by common mark or Jupyter; see\n# https://fredrikekre.github.io/Literate.jl/v2/tips/#admonitions-compatibility\nfunction preprocess_admonitions_for_notebook(str::AbstractString)\n    lines = split(str, '\\n'; keepempty = true)\n    out = String[]\n    i = 1\n    n = length(lines)\n    admonition_start =\n        r\"^# !!! (note|info|tip|warning|danger|compat|todo|details)(?:\\s+\\\"([^\\\"]*)\\\")?\\s*$\"\n    content_line = r\"^#     (.*)$\"  # Documenter admonition body: # then 4 spaces\n    blank_comment = r\"^#\\s*$\"      # # or # with only spaces\n\n    while i <= n\n        line = lines[i]\n        m = match(admonition_start, line)\n        if m !== nothing\n            typ = lowercase(m.captures[1])\n            custom_title = m.captures[2]\n            title = if custom_title !== nothing && !isempty(custom_title)\n                custom_title\n            else\n                get(_ADMONITION_DISPLAY_NAMES, typ, titlecase(typ))\n            end\n            push!(out, \"# > *$(title)*\")\n            push!(out, \"# >\")\n            i += 1\n            # Consume blank comment lines and content lines\n            while i <= n\n                l = lines[i]\n                if match(blank_comment, l) !== nothing\n                    push!(out, \"# >\")\n                    i += 1\n                elseif (cm = match(content_line, l)) !== nothing\n                    push!(out, \"# > \" * cm.captures[1])\n                    i += 1\n                else\n                    break\n                end\n            end\n            continue\n        end\n        push!(out, line)\n        i += 1\n    end\n    return join(out, '\\n')\nend\n\n# Inject a short \"download tutorial files\" sentence after the first markdown\n# heading in generated tutorial pages.\n#\n# Sample input:\n#   \"# Title\\nBody...\"\n# Sample output (conceptual):\n#   \"# Title\\n\\n*To follow along... [Julia script](.../tutorial.jl)...*\\n\\nBody...\"\n#\n# Download links:\n# - **Deployed / CI**: absolute URLs under `_DOCS_BASE_URL` when `_downloads_use_absolute_urls()` is true.\n# - **Local**: bare filenames (siblings of `generated_*.md` in `docs/src/tutorials/`).\nfunction add_download_links(content, jl_file, ipynb_file)\n    script_link, notebook_link = if _downloads_use_absolute_urls()\n        (\"$_DOCS_BASE_URL/tutorials/$(jl_file)\", \"$_DOCS_BASE_URL/tutorials/$(ipynb_file)\")\n    else\n        (jl_file, ipynb_file)\n    end\n    download_section = \"\"\"\n\n*To follow along, you can download this tutorial as a [Julia script (.jl)]($(script_link)) or [Jupyter notebook (.ipynb)]($(notebook_link)).*\n\n\"\"\"\n    # Insert after the first heading (which should be the title)\n    # Match the first heading line and replace it with heading + download section\n    m = match(r\"^(#+ .+)$\"m, content)\n    if m !== nothing\n        heading = m.match\n        content = replace(content, r\"^(#+ .+)$\"m => heading * download_section; count = 1)\n    end\n    return content\nend\n\n# Insert a setup preface and captured `Pkg.status()` into the first markdown\n# cell of a generated notebook, immediately after the first heading.\n#\n# Sample effect:\n# - First markdown cell gains a \"Set up\" blockquote and an embedded code block\n#   containing package versions from the docs build environment.\nfunction add_pkg_status_to_notebook(nb::Dict)\n    cells = get(nb, \"cells\", [])\n    if isempty(cells)\n        return nb\n    end\n\n    # Find the first markdown cell\n    first_markdown_idx = nothing\n    for (i, cell) in enumerate(cells)\n        if get(cell, \"cell_type\", \"\") == \"markdown\"\n            first_markdown_idx = i\n            break\n        end\n    end\n\n    if first_markdown_idx === nothing\n        return nb  # No markdown cell found, return unchanged\n    end\n\n    first_cell = cells[first_markdown_idx]\n    cell_source = get(first_cell, \"source\", [])\n\n    # Convert source array to string to find the first heading\n    source_text = join(cell_source)\n\n    # Find the first heading (lines starting with #)\n    heading_pattern = r\"^(#+\\s+.+?)$\"m\n    heading_match = match(heading_pattern, source_text)\n\n    if heading_match === nothing\n        return nb  # No heading found, return unchanged\n    end\n\n    # Capture Pkg.status() output at build time\n    io = IOBuffer()\n    Pkg.status(; io = io)\n    pkg_status_output = String(take!(io))\n\n    # Create the content to insert: blockquote \"Set up\" with setup instructions and pkg.status()\n    # Blockquote title and body; hyperlinks for IJulia and create an environment\n    preface_lines = [\n        \"\\n\",\n        \"> **Set up**\\n\",\n        \">\\n\",\n        \"> To run this notebook, first install the Julia kernel for Jupyter Notebooks using [IJulia](https://julialang.github.io/IJulia.jl/stable/manual/installation/), then [create an environment](https://pkgdocs.julialang.org/v1/environments/) for this tutorial with the packages listed with `using <PackageName>` further down.\\n\",\n        \">\\n\",\n        \"> This tutorial has demonstrated compatibility with these package versions. If you run into any errors, first check your package versions for consistency using `Pkg.status()`.\\n\",\n        \">\\n\",\n    ]\n\n    # Format Pkg.status() output as a code block inside the blockquote\n    pkg_status_lines = split(pkg_status_output, '\\n'; keepempty = true)\n    pkg_status_block = [\" > ```\\n\"]\n    for line in pkg_status_lines\n        push!(pkg_status_block, \" > \" * line * \"\\n\")\n    end\n    push!(pkg_status_block, \" > ```\\n\", \"\\n\")\n\n    # Find the first heading line in the source array\n    heading_line_idx = nothing\n    for (i, line) in enumerate(cell_source)\n        if match(heading_pattern, line) !== nothing\n            heading_line_idx = i\n            break\n        end\n    end\n\n    if heading_line_idx === nothing\n        return nb  # Couldn't find heading line\n    end\n\n    # Build new source array\n    new_source = String[]\n    # Add all lines up to and including the heading line\n    for i in 1:heading_line_idx\n        push!(new_source, cell_source[i])\n    end\n\n    # Add the preface and pkg.status content right after the heading\n    append!(new_source, preface_lines)\n    append!(new_source, pkg_status_block)\n\n    # Add all remaining lines after the heading\n    for i in (heading_line_idx + 1):length(cell_source)\n        push!(new_source, cell_source[i])\n    end\n\n    # Update the cell source\n    first_cell[\"source\"] = new_source\n    cells[first_markdown_idx] = first_cell\n\n    nb[\"cells\"] = cells\n    return nb\nend\n\n# Add italicized \"view online\" comment after each image from ```@raw html ... ``` (or\n# the raw HTML / markdown form Literate writes). Used as a postprocess in Literate.notebook.\n# Literate strips the backtick wrapper and outputs raw HTML; we match that multi-line block.\n# Sample effect:\n# - If a markdown cell contains one or more image fragments, append exactly one\n#   \"view online\" fallback note at the end of that cell.\n# - If the note already exists in the cell, no change is applied.\nfunction add_image_links(nb::Dict, outputfile_base::AbstractString)\n    tutorial_url = \"$_DOCS_BASE_URL/tutorials/$(outputfile_base)/\"\n    msg = \"_If image is not available when viewing in a Jupyter notebook, view the tutorial online [here]($tutorial_url)._\"\n    cells = get(nb, \"cells\", [])\n    for (idx, cell) in enumerate(cells)\n        get(cell, \"cell_type\", \"\") != \"markdown\" && continue\n        source = get(cell, \"source\", [])\n        isempty(source) && continue\n        text = join(source)\n        # Check if this cell already has the \"view online\" message to avoid duplicates\n        contains(text, \"If image is not available when viewing in a Jupyter notebook\") &&\n            continue\n        suffix = \"\\n\\n\" * msg * \"\\n\"\n        # If the cell has any of the image shapes below, we append one \"view online\" note.\n        # We build one alternation pattern from sub-patterns (each line is one case).\n        #\n        # HTML paragraph wrapping an <img> (Literate often emits <p>…<img>…</p>).\n        #   <p[^>]*>     — opening <p> and attributes\n        #   [\\s\\S]*?     — any chars, non-greedy, up to the first <img\n        #   <img…</p>   — from <img through closing </p>\n        p_with_img_pattern = r\"<p[^>]*>[\\s\\S]*?<img[\\s\\S]*?</p>\"\n        # Documenter @raw html chunk that Literate inlines in the notebook (backticks removed in output).\n        #   ```@raw html  — start marker\n        #   [\\s\\S]*?     — block body, non-greedy\n        #   ```          — end fence\n        raw_html_block_pattern = r\"```@raw html[\\s\\S]*?```\"\n        # Standard markdown image: ![alt text](url)\n        #   !\\[…\\]  — alt in brackets;  \\(…\\)  — path in parens\n        markdown_image_pattern = r\"!\\[[^\\]]*\\]\\([^\\)]*\\)\"\n        # A bare <img ...> not already covered by the <p>…<img>…</p> case above.\n        #   <img   — tag start;  [^>]*?  — attributes;  /?>  — self-closing or >\n        standalone_img_pattern = r\"<img[^>]*?/?>\"\n        # Union of the four cases: (?: A | B | C | D )\n        image_fragment_pattern = Regex(\n            \"(?:\" *\n            p_with_img_pattern.pattern * \"|\" *\n            raw_html_block_pattern.pattern * \"|\" *\n            markdown_image_pattern.pattern * \"|\" *\n            standalone_img_pattern.pattern * \")\",\n        )\n        if occursin(image_fragment_pattern, text)\n            text *= suffix\n        end\n        # Convert back to notebook source array (lines, last without trailing \\n if non-empty)\n        lines = split(text, \"\\n\"; keepempty = true)\n        new_source = String[]\n        for i in 1:length(lines)\n            if i < length(lines)\n                push!(new_source, lines[i] * \"\\n\")\n            else\n                isempty(lines[i]) || push!(new_source, lines[i])\n            end\n        end\n        cell[\"source\"] = new_source\n        cells[idx] = cell\n    end\n    nb[\"cells\"] = cells\n    return nb\nend\n\n#########################################################\n# Process tutorials with Literate\n#########################################################\n\n# Generate tutorial markdown + notebook artifacts from literate .jl sources.\n#\n# Pipeline:\n# 1) discover tutorial .jl files (excluding helper files starting with \"_\")\n# 2) generate Documenter-flavored markdown with injected download links\n# 3) generate notebook with admonition conversion, setup preface, and image note\nfunction make_tutorials()\n    tutorials_dir = abspath(joinpath(@__DIR__, \"src\", \"tutorials\"))\n    # Exclude helper scripts that start with \"_\"\n    if isdir(tutorials_dir)\n        tutorial_files =\n            filter(\n                x -> endswith(x, \".jl\") && !startswith(x, \"_\"),\n                readdir(tutorials_dir),\n            )\n        if !isempty(tutorial_files)\n            # Clean up old generated tutorial files\n            tutorial_outputdir = tutorials_dir\n            clean_old_generated_files(tutorial_outputdir)\n\n            for file in tutorial_files\n                @show file\n                infile_path = joinpath(tutorials_dir, file)\n                execute =\n                    if occursin(\"EXECUTE = TRUE\", uppercase(readline(infile_path)))\n                        true\n                    else\n                        false\n                    end\n\n                outputfile = string(\"generated_\", replace(\"$file\", \".jl\" => \"\"))\n\n                # Generate markdown\n                Literate.markdown(infile_path,\n                    tutorial_outputdir;\n                    name = outputfile,\n                    credit = false,\n                    flavor = Literate.DocumenterFlavor(),\n                    documenter = true,\n                    postprocess = (\n                        content -> add_download_links(\n                            insert_md(content),\n                            file,\n                            string(outputfile, \".ipynb\"),\n                        )\n                    ),\n                    execute = execute)\n\n                # Generate notebook (chain add_image_links after add_pkg_status_to_notebook).\n                # preprocess_admonitions_for_notebook converts Documenter admonitions to blockquotes\n                # so they render in Jupyter; markdown output keeps !!! style for Documenter.\n                Literate.notebook(infile_path,\n                    tutorial_outputdir;\n                    name = outputfile,\n                    credit = false,\n                    execute = false,\n                    preprocess = preprocess_admonitions_for_notebook,\n                    postprocess = nb ->\n                        add_image_links(add_pkg_status_to_notebook(nb), outputfile))\n            end\n        end\n    end\nend\n"
  },
  {
    "path": "docs/src/api/citation.md",
    "content": "### Citation\n\nUsers are requested to please cite the\n[following paper:](https://www.sciencedirect.com/science/article/pii/S2352711021000765)\n\n```bibtex\n@article{LARA2021100747,\ntitle = {PowerSystems.jl — A power system data management package for large scale modeling},\njournal = {SoftwareX},\nvolume = {15},\npages = {100747},\nyear = {2021},\nissn = {2352-7110},\ndoi = {https://doi.org/10.1016/j.softx.2021.100747},\nurl = {https://www.sciencedirect.com/science/article/pii/S2352711021000765},\nauthor = {José Daniel Lara and Clayton Barrows and Daniel Thom and Dheepak Krishnamurthy and Duncan Callaway},\nkeywords = {Power Systems, Julia, Energy},\n```\n\nPowerSystems has been developed as part of the [Sienna platform](https://www.nlr.gov/analysis/sienna.html)\nby the U.S. Department of Energy's National Laboratory of the Rockies\n([NLR](https://www.nlr.gov/), formerly NREL).\n"
  },
  {
    "path": "docs/src/api/developer_guidelines.md",
    "content": "# Developer Guidelines\n\nIn order to contribute to `PowerSystems.jl` repository please read the following sections of\n[`InfrastructureSystems.jl`](https://github.com/Sienna-Platform/InfrastructureSystems.jl)\ndocumentation in detail:\n\n 1. [Style Guide](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/style/)\n 2. [Contributing Guidelines](https://github.com/Sienna-Platform/PowerSystems.jl/blob/main/CONTRIBUTING.md)\n\nPull requests are always welcome to fix bugs or add additional modeling capabilities.\n\n**All the code contributions need to include tests with a minimum coverage of 70%**\n"
  },
  {
    "path": "docs/src/api/enumerated_types.md",
    "content": "# Specifying the type of...\n\nSome fields in PowerSystems.jl are specified with an option from a pre-defined list\n(Specified with [`IS.scoped_enums`](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/InfrastructureSystems/#InfrastructureSystems.@scoped_enum-Tuple%7BAny,%20Vararg%7BAny,%20N%7D%20where%20N%7D)).\n\nExample syntax:\n\n```\nset_fuel!(gen, ThermalFuels.COAL)\n```\n\nThese predefined lists are below:\n\n## [AC Buses](@id acbustypes_list)\n\n`ACBusTypes` categorize buses for modeling activities and denote which quantities are specified\nfor load flow calculations. `ACBusTypes` has the options:\n\n| Name       | Description                                                |\n|:---------- |:---------------------------------------------------------- |\n| `ISOLATED` | Disconnected from network                                  |\n| `PQ`       | Active and reactive power defined (load bus)               |\n| `PV`       | Active power and voltage magnitude defined (generator bus) |\n| `REF`      | Reference bus (θ = 0)                                      |\n| `SLACK`    | Slack bus                                                  |\n\n## [Prime Movers](@id pm_list)\n\nEach generator contains a field for `prime_mover::PrimeMovers`, based on the options in\n[EIA form 923](https://www.eia.gov/survey/form/eia_923/instructions.pdf).\n`PrimeMovers` has the options:\n\n| Name  | Description                                                                                            |\n|:----- |:------------------------------------------------------------------------------------------------------ |\n| `BA`  | Energy Storage, Battery                                                                                |\n| `BT`  | Turbines Used in a Binary Cycle (including those used for geothermal applications)                     |\n| `CA`  | Combined-Cycle – Steam Part                                                                            |\n| `CC`  | Combined-Cycle - Aggregated Plant *augmentation of EIA                                                 |\n| `CE`  | Energy Storage, Compressed Air                                                                         |\n| `CP`  | Energy Storage, Concentrated Solar Power                                                               |\n| `CS`  | Combined-Cycle Single-Shaft Combustion turbine and steam turbine share a single generator              |\n| `CT`  | Combined-Cycle Combustion Turbine Part                                                                 |\n| `ES`  | Energy Storage, Other                                                                                  |\n| `FC`  | Fuel Cell                                                                                              |\n| `FW`  | Energy Storage, Flywheel                                                                               |\n| `GT`  | Combustion (Gas) Turbine (including jet engine design)                                                 |\n| `HA`  | Hydrokinetic, Axial Flow Turbine                                                                       |\n| `HB`  | Hydrokinetic, Wave Buoy                                                                                |\n| `HK`  | Hydrokinetic, Other                                                                                    |\n| `HY`  | Hydraulic Turbine (including turbines associated with delivery of water by pipeline)                   |\n| `IC`  | Internal Combustion (diesel, piston, reciprocating) Engine                                             |\n| `PS`  | Energy Storage, Reversible Hydraulic Turbine (Pumped Storage)                                          |\n| `OT`  | Other                                                                                                  |\n| `ST`  | Steam Turbine (including nuclear, geothermal and solar steam; does not include combined-cycle turbine) |\n| `PVe` | Photovoltaic \\(*Note*: renaming from EIA PV to PVe to avoid conflict with `ACBusType.PV`\\)             |\n| `WT`  | Wind Turbine, Onshore                                                                                  |\n| `WS`  | Wind Turbine, Offshore                                                                                 |\n\n## [Fuels for Thermal Generators](@id tf_list)\n\nEach [`ThermalGen`](@ref) generator has a field for `fuel::ThermalFuels` where `ThermalFuels`\nare intended to reflect the options in the\n[Aggregated Fuel Codes](https://www.eia.gov/survey/form/eia_923/instructions.pdf) from the\nEIA Annual Energy Review. `ThermalFuels` has the options:\n\n| Name                                                                                                                               | EIA Fuel Code | Description                                                                                                                         |\n|:---------------------------------------------------------------------------------------------------------------------------------- |:------------- |:----------------------------------------------------------------------------------------------------------------------------------- |\n| `ANTHRACITE_COAL`                                                                                                                  | ANT           | Anthracite Coal                                                                                                                     |\n| `BITUMINOUS_COAL`                                                                                                                  | BIT           | Bituminous Coal                                                                                                                     |\n| `LIGNITE_COAL`                                                                                                                     | LIG           | Lignite Coal                                                                                                                        |\n| `SUBBITUMINOUS_COAL`                                                                                                               | SUB           | Subbituminous Coal                                                                                                                  |\n| `WASTE_COAL`                                                                                                                       | WC            | Waste/Other Coal (including anthracite culm, bituminous gob, fine coal, lignite waste, waste coal)                                  |\n| `REFINED_COAL`                                                                                                                     | RC            | Refined Coal (A coal product that improves heat content and reduces emissions. Excludes coal processed by coal preparation plants.) |\n| `SYNTHESIS_GAS_COAL`                                                                                                               | SGC           | Coal-Derived Synthesis Gas                                                                                                          |\n| `DISTILLATE_FUEL_OIL`                                                                                                              | DFO           | Distillate Fuel Oil (including diesel, No. 1, No. 2, and No. 4 fuel oils)                                                           |\n| `JET_FUEL`                                                                                                                         | JF            | Jet Fuel                                                                                                                            |\n| `KEROSENE`                                                                                                                         | KER           | Kerosene                                                                                                                            |\n| `PETROLEUM_COKE`                                                                                                                   | PC            | Petroleum Coke                                                                                                                      |\n| `RESIDUAL_FUEL_OIL`                                                                                                                | RFO           | Residual Fuel Oil (including No. 5 and No. 6 fuel oils, and bunker C fuel oil)                                                      |\n| `PROPANE`                                                                                                                          | PG            | Propane, gaseous                                                                                                                    |\n| `SYNTHESIS_GAS_PETROLEUM_COKE`                                                                                                     | SGP           | Petroleum Coke Derived Synthesis Gas                                                                                                |\n| `WASTE_OIL`                                                                                                                        | WO            | Waste/Other Oil (including crude oil, liquid butane, liquid propane, naphtha, oil waste, re-refined motor oil, sludge oil, tar oil) |\n| `BLASTE_FURNACE_GAS`                                                                                                               | BFG           | Blast Furnace Gas                                                                                                                   |\n| `NATURAL_GAS`                                                                                                                      | NG            | Natural Gas                                                                                                                         |\n| `OTHER_GAS`                                                                                                                        | OG            | Other Gas                                                                                                                           |\n| `AG_BYPRODUCT`                                                                                                                     | AB            | Agricultural By-products                                                                                                            |\n| `MUNICIPAL_WASTE`                                                                                                                  | MSW           | Municipal Solid Waste                                                                                                               |\n| `OTHER_BIOMASS_SOLIDS`                                                                                                             | OBS           | Other Biomass Solids                                                                                                                |\n| `WOOD_WASTE_SOLIDS`                                                                                                                | WDS           | Wood/Wood Waste Solids (including paper, pellets, railroad ties, utility poles, wood chips, bark, and wood waste solids)            |\n| `OTHER_BIOMASS_LIQUIDS`                                                                                                            | OBL           | Other Biomass Liquids                                                                                                               |\n| `SLUDGE_WASTE`                                                                                                                     | SLW           | Sludge Waste                                                                                                                        |\n| `BLACK_LIQUOR`                                                                                                                     | BLQ           | Black Liquor                                                                                                                        |\n| `WOOD_WASTE_LIQUIDS`                                                                                                               | WDL           | Wood Waste Liquids excluding Black Liquor (includes red liquor, sludge wood, spent sulfite liquor, and other wood-based liquids)    |\n| `LANDFILL_GAS`                                                                                                                     | LFG           | Landfill Gas                                                                                                                        |\n| `OTHEHR_BIOMASS_GAS`                                                                                                               | OBG           | Other Biomass Gas (includes digester gas, methane, and other biomass gasses)                                                        |\n| `NUCLEAR`                                                                                                                          | NUC           | Nuclear Uranium, Plutonium, Thorium                                                                                                 |\n| `WASTE_HEAT`                                                                                                                       | WH            | Waste heat not directly attributed to a fuel source                                                                                 |\n| `TIREDERIVED_FUEL`                                                                                                                 | TDF           | Tire-derived Fuels                                                                                                                  |\n| `COAL`*                                                                                                                            | N/A           | General Coal Fuels                                                                                                                  |\n| `Geothermal`*                                                                                                                      | GEO           | Geothermal Fuels                                                                                                                    |\n| `OTHER`                                                                                                                            | OTH           | Other type of fuel                                                                                                                  |\n| *Asterisk denotes fuel codes not directly from the current EIA 923 form but kept for compatibility with older versions of the form |               |                                                                                                                                     |\n\n## [Energy Storage](@id storagetech_list)\n\n`StorageTech` defines the storage technology used in an energy [`Storage`](@ref) system, based\non the options in [EIA form 923](https://www.eia.gov/survey/form/eia_923/instructions.pdf).\n`StorageTech` has the options:\n\n| Name          | Description                   |\n|:------------- |:----------------------------- |\n| `PTES`        | Pumped thermal energy storage |\n| `LIB`         | LiON Battery                  |\n| `LAB`         | Lead Acid Battery             |\n| `FLWB`        | Redox Flow Battery            |\n| `SIB`         | Sodium Ion Battery            |\n| `ZIB`         | Zinc Ion Battery              |\n| `HGS`         | Hydrogen Gas Storage          |\n| `LAES`        | Liquid Air Storage            |\n| `OTHER_CHEM`  | Other Chemical Storage        |\n| `OTHER_MECH`  | Other Mechanical Storage      |\n| `OTHER_THERM` | Other Thermal Storage         |\n\n## [Hydro Reservoir Units](@id hydroreservoir_list)\n\n`ReservoirDataType` specifies which units of measurement for a\n[`HydroReservoir`](@ref)'s `level`-related parameters (e.g., `level_targets`,\n`storage_level_limits`). It defines the units used to perform energy balance\ncalculations for a [`HydroReservoir`](@ref) and affects how the totals and targets are calculated.\nThe user is responsible for correctly managing data conversions when switching between\nthe different alternatives of `ReservoirDataType`, which has the options:\n\n| Name            | Units | Description                                                                                                                                                              |\n|:--------------- |:----- |:------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `USABLE_VOLUME` | m^3   | The volume of water that can be stored for levels between the penstock intake and the top reservoir level                                                                |\n| `TOTAL_VOLUME`  | m^3   | The total volume of the reservoir considering a total depletion of the water levels. This unit system usually requires the specification of a valid minimum volume level |\n| `HEAD`          | m     | The difference in elevations between the top water levels. It requires a valid conversion constant to go from head to potential energy stored.                           |\n| `ENERGY`        | MWh   | Uses energy units in MWh to approximate the water storage as a generic energy reservoir.                                                                                 |\n\n## [Facts Control Devices](@id factsmodes_list)\n\n`FACTSOperationModes` define the operation modes of a [`FACTSControlDevice`](@ref).\n`FACTSOperationModes` has the options:\n\n| Name  | Description                                                                                     |\n|:----- |:----------------------------------------------------------------------------------------------- |\n| `OOS` | Out-Of-Service (i.e., Series and Shunt links open)                                              |\n| `NML` | Normal mode of operation, where Series and Shunt links are operating                            |\n| `BYP` | Series link is bypassed (i.e., like a zero impedance line) and Shunt link operates as a STATCOM |\n\n## [Load Conformity](@id loadconform_list)\n\n`LoadConformity` defines whether a load is\n[conforming or non-nonforming](@ref conf_loads). `LoadConformity` has the options:\n\n| Name             | Description                                                       |\n|:---------------- |:----------------------------------------------------------------- |\n| `NON_CONFORMING` | Non-conforming load                                               |\n| `CONFORMING`     | Conforming load                                                   |\n| `UNDEFINED`      | Undefined or unknown whether load is conforming or non-conforming |\n\n## [Tranformer Control Objectives](@id xtf_crtl)\n\n`TransformerControlObjective` is used to select the control objective for a transformer's\ntap changer, which can be used to determine the tap position during power flow calculations.\n\n| Name                                    | Description                                                               |\n|:--------------------------------------- |:------------------------------------------------------------------------- |\n| `UNDEFINED`                             | Undefined                                                                 |\n| `VOLTAGE_DISABLED`                      | Has voltage control capabilities, which are disabled                      |\n| `REACTIVE_POWER_FLOW_DISABLED`          | Has reactive power flow control capabilities, which are disabled          |\n| `ACTIVE_POWER_FLOW_DISABLED`            | Has active power flow control capabilities, which are disabled            |\n| `CONTROL_OF_DC_LINE_DISABLED`           | Has capabilities to control a DC line quantity, which are disabled        |\n| `ASYMMETRIC_ACTIVE_POWER_FLOW_DISABLED` | Has asymmetric active power flow control capabilities, which are disabled |\n| `FIXED`                                 | Fixed tap and fixed phase shift                                           |\n| `VOLTAGE`                               | Voltage control                                                           |\n| `REACTIVE_POWER_FLOW`                   | Reactive power flow control                                               |\n| `ACTIVE_POWER_FLOW`                     | Active power flow control                                                 |\n| `CONTROL_OF_DC_LINE`                    | Control of a DC line quantity                                             |\n| `ASYMMETRIC_ACTIVE_POWER_FLOW`          | Asymmetric active power flow control                                      |\n\n## [Dynamic States](@id states_list)\n\n`StateTypes` are used to denote the type of dynamic equation a specific [state](@ref S) is subject\nto in [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/).\n`StateTypes` has the options:\n\n| Name           | Description                                                                      |\n|:-------------- |:-------------------------------------------------------------------------------- |\n| `Differential` | State evolves over time via a differential equation ``\\dot{x} = f(x)``           |\n| `Algebraic`    | State evolves over time by satisfying an algebraic equation ``0 = g(x)``         |\n| `Hybrid`       | Depending on specific parameters, the state can be `Differential` or `Algebraic` |\n\n## [Angle Units](@id angleunits_list)\n\n`AngleUnits` can be specified in:\n\n| Name      |\n|:--------- |\n| `DEGREES` |\n| `RADIANS` |\n\n## [Motor Load Technologies](@id motor_list)\n\n| Name           |\n|:-------------- |\n| `INDUCTION`    |\n| `SYNCHRONOUS`  |\n| `UNDETERMINED` |\n"
  },
  {
    "path": "docs/src/api/glossary.md",
    "content": "# Glossary and Acronyms\n\n[A](@ref) | [D](@ref) | [E](@ref) | [F](@ref) | [H](@ref) | [I](@ref) | [O](@ref) | [P](@ref) | [R](@ref) |\n[S](@ref) | [V](@ref) | [W](@ref) | [Z](@ref)\n\n### A\n\n  - *AC*: Alternating current\n\n  - *ACE*: Area control error\n\n  - *AGC*: Automatic generation control\n\n  - *AVR*: Automatic Voltage Regulator\n\n### D\n\n  - *DC*: Direct current\n\n  - *DERA1*:\n\n  - *Dynamic*: Refers to data and simulations for power system transient simulations using differential\n    equations. Common examples include signal stability analysis to verify the power system will\n    maintain stability in the few seconds following an unexpected fault or generator trip. For contrast,\n    see the definition for [Static](@ref S) data.\n\n### E\n\n  - *EMF*: Electromotive force\n  - *ESAC*: IEEE Type AC Excitation System model\n  - *ESDC*: IEEE Type DC Excitation System model\n  - *EXAC*: IEEE Type AC Excitation System (modified) model\n  - *EXPIC*: Proportional/Integral Excitation System from PSS/E\n  - *EXST*: IEEE Type ST (Static) Excitation System model\n  - *EX4VSA*: IEEE Excitation System for Voltage Security Assessment with Over-Excitation Limits.\n\n### F\n\n  - *Forecast*: Predicted values of a time-varying quantity that commonly features\n    a look-ahead and can have multiple data values representing each time period.\n    This data is used in simulation with receding horizons or data generated from\n    forecasting algorithms. See the article on [`Time Series Data`](@ref ts_data).\n\n  - *Forecast window*: Represents the forecasted value starting at a particular initial time.\n    See the article on [`Time Series Data`](@ref ts_data).\n\n### H\n\n  - *Horizon*: Is the duration of all time steps in one forecast. As of PowerSystems.jl\n    version 4.0, all horizons in `PowerSystems.jl` are represented as a `Dates.Period`.\n    For instance, many Day-ahead markets will have an hourly-[resolution](@ref R) forecast\n    for the next day, which would have a horizon of `Dates.Hour(24)` or `Dates.Day(1)`. If the\n    forecast included the next day plus a 24-hour lookahead window, the horizon would be\n    `Dates.Hour(48)` or `Dates.Day(2)`. See the article on [`Time Series Data`](@ref ts_data).\n\n  - *HVDC*: High-voltage DC\n\n### I\n\n  - *IEEET*: IEEE Type I Excitation System.\n\n  - *Injector* or *Injection*: Injectors refer to models that represent how a generator or storage\n    device *injects* power or current into the power system. Loads are negative injectors. In\n    `PowerSystems.jl`, some components can accept data for both [`StaticInjection`](@ref) and\n    [`DynamicInjection`](@ref) models for both [static](@ref S) and [dynamic](@ref D) modeling.\n\n  - *Interval*: The period of time between forecast initial times. In `PowerSystems.jl` all\n    intervals are represented using `Dates.Period` types. For instance, in a Day-Ahead market\n    simulation, the interval is usually `Hour(24)`.\n\n  - *Initial time*: The first time-stamp in a forecast window. See the article on\n    [`Time Series Data`](@ref ts_data).\n\n  - *IPC*: Interconnecting power converter\n\n### L\n\n  - *LCC*: Line Commutated Converter HVDC line\n\n### O\n\n  - *OEL*: Over Excitation Limiter\n\n### P\n\n  - *PLL*: Phase-locked loop\n\n  - *PSS*: Power System Stabilizer\n\n  - *PSSE* or *PSS/E*: Siemens' PSS®E Power System Simulator for Engineering\n\n  - *PPA*: Power purchase agreement\n\n  - *PSI*: [`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/latest/)\n\n  - *PSID*: [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/)\n\n  - *PSLF*: GE Vernova's Positive Sequence Load Flow Software\n\n  - *PSY*: `PowerSystems.jl` (this package)\n\n  - *pu* or *p.u.*: Per-unit\n\n### R\n\n  - *REECB1*: Renewable Energy Electric Controller Type B1\n  - *REPCA1*: REPCA1: Renewable Energy Power Controller Type A1\n  - *Resolution*: The period of time between each discrete value in a time series. All resolutions\n    are represented using `Dates.Period` types. For instance, a Day-ahead market data set usually\n    has a resolution of `Hour(1)`, a Real-Time market data set usually has a resolution of `Minute(5)`.\n\n### S\n\n  - *SCRX*: Bus Fed or Solid Fed Static Exciter\n\n  - *SEXS*: Simplified Excitation System model from PSS/E\n\n  - *SIL*: Surge impedance loading\n\n  - *States*: Correspond to the set of inputs, outputs or variables, that evolve dynamically in\n    [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/),\n    commonly via a differential-algebraic system of equations. In `PowerSystems.jl`, a component\n    associated to a `DynamicInjector` (for example an AVR) specifies the set of states that specific\n    component requires to be modeled accurately.\n\n  - *Static*: Typically refers to steady state data or models where the power system\n    and each of its components are assumed to be operating at a steady state equilibrium point. This\n    includes both power flow data for a single time point simulation as well as quasi-static time\n    series data and models, where the power system is at an equilibrium point at each time step.\n    Static data can be used as the input to single time point power flow models and production\n    cost models with, for example, 5-minute, 15-minute, or 1-hour [Resolution](@ref R).\n    For contrast, see the definition for [Dynamic](@ref D) data.\n\n  - *STAB*: Speed Sensitive Stabilizing PSS Model\n\n### V\n\n  - *VSCLine*: Voltage-Source Converter HVDC Line\n\n  - *VSM*: Virtual Synchronous Machine\n\n### W\n\n  - *Window*: A forecast window is one forecast run that starts at one [initial time](@ref I)\n    and extends through the forecast [horizon](@ref H). Typically, a forecast data set\n    contains multiple forecast windows, with sequential initial times. For example, a\n    year-long data set of day-ahead forecasts contains 365 forecast windows\n\n### Z\n\n  - *ZIP load*: A ZIP load model accounts for the voltage-dependency of a load and is primarily used\n    for dynamics modeling. It includes three kinds of load: constant impedance (Z), constant current (I),\n    and constant power (P), though many dynamics models just use the constant impedance model.\n    [`StandardLoad`](@ref) and [`ExponentialLoad`](@ref) are both ZIP load models:\n    [`StandardLoad`](@ref) breaks up the load into each of its three components, while\n    [`ExponentialLoad`](@ref) expresses the load as an exponential equation.\n"
  },
  {
    "path": "docs/src/api/internal.md",
    "content": "```@meta\nCollapsedDocStrings = true\n```\n\n# Internal API\n\n```@autodocs\nModules = [PowerSystems]\nPublic = false\n```\n"
  },
  {
    "path": "docs/src/api/psse_models.md",
    "content": "# [Supported PSS/e Models](@id psse_models_ref)\n\nPSS/e's dynamic model library is extensive. `PowerSystems.jl` currently supports parsing the following models for version 5.0:\n\n## Dynamic Generator Models\n\n### Machine Models\n\n| PSS/e Model | PowerSystems Component           |\n|:----------- |:-------------------------------- |\n| GENSAE      | [`SalientPoleExponential`](@ref) |\n| GENSAL      | [`SalientPoleQuadratic`](@ref)   |\n| GENROE      | [`RoundRotorExponential`](@ref)  |\n| GENCLS      | [`BaseMachine`](@ref)            |\n| GENROU      | [`RoundRotorQuadratic`](@ref)    |\n\n### Automatic Voltage Regulator (AVR) Models\n\n| PSS/e Model | PowerSystems Component |\n|:----------- |:---------------------- |\n| IEEET1      | [`IEEET1`](@ref)       |\n| ESDC1A      | [`ESDC1A`](@ref)       |\n| ESDC2A      | [`ESDC2A`](@ref)       |\n| ESAC1A      | [`ESAC1A`](@ref)       |\n| ESAC6A      | [`ESAC6A`](@ref)       |\n| ESAC8B      | [`ESAC8B`](@ref)       |\n| EXAC1       | [`EXAC1`](@ref)        |\n| EXAC1A      | [`EXAC1A`](@ref)       |\n| EXAC2       | [`EXAC2`](@ref)        |\n| EXPIC1      | [`EXPIC1`](@ref)       |\n| ESST1A      | [`ESST1A`](@ref)       |\n| ESST4B      | [`ESST4B`](@ref)       |\n| SCRX        | [`SCRX`](@ref)         |\n| SEXS        | [`SEXS`](@ref)         |\n| EXST1       | [`EXST1`](@ref)        |\n| ST6B        | [`ST6B`](@ref)         |\n| ST8C        | [`ST8C`](@ref)         |\n\n### Turbine Governor Models\n\n| PSS/e Model | PowerSystems Component     |\n|:----------- |:-------------------------- |\n| GAST        | [`GasTG`](@ref)            |\n| GGOV1       | [`GeneralGovModel`](@ref)  |\n| HYGOV       | [`HydroTurbineGov`](@ref)  |\n| IEEEG1      | [`IEEETurbineGov1`](@ref)  |\n| TGOV1       | [`SteamTurbineGov1`](@ref) |\n| TGOV1DU     | [`SteamTurbineGov1`](@ref) |\n| DEGOV1      | [`DEGOV1`](@ref)           |\n| PIDGOV      | [`PIDGOV`](@ref)           |\n| WPIDHY      | [`WPIDHY`](@ref)           |\n\n### Power System Stabilizer (PSS) Models\n\n| PSS/e Model | PowerSystems Component |\n|:----------- |:---------------------- |\n| IEEEST      | [`IEEEST`](@ref)       |\n| STAB1       | [`STAB1`](@ref)        |\n\n## Dynamic Inverter Models\n\n### Converter Models\n\n| PSS/e Model | PowerSystems Component                  |\n|:----------- |:--------------------------------------- |\n| REGCA1      | [`RenewableEnergyConverterTypeA`](@ref) |\n\n### Active and Reactive Power Control Models\n\n| PSS/e Model | PowerSystems Component                                                                                      |\n|:----------- |:----------------------------------------------------------------------------------------------------------- |\n| REECB1      | [`ActiveRenewableControllerAB`](@ref), [`ReactiveRenewableControllerAB`](@ref), [`RECurrentControlB`](@ref) |\n| REPCA1      | [`ActiveRenewableControllerAB`](@ref), [`ReactiveRenewableControllerAB`](@ref)                              |\n\n## Additional Models\n\n| PSS/e Model | PowerSystems Component                    |\n|:----------- |:----------------------------------------- |\n| DERA1       | [`AggregateDistributedGenerationA`](@ref) |\n\n## See also\n\n  - Parsing [PSS/e dynamic data](@ref dyr_data)\n  - Parsing [Matpower or PSS/e RAW Files](@ref pm_data)\n"
  },
  {
    "path": "docs/src/api/public.md",
    "content": "# Public API Reference\n\n## Modeling\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"PowerSystems.jl\",\n           \"branches.jl\",\n           \"components.jl\",\n           \"injection.jl\",\n           \"devices.jl\",\n           \"loads.jl\",\n           \"supplemental_constructors\",\n           \"generation.jl\",\n           \"reserves.jl\",\n           \"storage.jl\",\n           \"services.jl\",\n           \"topological_elements.jl\",\n           \"dynamic_models.jl\",\n           \"static_models.jl\",\n           \"subsystems.jl\",\n           \"static_injection_subsystem.jl\",\n           \"dynamic_models.jl\",\n           \"operational_cost.jl\",\n           \"cost_function_timeseries.jl\",\n           \"definitions.jl\"\n           ]\nPublic = true\nPrivate = false\n```\n\n## Supplemental Attributes\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"outages.jl\",\n           \"contingencies.jl\",\n           \"impedance_correction.jl\",\n           \"plant_attribute.jl\"\n           ]\nPublic = true\nPrivate = false\n```\n\n```@autodocs\nModules = [IS]\nPages   = [\"geographic_supplemental_attribute.jl\"\n        ]\nOrder = [:type, :function]\nFilter = t -> nameof(t) in names(PowerSystems)\n```\n\n## Operating Costs\n\n```@autodocs\nModules = [IS]\nPages   = [\"production_variable_cost_curve.jl\",\n            \"cost_aliases.jl\",\n            \"value_curve.jl\",\n           ]\nOrder = [:type, :function]\nFilter = t -> nameof(t) in names(PowerSystems)\n```\n\n## Time Series\n\n```@autodocs\nModules = [IS]\nPages   = [\"abstract_time_series.jl\",\n           \"deterministic.jl\",\n           \"deterministic_single_time_series.jl\",\n           \"probabilistic.jl\",\n           \"scenarios.jl\",\n           \"static_time_series.jl\",\n           \"single_time_series.jl\",\n           \"forecasts.jl\",\n           ]\nOrder = [:type, :function]\nFilter = t -> nameof(t) in names(PowerSystems)\n```\n\n```@autodocs\nModules = [IS]\nPages   = [\"time_series_cache.jl\",\n            \"time_series_interface.jl\",\n            \"time_series_structs.jl\",\n            \"time_series_storage.jl\",\n            \"time_series_parser.jl\",\n            \"utils/print.jl\"]\nOrder = [:type, :function]\nFilter = t -> nameof(t) in names(PowerSystems)\n```\n\n## System\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"get_components_interface.jl\", \"base.jl\"]\nPublic = true\nPrivate = false\nFilter = t -> t ∈ [System]\n```\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"get_components_interface.jl\", \"base.jl\"]\nPublic = true\nPrivate = false\nFilter = t -> t ∉ [System]\n```\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"utils/print.jl\",\n           \"utils/generate_struct_files.jl\"]\nPublic = true\nPrivate = false\nFilter = t -> t ∉ [System]\n```\n\n## Advanced Component Selection\n\nThe primary way to retrieve components in PowerSystems.jl is with the [`get_components`](@ref) and similar `get_*` methods above. The following `ComponentSelector` interface offers advanced, repeatable component selection primarily for multi-scenario post-processing analytics. See [`PowerAnalytics.jl`](https://sienna-platform.github.io/PowerAnalytics.jl/stable/).\n\n```@autodocs\nModules = [IS]\nPages   = [\"component_selector.jl\"]\nFilter  = t -> !(t isa AbstractString) && nameof(t) in names(PowerSystems) && getproperty(PowerSystems, nameof(t)) === t && !(nameof(t) in [:SingularComponentSelector, :PluralComponentSelector, :DynamicallyGroupedComponentSelector, :subtype_to_string, :component_to_qualified_string])\n```\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"component_selector_interface.jl\"]\nPublic  = true\nPrivate = false\n```\n\n```@autodocs\nModules = [IS]\nPages   = [\"component_selector.jl\"]\nFilter  = t -> !(t isa AbstractString) && nameof(t) in names(PowerSystems) && getproperty(PowerSystems, nameof(t)) === t && (nameof(t) in [:SingularComponentSelector, :PluralComponentSelector, :DynamicallyGroupedComponentSelector, :subtype_to_string, :component_to_qualified_string])\n```\n\n## Additional Component Methods\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"supplemental_accessors.jl\",\n           \"supplemental_setters.jl\"]\nPublic = true\nPrivate = false\n```\n\n## [Deprecated Methods](@id deprecated)\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"deprecated.jl\"]\nPublic = true\nPrivate = false\n```\n\n## Parsing\n\n```@autodocs\nModules = [PowerSystems]\nPages = [\"parsers/power_system_table_data.jl\",\n         \"parsers/power_models_data.jl\",\n         \"parsers/TAMU_data.jl\",\n         \"parsers/psse_dynamic_data.jl\",\n         \"parsers/pm_io/common.jl\",\n         \"parsers/im_io/matlab.jl\"]\nPublic = true\nPrivate = false\nFilter = t -> t ∉ [System]\n```\n\n## [Logging](@id logging)\n\n```@autodocs\nModules = [PowerSystems]\nPages = [\"utils/logging.jl\"]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/api/static_injection_subtypes.md",
    "content": "# StaticInjection Subtypes Comparison\n\nThis document summarizes the similarities and differences between [`StaticInjection`](@ref) subtypes in PowerSystems.jl, with emphasis on generators, loads, storage, and sources. Some control-related subtypes--like FACTS devices--are omitted from the below charts, simply because they have very little in common with the other subtypes. For all subtypes of [`StaticInjection`](@ref), see [Type Tree](@ref \"Type Tree\").\n\n* * *\n\n## Power Limits Fields Comparison\n\n### Generators\n\n| Type                           | `active_power_limits` | `max_active_power` | `reactive_power_limits` | `max_reactive_power` |\n|:------------------------------ |:--------------------- |:------------------ |:----------------------- |:-------------------- |\n| [`ThermalStandard`](@ref)      | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n| [`ThermalMultiStart`](@ref)    | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n| [`RenewableDispatch`](@ref)    | ❌                     | ❌ ¹                | ✅ `MinMax` (optional)   | ❌                    |\n| [`RenewableNonDispatch`](@ref) | ❌                     | ❌                  | ❌                       | ❌                    |\n| [`HydroDispatch`](@ref)        | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n| [`HydroTurbine`](@ref)         | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n| [`HydroPumpTurbine`](@ref)     | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n\n### Loads\n\n| Type                                | `active_power_limits` | `max_active_power` | `reactive_power_limits` | `max_reactive_power` |\n|:----------------------------------- |:--------------------- |:------------------ |:----------------------- |:-------------------- |\n| [`PowerLoad`](@ref)                 | ❌                     | ✅ `Float64`        | ❌                       | ✅ `Float64`          |\n| [`StandardLoad`](@ref)              | ❌                     | ⊕                  | ❌                       | ⊕                    |\n| [`ExponentialLoad`](@ref)           | ❌                     | ✅ `Float64`        | ❌                       | ✅ `Float64`          |\n| [`MotorLoad`](@ref)                 | ❌                     | ✅ `Float64`        | ✅ `MinMax` (optional)   | ❌                    |\n| [`InterruptiblePowerLoad`](@ref)    | ❌                     | ✅ `Float64`        | ❌                       | ✅ `Float64`          |\n| [`InterruptibleStandardLoad`](@ref) | ❌                     | ⊕                  | ❌                       | ⊕                    |\n| [`ShiftablePowerLoad`](@ref)        | ✅ `MinMax`            | ✅ `Float64`        | ❌                       | ✅ `Float64`          |\n\n### Storage & Source\n\n| Type                             | `active_power_limits` | `max_active_power` | `reactive_power_limits` | `max_reactive_power` |\n|:-------------------------------- |:--------------------- |:------------------ |:----------------------- |:-------------------- |\n| [`EnergyReservoirStorage`](@ref) | ❌ ²                   | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n| [`Source`](@ref)                 | ✅ `MinMax`            | ❌                  | ✅ `MinMax` (optional)   | ❌                    |\n\n¹ Uses `rating * power_factor` dynamically; no stored field\n\n² EnergyReservoirStorage uses `input_active_power_limits` and `output_active_power_limits` instead\n\nHere, \"`MinMax` (optional)\" means `Union{MinMax, Nothing}`, with `nothing` repesenting \"no limits\" and being the default.\n\n⊕ = Split across 3 ZIP fields: `*_constant_*`, `*_impedance_*`, `*_current_*`\n\n* * *\n\n## Generator-Specific Fields\n\n| Field              | Thermal* | [`RenewableDispatch`](@ref) | [`RenewableNonDispatch`](@ref) | [`HydroDispatch`](@ref) | [`HydroTurbine`](@ref) | [`HydroPumpTurbine`](@ref) |\n|:------------------ |:-------- |:--------------------------- |:------------------------------ |:----------------------- |:---------------------- |:-------------------------- |\n| `rating`           | ✅        | ✅                           | ✅                              | ✅                       | ✅                      | ✅                          |\n| `prime_mover_type` | ✅        | ✅                           | ✅                              | ✅                       | ✅                      | ✅                          |\n| `fuel`             | ✅        | ❌                           | ❌                              | ❌                       | ❌                      | ❌                          |\n| `status`           | ✅        | ❌                           | ❌                              | ✅                       | ❌                      | ✅                          |\n| `must_run`         | ✅        | ❌                           | ❌                              | ❌                       | ❌                      | ✅                          |\n| `ramp_limits`      | ✅        | ❌                           | ❌                              | ✅                       | ✅                      | ✅                          |\n| `time_limits`      | ✅        | ❌                           | ❌                              | ✅                       | ✅                      | ✅                          |\n| `power_factor`     | ❌        | ✅                           | ✅                              | ❌                       | ❌                      | ❌                          |\n| `efficiency`       | ❌        | ❌                           | ❌                              | ❌                       | ✅                      | ✅                          |\n| `operation_cost`   | ✅        | ✅                           | ❌                              | ✅                       | ✅                      | ✅                          |\n\n\\* Thermal = [`ThermalStandard`](@ref), [`ThermalMultiStart`](@ref)\n\n* * *\n\n## Load-Specific Fields\n\n| Field                   | [`PowerLoad`](@ref) | [`StandardLoad`](@ref) | [`ExponentialLoad`](@ref) | [`MotorLoad`](@ref) | Interruptible* | Shiftable |\n|:----------------------- |:------------------- |:---------------------- |:------------------------- |:------------------- |:-------------- |:--------- |\n| `active_power`          | ✅                   | ⊕                      | ✅                         | ✅                   | ✅              | ✅         |\n| `reactive_power`        | ✅                   | ⊕                      | ✅                         | ✅                   | ✅              | ✅         |\n| `conformity`            | ✅                   | ✅                      | ✅                         | ❌                   | ✅              | ❌         |\n| `operation_cost`        | ❌                   | ❌                      | ❌                         | ❌                   | ✅              | ✅         |\n| `rating`                | ❌                   | ❌                      | ❌                         | ✅                   | ❌              | ❌         |\n| `α`, `β` (voltage exp.) | ❌                   | ❌                      | ✅                         | ❌                   | ❌              | ❌         |\n\n\\* Interruptible = [`InterruptiblePowerLoad`](@ref), [`InterruptibleStandardLoad`](@ref); Shiftable = [`ShiftablePowerLoad`](@ref)\n\n* * *\n\n## Universal Fields (All StaticInjection)\n\n| Field              | Present in ALL |\n|:------------------ |:-------------- |\n| `name`             | ✅              |\n| `available`        | ✅              |\n| `bus`              | ✅              |\n| `base_power`       | ✅              |\n| `services`         | ✅              |\n| `dynamic_injector` | ✅              |\n| `ext`              | ✅              |\n| `internal`         | ✅              |\n\n* * *\n\n## Operation Cost Types by Device\n\n| Device Category            | Cost Type                                                    |\n|:-------------------------- |:------------------------------------------------------------ |\n| [`ThermalGen`](@ref)       | [`ThermalGenerationCost`](@ref) or [`MarketBidCost`](@ref)   |\n| [`HydroGen`](@ref)         | [`HydroGenerationCost`](@ref) or [`MarketBidCost`](@ref)     |\n| [`RenewableGen`](@ref)     | [`RenewableGenerationCost`](@ref) or [`MarketBidCost`](@ref) |\n| [`ControllableLoad`](@ref) | [`LoadCost`](@ref) or [`MarketBidCost`](@ref)                |\n| [`Storage`](@ref)          | [`StorageCost`](@ref) or [`MarketBidCost`](@ref)             |\n| [`Source`](@ref)           | [`ImportExportCost`](@ref)                                   |\n\n* * *\n"
  },
  {
    "path": "docs/src/api/type_tree.md",
    "content": "# Type Tree\n\nHere is the complete `PowerSystems.jl` type hierarchy:\n\n```@repl types\nusing PowerSystems #hide\nimport TypeTree: tt #hide\ndocs_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"utils\"); #hide\ninclude(joinpath(docs_dir, \"docs_utils.jl\")); #hide\nprint(join(tt(PowerSystems.IS.InfrastructureSystemsType), \"\")) #hide\n```\n"
  },
  {
    "path": "docs/src/api/valuecurve_options.md",
    "content": "# [`ValueCurve` Options](@id curve_table)\n\nOperating cost data typically includes both fixed and variable costs. See the how-to on [Adding an Operating Cost](@ref cost_how_to) for a demonstration of defining an operating cost.\n\nIn PowerSystems.jl, the *variable* portion of the operating cost can be represented as linear, quadratic, or piecewise input-output curves; potentially piecewise marginal heat rates; average heat rates; and more, as best fits the input data. This is done by constructing various subtypes of [`ValueCurve`](@ref).\n\nThis summary table shows each way to construct a `ValueCurve` with the user-friendly subtype aliases. The `ValueCurve`s make no assumption about units; the example interpretation given here assumes that the variable cost `ValueCurve` will be wrapped in a [`CostCurve`](@ref) with natural units. Note that all four `Piecewise` options here fundamentally represent the same curve. More information and explanatory plots are provided for each subtype alias in the subheadings below.\n\n| Description                                                                                                               | Example                                                              | Example interpretation                                                                                                   |\n|:------------------------------------------------------------------------------------------------------------------------- |:-------------------------------------------------------------------- |:------------------------------------------------------------------------------------------------------------------------ |\n| Linear input-output curve with *zero* no-load cost (constant average rate)                                                | `LinearCurve(5.0)`                                                   | \\$5/MWh                                                                                                                  |\n| Linear input-output curve with potentially *nonzero* no-load cost (constant marginal rate)                                | `LinearCurve(5.0, 15.0)`                                             | \\$5/MWh + \\$15/hr                                                                                                        |\n| Quadratic input-output curve with potentially nonzero no-load cost                                                        | `QuadraticCurve(1.0, 1.0, 18.0)`                                     | $C(P) = 1 P^2 + 1 P + 18$ where $C$ is \\$/hr, $P$ is MW                                                                  |\n| Piecewise linear curve specified by cost values at production points                                                      | `PiecewisePointCurve([(1.0, 20.0), (2.0, 24.0), (3.0, 30.0)])`       | \\$20/hr @ 1 MW, \\$24/hr @ 2 MW, \\$30/hr @ 3 MW, linear  \\$/hr interpolation between these points                         |\n| Piecewise linear curve specified by initial value and marginal rates (slopes) between production points                   | `PiecewiseIncrementalCurve(20.0, [1.0, 2.0, 3.0], [4.0, 6.0])`       | \\$20/hr @ 1 MW plus additional \\$4/MWh from 1 MW to 2 MW plus additional \\$6/MWh from 2 MW to 3 MW                       |\n| No-load cost plus piecewise linear curve specified by initial value and marginal rates (slopes) between production points | `PiecewiseIncrementalCurve(18.0, 20.0, [1.0, 2.0, 3.0], [4.0, 6.0])` | \\$18/hr no-load cost; \\$20/hr @ 1 MW plus additional \\$4/MWh from 1 MW to 2 MW plus additional \\$6/MWh from 2 MW to 3 MW |\n| Piecewise linear curve specified by initial value and average rates between production points                             | `PiecewiseAverageCurve(20.0, [1.0, 2.0, 3.0], [12.0, 10.0])`         | \\$20/hr @ 1 MW, \\$12/MWh @ 2 MW, \\$10/MWh @ 3 MW, linear  \\$/hr interpolation between these points                       |\n\n## [`LinearCurve`](@ref)\n\nSpecify the marginal cost of production $M$ and optionally the no-load cost $C$, which defaults to zero. Here is a graphical representation:\n\n```@raw html\n<img src=\"../../assets/cost_plot_drawings/LinearCurve.png\" width=\"75%\"/>\n```\n\n## [`QuadraticCurve`](@ref)\n\nSpecify the quadratic ($Q$), proportional ($M$), and constant ($C$) terms of a function that defines the input-output curve:\n\n```@raw html\n<img src=\"../../assets/cost_plot_drawings/QuadraticCurve.png\" width=\"75%\"/>\n```\n\n## [`PiecewisePointCurve`](@ref)\n\nSpecify a vector of $K$ (production, cost) pairs (i.e., $(P_k, C_k)$ for $k = 1, \\dots, K$) to define the input-output curve:\n\n```@raw html\n<img src=\"../../assets/cost_plot_drawings/PiecewisePointCurve.png\" width=\"75%\"/>\n```\n\n## [`PiecewiseIncrementalCurve`](@ref)\n\nSpecify the cost $C_1$ at the least production point given (NOT the cost at zero production), a vector of $K$ production points $P_1, \\dots, P_k$, and a vector of $K-1$ marginal rates $M_1, \\dots, M_{k-1}$, that represent the slopes of the curve segments between the points. $C_1$ may be `nothing`, which results in a not-fully-defined curve. The no-load cost $C_0$ can optionally be specified as a first argument; it is not part of the representation of the curve, just another piece of data that may be stored:\n\n```@raw html\n<img src=\"../../assets/cost_plot_drawings/PiecewiseIncrementalCurve.png\" width=\"75%\"/>\n```\n\n## [`PiecewiseAverageCurve`](@ref)\n\nSpecify the cost $C_1$ at the least production point given (NOT the cost at zero production), a vector of $K$ production points $P_1, \\dots, P_k$, and a vector of $K-1$ average rates $R_1, \\dots, R_{k-1}$ at the $K-1$ latter production points:\n\n```@raw html\n<img src=\"../../assets/cost_plot_drawings/PiecewiseAverageCurve.png\" width=\"75%\"/>\n```\n"
  },
  {
    "path": "docs/src/explanation/buses_type_explanation.md",
    "content": "# [Understanding ACBusTypes](@id bustypes)\n\n`PowerSystems.jl` supports multiple types of AC buses, [listed here](@ref acbustypes_list).\nWhen creating nodal datasets, the definitions for AC Buses can have a significant impact on the\ntopology logic for the network.\n\n## Voltage Control Types\n\n  - `PQ`:\n\n      + **Known:** Real Power Injection ($P$) and Reactive Power Injection ($Q$). These are typically the loads at that bus or fixed power factor generators.\n      + **Unknown:** Voltage Magnitude ($|V|$) and Voltage Angle ($\\delta$).\n      + Represents a bus where the voltage magnitude and angle are free to vary based on the system conditions.\n\n  - `PV`:\n\n      + **Known:** Real Power Injection ($P$) and Voltage Magnitude ($|V|$).\n      + **Unknown:** Reactive Power Injection ($Q$) and Voltage Angle ($\\delta$).\n      + Typically represents a bus with an injector connected, where the injector controls the reactive power output and regulates the bus voltage magnitude to a setpoint.\n\n## Reference and Slack Buses\n\nThere is a nuanced distinction between a slack bus and a reference bus. In most small test sytems and academic discussions, the system has a single slack bus which is also the reference bus. However, for large interconnected cases or cases with a very radial structure, having a single bus that takes on all the real power mistmatch in the system can lead to erroneous results. In PowerSystems.jl we distinguish the posibility of having slacks and reference buses. Is up to the modeler to decide how to handle the classifications inside of the applications. In other words, wether a reference bus is also a slack or viceversa is left to the application developer.\n\n  - `SLACK`:\n\n      + Known: Voltage Magnitude ($|V|$) and Voltage Angle ($\\delta$) **when the slack and the reference are the same bus, otherwise is unknown**.\n      + Unknown: Real Power ($P$) and Reactive Power ($Q$). These values are calculated as residuals after the power flow solution converges to account for system losses and imbalances and are allocated using participation factors in the model formulation.\n      + This kind of bus absorbs or supplies the difference between the total generation and total load plus losses in the system. There can be several slack buses in a system.\n\n  - Ref:\n\n      + Known: Voltage Magnitude ($|V|$) and Voltage Angle ($\\delta$). Typically, the angle is set to 0 degrees for simplicity, and the voltage is set to a fixed value per unit.0 degrees for simplicity and the voltage is set to a fixed value per unit.\n      + Unknown: Real Power ($P$) and Reactive Power ($Q$). These values are calculated as residuals after the power flow solution converges to account for system losses and imbalances when there is a single slack bus that matches the reference bus.\n      + Serves as the \"reference\" for all other bus voltage angles in the AC interconnected system.\n\nFor the study of large interconnected areas that include different asynchronous AC networks connected through HVDC, the system can contain multiple reference buses. Since not all modeling efforts require a properly set reference bus, e.g., Zonal Modeling, **PowerSystems.jl does not perform a verification that the system buses are adequately set. This feature is implemented in [`PowerNetworkMatrices.jl`](https://sienna-platform.github.io/PowerNetworkMatrices.jl/stable/).**\n\n## Isolated Buses and the `available` field\n\nIn certain modeling applications, particularly power flow modeling tools, the designation of\n\"isolated\" is used to signal that the bus is temporarily disconnected from the network, as are any other components attached to it. However, in `PowerSystems.jl`, a bus and its components can be excluded from an analysis or optimization without changing the underlying network topology by setting the `available` field to false: `set_available!(bus, false)`.\n\nIn PowerSystems.jl the `ISOLATED` type means exactly that: The bus is not connected to the network. In\nresource analysis where systems contain isolated subsystems that can be ignored for the purposes of the power flow but are relevant when performing optimization, the `ISOLATED` designation provides the capability to describe those situations in precise terms. `ISOLATED` buses can also be made unavailable to make the components attached to them also unavailable.\n"
  },
  {
    "path": "docs/src/explanation/conforming_and_non_conforming_loads.md",
    "content": "# [Conforming and Non-Conforming Loads](@id conf_loads)\n\nThe difference between conforming and non-conforming loads is not particularly significant for how PowerSystems.jl manages data, as loads can be assigned either aggregate or individual time series.\n\n## Definitions and use cases\n\nAt its core, the distinction is about forecastability. The De Facto-Criteria and Practical Uses of this distinction comes from CAISO's Energy Imbalance Market (EIM) definitions. This section draws from the [CAISO EIM's \"Non-Conforming Load FAQ\"](https://www.westerneim.com/Documents/EIM-Non-Conforming-Load-FAQ.pdf) document.\n\nConforming loads are the typically residential and commercial loads that, in aggregate, follow a predictable daily and seasonal pattern influenced by factors like time of day, day of the week, and weather conditions. This predictability allows modelers to use aggregate forecasts of the total area load with a high degree of accuracy and then desagregate the curve using participation factors.\n\nNon-conforming loads, on the other hand have patterns of consumption that don't follow the aggregate behavior. Their consumption does not follow typical patterns and can fluctuate with different rates as the total system load. These are often large industrial processes with unique operational cycles. For example:\n\n  - Electric Arc Furnaces: Used in steel manufacturing, electric arc furnaces cause massive, sudden spikes in power demand when they are in operation. Depending on the time-scale of modeling these loads can require a consumption pattern that mathches the underlying industrial process.\n\n  - Large Data Centers: While having a relatively constant base load, the computational demands of large data centers almost never change with the patterns from the rest of the system. These loads tend to be flat and in some advanced models include the behavior of compute load dispatch algorithms that conduct geographic price arbitrage.\n\n  - Traction Loads for Railways: The movement of electric trains results in fluctuating power demand along the railway lines based on the transportation demand.\n\n  - Pumping Loads: Similarly to tranction loads, pumping loads can change according to water or gas demand and supply needs and not system level behavior. In its data collection manuals, WECC specifies that pumping loads are typically modeled as non-conforming in power flow cases.\n\n## Modeling using PowerSystems.jl\n\nDrawing again from CAISO's EIM procedures, the management of non-conforming loads involves:\n\n 1. **Segregated Data Submission**: The historical consumption data for the non-conforming load must be separated from the general, or \"conforming,\" load data. This \"cleanses\" the historical data used to train weather-based load forecasting models, thereby improving their accuracy for the bulk of the system's load.\n\n 2. **Independent Forecasting**: While the system operator forecasts the aggregate conforming load, the entity responsible for the non-conforming load is often required to submit its own forecast or schedule.\n\n 3. **Specialized Modeling**: In market and operational models, non-conforming loads are often treated as a type of resource. For instance, in the CAISO market, they are represented as \"Dispatchable Demand Response\" (DDR) resources, which are essentially modeled as negative generation. This allows their behavior to be explicitly accounted for in market clearing and dispatch instructions.\n\nIf a modeler wants to account for the differences in behavior between various loads, they only need to assign a distinct time series to each load. In `PowerSystems.jl`, we keep track of data related to \"conformity\" for monitoring purposes. This data is defined in the `conformity` field for concrete subtypes of [`StaticLoad`](@ref) and has the [options listed here](@ref loadconform_list). However, the behavioral variations described in the literature are already taken into consideration through the ways modelers can manage these time series assignments.\n\n### See also:\n\n  - Parsing [time series](@ref parsing_time_series)\n"
  },
  {
    "path": "docs/src/explanation/dynamic_data.md",
    "content": "# Dynamic Devices\n\n## Static and Dynamic Data Layers\n\n`PowerSystems.jl` uses two categories to define data for dynamic simulations:\n\n 1. [Static](@ref S) components, which includes the data needed to run a power flow problem\n 2. [Dynamic](@ref D) components are those that define differential equations to run a transient simulation. These dynamic\n    data are attached to the static components.\n\nAlthough `PowerSystems.jl` is not constrained to only PSS/e files, commonly the data for a\ndynamic simulation comes in a pair of files: One for the static data power flow case (e.g.,\n`.raw` file) and a second one with the dynamic components information (e.g., `.dyr` file).\nHowever, `PowerSystems.jl` is able to take any power flow case and specify dynamic\ncomponents to it. The two data layers in `PowerSystems.jl` are similar to the data\ndivision between those two files.\n\n### Layer 1: Static Components\n\nThe first data layer contains all the information necessary to run a power flow problem:\n\n  - Vector of `Bus` elements, that define all the buses in the network.\n  - Vector of `Branch` elements, that define all the branches elements (that connect two buses) in the network.\n  - Vector of `StaticInjection` elements, that define all the devices connected to buses that can inject (or withdraw) power. These static devices, typically generators, in `PowerSimulationsDynamics` are used to solve the Power Flow problem that determines the active and reactive power provided for each device.\n  - Vector of `PowerLoad` elements, that define all the loads connected to buses that can withdraw current. These are also used to solve the Power Flow.\n  - Vector of `Source` elements, that define source components behind a reactance that can inject or withdraw current.\n  - The base of power used to define per unit values, in MVA as a `Float64` value.\n  - The base frequency used in the system, in Hz as a `Float64` value.\n\n### Layer 2: Dynamic Components\n\nThe second data layer contains the *additional* information describing the dynamic response\nof certain components in the `System`. This data is all attached to components defined in\nthe static data layer:\n\n  - (Optional) Selecting which of the `Lines` (of the `Branch` vector) elements must be modeled of `DynamicLines` elements, that can be used to model lines with differential equations.\n  - Vector of `DynamicInjection` elements. These components must be attached to a `StaticInjection` that connects the power flow solution to the dynamic formulation of such device.\n\n`DynamicInjection` can be `DynamicGenerator` or `DynamicInverter`, and its specific formulation (i.e. differential equations) will depend on the specific components that define each device (see the sections below). As\na result, it is possible to flexibly define dynamic data models and methods according to\nthe analysis requirements. [`DynamicInjection`](@ref) components use a parametric\ntype pattern to materialize the full specification of the dynamic injection model with\nparameters. This design enable the use of parametric methods to specify the mathematical\nmodel of the dynamic components separately.\n\n[`DynamicInjection`](@ref) components also implement some additional information useful for\nthe modeling, like the usual states assumed by the model and the number of states. These values are\nderived from the documentation associated with the model, for instance PSS/e models provide\nparameters, states and variables. Although `PowerSystems.jl` doesn't assume a specific\nmathematical model for the components, the default values for these parameters are derived\ndirectly from the data model source.\n\n## Dynamic Generator Structure\n\nEach generator is a data structure that is defined by the following components:\n\n  - [Machine](@ref Machine): That defines the stator electro-magnetic dynamics.\n  - [Shaft](@ref Shaft): That describes the rotor electro-mechanical dynamics.\n  - [Automatic Voltage Regulator](@ref AVR): Electromotive dynamics to model an AVR controller.\n  - [Power System Stabilizer](@ref PSS): Control dynamics to define an stabilization signal for the AVR.\n  - [Prime Mover and Turbine Governor](@ref TurbineGov): Thermo-mechanical dynamics and associated controllers.\n\n```@raw html\n<img src=\"../../assets/gen_metamodel.png\" width=\"75%\"/>\n```\n\n## Dynamic Inverter Structure\n\nEach inverter is a data structure that is defined by the following components:\n\n  - [DC Source](@ref DCSource): Defines the dynamics of the DC side of the converter.\n  - [Frequency Estimator](@ref FrequencyEstimator): That describes how the frequency of the grid\n    can be estimated using the grid voltages. Typically a phase-locked loop (PLL).\n  - [Outer Loop Control](@ref OuterControl): That describes the active and reactive power\n    control dynamics.\n  - [Inner Loop Control](@ref InnerControl): That can describe virtual impedance,\n    voltage control and current control dynamics.\n  - [Converter](@ref Converter): That describes the dynamics of the pulse width modulation (PWM)\n    or space vector modulation (SVM).\n  - [Filter](@ref Filter): Used to connect the converter output to the grid.\n\n```@raw html\n<img src=\"../../assets/inv_metamodel.png\" width=\"75%\"/>\n``` ⠀\n```\n"
  },
  {
    "path": "docs/src/explanation/per_unit.md",
    "content": "# [Per-unit Conventions](@id per_unit)\n\nIt is often useful to express power systems data in relative terms using per-unit conventions.\n`PowerSystems.jl` supports the automatic conversion of data between three different unit systems:\n\n 1. `\"NATURAL_UNITS\"`: The naturally defined units of each parameter (typically MW).\n 2. `\"SYSTEM_BASE\"`: Parameter values are divided by the system `base_power`.\n 3. `\"DEVICE_BASE\"`: Parameter values are divided by the device `base_power`.\n\n`PowerSystems.jl` supports these unit systems because different power system tools and data\nsets use different units systems by convention, such as:\n\n  - Dynamics data is often defined in device base\n  - Network data (e.g., reactance, resistance) is often defined in system base\n  - Production cost modeling data is often gathered from variety of data sources,\n    which are typically defined in natural units\n\nThese three unit bases allow easy conversion between unit systems.\nThis allows `PowerSystems.jl` users to input data in the formats they have available,\nas well as view data in the unit system that is most intuitive to them.\n\nYou can get and set the unit system setting of a `System` with [`get_units_base`](@ref) and\n[`set_units_base_system!`](@ref). To support a less stateful style of programming,\n`PowerSystems.jl` provides the `Logging.with_logger`-inspired \"context manager\"-type\nfunction [`with_units_base`](@ref), which sets the unit system to a particular value,\nperforms some action, then automatically sets the unit system back to its previous value.\n\nConversion between unit systems does not change\nthe stored parameter values. Instead, unit system conversions are made when accessing\nparameters using the [accessor functions](@ref dot_access), thus making it\nimperative to utilize the accessor functions instead of the \"dot\" accessor methods to\nensure the return of the correct values. The units of the parameter values stored in each\nstruct are defined in `src/descriptors/power_system_structs.json`.\n\nThere are some unit system conventions in `PowerSystems.jl` when defining new components.\nCurrently, when you define components that aren't attached to a `System`,\nyou must define all fields in `\"DEVICE_BASE\"`, except for certain components that don't\nhave their own `base_power` rating, such as [`Line`](@ref)s, where the `rating` must be\ndefined in `\"SYSTEM_BASE\"`.\n\nIn the future, `PowerSystems.jl` hopes to support defining components in natural units.\nFor now, if you want to define data in natural units, you must first\nset the system units to `\"NATURAL_UNITS\"`, define an empty component, and then use the\n[accessor functions](@ref dot_access) (e.g., getters and setters), to define each field\nwithin the component. The accessor functions will then do the data conversion from your\ninput data in natural units (e.g., MW or MVA) to per-unit.\n\nBy default, `PowerSystems.jl` uses `\"SYSTEM_BASE\"` because many optimization problems won't\nconverge when using natural units. If you change the unit setting, it's suggested that you\nswitch back to `\"SYSTEM_BASE\"` before solving an optimization problem (for example in\n[`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/stable/)).\n\n!!! note\n\n    Check the [`Transformers per unit explanation`](@ref transformers_pu) for details on how\n    the per-unit is managed\n"
  },
  {
    "path": "docs/src/explanation/plant_attributes.md",
    "content": "# [Plant Attributes](@id plant_attributes)\n\n## The Unit vs. Plant Aggregation Problem\n\nIn power systems modeling, there is a fundamental tension between different levels of aggregation.\nReal-world power plants often consist of multiple generating units that share physical infrastructure,\nbut data sources and modeling requirements vary in how they represent this relationship:\n\n  - **Unit-level data**: Individual generators with their own capacity, cost curves, and operational constraints\n  - **Plant-level data**: Aggregated capacity and characteristics representing an entire facility\n\nFor interoperable analysis across different tools and datasets, it is often necessary to track\n**both** the plant and the individual units within it. This is particularly important when:\n\n 1. **Data integration**: Combining datasets that use different aggregation levels\n 2. **Shared infrastructure constraints**: Units on the same shaft, penstock, or point of common coupling\n    have operational dependencies that must be modeled together\n 3. **Market operations**: ISOs may require unit-level bidding while planning studies use plant-level data\n 4. **Regulatory reporting**: Different reports require different aggregation levels\n\nPowerSystems.jl addresses this challenge through **Plant Attributes**, which are\n[`SupplementalAttribute`](@ref supplemental_attributes) types that group individual generator\ncomponents into logical plant structures while preserving the detailed unit-level information.\n\n## Plant Attribute Types\n\nPowerSystems.jl provides five specialized plant attribute types, each designed for a specific\ngeneration technology:\n\n```mermaid\nclassDiagram\n    SupplementalAttribute <|-- PowerPlant\n    PowerPlant <|-- ThermalPowerPlant\n    PowerPlant <|-- CombinedCycleBlock\n    PowerPlant <|-- CombinedCycleFractional\n    PowerPlant <|-- HydroPowerPlant\n    PowerPlant <|-- RenewablePowerPlant\n```\n\n### ThermalPowerPlant\n\nRepresents conventional thermal power plants with synchronous generators. Multiple units can\nshare a common **shaft**, which is relevant for modeling mechanical coupling constraints.\n\n| Field               | Type                      | Description                                    |\n|:------------------- |:------------------------- |:---------------------------------------------- |\n| `name`              | `String`                  | Name of the power plant                        |\n| `shaft_map`         | `Dict{Int, Vector{UUID}}` | Mapping of shaft numbers to unit UUIDs         |\n| `reverse_shaft_map` | `Dict{UUID, Int}`         | Reverse mapping from unit UUID to shaft number |\n\n### CombinedCycleBlock\n\nRepresents combined cycle plants using a block configuration. Models the relationship between\ncombustion turbines (CTs) and steam turbines through the Heat Recovery Steam Generator (HRSG).\n\n| Field                           | Type                         | Description                                  |\n|:------------------------------- |:---------------------------- |:-------------------------------------------- |\n| `name`                          | `String`                     | Name of the combined cycle block             |\n| `configuration`                 | `CombinedCycleConfiguration` | Configuration type (see below)               |\n| `heat_recovery_to_steam_factor` | `Float64`                    | Factor for heat recovery to steam conversion |\n| `hrsg_ct_map`                   | `Dict{Int, Vector{UUID}}`    | HRSG to CT unit mappings (inputs)            |\n| `hrsg_ca_map`                   | `Dict{Int, Vector{UUID}}`    | HRSG to CA unit mappings (outputs)           |\n| `ct_hrsg_map`                   | `Dict{UUID, Vector{Int}}`    | Reverse CT to HRSG mapping                   |\n| `ca_hrsg_map`                   | `Dict{UUID, Vector{Int}}`    | Reverse CA to HRSG mapping                   |\n\nThe `CombinedCycleConfiguration` enum describes the plant layout. Combined cycle plants are\ntypically described using a \"CTs x STs\" notation (e.g., 2x1 means two combustion turbines\nfeeding one steam turbine through a Heat Recovery Steam Generator). However, the EIA\n[prime mover codes](@ref pm_list) employ CT and CA to distinguish between the combustion\nturbine units and the steam portion of the combined cycle respectively.\n\n```@raw html\n<figure>\n<img src=\"https://www.eia.gov/todayinenergy/images/2022.04.25/main.svg\" alt=\"Combined cycle configurations\" style=\"max-width: 100%;\"/>\n<figcaption>Combined cycle power plant configurations. Source: <a href=\"https://www.eia.gov/todayinenergy/detail.php?id=52158\">U.S. Energy Information Administration</a></figcaption>\n</figure>\n```\n\n| Value                          | Configuration      | Description                              |\n|:------------------------------ |:------------------ |:---------------------------------------- |\n| `SingleShaftCombustionSteam`   | 1x1 (single shaft) | Single CT + single ST on one shaft       |\n| `SeparateShaftCombustionSteam` | 1x1 (multi-shaft)  | Single CT + single ST on separate shafts |\n| `DoubleCombustionOneSteam`     | 2x1                | Two CTs feeding one ST via HRSG          |\n| `TripleCombustionOneSteam`     | 3x1                | Three CTs feeding one ST via HRSG        |\n| `Other`                        | Various            | Other configurations (e.g., 4x1, 2x2)    |\n\nFor more information on combined cycle configurations, see the\n[U.S. Energy Information Administration article on combined-cycle plants](https://www.eia.gov/todayinenergy/detail.php?id=52158).\n\n### CombinedCycleFractional\n\nRepresents combined cycle generation when each unit represents a specific configuration with\nan aggregate heat rate. Unlike [`CombinedCycleBlock`](@ref), which models the CT/CA relationship\nthrough the HRSG, the fractional representation uses **operation exclusion groups** to define\nwhich units can operate simultaneously. Only generators with the `CC` (combined cycle)\n[prime mover type](@ref pm_list) can be added.\n\n| Field                             | Type                         | Description                                              |\n|:--------------------------------- |:---------------------------- |:-------------------------------------------------------- |\n| `name`                            | `String`                     | Name of the combined cycle fractional plant              |\n| `configuration`                   | `CombinedCycleConfiguration` | Configuration type (see table above)                     |\n| `operation_exclusion_map`         | `Dict{Int, Vector{UUID}}`    | Mapping of exclusion group numbers to unit UUIDs         |\n| `inverse_operation_exclusion_map` | `Dict{UUID, Int}`            | Reverse mapping from unit UUID to exclusion group number |\n\n### HydroPowerPlant\n\nRepresents hydroelectric plants where multiple turbines may share a common **penstock**\n(the pipe that delivers water to the turbines). Shared penstocks create operational\ndependencies between units.\n\n| Field                  | Type                      | Description                                       |\n|:---------------------- |:------------------------- |:------------------------------------------------- |\n| `name`                 | `String`                  | Name of the hydro power plant                     |\n| `penstock_map`         | `Dict{Int, Vector{UUID}}` | Mapping of penstock numbers to unit UUIDs         |\n| `reverse_penstock_map` | `Dict{UUID, Int}`         | Reverse mapping from unit UUID to penstock number |\n\n### RenewablePowerPlant\n\nRepresents renewable energy plants (wind farms, solar farms) where multiple generators or\nstorage devices connect through a common **Point of Common Coupling (PCC)** to the grid.\n\n| Field             | Type                      | Description                                  |\n|:----------------- |:------------------------- |:-------------------------------------------- |\n| `name`            | `String`                  | Name of the renewable power plant            |\n| `pcc_map`         | `Dict{Int, Vector{UUID}}` | Mapping of PCC numbers to unit UUIDs         |\n| `reverse_pcc_map` | `Dict{UUID, Int}`         | Reverse mapping from unit UUID to PCC number |\n\n## Creating Plant Attributes\n\n### Basic Construction\n\nAll plant attributes can be created with just a name; the infrastructure mappings are populated\nwhen units are added:\n\n```julia\n# Create empty plant attributes\nthermal_plant = ThermalPowerPlant(; name = \"Coal Plant A\")\nhydro_plant = HydroPowerPlant(; name = \"Dam Complex\")\nrenewable_plant = RenewablePowerPlant(; name = \"Wind Farm North\")\ncc_block = CombinedCycleBlock(;\n    name = \"CC Unit 1\",\n    configuration = CombinedCycleConfiguration.DoubleCombustionOneSteam,\n)\ncc_fractional = CombinedCycleFractional(;\n    name = \"CC Fractional 1\",\n    configuration = CombinedCycleConfiguration.DoubleCombustionOneSteam,\n)\n```\n\n### Adding Units to Plants\n\nUnits are added to plants using [`add_supplemental_attribute!`](@ref), which requires\nspecifying the infrastructure number (shaft, penstock, PCC, or HRSG):\n\n```julia\n# Add thermal generators to a plant (shaft_number is required)\nadd_supplemental_attribute!(sys, gen1, thermal_plant; shaft_number = 1)\nadd_supplemental_attribute!(sys, gen2, thermal_plant; shaft_number = 1)  # Same shaft\nadd_supplemental_attribute!(sys, gen3, thermal_plant; shaft_number = 2)  # Different shaft\n\n# Add hydro turbines to a plant (penstock_number is required)\nadd_supplemental_attribute!(sys, turbine1, hydro_plant, 1)  # Penstock 1\nadd_supplemental_attribute!(sys, turbine2, hydro_plant, 1)  # Same penstock\nadd_supplemental_attribute!(sys, turbine3, hydro_plant, 2)  # Penstock 2\n\n# Add renewable generators to a plant (pcc_number is required)\nadd_supplemental_attribute!(sys, wind_gen1, renewable_plant, 1)  # PCC 1\nadd_supplemental_attribute!(sys, battery, renewable_plant, 1)    # Same PCC\n\n# Add CT and CA units to combined cycle block (hrsg_number is required)\n# Note: Only CT (combustion turbine) and CA (combined cycle steam part) prime movers are allowed\nadd_supplemental_attribute!(sys, ct_unit, cc_block; hrsg_number = 1)\nadd_supplemental_attribute!(sys, steam_unit, cc_block; hrsg_number = 1)\n\n# Add CC units to combined cycle fractional (exclusion_group is required)\n# Note: Only CC (combined cycle) prime mover type is allowed\nadd_supplemental_attribute!(sys, cc_config1, cc_fractional; exclusion_group = 1)\nadd_supplemental_attribute!(sys, cc_config2, cc_fractional; exclusion_group = 1)\nadd_supplemental_attribute!(sys, cc_config3, cc_fractional; exclusion_group = 2)\n```\n\n## Querying Plant Information\n\n### Getting All Units in a Plant\n\nUse [`get_associated_components`](@ref) to retrieve all units associated with a plant:\n\n```julia\n# Get all generators in a thermal plant\nfor gen in get_associated_components(sys, thermal_plant; component_type = ThermalGen)\n    @show get_name(gen)\nend\n```\n\n### Getting Units by Infrastructure\n\nQuery units connected to specific infrastructure elements:\n\n```julia\n# Get all generators on shaft 1\ngens_on_shaft_1 = get_components_in_shaft(sys, thermal_plant, 1)\n\n# Get all turbines on penstock 2\nturbines_on_penstock_2 = get_components_in_penstock(sys, hydro_plant, 2)\n\n# Get all generators/storage at PCC 1\ncomponents_at_pcc_1 = get_components_in_pcc(sys, renewable_plant, 1)\n\n# Get all generators in exclusion group 1\ngens_in_group_1 = get_components_in_exclusion_group(sys, cc_fractional, 1)\n```\n\n### Accessing Infrastructure Maps\n\nDirect access to the mapping dictionaries is available through accessor functions:\n\n```julia\n# ThermalPowerPlant\nshaft_map = get_shaft_map(thermal_plant)           # Dict{Int, Vector{UUID}}\nreverse_map = get_reverse_shaft_map(thermal_plant) # Dict{UUID, Int}\n\n# HydroPowerPlant\npenstock_map = get_penstock_map(hydro_plant)\nreverse_map = get_reverse_penstock_map(hydro_plant)\n\n# RenewablePowerPlant\npcc_map = get_pcc_map(renewable_plant)\nreverse_map = get_reverse_pcc_map(renewable_plant)\n\n# CombinedCycleBlock\nct_map = get_hrsg_ct_map(cc_block)     # HRSG -> CTs\nca_map = get_hrsg_ca_map(cc_block)     # HRSG -> CAs\nconfig = get_configuration(cc_block)   # CombinedCycleConfiguration\nfactor = get_heat_recovery_to_steam_factor(cc_block)\n\n# CombinedCycleFractional\nexclusion_map = get_operation_exclusion_map(cc_fractional)\ninverse_map = get_inverse_operation_exclusion_map(cc_fractional)\nconfig = get_configuration(cc_fractional)  # CombinedCycleConfiguration\n```\n\n## Removing Units from Plants\n\nUnits can be removed from plants while preserving both the unit and the plant:\n\n```julia\nremove_supplemental_attribute!(sys, gen1, thermal_plant)\nremove_supplemental_attribute!(sys, turbine1, hydro_plant)\nremove_supplemental_attribute!(sys, wind_gen1, renewable_plant)\nremove_supplemental_attribute!(sys, ct_unit, cc_block)\nremove_supplemental_attribute!(sys, cc_config1, cc_fractional)\n```\n\n## Complete Example\n\nHere is a complete example demonstrating the workflow for a thermal power plant:\n\n```julia\nusing PowerSystems\n\n# Create a system with thermal generators\nsys = System(100.0)  # 100 MVA base\n\nbus = ACBus(;\n    number = 1,\n    name = \"Bus1\",\n    bustype = ACBusTypes.REF,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.1),\n    base_voltage = 230.0,\n)\nadd_component!(sys, bus)\n\n# Create three thermal units\ngen1 = ThermalStandard(;\n    name = \"Unit1\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 100.0,\n    reactive_power = 0.0,\n    rating = 120.0,\n    active_power_limits = (min = 30.0, max = 100.0),\n    reactive_power_limits = (min = -50.0, max = 50.0),\n    ramp_limits = nothing,\n    operation_cost = ThermalGenerationCost(nothing),\n    base_power = 100.0,\n    time_limits = nothing,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n)\n\ngen2 = ThermalStandard(;\n    name = \"Unit2\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 100.0,\n    reactive_power = 0.0,\n    rating = 120.0,\n    active_power_limits = (min = 30.0, max = 100.0),\n    reactive_power_limits = (min = -50.0, max = 50.0),\n    ramp_limits = nothing,\n    operation_cost = ThermalGenerationCost(nothing),\n    base_power = 100.0,\n    time_limits = nothing,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n)\n\ngen3 = ThermalStandard(;\n    name = \"Unit3\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 50.0,\n    reactive_power = 0.0,\n    rating = 60.0,\n    active_power_limits = (min = 15.0, max = 50.0),\n    reactive_power_limits = (min = -25.0, max = 25.0),\n    ramp_limits = nothing,\n    operation_cost = ThermalGenerationCost(nothing),\n    base_power = 50.0,\n    time_limits = nothing,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n)\n\nadd_component!(sys, gen1)\nadd_component!(sys, gen2)\nadd_component!(sys, gen3)\n\n# Create a plant attribute\nplant = ThermalPowerPlant(; name = \"Coal Plant Alpha\")\n\n# Add the plant to the system (optional, for serialization)\nadd_supplemental_attribute!(sys, plant)\n\n# Associate generators with the plant\n# Units 1 and 2 share shaft 1, Unit 3 is on shaft 2\nadd_supplemental_attribute!(sys, gen1, plant; shaft_number = 1)\nadd_supplemental_attribute!(sys, gen2, plant; shaft_number = 1)\nadd_supplemental_attribute!(sys, gen3, plant; shaft_number = 2)\n\n# Query generators on shaft 1\nshaft_1_gens = get_components_in_shaft(sys, plant, 1)\nprintln(\"Generators on Shaft 1:\")\nfor gen in shaft_1_gens\n    println(\"  - $(get_name(gen)): $(get_active_power_limits(gen).max) MW\")\nend\n\n# Get total plant capacity\nall_gens = collect(get_associated_components(sys, plant; component_type = ThermalGen))\ntotal_capacity = sum(get_active_power_limits(g).max for g in all_gens)\nprintln(\"Total plant capacity: $total_capacity MW\")\n```\n\n## Supported Component Types\n\nEach plant attribute type supports specific component types:\n\n| Plant Type                | Supported Components                                     |\n|:------------------------- |:-------------------------------------------------------- |\n| `ThermalPowerPlant`       | `ThermalGen` (all subtypes)                              |\n| `CombinedCycleBlock`      | `ThermalGen` with `CT` or `CA` prime mover only          |\n| `CombinedCycleFractional` | `ThermalGen` with `CC` prime mover only                  |\n| `HydroPowerPlant`         | `HydroTurbine`, `HydroPumpTurbine` (not `HydroDispatch`) |\n| `RenewablePowerPlant`     | `RenewableGen`, `EnergyReservoirStorage`                 |\n\n## Serialization\n\nPlant attributes are fully serializable with the system. The infrastructure mappings (UUIDs)\nare preserved during JSON serialization and correctly restored on deserialization, maintaining\nthe plant-unit relationships across save/load cycles.\n\n## See Also\n\n  - [`SupplementalAttribute`](@ref supplemental_attributes) - Base concept for supplemental data\n  - [`ThermalPowerPlant`](@ref) - API reference\n  - [`CombinedCycleBlock`](@ref) - API reference\n  - [`CombinedCycleFractional`](@ref) - API reference\n  - [`HydroPowerPlant`](@ref) - API reference\n  - [`RenewablePowerPlant`](@ref) - API reference\n"
  },
  {
    "path": "docs/src/explanation/power_concepts.md",
    "content": "# [Power Concepts: Base Power, Rating, and Max Active Power](@id power_concepts)\n\nWhen working with generators in PowerSystems.jl, it's important to understand the distinction between three key power concepts: base power, rating, and maximum active power. These concepts serve different purposes and are stored using different unit conventions.\n\n## Base Power\n\n**Base power** is the reference power value used for per-unitization of a specific device.\n\n  - **Purpose**: Serves as the denominator when converting device parameters to per-unit values\n  - **Units**: Always stored in **natural units** (MVA)\n  - **Typical value**: The nameplate capacity of the device\n  - **Access**: Retrieved using `get_base_power(device)`\n\nBase power is a fundamental parameter for the per-unit system and represents the natural scale of the device. For more details on per-unitization, see the [Per-unit Conventions](@ref per_unit) page.\n\n## Rating\n\n**Rating** represents the maximum AC side output power rating of the synchronous machine or generator.\n\n  - **Purpose**: Defines the maximum apparent power (MVA) that the generator's electrical components can safely handle\n\n  - **Units**: Stored in per-unit using **device base** (i.e., divided by the device's `base_power`)\n\n  - **Physical meaning**: The maximum MVA output considering electrical constraints such as:\n\n      + Stator winding thermal limits\n      + Rotor field winding limits\n      + Cooling system capacity\n\n  - **Access**: Retrieved using `get_rating(device)`\n\nThe rating is typically determined by the electrical design and thermal limits of the synchronous machine itself. It represents the maximum capability of the electrical generator, independent of the prime mover.\n\n## Maximum Active Power\n\n**Maximum active power** represents the maximum real power output of the prime mover.\n\n  - **Purpose**: Defines the maximum real power (MW) that the prime mover can deliver\n\n  - **Units**: Stored in per-unit using **device base** (i.e., divided by the device's `base_power`)\n\n  - **Physical meaning**: The maximum MW output considering prime mover constraints such as:\n\n      + Turbine capacity (for steam, gas, or hydro turbines)\n      + Combustion chamber limits (for gas turbines)\n      + Boiler capacity (for steam generators)\n      + Fuel flow limitations\n\n  - **Access**: Retrieved using `get_max_active_power(device)`\n\nThe maximum active power is determined by the mechanical system that drives the generator. This is often less than the rating when considering only real power production.\n\n## Key Distinctions\n\n### Storage Convention Summary\n\n| Concept          | Storage Units       | Accessor Function        |\n|:---------------- |:------------------- |:------------------------ |\n| Base Power       | Natural units (MVA) | `get_base_power()`       |\n| Rating           | Device base (p.u.)  | `get_rating()`           |\n| Max Active Power | Device base (p.u.)  | `get_max_active_power()` |\n\n### Physical Interpretation\n\nThe relationship between these three quantities can be understood as follows:\n\n  - **Base Power**: \"What is the natural scale of this device?\"\n  - **Rating**: \"What is the maximum apparent power the electrical generator can produce?\"\n  - **Max Active Power**: \"What is the maximum real power the prime mover can deliver?\"\n\n### Example\n\nConsider a thermal generator with:\n\n  - `base_power = 100.0` MVA (stored in natural units)\n  - `rating = 1.0` p.u. (equals 100 MVA when converted to natural units)\n  - `max_active_power = 0.95` p.u. (equals 95 MW when converted to natural units)\n\nIn this example:\n\n  - The generator's electrical components can handle up to 100 MVA\n  - The prime mover (e.g., steam turbine) can deliver up to 95 MW of real power\n  - The difference accounts for the fact that the turbine's mechanical power limit is slightly below the generator's electrical rating\n\n### Unit System Conversions\n\nWhen you access these values through the PowerSystems.jl accessor functions, they are automatically converted based on the current unit system setting:\n\n```julia\n# Assuming base_power = 100 MVA, rating = 1.0 p.u., max_active_power = 0.95 p.u.\nsys = System(100.0)  # System base power = 100 MVA\ngen = get_component(ThermalStandard, sys, \"gen1\")\n\n# In DEVICE_BASE\nset_units_base_system!(sys, \"DEVICE_BASE\")\nget_base_power(gen)                    # Returns: 100.0 MVA (always natural units)\nget_rating(gen)                        # Returns: 1.0 p.u. (on device base)\nget_max_active_power(gen)              # Returns: 0.95 p.u. (on device base)\n\n# In NATURAL_UNITS\nset_units_base_system!(sys, \"NATURAL_UNITS\")\nget_base_power(gen)                    # Returns: 100.0 MVA (always natural units)\nget_rating(gen)                        # Returns: 100.0 MVA (converted from p.u.)\nget_max_active_power(gen)              # Returns: 95.0 MW (converted from p.u.)\n\n# In SYSTEM_BASE\nset_units_base_system!(sys, \"SYSTEM_BASE\")\nget_base_power(gen)                    # Returns: 100.0 MVA (always natural units)\nget_rating(gen)                        # Returns: 1.0 p.u. (on system base, assuming system base = device base)\nget_max_active_power(gen)              # Returns: 0.95 p.u. (on system base)\n```\n\n!!! note\n\n    Base power is **always** returned in natural units (MVA) regardless of the unit system setting. The rating and maximum active power are stored in device base but are automatically converted when accessed based on the current unit system setting.\n\n## See Also\n\n  - [Per-unit Conventions](@ref per_unit) - Detailed explanation of unit systems in PowerSystems.jl\n  - [`ThermalStandard`](@ref) - Generator type with these power parameters\n  - [`get_units_base`](@ref) and [`set_units_base_system!`](@ref) - Functions for managing unit systems\n"
  },
  {
    "path": "docs/src/explanation/supplemental_attributes.md",
    "content": "# [Supplemental Attributes](@id supplemental_attributes)\n\nWhile the [`ext` field is a mechanism](@ref additional_fields) for adding arbitrary metadata. PowerSystems.jl, has moved towards a more structured and formalized way of handling supplemental data using `SupplementalAttribute` structs. This is designed to store metadata in a more organized fashion than a generic dictionary. These attributes are intended to be attached to a [`Component`](@ref) types.\n\nSupplemmental attributes can be shared between components or have 1-1 relationships. This is particularly\nuseful to represent components in the same geographic location or outages for multiple components. Conversely, components can contain many attributes.\n\n```mermaid\nflowchart LR\n    A[\"Attribute A\"] --> B[\"Component 1\"]\n    A -->  C[\"Component2\"]\n    D[\"Attribute B\"] -->  C[\"Component 2\"]\n    E[\"Attribute C\"] -->  F[\"Component 3\"]\n```\n\nSupplemental attributes can also contain timeseries in the same fashion that a component can allowing the user to model time varying attributes like outage time series or weather dependent probabilities. See the section [`Working with Time Series Data`](@ref tutorial_time_series) for details on time series handling.\n\n## Getting the attributes in a system\n\nYou can retrieve the attributes in a system using the function [`get_supplemental_attributes`](@ref).\nYou must pass a supplemental attribute type, which can be concrete or abstract. If you pass an abstract type, all concrete types\nthat are subtypes of the abstract type will be returned.\n\n```julia\nfor outage in get_supplemental_attributes(FixedForcedOutage, system)\n    @show summary(outage)\nend\n```\n\nYou can optionally pass a filter function to reduce the returned attributes. This example will\nreturn only FixedForcedOutage instances that have a mean time to recovery greater than or equal to 0.5.\n\n```julia\nfor outage in get_supplemental_attributes(\n    x -> get_mean_time_to_recovery(x) >= 0.5,\n    FixedForcedOutage,\n    system,\n)\n    @show summary(outage)\nend\n```\n\n## Getting the attributes associated with a component\n\nYou can retrieve the attributes associated with a component using the function [`get_supplemental_attributes`](@ref).\nThis method signatures are identical to the versions above that operate on a system; just swap the system for a component.\n\nYou must pass a supplemental attribute type, which can be concrete or abstract. If you pass an abstract type, all concrete types\nthat are subtypes of the abstract type will be returned.\n\n```julia\ngen1 = get_component(ThermalStandard, system, \"gen1\")\nfor outage in get_supplemental_attributes(FixedForcedOutage, gen)\n    @show summary(outage)\nend\n```\n\nYou can optionally pass a filter function to reduce the returned attributes. This example will\nreturn only FixedForcedOutage instances that have a mean time to recovery greater than or equal to 0.5.\n\n```julia\nfor outage in get_supplemental_attributes(\n    x -> get_mean_time_to_recovery(x) >= 0.5,\n    gen,\n    FixedForcedOutage,\n)\n    @show summary(outage)\nend\n```\n\n## Getting the attributes associated with a component type\n\nYou can retrieve the attributes associated with any component of a given type\nusing the function [`get_associated_supplemental_attributes`](@ref). If one attribute is attached to\nmultiple components of the given type, it will still only appear once in the result.\n\n 1. Get all the attributes associated with all components of a given type.\n\n    ```julia\n    for outage in get_associated_supplemental_attributes(system, ThermalStandard)\n        @show summary(outage)\n    end\n    ```\n\n 2. Same as #1, but filter the results by attribute type, which can be concrete or abstract.\n\n    ```julia\n    for outage in\n        get_associated_supplemental_attributes(\n        system,\n        ThermalStandard;\n        attribute_type = FixedForcedOutage,\n    )\n        @show summary(outage)\n    end\n    ```\n\n## Getting the components associated with an attribute\n\nYou can retrieve the components associated with a single supplemental attribute using the\nfunction [`get_associated_components`](@ref).\n\n 1. Get all components associated with a single supplemental attribute.\n\n    ```julia\n    outage = first(get_supplemental_attributes(FixedForcedOutage, system))\n    for component in get_associated_components(system, outage)\n        @show summary(component)\n    end\n    ```\n\n 2. Same as #1, but filter the results by component type, which can be concrete or abstract.\n\n    ```julia\n    outage = first(get_supplemental_attributes(FixedForcedOutage, system))\n    for component in get_associated_components(system, outage; component_type = ThermalStandard)\n        @show summary(component)\n    end\n    ```\n\n## Getting the components associated with an attribute type\n\nYou can retrieve the components associated with any supplemental attribute of a given type\nusing the function [`get_associated_components`](@ref).\n\n 1. Get all components associated with any supplemental attribute of a given type.\n\n    ```julia\n    for component in get_associated_components(system, FixedForcedOutage)\n        @show summary(component)\n    end\n    ```\n\n 2. Same as #1, but filter the results by component type, which can be concrete or abstract.\n\n    ```julia\n    for component in\n        get_associated_components(system, FixedForcedOutage; component_type = ThermalStandard)\n        @show summary(component)\n    end\n    ```\n\n## Getting component / supplemental attribute pairs\n\nThe function [`get_component_supplemental_attribute_pairs`](@ref) returns a vector of component / supplemental\nattribute pairs based on types and optional filters. This can be more efficient than double for loops\nthat iterate over components and their associated attributes independently.\n\n```julia\nfor (gen, outage) in get_component_supplemental_attribute_pairs(\n    ThermalStandard,\n    FixedForcedOutage,\n    system,\n)\n    @show summary(gen) summary(outage)\nend\n```\n\n## Adding Time Series to an attribute\n\n## Existing Supplemental Attributes in PowerSystems\n\n  - [`GeographicInfo`](@ref)\n  - [`ImpedanceCorrectionData`](@ref)\n\n### Contingency Attributes\n\n  - [`FixedForcedOutage`](@ref)\n  - [`GeometricDistributionForcedOutage`](@ref)\n  - [`PlannedOutage`](@ref)\n\n### Plant Attributes\n\nPlant attributes are a specialized category of supplemental attributes for grouping individual\ngenerator units into logical plant structures. See [Plant Attributes](@ref plant_attributes)\nfor detailed documentation.\n\n  - [`ThermalPowerPlant`](@ref) - Thermal plants with shared shafts\n  - [`CombinedCycleBlock`](@ref) - Combined cycle plants with HRSG configurations\n  - [`CombinedCycleFractional`](@ref) - Combined cycle plants with aggregate heat rate and exclusion groups\n  - [`HydroPowerPlant`](@ref) - Hydro plants with shared penstocks\n  - [`RenewablePowerPlant`](@ref) - Renewable plants with shared PCCs\n"
  },
  {
    "path": "docs/src/explanation/system.md",
    "content": "# [System](@id system_doc)\n\nThe `System` is the main container of components and the time series data references.\n`PowerSystems.jl` uses a hybrid approach to data storage, where the component data and time\nseries references are stored in volatile memory while the actual time series data is stored\nin an HDF5 file. This design loads into memory the portions of the data that are relevant\nat time of the query, and so avoids overwhelming the memory resources.\n\n```@raw html\n<img src=\"../../assets/System.png\" width=\"50%\"/>\n```\n\n## Accessing components stored in the `System`\n\n`PowerSystems.jl` implements a wide variety of methods to search for components to\naid in data manipulation. Most of these use the [Type Structure](@ref type_structure) to\nretrieve all components of a certain `Type`.\n\nFor example, the most common search function is [`get_components`](@ref), which\ntakes a desired device `Type` (concrete or abstract) and retrieves all components in that\ncategory from the `System`. It also accepts filter functions for a more\nrefined search.\n\nGiven the potential size of the return,\n`PowerSystems.jl` returns Julia iterators in order to avoid unnecessary memory allocations.\nThe container is optimized for iteration over abstract or concrete component\ntypes as described by the [Type Structure](@ref type_structure).\n\n## [Accessing data stored in a component](@id dot_access)\n\n__Using the \"dot\" access to get a parameter value from a component is actively discouraged, use \"getter\" functions instead__\n\nUsing code autogeneration, `PowerSystems.jl` implements accessor (or \"getter\") functions to\nenable the retrieval of parameters defined in the component struct fields. Julia syntax enables\naccess to this data using the \"dot\" access (e.g. `component.field`), however\n_this is actively discouraged_ for two reasons:\n\n 1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.\n 2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit section](@ref per_unit) for more details)\n\n## [Using subsystems](@id subsystems)\n\nFor certain applications, such as those that employ dispatch coordination methods or decomposition approaches, it is useful to be able to split components into subsystems based upon user-defined criteria. The  `System` provides `subsystem` containers for this purpose. Each subsystem is defined by a name and can hold references to any number of components.\n\nThe following commands demonstrate how to create subsystems and add components.\n\n```@repl subsystem\nusing PowerSystems;\nusing PowerSystemCaseBuilder;\nsys = build_system(PSISystems, \"c_sys5_pjm\")\nadd_subsystem!(sys, \"1\")\nadd_subsystem!(sys, \"2\")\n```\n\nDevices in the system can be assigned to the subsystems in the following way using the function [`add_component_to_subsystem!`](@ref)\n\n```@repl subsystem\ng = get_component(ThermalStandard, sys, \"Alta\")\nadd_component_to_subsystem!(sys, \"1\", g)\n\ng = get_component(ThermalStandard, sys, \"Sundance\")\nadd_component_to_subsystem!(sys, \"2\", g)\n```\n\nTo retrieve components assigned to a specific subsystem, add the `subsystem_name` keyword argument to `get_components`.\n\n```@repl subsystem\ngens_1 = get_components(ThermalStandard, sys; subsystem_name = \"1\")\nget_name.(gens_1)\n\ngens_2 = get_components(ThermalStandard, sys; subsystem_name = \"2\")\nget_name.(gens_2)\n```\n\nOne useful feature that requires care when used is generating a new [`System`](@ref) from a `subsystem` assignment.\n\nThe function [`from_subsystem`](@ref) will allow the user to produce a new [`System`](@ref) that can be used or exported.\nThis functionality requires careful subsystem assignemnt of the devices and its dependencies. Following from the example in this document, you can export a system as follows:\n\n```@repl subsystem\nfrom_subsystem(sys, \"1\")\n```\n\n!!! warning\n\n    The system is invalid because the bus connected to the Alta generator is not part of the subsystem. We can add it, and then run [`from_subsystem`](@ref) again\n\n```@repl subsystem\ng = get_component(ThermalStandard, sys, \"Alta\")\nb = get_bus(g)\nadd_component_to_subsystem!(sys, \"1\", b)\nfrom_subsystem(sys, \"1\")\n```\n\nAdvanced users can use the keyword `runchecks=false` and avoid any topological check in the process.\nIt is highly recommended that users only do this if they clearly understand how to validate the resulting system before using it for modeling.\n"
  },
  {
    "path": "docs/src/explanation/time_series.md",
    "content": "# [Time Series Data](@id ts_data)\n\n## Categories of Time Series\n\nThe bulk of the data in many power system models is time series data. Given the potential\ncomplexity, `PowerSystems.jl` has a set of definitions to organize this data and\nenable consistent modeling.\n\n`PowerSystems.jl` supports two categories of time series data depending on the\nprocess to obtain the data and its interpretation:\n\n  - [Static Time Series Data](@ref)\n  - [Forecasts](@ref)\n\nThese categories are are all subtypes of `TimeSeriesData` and fall within this time series\ntype hierarchy:\n\n```@repl\nusing PowerSystems #hide\nimport TypeTree: tt #hide\ndocs_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"utils\"); #hide\ninclude(joinpath(docs_dir, \"docs_utils.jl\")); #hide\nprint(join(tt(TimeSeriesData), \"\")) #hide\n```\n\n### Static Time Series Data\n\nA static time series data is a single column of data where each time period has a single\nvalue assigned to a component field, such as its maximum active power. This data commonly\nis obtained from historical information or the realization of a time-varying quantity.\n\nStatic time series usually comes in the following format, with a set [resolution](@ref R)\nbetween the time-stamps:\n\n| DateTime            | Value |\n|:------------------- |:-----:|\n| 2020-09-01T00:00:00 | 100.0 |\n| 2020-09-01T01:00:00 | 101.0 |\n| 2020-09-01T02:00:00 | 99.0  |\n\nThis example is a 1-hour resolution static time-series.\n\nIn PowerSystems, a static time series is represented using [`SingleTimeSeries`](@ref).\n\n### Forecasts\n\nA forecast time series includes predicted values of a time-varying quantity that commonly\nincludes a look-ahead window and can have multiple data values representing each time\nperiod. This data is used in simulation with receding horizons or data generated from\nforecasting algorithms.\n\nKey forecast format parameters are the forecast [resolution](@ref R), the\n[interval](@ref I) of time between forecast [initial times](@ref I), and the number of\n[forecast windows](@ref F) (or forecasted values) in the forecast [horizon](@ref H).\n\nForecast data usually comes in the following format, where a column represents the time\nstamp associated with the [initial time](@ref I) of the forecast, and the remaining columns\nrepresent the forecasted values at each step in the forecast [horizon](@ref H).\n\n| DateTime            | 0     | 1     | 2     | 3    | 4     | 5     | 6     | 7     |\n|:------------------- |:-----:|:-----:|:-----:|:----:|:-----:|:-----:|:-----:|:----- |\n| 2020-09-01T00:00:00 | 100.0 | 101.0 | 101.3 | 90.0 | 98.0  | 87.0  | 88.0  | 67.0  |\n| 2020-09-01T01:00:00 | 101.0 | 101.3 | 99.0  | 98.0 | 88.9  | 88.3  | 67.1  | 89.4  |\n| 2020-09-01T02:00:00 | 99.0  | 67.0  | 89.0  | 99.9 | 100.0 | 101.0 | 112.0 | 101.3 |\n\nThis example forecast has a [interval](@ref I) of 1 hour and a [horizon](@ref H) of 8.\n\nPowerSystems defines the following Julia structs to represent forecasts:\n\n  - [`Deterministic`](@ref): Point forecast without any uncertainty representation.\n  - [`Probabilistic`](@ref): Stores a discretized cumulative distribution functions\n    (CDFs) or probability distribution functions (PDFs) at each time step in the\n    look-ahead window.\n  - [`Scenarios`](@ref): Stores a set of probable trajectories for forecasted quantity\n    with equal probability.\n\n## Multiple Forecast Intervals\n\nPowerSystems supports attaching multiple forecast groups to the same component, where each\ngroup shares the same name and resolution but differs by [interval](@ref I). This is useful\nwhen a component needs forecasts updated at different frequencies — for example, an\nhourly-updated forecast and a daily-updated forecast for the same quantity.\n\nUse [`transform_single_time_series!`](@ref) with `delete_existing = false` to create\nmultiple [`DeterministicSingleTimeSeries`](@ref) transforms from the same\n[`SingleTimeSeries`](@ref), each with a different interval:\n\n```julia\n# Create a 30-minute interval forecast\ntransform_single_time_series!(sys, Hour(1), Minute(30); delete_existing = false)\n# Create a 1-hour interval forecast from the same underlying data\ntransform_single_time_series!(sys, Hour(1), Hour(1); delete_existing = false)\n```\n\nWhen multiple forecasts share the same name and resolution, you must specify the `interval`\nkeyword argument to disambiguate retrieval and removal:\n\n```julia\n# Retrieve a specific interval's forecast\nts = get_time_series(DeterministicSingleTimeSeries, component, \"max_active_power\";\n    interval = Minute(30))\n\n# Query forecast parameters for a specific interval\nget_forecast_horizon(sys; interval = Minute(30))\nget_forecast_initial_times(sys; interval = Hour(1))\n\n# Remove only one interval's forecasts\nremove_time_series!(sys, DeterministicSingleTimeSeries, component, \"max_active_power\";\n    interval = Minute(30))\n```\n\nOmitting `interval` when multiple intervals exist for the same name will raise an\n`ArgumentError`.\n\n## Data Storage\n\nBy default PowerSystems stores time series data in an HDF5 file.\nThis prevents\nlarge datasets from overwhelming system memory. Refer to this\n[page](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/dev_guide/time_series/#Data-Format)\nfor details on how the time series data is stored in HDF5 files.\n\nTime series data can be stored actual component values (for instance MW) or scaling\nfactors intended to be multiplied by a scalar to generate the component values.\nBy default PowerSystems treats the values in the time\nseries data as physical units. In order to specify them as scaling factors, you\nmust pass the accessor function that provides the multiplier value (e.g.,\n`get_time_series_array`). The scaling factor multiplier\nmust be passed into the forecast when you create it to use this option.\n\nThe time series contains fields for `scaling_factor_multiplier` and `data`\nto identify the details of  th `Component` field that the time series describes, and the\ntime series `data`. For example: we commonly want to use a time series to\ndescribe the maximum active power capability of a renewable generator. In this case, we\ncan create a `SingleTimeSeries` with a `TimeArray` and an accessor function to the\nmaximum active power field in the struct describing the generator. In this way, we can\nstore a scaling factor time series that will get multiplied by the maximum active power\nrather than the magnitudes of the maximum active power time series.\n\nExamples of how to create and add time series to system can be found in the\n[Add Time Series Example](https://sienna-platform.github.io/PowerSystems.jl/stable/tutorials/add_forecasts/)\n"
  },
  {
    "path": "docs/src/explanation/transformer_per_unit_models.md",
    "content": "# [Transformer per unit transformations](@id transformers_pu)\n\nThe per-unit (p.u.) system is a fundamental tool in power system analysis, especially when dealing with transformers. It simplifies calculations by normalizing all quantities (voltage, current, power, impedance) to a common base. This effectively \"retains\" the ideal transformer from the circuit diagram because the per-unit impedance of a transformer remains the same when referred from one side to the other. This page is not a comprehensive guide on transformer per-unit calculations, a more in depth explanation can be found in [`this link`](https://en.wikipedia.org/wiki/Per-unit_system) or basic power system literature.\n\n## Establishing Base Values\n\nFor a multi-voltage system with transformers, you need to establish consistent base values across different voltage zones.\n\n  - Transformer Voltage Base ($V_{base, LL}$):\n\n      + The voltage base is determined by the transformer's nominal line-to-line voltage ratio:\n        $$V_{base, \\text{secondary}} = V_{base, \\text{primary}} \\times \\frac{V_{\\text{rated, secondary}}}{V_{\\text{rated, primary}}}$$\n        Where $V_{\\text{rated, secondary}}$ and $V_{\\text{rated, primary}}$ are the transformer's nominal (rated) line-to-line voltages on its secondary and primary sides, respectively.\n      + This value can be slightly different that the attached bus voltage value. In certain low voltage systems, transformers with a higher base voltage can be connected to buses with lower voltage set points. As of PowerSystems v5 transformers now have field for the base voltage.\n\n  - How is the data stored?: Transformer impedance (usually reactive impedance, $X_{pu}$) is typically given on its own nameplate ratings (rated MVA and rated voltages). **The data in PowerSystems.jl is stored in the device base** and transformer to the system base when using the correct getter functions.\n\n  - **Derived Base Impedance ($Z_{base}$):**\n\n      + Once $S_{base, 3\\phi}$ and $V_{base, LL}$ are established for each voltage zone, the base impedance can be calculated as follows:\n\n        $$Z_{base} = \\frac{(V_{base, LL})^2}{S_{base, 3\\phi}}$$\n        Where $V_{base, LL}$ is in kV and $S_{base, 3\\phi}$ is in MVA, resulting in $Z_{base}$ in Ohms ($\\Omega$).\n\n### Transformer Impedance Transformations\n\nThe most significant advantage of the per-unit system for transformers is that **the per-unit impedance of a transformer is the same on both sides**, provided the base voltages are chosen according to the transformer's turns ratio and the base power is consistent.\n\n  - Changing Base for Transformer Impedance: If the system-wide base $S_{base, 3\\phi}$ and the zone-specific voltage bases ($V_{base, \\text{primary zone}}$ and $V_{base, \\text{secondary zone}}$) differ from the transformer's ratings, you need to convert the transformer's per-unit impedance to the new system base.\n\n    The formula for changing base of an impedance is:\n\n    $$Z_{pu, \\text{new}} = Z_{pu, \\text{old}} \\times \\left(\\frac{S_{base, \\text{new}}}{S_{rated, \\text{old}}}\\right) \\times \\left(\\frac{V_{rated, \\text{old}}}{V_{base, \\text{new}}}\\right)^2$$\n\n      + Here, $S_{base, \\text{new}}$ is your chosen system-wide base MVA.\n      + $S_{rated, \\text{old}}$ is the transformer's rated MVA (from nameplate).\n      + $V_{rated, \\text{old}}$ is the transformer's rated voltage on the side you are considering (e.g., if you're transforming the impedance to the primary side's base, use the primary rated voltage).\n      + $V_{base, \\text{new}}$ is the *new* system base voltage for that side of the transformer.\n\n    When calculating the transformer's impedance on the system base, you only need to perform this calculation once. Since the per-unit impedance of a transformer is the same when referred from one side to the other (given correct base voltage selection), the $Z_{pu, \\text{new}}$ calculated for the transformer will be used regardless of which side you are viewing it from in the per-unit circuit diagram.\n\n!!! note\n\n    The return value of the getter functions, e.g., [`get_x`](@ref) for the transformer impedances will perform the transformations following the convention in [`Per-unit Conventions`](@ref per_unit).\n"
  },
  {
    "path": "docs/src/explanation/type_structure.md",
    "content": "# [Type Structure](@id type_structure)\n\nPowerSystems.jl provides a type hierarchy to contain power system data.\n\n## Types in PowerSystems\n\nIn PowerSystems.jl, data that describes infrastructure components is held in `struct`s.\nFor example, an `ACBus` is a `struct` with the following parameters to describe a bus\non an AC network:\n\n```@repl types\nusing PowerSystems #hide\nimport TypeTree: tt #hide\ndocs_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"utils\"); #hide\ninclude(joinpath(docs_dir, \"docs_utils.jl\")); #hide\nprint_struct(ACBus) #hide\n```\n\n## Type Hierarchy\n\nPowerSystems is intended to organize data by the behavior of the devices that\nthe data represents. A type hierarchy has been defined with several levels of\nabstract types starting with `InfrastructureSystemsType`. There are a bunch of subtypes of\n`InfrastructureSystemsType`, but the important ones to know about are:\n\n  - `System`: overarching `struct` that collects all of the `Component`s\n\n  - `Component`: includes all elements of power system data\n\n      + `Topology`: includes non physical elements describing network connectivity\n      + `Service`: includes descriptions of system requirements (other than energy balance)\n      + `Device`: includes descriptions of all the physical devices in a power system\n\n  - `InfrastructureSystems.DeviceParameter`: includes structs that hold data describing the\n    dynamic, or economic capabilities of `Device`.\n\n  - `TimeSeriesData`: Includes all time series types\n\n      + `Forecast`: includes structs to define time series of forecasted data where multiple\n        values can represent each time stamp\n      + `StaticTimeSeries`: includes structs to define time series with a single value for each\n        time stamp\n\nThe abstract hierarchy enables categorization of the devices by their operational\ncharacteristics and modeling requirements.\n\nFor instance, generation is classified by the distinctive\ndata requirements for modeling in three categories: [`ThermalGen`](@ref), [`RenewableGen`](@ref),\nand [`HydroGen`](@ref).\n\n`PowerSystems.jl` has a category [`Topology`](@ref) of topological components\n(e.g., [`ACBus`](@ref), [`Arc`](@ref)), separate from the physical components.\n\nThe hierarchy also includes components absent in standard data models, such as services.\nThe services category includes reserves, transfers and [`AGC`](@ref). The power of `PowerSystems.jl`\nlies in providing the abstraction without an implicit mathematical representation of the component.\n\nAs a result of this design, developers can define model logic entirely based on abstract\ntypes and create generic code to support modeling technologies that are not yet\nimplemented in the package.\n\n```@raw html\n<img src=\"../../assets/AbstractTree.png\" width=\"75%\"/>\n``` ⠀\n```\n"
  },
  {
    "path": "docs/src/generate_input_config_table.jl",
    "content": "@info \"Generating Input Configuration Descriptor Table\"\nfunction create_md()\n    descriptor = PowerSystems._read_config_file(\n        joinpath(\n            dirname(pathof(PowerSystems)),\n            \"descriptors\",\n            \"power_system_inputs.json\",\n        ),\n    )\n\n    columns = [\n        \"name\",\n        \"description\",\n        \"unit\",\n        \"unit_system\",\n        \"base_reference\",\n        \"default_value\",\n        \"value_options\",\n        \"value_range\",\n    ]\n    header = \"| \" * join(columns, \" | \") * \" |\\n\" * repeat(\"|----\", length(columns)) * \"|\\n\"\n\n    s = \"## [`PowerSystemTableData` Accepted CSV Columns](@id tabledata_input_config) \\n\\n\"\n    s = string(\n        s,\n        \"The following tables describe default CSV column definitions accepted by the \",\n    )\n    s = string(\n        s,\n        \"`PowerSystemeTableData` parser defined by `src/descriptors/power_system_inputs.json`:\\n\\n\",\n    )\n    for (cat, items) in descriptor\n        csv = \"\"\n        for name in PowerSystems.INPUT_CATEGORY_NAMES\n            if name[2] == cat\n                csv = name[1]\n                break\n            end\n        end\n\n        csv == \"\" && continue\n\n        s = string(s, \"### $csv.csv:\\n\\n\")\n        s = string(s, header)\n        for item in items\n            extra_cols = setdiff(keys(item), columns)\n            if !isempty(extra_cols)\n                # make sure that there arent unexpected entries\n                throw(@error \"config file fields not included in header\" extra_cols)\n            end\n            row = []\n            for col in columns\n                val = string(get(item, col, \" \"))\n                if col == \"default_value\" && val == \" \"\n                    val = \"*REQUIRED*\"\n                end\n                push!(row, val)\n            end\n            s = string(s, \"|\" * join(row, \"|\") * \"|\\n\")\n        end\n        s = string(s, \"\\n\")\n    end\n    s = replace(s, r\"[_$]\" => s\"\\\\\\g<0>\")\n    return s\nend\n\ntxt = create_md()\n\nopen(\n    \"/Users/cbarrows/Documents/repos/PowerSystems.jl/docs/src/modeler_guide/markdown.txt\",\n    \"w\",\n) do f\n    write(f, txt)\nend\n"
  },
  {
    "path": "docs/src/generate_validation_table.jl",
    "content": "@info \"Generating Validation Table\"\nfunction generate_validation_table(filepath::AbstractString)\n    descriptor = InfrastructureSystems.read_validation_descriptor(\n        joinpath(PSYPATH, \"descriptors\", \"power_system_structs.json\"),\n    )\n    open(filepath, \"w\") do io\n        write(io, \"# Data Requirements\\n\\n\")\n        write(\n            io,\n            \"|  Struct Name  |  Field Name  |  DataType  |  Min  |  Max  |  Action  |\\n\",\n        )\n        write(\n            io,\n            \"|---------------|--------------|------------|-------|-------|----------|\\n\",\n        )\n        for item in descriptor\n            for field in item[\"fields\"]\n                write(io, \"|$(item[\"struct_name\"])|$(field[\"name\"])|$(field[\"data_type\"])|\")\n                if haskey(field, \"valid_range\")\n                    if field[\"valid_range\"] isa Dict\n                        valid_min = field[\"valid_range\"][\"min\"]\n                        valid_max = field[\"valid_range\"][\"max\"]\n                        for value in (valid_min, valid_max)\n                            write(io, isnothing(value) ? \"null\" : string(value))\n                            write(io, \"|\")\n                        end\n                    else\n                        write(io, \"$(field[\"valid_range\"])|$(field[\"valid_range\"])|\")\n                    end\n                else\n                    write(io, \"-|-\")\n                end\n                if haskey(field, \"validation_action\")\n                    write(io, \"$(field[\"validation_action\"])|\\n\")\n                else\n                    write(io, \"|-\\n\")\n                end\n            end\n        end\n    end\nend\n\ngenerate_validation_table(joinpath(PSYPATH, \"../docs/src/man/data_requirements_table.md\"))\n"
  },
  {
    "path": "docs/src/how_to/add_component_natural_units.md",
    "content": "# Add a Component in Natural Units\n\n```@setup add_in_nu\nusing PowerSystems; #hide\nusing PowerSystemCaseBuilder #hide\nsystem = build_system(PSISystems, \"modified_RTS_GMLC_DA_sys\"); #hide\n```\n\n`PowerSystems.jl` has [three per-unitization options](@ref per_unit) for getting, setting\nand displaying data.\n\nCurrently, only one of these options -- `\"DEVICE_BASE\"` -- is supported when using a\nconstructor function define a component. You can see\n[an example of the default capabilities using `\"DEVICE_BASE\"` here](@ref \"Adding Loads and Generators\").\n\nWe hope to add capability to define components in\n`\"NATURAL_UNITS\"` with constructors in the future, but for now, below is a workaround\nfor users who prefer to define data using `\"NATURAL_UNITS\"` (e.g., MW, MVA, MVAR, or MW/min):\n\n### Step 1: Set Units Base\n\nSet your (previously-defined) `System`'s units base to `\"NATURAL_UNITS\"`:\n\n```@repl add_in_nu\nset_units_base_system!(system, \"NATURAL_UNITS\")\n```\n\nNow, the \"setter\" functions have been switched to define data using natural units (MW, MVA,\netc.), taking care of the necessary data conversions behind the scenes.\n\n### Step 2: Define Empty Component\n\nDefine an empty component with `0.0` or `nothing` for all the power-related fields except\n`base_power`, which is always in MVA.\n\nFor example:\n\n```@repl add_in_nu\ngas1 = ThermalStandard(;\n    name = \"gas1\",\n    available = true,\n    status = true,\n    bus = get_component(ACBus, system, \"Cobb\"), # Attach to a previously-defined bus named Cobb\n    active_power = 0.0,\n    reactive_power = 0.0,\n    rating = 0.0,\n    active_power_limits = (min = 0.0, max = 0.0),\n    reactive_power_limits = nothing,\n    ramp_limits = nothing,\n    operation_cost = ThermalGenerationCost(nothing),\n    base_power = 30.0, # MVA\n    time_limits = (up = 8.0, down = 8.0), # Hours, unaffected by per-unitization\n    must_run = false,\n    prime_mover_type = PrimeMovers.CC,\n    fuel = ThermalFuels.NATURAL_GAS,\n);\n```\n\n### Step 3: Attach the Component\n\nAttach the component to your `System`:\n\n```@repl add_in_nu\nadd_component!(system, gas1)\n```\n\n### Step 4: Add Data with \"setter\" Functions\n\nUse individual \"setter\" functions to set each the value of each numeric field in natural\nunits:\n\n```@repl add_in_nu\nset_rating!(gas1, 30.0) #MVA\nset_active_power_limits!(gas1, (min = 6.0, max = 30.0)) # MW\nset_reactive_power_limits!(gas1, (min = 6.0, max = 30.0)) # MVAR\nset_ramp_limits!(gas1, (up = 6.0, down = 6.0)) #MW/min\n```\n\nNotice the return values are divided by the `base_power` of 30 MW, showing the setters have\ndone the per-unit conversion into `\"DEVICE_BASE\"` behind the scenes.\n\n!!! tip\n\n    Steps 2-4 can be called within a `for` loop to define many components at once (or step 3\n    can be replaced with [`add_components!`](@ref) to add all components at once).\n\n#### See Also\n\n  - [Read more to understand per-unitization in PowerSystems.jl](@ref per_unit)\n  - Learn how to use the default constructors and explore the per-unitization settings in\n    [Create and Explore a Power `System`](@ref)\n"
  },
  {
    "path": "docs/src/how_to/add_cost_curve.md",
    "content": "# [Adding an Operating Cost](@id cost_how_to)\n\nThis how-to guide covers the steps to select and add an operating cost to a component,\nsuch as a generator, load, or energy storage system.\n\n```@setup costcurve\nusing PowerSystems #hide\n```\n\nTo begin, the user must make 2 or 3 decisions before defining the operating cost:\n\n 1. Select an appropriate [`OperationalCost`](@ref) from the [`OperationalCost`](@ref)\n    options. In general, each operating cost has parameters to define fixed and variable costs.\n    To be able to define an `OperationalCost`, you must first select a curve to represent the\n    variable cost(s).\n\n     1. If you selected [`ThermalGenerationCost`](@ref) or [`HydroGenerationCost`](@ref),\n        select either a [`FuelCurve`](@ref) or [`CostCurve`](@ref) to represent the variable\n        cost, based on the units of the generator's data.\n\n          * If you have data in terms of heat rate or water flow, use [`FuelCurve`](@ref).\n          * If you have data in units of currency, such as \\$/MWh, use [`CostCurve`](@ref).\n            If you selected another `OperationalCost` type, the variable cost is represented\n            as a `CostCurve`.\n\n 2. Select a [`ValueCurve`](@ref) to represent the variable cost data by comparing the format\n    of your variable cost data to the [Variable Cost Representations table](@ref curve_table)\n    and the [`ValueCurve`](@ref) options.\n\nThen, the user defines the cost by working backwards:\n\n 1. Define the variable cost's `ValueCurve`\n 2. Use the `ValueCurve` to define the selected `CostCurve` or `FuelCurve`\n 3. Use the `CostCurve` or `FuelCurve` to define the `OperationalCost`\n\nLet's look at a few examples.\n\n## Example 1: A Renewable Generator\n\nWe have a renewable unit that produces at \\$22/MWh.\n\nFollowing the decision steps above:\n\n 1. We select [`RenewableGenerationCost`](@ref) to represent this renewable generator.\n 2. We select a [`LinearCurve`](@ref) to represent the \\$22/MWh variable cost.\n\nFollowing the implementation steps, we define `RenewableGenerationCost` by nesting the\ndefinitions:\n\n```@repl costcurve\nRenewableGenerationCost(; variable = CostCurve(; value_curve = LinearCurve(22.0)))\n```\n\n## Example 2: A Thermal Generator with Input/Output Data\n\nWe have a thermal generating unit that has a heat input of 1400 GJ/h at 100 MW and 2200 GJ/MWh at\n200 MW, plus a fixed cost of \\$6.0/hr, a start-up cost of \\$2000, and a shut-down cost of\n\\$1000. Its fuel cost is \\$20/GJ.\n\nFollowing the decision steps above:\n\n 1. We select [`ThermalGenerationCost`](@ref) to represent this thermal generator.\n 2. We select [`FuelCurve`](@ref) because we have consumption in units of fuel (GJ/MWh)\n    instead of currency.\n 3. We select a [`PiecewisePointCurve`](@ref) to represent the piecewise linear heat rate\n    curve.\n\nThis time, we'll define each step individually, beginning with the heat rate curve:\n\n```@repl costcurve\nheat_rate_curve = PiecewisePointCurve([(100.0, 1400.0), (200.0, 2200.0)])\n```\n\nUse the heat rate to define the fuel curve, including the cost of fuel:\n\n```@repl costcurve\nfuel_curve = FuelCurve(; value_curve = heat_rate_curve, fuel_cost = 20.0)\n```\n\nFinally, define the full operating cost:\n\n```@repl costcurve\ncost = ThermalGenerationCost(;\n    variable = fuel_curve,\n    fixed = 6.0,\n    start_up = 2000.0,\n    shut_down = 1000.0,\n)\n```\n\nThis `OperationalCost` can be used when defining a component or added to an existing component using\n`set_operation_cost!`.\n\n## Example 3: A Thermal Generator with Marginal Heat Rate Data\n\nOften times, generator efficiency data is provided in the form of marginal heat rates (the additional\nheat input energy required per MWh of electrical output energy) as a function of generator output.\nFor example, the thermal unit above can be described by a heat input of 1400 GJ/h at 100 MW with a marginal\nheat rate of 8 GJ/MWh across the operating range (100 MW - 200 MW).\n\nIn this case, we can specify the heat rate curve with [`PiecewiseIncrementalCurve`](@ref) via the marginal\nheat rate directly:\n\n```@repl costcurve\nheat_rate_curve = PiecewiseIncrementalCurve(1400.0, [100.0, 200.0], [8.0])\n```\n\nThe [`FuelCurve`](@ref) and [`ThermalGenerationCost`](@ref) are specified in the same way despite the\ndiffering representation of the value curve:\n\n```@repl costcurve\nfuel_curve = FuelCurve(; value_curve = heat_rate_curve, fuel_cost = 20.0)\ncost = ThermalGenerationCost(;\n    variable = fuel_curve,\n    fixed = 6.0,\n    start_up = 2000.0,\n    shut_down = 1000.0,\n)\n```\n\nNote that the [`ThermalGenerationCost`](@ref) defined in Example 2 and 3 are functionally equivalent.\n"
  },
  {
    "path": "docs/src/how_to/add_fuel_curve_timeseries.md",
    "content": "# [Add Time Series Fuel Cost Data](@id fuel_curve_timeseries)\n\nThis how-to guide demonstrates how to add time-varying fuel costs to a thermal generator\nthat uses a [`ThermalGenerationCost`](@ref) with a [`FuelCurve`](@ref). This is useful when\nfuel prices vary over time, such as with natural gas prices that change throughout the day\nor across seasons.\n\n```@setup fuelcosts\nusing PowerSystems\nusing Dates\nusing TimeSeries\nusing DataStructures: SortedDict\n\n# Create a bus\nbus = ACBus(;\n    number = 1,\n    name = \"bus1\",\n    available = true,\n    bustype = ACBusTypes.REF,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.1),\n    base_voltage = 230.0,\n)\n\n# Define the heat rate curve\nheat_rate_curve = PiecewisePointCurve([\n    (100.0, 7.0),   # At 100 MW: 7 GJ/MWh\n    (200.0, 8.0),   # At 200 MW: 8 GJ/MWh\n    (300.0, 9.5),   # At 300 MW: 9.5 GJ/MWh\n])\n\n# Create a FuelCurve with an initial scalar fuel cost\nfuel_curve = FuelCurve(;\n    value_curve = heat_rate_curve,\n    fuel_cost = 5.0,  # Initial fuel cost: $5.0/GJ\n)\n\n# Create the ThermalGenerationCost\nthermal_cost = ThermalGenerationCost(;\n    variable = fuel_curve,\n    fixed = 10.0,\n    start_up = 5000.0,\n    shut_down = 2000.0,\n)\n\n# Create the thermal generator\ngenerator = ThermalStandard(;\n    name = \"generator1\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 250.0,\n    reactive_power = 50.0,\n    rating = 300.0,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.NATURAL_GAS,\n    active_power_limits = (min = 50.0, max = 300.0),\n    reactive_power_limits = (min = -50.0, max = 100.0),\n    ramp_limits = (up = 5.0, down = 5.0),\n    time_limits = (up = 2.0, down = 1.0),\n    operation_cost = thermal_cost,\n    base_power = 100.0,\n)\n\n# Create the system and add components\nsys = System(100.0)\nadd_component!(sys, bus)\nadd_component!(sys, generator)\n```\n\n## Overview\n\nThis guide assumes you have already defined a [`System`](@ref) with a thermal generator (e.g., [`ThermalStandard`](@ref)) that has a\n[`ThermalGenerationCost`](@ref) containing a [`FuelCurve`](@ref). The generator's\n`FuelCurve` must specify a heat rate curve (fuel consumption at different power outputs)\nand an initial scalar fuel cost value, which will be replaced with time series data.\n\nTo add time-varying fuel costs, you need to:\n\n 1. **Create time series fuel cost data**: Prepare your fuel price data as either\n    [`SingleTimeSeries`](@ref) (for simple time-varying data like historical prices) or\n    [`Deterministic`](@ref) (for forecast windows used in day-ahead scheduling with rolling\n    horizons).\n\n 2. **Attach the time series to the generator**: Use the [`set_fuel_cost!`](@ref) function\n    to attach the time series data to the generator component. The component must already\n    be added to the system before attaching time series.\n\n 3. **Verify and retrieve the data**: Use [`get_fuel_cost`](@ref) to retrieve the time\n    series data and verify it was attached correctly.\n\n**Key requirements:**\n\n  - The generator must use a [`FuelCurve`](@ref) (not a [`CostCurve`](@ref)) in its\n    [`ThermalGenerationCost`](@ref) to enable time series fuel costs\n  - Time series resolution should match your simulation resolution (e.g., Hour(1) for\n    hourly simulations)\n  - Fuel cost units should be in \\$/GJ (or \\$/MBtu, etc.) and heat rate in GJ/MWh (or\n    MBtu/MWh); their product gives the effective cost in \\$/MWh\n\n## Step 1: Create Time Series Fuel Cost Data\n\nCreate time series data representing fuel costs that vary throughout the day. This example\nuses hourly natural gas prices with [`SingleTimeSeries`](@ref):\n\n```@repl fuelcosts\n# Define the initial time and resolution\ninitial_time = DateTime(\"2024-01-01T00:00:00\")\nresolution = Hour(1)\n\n# Create hourly fuel cost data for 24 hours\n# Prices are higher during peak hours (midday to early evening) and lower at night\nfuel_cost_data = [\n    4.5, 4.3, 4.2, 4.1, 4.2, 4.5,  # 00:00 - 05:00 (low overnight prices)\n    5.0, 5.5, 6.0, 6.5, 7.0, 7.5,  # 06:00 - 11:00 (morning ramp)\n    8.0, 8.0, 7.8, 7.8, 7.5, 7.0,  # 12:00 - 17:00 (afternoon peak)\n    6.5, 6.0, 5.5, 5.0, 4.8, 4.6,  # 18:00 - 23:00 (evening decline)\n]\n\n# Create timestamps for each data point\ntimestamps =\n    collect(initial_time:resolution:(initial_time + Hour(length(fuel_cost_data) - 1)))\n\n# Create a TimeArray with timestamps and data\ntime_array = TimeArray(timestamps, fuel_cost_data)\n\n# Create a SingleTimeSeries from the TimeArray\nfuel_cost_timeseries = SingleTimeSeries(;\n    name = \"fuel_cost\",\n    data = time_array,\n)\n```\n\n## Step 2: Attach Time Series to the Generator\n\nUse the [`set_fuel_cost!`](@ref) function to attach the time series data to your\npreviously defined [`System`](@ref) and generator (e.g., [`ThermalStandard`](@ref)):\n\n```@repl fuelcosts\n# Add the time series fuel cost to the generator\nset_fuel_cost!(sys, generator, fuel_cost_timeseries)\n```\n\n## Step 3: Verify and Retrieve Time Series Data\n\nNow the generator has time-varying fuel costs. You can retrieve the time series data:\n\n```@repl fuelcosts\n# Get the fuel cost time series starting at the initial time\nfuel_forecast = get_fuel_cost(generator; start_time = initial_time)\n\n# Display the first few values\nfirst(TimeSeries.values(fuel_forecast), 6)\n```\n\nYou can also query for a specific time window:\n\n```@repl fuelcosts\n# Get fuel costs for a specific 12-hour period starting at 6 AM\nmorning_time = DateTime(\"2024-01-01T06:00:00\")\nfuel_forecast_morning = get_fuel_cost(generator; start_time = morning_time, len = 12)\n\n# Display these values\nTimeSeries.values(fuel_forecast_morning)\n```\n\n## See Also\n\n  - [Add an Operating Cost](@ref cost_how_to) - General guide for adding operational costs\n  - [Parse Time Series Data from .csv files](@ref parsing_time_series) - How to load time series from CSV files\n  - [Working with Time Series Data](@ref tutorial_time_series) - Tutorial on time series data in PowerSystems\n  - [`ThermalGenerationCost`](@ref) - API reference for thermal generation costs\n  - [`FuelCurve`](@ref) - API reference for fuel curves\n"
  },
  {
    "path": "docs/src/how_to/add_new_types.md",
    "content": "# Add a New or Custom Type\n\nThis page describes how developers should add types to `PowerSystems.jl`\n\n## Type Hierarchy\n\nAll structs that correlate to power system components must be subtypes of the\n[`Component`](@ref) abstract type. Browse its type hierachy to choose an appropriate\nsupertype for your new struct.\n\n## Interfaces\n\nRefer to the\n[managing components guide](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/dev_guide/components_and_container/)\nfor component requirements.\n\nIn particular, please note the methods `supports_time_series` (default = false) and\n`supports_supplemental_attributes` (default = true) that you may need to implement.\n\n**Note**: `get_internal` and `get_name` are imported into `PowerSystems`, so you should\nimplement your methods as `PowerSystems` methods.\n\nSome abstract types define required interface functions in docstring. Be sure\nto implement each of them for your new type.\n\nFormalized documentation for each abstract type is TBD.\n\n## Specialize an Existing Type\n\nThere are scenarios where you may want to make a new type that is identical to\nan existing type except for one attribute or behavior, and don't want to\nduplicate the entire existing type and methods. In programming languages that\nsupport inheritance you would derive a new class from the existing class and\nautomatically inherit its fields and methods. Julia doesn't support that.\nHowever, you can achieve a similar result with a forwarding macro.\nThe basic idea is that you include the existing type within your struct and\nthen use a macro to automatically forward specific methods to that instance.\n\nA few PowerSystems structs use the macro `InfrastructureSystems.@forward` to\ndo this. Refer to the struct [`RoundRotorQuadratic`](@ref) for an example of how to\nuse this.\n\n## Custom Rules\n\nSome types require special checks before they can be added to or removed from a\nsystem. One example is the case where a component includes another component\nthat is also stored in the system. We must ensure that the parent component\ndoes not contain a reference to another component that is not already attached\nto the system.\n\nSimilarly, if the child object is removed from the system we must also remove\nthe parent's reference to that child.\n\nThe source file `src/base.jl` provides functions that you can implement for\nyour new type to manage these scenarios.\n\n  - `check_component_addition(sys::System, component::Component; kwargs...)`\n  - `handle_component_addition!(sys::System, component::Component; kwargs...)`\n  - `check_component_removal(sys::System, component::Component; kwargs...)`\n  - `handle_component_removal!(sys::System, component::Component; kwargs...)`\n\nThe functions `add_component!()` and `remove_component!()` call the check\nfunction before performing actions and then call the handle function\nafterwards. The default behavior of these functions is to do nothing. Implement\nversions that take your type in order to add your own checks or perform\nadditional actions.\n\nBeware of the condition where a custom method is already implemented for a\nsupertype of your type.\n\nNote that you can call the helper functions `is_attached(component, system)`\nand `throw_if_not_attached(component, system)`.\n\n### Custom Validation\n\nYou can implement three methods to perform custom validation or correction for your type.\nPowerSystems calls all of these functions in `add_component!`.\n\n  - `sanitize_component!(component::Component, sys::System)`: intended to make standard data corrections (e.g. voltage angle in degrees -> radians)\n  - `validate_component(component::Component)`: intended to check component field values for internal consistency\n  - `validate_component_with_system(component::Component, sys::System)`: intended to check component field values for consistency with system\n\n### Struct Requirements for Serialization of custom components\n\nOne key feature of `PowerSystems.jl` is the serialization capabilities. Supporting\nserialization and de-serialization of custom components requires the implementation of\nseveral methods. The serialization code converts structs to dictionaries where the struct\nfields become dictionary keys.\n\nThe code imposes these requirements:\n\n 1. The InfrastructureSystems methods `serialize` and `deserialize` must be\n    implemented for the struct. InfrastructureSystems implements a method that\n    covers all subtypes of `InfrastructureSystemsType`. All PowerSystems\n    components should be subtypes of `PowerSystems.Component` which is a subtype\n    `InfrastructureSystemsType`, so any new structs should be covered as well.\n 2. All struct fields must be able to be encoded in JSON format or be covered be\n    covered by `serialize` and `deserialize` methods. Basic types, such as\n    numbers and strings or arrays and dictionaries of numbers and strings,\n    should just work. Complex containers with symbols may not.\n 3. Structs relying on the default `deserialize` method must have a kwarg-only\n    constructor. The deserialization code constructs objects by splatting the\n    dictionary key/value pairs into the constructor.\n 4. Structs that contain other PowerSystem components (like a generator contains\n    a bus) must serialize those components as UUIDs instead of actual values.\n    The deserialization code uses the UUIDs as a mechanism to restore a\n    reference to the actual object rather a new object with identical values. It\n    also significantly reduces the size of the JSON file.\n\nRefer to `InfrastructureSystems.serialize_struct` for example behavior. New\nstructs that are not subtypes of `InfrastructureSystemsType` may be able to\ncall it directly.\n\n#### How to trouble-shoot serialization issues\n\nHere are some examples of potential problems and solutions if you need to implement custom\n`InfrastructureSystems.serialize` and `InfrastructureSystems.deserialize` methods\nfor your type.:\n\n**Problem**: Your struct contains a field defined as an abstract type. The\ndeserialization process doesn't know what concrete type to construct.\n\n*Solution*: Encode the concrete type into the serialized dictionary as a string.\n\n*Example*:  `serialize` and `deserialize` methods for `DynamicBranch` in\n`src/models/dynamic_branch.jl`.\n\n**Problem**: Similar to above in that a field is defined as an abstract type\nbut the struct is parameterized on the actual concrete type.\n\n*Solution*: Use the fact that the concrete type is encoded into the serialized\ntype of the struct and extract it in a customized `deserialze` method.\n\n*Example*: `deserialize` method for `OuterControl` in\n`src/models/OuterControl.jl`.\n\n### Adding `PowerSystems.jl` as a dependency in a modeling package\n\n```julia\nmodule MyModelingModule\n\nimport PowerSystems as PSY\nimport InfrastructureSystems as IS\n\nexport MyDevice\nexport get_name\n\nmutable struct MyDevice <: PSY.Device\n    name::String\n    internal::IS.InfrastructureSystemsInternal\nend\n\nfunction MyDevice(name::String)\n    return MyDevice(name, IS.InfrastructureSystemsInternal())\nend\n\nPSY.get_name(val::MyDevice) = val.name\n\nend\n```\n\n## [Auto-generating Structs](@id autogen)\n\nMost `PowerSystems.jl` structs are auto-generated from the JSON descriptor file\n`src/descriptors/power_system_structs.json`.\nYou can add your new struct\nhere or write it manually when contributing code to the repository.\n\nIf all you need is the basic struct definition and getter/setter functions then\nyou will likely find the auto-generation helpful.\n\nIf you will need to write specialized functions for the type then you will\nprobably want to write it manually.\n\nPlease refer to the docstrings for the functions `generate_struct`\nand `generate_structs`. Full details are in the InfrastructureSystems documentation at\n[https://sienna-platform.github.io/InfrastructureSystems.jl/stable/dev_guide/auto_generation/](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/dev_guide/auto_generation/).\n\n### Testing the addition of new struct to the code base\n\nIn order to merge new structs to the code base, your struct needs to pass several tests.\n\n 1. addition to `System`\n 2. retrieval from `System`\n 3. serialization/de-serialization\n\nThe following code block is an example of the code that the new struct needs to pass\n\n```julia\nusing PowerSystems\n\nsys = System(100.0)\ndevice = NewType(data)\n\n# add your component to the system\nadd_component!(sys, device)\nretrived_device = get_component(NewType, sys, \"component_name\")\n\n# Serialize\nto_json(sys, \"sys.json\")\n\n# Re-create the system and find your component.\nsys2 = System(\"sys.json\")\nserialized_device = get_component(NewType, sys, \"component_name\")\n\n@test get_name(retrieved_device) == get_name(serialized_device)\n```\n"
  },
  {
    "path": "docs/src/how_to/adding_additional_fields.md",
    "content": "# [Add additional data to a component](@id additional_fields)\n\nAll `PowerSystems.jl` components have an `ext` field that contains an empty `Dictionary`.\nThis Dictionary is useful to contain additional required data where there is no need to\ncreate new behaviors with that data. A simple example is the addition of geographic\ninformation, if needed.\n\n#### Example\n\n```@setup generated_adding_additional_fields\nusing PowerSystems #hide\nusing PowerSystemCaseBuilder #hide\nsystem = build_system(PSISystems, \"modified_RTS_GMLC_DA_sys\"); #hide\n```\n\n__Step 1:__ Use `get_ext` to get the `ext` field of the desired components and assign your data:\n\n```@repl generated_adding_additional_fields\nfor g in get_components(ThermalStandard, system)\n    external_field = get_ext(g)\n    external_field[\"my_data\"] = 1.0\nend\n```\n\nHere, we added additional data called `my_data` to the [`ThermalStandard`](@ref)\ngenerators in a previously defined [`System`](@ref).\n\n__Step 2:__ Retrieve your data using `get_ext` again\n\nFirst, retrieve the first ThermalStandard generator:\n\n```@repl generated_adding_additional_fields\ngen = collect(get_components(ThermalStandard, system))[1];\n```\n\nThen, retrieve `my_data` from the generator and verify it is 1.0, as assigned.\n\n```@repl generated_adding_additional_fields\nretrieved_data = get_ext(gen)[\"my_data\"]\n```\n"
  },
  {
    "path": "docs/src/how_to/build_system_with_files.md",
    "content": "# [Building a System from CSV Files](@id system_from_csv)\n\nIf you have input data on the component specifications and time series data formatted in\nCSV files, rather than a Matpower or PSS/e file that can be\n[parsed automatically](@ref pm_data), the basic formula to build a [`System`](@ref)\nmanually is:\n\n 1. Format all .csv data into row-column format, where there is a row for each component and a\n    column for each input parameter. Load each .csv into a `DataFrame`.\n 2. Define a [`System`](@ref).\n 3. Starting with the buses, write a `for` loop for each component `Type` to loop over the\n    `DataFrame`, using a constructor from `PowerSystems.jl`'s Model Library to define a\n    component for each row. Hard-code any required parameters that are missing in\n    your dataset. Use [`add_component!`](@ref) to add each component to the [`System`](@ref).\n 4. Similarly, add cost and time series data either within each `for` loop, or after the\n    components have been defined using [`begin_time_series_update`](@ref).\n 5. [Save your `System` to a JSON](@ref \"Write, View, and Load Data with a JSON\") once you are\n    finished\n\nThe following example demonstrates this process for selected component\ntypes (e.g., [`ACBus`](@ref), [`ThermalStandard`](@ref), [`RenewableDispatch`](@ref)), but\nthe same principles apply to build any of the components in `PowerSystems.jl`'s Model\nLibrary.\n\nFeel free to reuse the code below, ensuring that you customize the exact file names,\ndata columns, column names, and hard-coded parameters in the `for` loops based on the data\nyou have available.\n\n## Prerequisites\n\nIn this example, it is assumed that the CSV files are stored in a directory\ncalled `MyData`. In each section below, ensure your data follows the row-column format\nbefore beginning, and that your data are in the given units.\n\nThese are the depedencies needed for this how-to:\n\n```julia\nusing PowerSystems\nusing CSV\nusing DataFrames\nusing Dates\nusing TimeSeries\n```\n\n## Build the base [`System`](@ref)\n\n```julia\nsystem_base_power = 100.0\nsys = System(system_base_power)\n```\n\nBegin by building the base [`System`](@ref) using the base power in MVA.\n\n## Add Buses and Network Topology\n\nIn this example, we assume that the component data for the buses are contained in a CSV\nfile, `Buses.csv`. Each row is an individual bus, and there is a column for each input parameter:\n\n| Bus Number | BusType | Magnitude (p.u.) | Voltage-Max (p.u.) | Voltage-Min (p.u.) | Base Voltage (kV) | Region |\n|:---------- |:------- |:---------------- |:------------------ |:------------------ |:----------------- |:------ |\n| 1          | ref     | 1                | 1.06               | 0.94               | 138               | R1     |\n| 2          | ref     | 1                | 1.06               | 0.94               | 345               | R2     |\n| ...        | ...     | ...              | ...                | ...                | ...               | ...    |\n\nRead in the contents of the CSV file `Buses.csv` to a data frame and customize\nthe parameter names based on the column names in your CSV file.\n\n```julia\nbus_params = CSV.read(\"MyData/Buses.csv\", DataFrame)\n\nmin_volt = \"Voltage-Min (p.u.)\"\nmax_volt = \"Voltage-Max (p.u.)\"\nbase_volt = \"Base Voltage (kV)\"\nbus_number = \"Bus Number\"\nregion = \"Region\"\n```\n\nIn this example, we assume that the buses are sorted into `Areas`, where\n[`Area`](@ref) is an optional parameter in the [`ACBus`](@ref) constructor.\nBecause we will be sorting our buses into these areas as we construct the\nbuses, we must first attach the areas to our [`System`](@ref).\n\n```julia\nregions = unique(bus_params[:, region])\n\nfor reg in regions\n    area = Area(reg)\n    add_component!(sys, area)\nend\n```\n\nYou could similarly add [`LoadZone`](@ref)s at this point, if they are relevant\nfor your system.\n\nNow, we are ready to build the buses in the `for` loop, using the\n[`ACBus`](@ref) constructor, using the input data available in our `Buses.csv`,\nand hard coding any missing data.\n\n```julia\nfor row in eachrow(bus_params)\n    bus = ACBus(;\n        number = row[bus_number],\n        name = \"bus$(row[bus_number])\",\n        available = true,\n        bustype = ACBusTypes.PQ,\n        angle = 0.0,\n        magnitude = 1.0,\n        voltage_limits = (min = row[min_volt], max = row[max_volt]),\n        base_voltage = row[base_volt],\n        area = get_component(Area, sys, row[region]),\n    )\n    add_component!(sys, bus)\nend\n```\n\n## Add Branches\n\nThe next step is to build the [`Branch`](@ref) components in the system. In this\nexample, we only have two branch types: a [`Line`](@ref), if the connecting buses\nhave the same base voltage; and a [`Transformer2W`](@ref) if they\nhave different base voltages. You may need to implement additional logic if you\nhave other branch types as well.\n\nWe assume the data for each [`Branch`](@ref) is contained in a `Branches.csv`.\nThe conventions used in `Bus from` and `Bus to` must be consistent with the\nconventions used in the `Bus Number` column of `Buses.csv`.\n\n| Branch Number | Bus from | Bus to | Reactance (p.u.) | Resistance (p.u.) | Max Flow (MW) | Min Flow (MW) |\n|:------------- |:-------- |:------ |:---------------- |:----------------- |:------------- |:------------- |\n| 1             | 1        | 2      | 0.0999           | 0.0303            | 600           | -600          |\n| 2             | 4        | 5      | 0.00798          | 0.00176           | 1700          | -1700         |\n| ...           | ...      | ...    | ...              | ...               | ...           | ...           |\n\nRead in the contents of the CSV file `Branches.csv` to a data frame and customize\nthe parameter names based on the column names in your CSV file.\n\n```julia\nbranch_params = CSV.read(\"MyData/Branches.csv\", DataFrame)\n\nbranch_num = \"Branch Number\"\nbus_from_col = \"Bus from\"\nbus_to_col = \"Bus to\"\nreactance = \"Reactance (p.u.)\"\nresistance = \"Resistance (p.u.)\"\nmax_flow = \"Max Flow (MW)\"\n```\n\nBuild the lines and transformers using the [`Line`](@ref) and\n[`Transformer2W`](@ref) constructors.\n\n```julia\nfor row in eachrow(branch_params)\n    bus_from = get_bus(sys, row[bus_from_col])\n    bus_to = get_bus(sys, row[bus_to_col])\n    if get_base_voltage(bus_to) == get_base_voltage(bus_from)\n        branch = Line(;\n            name = \"line$(row[branch_num])\",\n            available = true,\n            active_power_flow = 0.0,\n            reactive_power_flow = 0.0,\n            arc = Arc(; from = bus_from, to = bus_to),\n            r = row[resistance],\n            x = row[reactance],\n            b = (from = 0.0, to = 0.0),\n            rating = row[max_flow] / system_base_power,\n            angle_limits = (min = 0.0, max = 0.0),\n        )\n    else\n        branch = Transformer2W(;\n            name = \"tline$(row[branch_num])\",\n            available = true,\n            active_power_flow = 0.0,\n            reactive_power_flow = 0.0,\n            arc = Arc(; from = bus_from, to = bus_to),\n            r = row[resistance],\n            x = row[reactance],\n            primary_shunt = 0.0,\n            rating = row[max_flow] / system_base_power,\n        )\n    end\n    add_component!(sys, branch)\nend\n```\n\n!!! warning\n\n    When defining a branch that isn't attached to a `System` yet, you must define the\n    thermal rating of the transmission line [per-unitized in \"SYSTEM_BASE\"](@ref per_unit)\n    using the base power of the `System` you plan to connect it to -- defined above as\n    `system_base_power`.\n\n## Adding Thermal Generators and their Costs\n\n### Build Thermal Generators\n\nWe assume the data needed to build each [`ThermalStandard`](@ref) unit is found\nin a CSV file `Thermal_Gens.csv`. The following table is a snapshot of the\nfirst 7 columns of an example `Thermal_Gens.csv`:\n\n| Gen Name   | Bus | Rating (MVA) | Min Stable Level (MW) | Max Capacity (MW) | PrimeMoveType | Fuel Type    | ... |\n|:---------- |:--- |:------------ |:--------------------- |:----------------- |:------------- |:------------ |:--- |\n| Biomass 01 | 12  | 3            | 0.9                   | 3.0               | OT            | AG_BIPRODUCT | ... |\n| Biomass 02 | 103 | 1.2          | 0.36                  | 1.2               | OT            | AG_BIPRODUCT | ... |\n| ...        | ... | ...          | ...                   | ...               | ...           | ...          | ... |\n\nThe naming convention used for the contents of the `Bus` column must be consistent\nwith the convention used in the `Bus Number` column of `Buses.csv`.\n\nRead in the contents of the CSV file `Thermal_Gens.csv` to a data frame and\ncustomize the parameter names based on the column names in your CSV file.  Note\nthat the [`PrimeMovers`](@ref pm_list) in the `thermal_gens` data frame are\nconsistent with EIA Form 923, and the `Fuel Type` column data are consistent\nwith the [`ThermalFuels`](@ref tf_list) naming convention.\n\n```julia\nthermal_gens = CSV.read(\"MyData/Thermal_Gens.csv\", DataFrame)\n\nname = \"Gen Name\"\nbus_connection = \"Bus\"\nrate = \"Rating (MVA)\"\nmin_active_power = \"Min Stable Level (MW)\"\nmax_active_power = \"Max Capacity (MW)\"\nramp_up = \"Max Ramp Up (MW/min)\"\nramp_down = \"Max Ramp Down (MW/min)\"\nmin_up = \"Min Up Time (h)\"\nmin_down = \"Min Down Time (h)\"\nprime_move = \"PrimeMoveType\"\nfuel = \"Fuel Type\"\n```\n\nBuild the thermal generator components using the [`ThermalStandard`](@ref)\nconstructor and data stored in the `thermal_gens` data frame.\n\n!!! warning\n\n    When you define components that aren't attached to a `System` yet, the constructors\n    assume define all fields related to power are\n    [per-unitized in \"DEVICE_BASE\"](@ref per_unit). Divide all fields with units such as MW,\n    MVA, MVAR, or MW/min using the `base_power` of the component (with the exception of\n    `base_power` itself, which is in MVA).\n\nSince the example data is missing base power, we set base power equal to the rating data, and the\nrating parameter to 1.0:\n\n```julia\nfor row in eachrow(thermal_gens)\n    base = row[rate]\n    thermal = ThermalStandard(;\n        name = row[name],\n        available = true,\n        status = true,\n        bus = get_bus(sys, row[bus_connection]),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        rating = 1.0,\n        active_power_limits = (\n            min = row[min_active_power] / base,\n            max = row[max_active_power] / base,\n        ),\n        reactive_power_limits = (min = 0.0, max = 0.0),\n        ramp_limits = (up = row[ramp_up] / base, down = row[ramp_down] / base),\n        operation_cost = ThermalGenerationCost(nothing),\n        base_power = base,\n        time_limits = (up = row[min_up], down = row[min_down]),\n        prime_mover_type = row[prime_move],\n        fuel = row[fuel],\n    )\n    add_component!(sys, thermal)\nend\n```\n\n### Add [`ThermalGenerationCost`](@ref)\n\nIn this example the [`ThermalGenerationCost`](@ref) constructor is defined by a\n[`FuelCurve`](@ref). We are also assuming that the data needed to build each\n[`FuelCurve`](@ref) can be found in two separate CSV files. The first,\n`Thermal_Gens.csv`, has already been defined in the previous step. The second,\n`Thermal_Fuel_Rates.csv`, contains information regarding each [`FuelType`](@ref\ntf_list) and its cost:\n\n| Fuel Type    | Fuel Price | CO2 rate | NOX rate | SO2 rate |\n|:------------ |:---------- |:-------- |:-------- |:-------- |\n| COAL         | 1.8        | 203.5    | 0.382    | 0.33     |\n| NATURAL_GAS  | 5.4        | 118      | 0.079    | 0.001    |\n| OIL          | 21         | 123.1    | 0.176    | 0.006    |\n| AG_BIPRODUCT | 2.4        | 130      | 0.177    | 0.006    |\n| GEOTHERMAL   | 0          | 0        | 0.177    | 0.006    |\n\nRead in `Thermal_Fuel_Rates.csv`, customize parameter names based on\nthe column names in your CSV file, and create a dictionary pairing fuel types\nand fuel prices. Ensure that the strings populating the `Fuel Type` column\nmatch the strings populating the `Fuel Type` column of the `thermal_gens`\ndata frame.\n\n```julia\nfuel_params = CSV.read(\"MyData/Thermal_Fuels_Rates.csv\", DataFrame)\n\ntype = \"Fuel Type\"\nprice = \"Fuel Price\"\n\nfuel_cost_dict = Dict{ThermalFuels, Float64}()\nfor row in eachrow(fuel_params)\n    fuel_cost_dict[row[type]] = row[price]\nend\n```\n\nNext, we will create column name variables for heat rate bases, heat rates,\nload points, fixed, start up, and shut down costs from the thermal_gens\ndata frame.  Use this data to build the [`PiecewiseIncrementalCurve`](@ref) and\nthe [`FuelCurve`](@ref) functions, and add them to their associated thermal\ngenerator.\n\n```julia\ngen_name = \"Generator Name\"\nheat_rate_base = \"Heat Rate Base (MMBTU/hr)\"\nheat_rate = \"Heat Rate (MMBTU/hr)\"\nload_point = \"Load Point Band (MW)\"\nfixed_cost = \"Fixed Cost (dollar)\"\nstart_up_cost = \"Start Up Cost (dollar)\"\nshut_down_cost = \"Shut Down Cost (dollar)\"\n\nfor row in eachrow(thermal_gens)\n    thermal = get_component(ThermalStandard, sys, row[gen_name])\n    heat_rate_curve =\n        PieceWiseIncrementalCurve(row[heat_rate_base], row[load_point], row[heat_rate])\n    fuel_curve =\n        FuelCurve(;\n            value_curve = heat_rate_curve,\n            fuel_cost = fuel_cost_dict[row[fuel]],\n        )\n    cost_thermal = ThermalGenerationCost(;\n        variable = fuel_curve,\n        fixed = row[fixed_cost],\n        start_up = row[start_up_cost],\n        shut_down = row[shut_down_cost],\n    )\n    set_operation_cost!(thermal, cost_thermal)\nend\n```\n\nFor more information regarding thermal cost functions please visit\n[`ThermalGenerationCost`](@ref).\n\n## Adding Renewable Generators and Their Time Series\n\nThe following section demonstrates how to add solar generators and their time\nseries to a [`System`](@ref). However, if you desire to add other\n[`RenewableDispatch`](@ref) generator types, such as wind, the process is exactly the\nsame, with changing the [prime mover type](@ref pm_list) from `PrimeMovers.PVe` to\n`PrimeMovers.WT`.\n\nWe assume the data needed to build each solar powered\n[`RenewableDispatch`](@ref) unit is found in the CSV file `Solar_Gens.csv`,\nsnapshotted below.  The convention used for the contents of the `Bus` column\nmust be consistent with the convention used in the `Bus Number` column of\n`Buses.csv`:\n\n| Gen Name | Number | Bus | Rating (MVA) |\n|:-------- |:------ |:--- |:------------ |\n| Solar 01 | 1      | 32  | 746.76       |\n| Solar 02 | 2      | 92  | 369.26       |\n| ...      | ...    | ... | ...          |\n\nRead in the contents of the CSV file `Solar_Gens.csv` to a data frame, and\ncustomize the parameter names based on the column names in your CSV file and\nthe desired prime mover type.\n\n```julia\nsolar_gens = CSV.read(\"MyData/Solar_Gens.csv\", DataFrame)\n\nname = \"Gen Name\"\nnum = \"Number\"\nbus_connection = \"Bus\"\nrate = \"Rating (MVA)\"\nprime_mover = PrimeMovers.PVe\n```\n\nBefore building the solar generators, we must also set up the solar generators'\ntime series. In this example, we assume that each solar generator has a unique\ntime series, and all of these time series are contained in one file:\n`MyData/Solar_Time_Series.csv`. Here is a snapshot of this time series CSV\nfile, where the first column contains time stamps, and the remaining columns\nare titled with its respective generator's name, and contain the time series\nvalues in MW for each solar generator:\n\n| Time Stamp   | Solar 01 | Solar 02 | Solar 03 | ... |\n|:------------ |:-------- |:-------- |:-------- |:--- |\n| ...          | ...      | ...      | ...      | ... |\n| 1/1/23 09:00 | 51.36    | 118.11   | 54.92    | ... |\n| 1/1/23 10:00 | 138.61   | 200.32   | 6.85     | ... |\n| ...          | ...      | ...      | ...      | ... |\n\nEach time series for its respective solar generator has an hourly resolution,\nand is for the year 2023, plus one full day into 2024, for a total of 366 days,\nand 8784 values per column.\n\nCreate a data frame from `Solar_Time_Series.csv` and define variables for the\naforementioned resolution and time stamps:\n\n```julia\nsolar_time_series = CSV.read(\"MyData/Solar_Time_Series.csv\", DataFrame)\n\nresolution = Dates.Hour(1);\ntimestamps = range(DateTime(\"2023-01-01T00:00:00\"); step = resolution, length = 8784);\n```\n\nIn this example, we assume that the [`RenewableGenerationCost`](@ref) is at\nzero marginal cost. If the marginal cost is not zero, follow similar steps to\nbuilding the [`ThermalGenerationCost`](@ref) constructor from above, but for\nthe [`RenewableGenerationCost`](@ref) constructor instead.\n\nMoreover, since the example data is missing base power, we use the range of\nvalues in the time series data to determine the value of the base power which\nwill be used to normalize the time series, and set the generator's rating\nparameter to 1.0. (If your data reports a base power, use that for the\ngenerator's base power, and rating data for the generator's rating).\n\nIn the same `for` loop, we will build the solar generator components using the\n[`RenewableDispatch`](@ref) constructor and data stored in the `solar_gens`\ndata frame, and build and attach each solar generator's time series:\n\n```julia\nfor row in eachrow(solar_gens)\n    norm = maximum(solar_time_series[:, row[name]])\n    solar_data_MW = solar_time_series[:, row[name]]\n    base = row[rate]\n    if any((solar_data_MW ./ base) .> 1.0)\n        @warn \"Generator $(row[name]) has a production larger than its base power. Normalizing by its maximum\"\n        base = norm\n    end\n    solar_array = TimeArray(timestamps, (solar_data_MW ./ base)) # normalize data\n    solar_TS = SingleTimeSeries(;\n        name = \"max_active_power\",\n        data = solar_array,\n        scaling_factor_multiplier = get_max_active_power,\n    )\n    solar = RenewableDispatch(;\n        name = row[name],\n        available = true,\n        bus = get_bus(sys, row[bus_connection]),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        rating = 1.0,\n        prime_mover_type = prime_mover,\n        reactive_power_limits = (min = 0.0, max = 0.0),\n        power_factor = 1.0,\n        operation_cost = RenewableGenerationCost(zero(CostCurve)),\n        base_power = base,\n    )\n    add_component!(sys, solar)\n    add_time_series!(sys, solar, solar_TS)\nend\n```\n\n## Adding Hydro Generators and Their Time Series\n\nWe assume the data needed to build each [`HydroDispatch`](@ref) unit is found\nin a CSV file `Hydro_Gens.csv`, snapshotted below. The convention used for the\ncontents of the `Bus` column must be consistent with the convention used in the\n`Bus Number` column of `Buses.csv`.\n\n| Gen Name | Number | Bus | Min Stable Level (MW) | Max Capacity (MW) | Max Ramp Up (MW/min) | ... |\n|:-------- |:------ |:--- |:--------------------- |:----------------- |:-------------------- |:--- |\n| Hydro 01 | 1      | 56  | 0.0                   | 75.0              | 0.83                 | ... |\n| Hydro 02 | 2      | 66  | 0.0                   | 77.0              | 0.86                 | ... |\n| ...      | ...    | ... | ...                   | ...               | ...                  | ... |\n\nRead in the contents of the CSV file `Hydro_Gens.csv` to a data frame and\ncustomize the parameter names based on the column names in your CSV file.\n\n```julia\nhydro_gens = CSV.read(\"MyData/Hydro_Gens.csv\", DataFrame)\n\nname = \"Gen Name\"\nbus_connection = \"Bus\"\nnum = \"Number\"\nrate = \"Rating (MVA)\"\nmin_active_power = \"Min Stable Level (MW)\"\nmax_active_power = \"Max Capacity (MW)\"\nramp_up = \"Max Ramp Up (MW/min)\"\nramp_down = \"Max Ramp Down (MW/min)\"\nmin_up = \"Min Up Time (h)\"\nmin_down = \"Min Down Time (h)\"\n```\n\nBefore building the hydro generators, we must also set up the hydro generators'\ntime series. In this example, we assume that each hydro generator has a unique\ntime series, and all of these time series are contained in one file:\n`MyData/Hydro_Time_Series.csv`. Here is a snapshot of this time series CSV\nfile, where the first column contains time stamps, and the remaining columns\nare titled with its respective generator's name, and contain the time series\nvalues in MW for each hydro generator:\n\n| Time Stamp  | Hydro 01 | Hydro 02 | Hydro 03 | ... |\n|:----------- |:-------- |:-------- |:-------- |:--- |\n| 1/1/23 0:00 | 0.325386 | 0.325409 | 0.314454 | ... |\n| 1/1/23 1:00 | 0.325386 | 0.325409 | 0.314454 | ... |\n| ...         | ...      | ...      | ...      | ... |\n\nEach time series for its respective hydro generator has an hourly resolution,\nand is for the year 2023, plus one full day into 2024, for a total of 366 days,\nand 8784 values per column.\n\nCreate a data frame from `Hydro_Time_Series.csv` and define variables for the\naforementioned resolution and time stamps:\n\n```julia\nhydro_time_series = CSV.read(\"MyData/Hydro_Time_Series.csv\", DataFrame)\n\nresolution = Dates.Hour(1);\ntimestamps = range(DateTime(\"2023-01-01T00:00:00\"); step = resolution, length = 8784);\n```\n\nIn this example, we assume that the [`HydroGenerationCost`](@ref) has both zero\nfixed and variable costs. Moreover, since the example data is missing base\npower, we use the range of values in the time series data to determine the\nvalue of the base power which will be used to normalize the time series and\nother parameters, and set the generator's rating parameter to 1.0. (If your\ndata reports a base power, use that for the generator's base power, and rating\ndata for the generator's rating).\n\nIn the same `for` loop, we will build the hydro generator components using the\n[`HydroDispatch`](@ref) constructor and data stored in the `hydro_gens`\ndata frame, and build and attach each hydro generator's time series:\n\n```julia\nfor row in eachrow(hydro_gens)\n    norm = maximum(hydro_time_series[:, row[name]])\n    hydro_data_MW = hydro_time_series[:, row[name]]\n    base = row[rate]\n    if any((hydro_data_MW ./ base) .> 1.0)\n        @warn \"Generator $(row[name]) has a production larger than its base power. Normalizing by its maximum\"\n        base = norm\n    end\n    hydro_array = TimeArray(timestamps, (hydro_data_MW ./ base)) # normalize data\n    hydro_TS = SingleTimeSeries(;\n        name = \"max_active_power\",\n        data = hydro_array,\n        scaling_factor_multiplier = get_max_active_power,\n    )\n    hydro = HydroDispatch(;\n        name = row[name],\n        available = true,\n        bus = get_bus(sys, row[bus_connection]),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        rating = 1.0,\n        prime_mover_type = PrimeMovers.HA,\n        active_power_limits = (\n            min = row[min_active_power] / base,\n            max = row[max_active_power] / base,\n        ),\n        reactive_power_limits = (min = 0.0, max = 0.0),\n        ramp_limits = (up = row[ramp_up] / base, down = row[ramp_down] / base),\n        time_limits = (up = row[min_up], down = row[min_down]),\n        base_power = base,\n        operation_cost = HydroGenerationCost(zero(LinearCurve), 0.0),\n    )\n    add_component!(sys, hydro)\n    add_time_series!(sys, hydro, hydro_TS)\nend\n```\n\n## Adding Loads and Their Time Series\n\nIn this example, we assume that all loads will be represented as\n[`PowerLoad`](@ref) components, and that the loads are located in three\nregions. Each region has one unique time series, and every load in each region\nis assigned its region's normalized time series profile.\n\nThe data needed to build each [`PowerLoad`](@ref) unit is found in the CSV file\n`Loads.csv`, snapshotted below. The convention used for the contents of the\n`Bus` column must be consistent with the convention used in the `Bus Number`\ncolumn of `Buses.csv`, and similarly for the `Region` column.\n\n| Load Number | Bus | Region | Participation Factor |\n|:----------- |:--- |:------ |:-------------------- |\n| 1           | 1   | R1     | 0.047168669          |\n| 2           | 2   | R2     | 0.0184963            |\n| ...         | ... | ...    | ...                  |\n\nRead in the contents of the CSV file `Loads.csv` to a data frame and customize\nthe parameter names based on the column names in your CSV file.\n\n```julia\nload_params = CSV.read(\"MyData/Loads.csv\", DataFrame)\n\nregion = \"Region\"\nbus_connection = \"Bus\"\nfactor = \"Load Participation Factor\"\nnumber = \"Load Number\"\n```\n\nBefore building the loads, we must also set up the loads' time series. In this\nexample, we assume that each load region has a unique time series, and all of\nthese time series are contained in one file: `MyData/Load_Time_Series.csv`.\nHere is a snapshot of this time series CSV file, where the first column\ncontains time stamps, and the remaining columns are titled with its respective\nregion's name, and contain the time series values in MW for each region:\n\n| Time Stamp  | R1         | R2         | R3         |\n|:----------- |:---------- |:---------- |:---------- |\n| 1/1/23 0:00 | 5465.7296  | 1904.4448  | 2486.38409 |\n| 1/1/23 1:00 | 4994.53821 | 1726.22134 | 2273.63274 |\n| ...         | ...        | ...        | ...        |\n\nEach time series for its respective load region has an hourly resolution, and\nis for the year 2023, plus one full day into 2024, for a total of 366 days, and\n8784 values per column. Ensure that your time series file is similarly\nformatted.\n\nCreate a data frame from `Load_Time_Series.csv` and define variables for the\naforementioned resolution and time stamps:\n\n```julia\nload_time_series = CSV.read(\"MyData/Load_Time_Series.csv\", DataFrame)\n\nresolution = Dates.Hour(1);\ntimestamps = range(DateTime(\"2023-01-01T00:00:00\"); step = resolution, length = 8784);\n```\n\nConstruct and attach the loads to the system using the [`PowerLoad`](@ref)\nconstructor according to their regions. Because all loads in each region share\na time series profile, the `max_active_power` of each load will depend on the\nmaximum time series value of its region and its load participation factor.\n\n```julia\nfor row in eachrow(load_params)\n    num = row[number]\n    max = maximum(load_time_series[:, row[region]])\n    load = PowerLoad(;\n        name = \"load$num\",\n        available = true,\n        bus = get_bus(sys, row[bus_connection]),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        base_power = system_base_power,\n        max_active_power = (max) * (row[factor]) / system_base_power,\n        max_reactive_power = 0.0,\n    )\n    add_component!(sys, load)\nend\n```\n\nIn a `for` loop, iterate over the regions in your [`System`](@ref), and use the\n[`begin_time_series_update`](@ref) function to create and attach the respective\nloads' time series to every load in a region at once. Note: due to how\n`max_active_power` is defined, the time series values are normalized to its\nmaximum.\n\n```julia\nregions = unique(load_params[:, region])\n\nfor reg in regions\n    norm = maximum(load_time_series[:, reg])\n    load_array = TimeArray(\n        timestamps,\n        (load_time_series[:, reg] ./ norm),\n    )\n    load_TS = SingleTimeSeries(;\n        name = \"max_active_power\",\n        data = load_array,\n        scaling_factor_multiplier = get_max_active_power,\n    )\n    region = get_component(Area, sys, reg)\n    begin_time_series_update(sys) do\n        for component in get_components_in_aggregation_topology(PowerLoad, sys, region)\n            add_time_series!(sys, component, load_TS)\n        end\n    end\nend\n```\n\n## Customizing and Expanding\n\nAdditional resources to help you built your own custom [`System`](@ref):\n\n  - See how to [Add additional data to a component](@ref additional_fields)\n  - Learn about [Adding Data for Dynamic Simulations](@ref), which could also be loaded in a\n    `for` loop from a .csv, if you don't have PSS/e files available for\n    [automated parsing](@ref dyr_data)\n  - See more on how to [Parse Time Series Data from .csv's](@ref parsing_time_series)\n  - See how to [Add a New or Custom Type](@ref)\n  - See how to [Add a Component in Natural Units](@ref), which is an alternative to the\n    per-unitized `for` loops above, but requires more code\n  - See how to [Write, View, and Load Data with a JSON](@ref) to efficiently save your\n    [`System`](@ref) once you've built it\n"
  },
  {
    "path": "docs/src/how_to/create_hydro_datasets.md",
    "content": "# [Define Hydro Generators with Reservoirs](@id hydro_resv)\n\nIn the current version of `PowerSystems.jl` there is support and testing for hydropower generation plants with the following structures:\n\n## Shared Upstream Reservoir\n\n```mermaid\nflowchart TB\n subgraph s1[\"Hydro Plant 2\"]\n        B[\"Turbine A\"]\n        C[\"Turbine B\"]\n  end\n subgraph s2[\"HydroPlant 1\"]\n        D[\"Turbine C\"]\n  end\n    A --- C\n    A[\"Reservoir\"] --- B & D\n\n```\n\nFor this model, attach an upstream [`HydroReservoir`](@ref) to any number of [`HydroTurbine`](@ref)s. This can model different power house elevations to consider the effect of the elevation and pressure heads on the specific turbines inside of a power plant.\n\n### Example: Single Turbine with Single Reservoir\n\n```julia\nusing PowerSystems\nimport PowerSystems as PSY\n\n# Create a system\nsys = System(100.0)\nset_units_base_system!(sys, \"NATURAL_UNITS\")\n\n# Create and add a bus\nbus = ACBus(;\n    number = 1,\n    name = \"bus1\",\n    available = true,\n    bustype = ACBusTypes.PV,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.1),\n    base_voltage = 230.0,\n    area = nothing,\n    load_zone = nothing,\n)\nadd_component!(sys, bus)\n\n# Create a HydroTurbine\nturbine = HydroTurbine(;\n    name = \"Turbine1\",\n    available = true,\n    bus = bus,\n    active_power = 50.0,\n    reactive_power = 10.0,\n    rating = 100.0,\n    base_power = 100.0,\n    active_power_limits = (min = 10.0, max = 100.0),\n    reactive_power_limits = (min = -50.0, max = 50.0),\n    powerhouse_elevation = 500.0,  # meters above sea level\n    efficiency = 0.9,\n    conversion_factor = 1.0,\n    outflow_limits = (min = 0.0, max = 1000.0),  # m³/s\n    travel_time = 0.5,  # hours\n)\nadd_component!(sys, turbine)\n\n# Create a HydroReservoir\nreservoir = HydroReservoir(;\n    name = \"Reservoir1\",\n    available = true,\n    storage_level_limits = (min = 1000.0, max = 10000.0),  # m³\n    initial_level = 0.8,  # 80% of max\n    spillage_limits = (min = 0.0, max = 500.0),\n    inflow = 100.0,  # m³/h\n    outflow = 50.0,  # m³/h\n    level_targets = 0.7,\n    intake_elevation = 600.0,  # meters above sea level\n    head_to_volume_factor = LinearCurve(1.0),\n)\nadd_component!(sys, reservoir)\n\n# Link the turbine to the reservoir as a downstream turbine\nset_downstream_turbine!(reservoir, turbine)\n\n# Verify the connection\n@assert has_downstream_turbine(reservoir, turbine)\n@assert length(get_connected_head_reservoirs(sys, turbine)) == 1\n```\n\n### Example: Multiple Turbines with Single Reservoir\n\n```julia\n\nsys = System(100.0)\nset_units_base_system!(sys, \"NATURAL_UNITS\")\n\n# Create and add a bus\nbus = ACBus(;\n    number = 1,\n    name = \"bus1\",\n    available = true,\n    bustype = ACBusTypes.PV,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.1),\n    base_voltage = 230.0,\n    area = nothing,\n    load_zone = nothing,\n)\nadd_component!(sys, bus)\n# Create multiple turbines and connect them to a single reservoir\nturbines = []\nfor i in 1:5\n    turbine = HydroTurbine(;\n        name = \"Turbine$i\",\n        available = true,\n        bus = bus,\n        active_power = 20.0,\n        reactive_power = 5.0,\n        rating = 50.0,\n        base_power = 100.0,\n        active_power_limits = (min = 5.0, max = 50.0),\n        reactive_power_limits = nothing,\n        powerhouse_elevation = 500.0 + i * 10.0,  # Different elevations\n        efficiency = 0.85 + i * 0.02,\n    )\n    add_component!(sys, turbine)\n    push!(turbines, turbine)\nend\n\n# Link all turbines at once\nset_downstream_turbines!(reservoir, turbines)\n\n# Verify connections\n@assert has_downstream_turbine(reservoir)\n@assert length(get_downstream_turbines(reservoir)) == 5\n```\n\n## Head and Tail Reservoirs for Pumped Hydropower Plants\n\nFor this model, attach two [`HydroReservoir`](@ref)s to any number of [`HydroPumpTurbine`](@ref)s. The turbine and reservoir structs store the elevations to calculate the elevation and pressure heads for the facility.\n\n```mermaid\nflowchart TB\n subgraph s1[\"Pumped Hydro Plant\"]\n        B[\"Turbine A\"]\n        C[\"Turbine B\"]\n  end\n    A[\"Head Reservoir\"] --- B\n    A --- C\n    C --- D\n    B --- D[\"Tail Reservoir\"]\n```\n\n### Example: Pumped Hydro with Head and Tail Reservoirs\n\n```julia\n# Create a HydroPumpTurbine\npump_turbine = HydroPumpTurbine(;\n    name = \"PumpTurbine1\",\n    available = true,\n    bus = bus,\n    active_power = 50.0,\n    reactive_power = 10.0,\n    rating = 200.0,\n    active_power_limits = (min = 20.0, max = 200.0),  # Generation mode\n    reactive_power_limits = (min = -100.0, max = 100.0),\n    active_power_limits_pump = (min = 30.0, max = 180.0),  # Pumping mode\n    outflow_limits = (min = 0.0, max = 500.0),\n    powerhouse_elevation = 400.0,\n    base_power = 100.0,\n    ramp_limits = (up = 20.0, down = 20.0),\n    time_limits = nothing,\n    status = PSY.PumpHydroStatusModule.PumpHydroStatus.OFF,\n    time_at_status = 0.0,\n    efficiency = (turbine = 0.9, pump = 0.85),\n    transition_time = (turbine = 0.25, pump = 0.25),  # hours\n    minimum_time = (turbine = 1.0, pump = 1.0),  # hours\n    conversion_factor = 1.0,\n)\nadd_component!(sys, pump_turbine)\n\n# Create head (upper) reservoir\nhead_reservoir = HydroReservoir(;\n    name = \"HeadReservoir\",\n    available = true,\n    storage_level_limits = (min = 5000.0, max = 50000.0),\n    initial_level = 0.6,\n    spillage_limits = nothing,\n    inflow = 200.0,\n    outflow = 100.0,\n    level_targets = 0.5,\n    intake_elevation = 800.0,\n    head_to_volume_factor = LinearCurve(1.0),\n)\nadd_component!(sys, head_reservoir)\n\n# Create tail (lower) reservoir\ntail_reservoir = HydroReservoir(;\n    name = \"TailReservoir\",\n    available = true,\n    storage_level_limits = (min = 3000.0, max = 30000.0),\n    initial_level = 0.4,\n    spillage_limits = nothing,\n    inflow = 50.0,\n    outflow = 100.0,\n    level_targets = 0.5,\n    intake_elevation = 200.0,\n    head_to_volume_factor = LinearCurve(1.0),\n)\nadd_component!(sys, tail_reservoir)\n\n# Link reservoirs to pump-turbine\n# Head reservoir feeds into the turbine (downstream)\nset_downstream_turbine!(head_reservoir, pump_turbine)\n\n# Tail reservoir receives flow from the turbine (upstream)\nset_upstream_turbine!(tail_reservoir, pump_turbine)\n\n# Verify connections\n@assert has_downstream_turbine(head_reservoir, pump_turbine)\n@assert has_upstream_turbine(tail_reservoir, pump_turbine)\n@assert length(get_connected_head_reservoirs(sys, pump_turbine)) == 1\n@assert length(get_connected_tail_reservoirs(sys, pump_turbine)) == 1\n```\n\n## Key Component Fields\n\n### HydroTurbine\n\nKey fields for [`HydroTurbine`](@ref):\n\n  - `powerhouse_elevation::Float64`: Height in meters above sea level of the powerhouse\n  - `efficiency::Float64`: Turbine efficiency [0, 1.0]\n  - `turbine_type::HydroTurbineType`: Type of turbine (e.g., `HydroTurbineType.UNKNOWN`, `HydroTurbineType.FRANCIS`, `HydroTurbineType.PELTON`, `HydroTurbineType.KAPLAN`)\n  - `conversion_factor::Float64`: Conversion factor from flow/volume to energy (m³ -> p.u-hr)\n  - `outflow_limits::Union{Nothing, MinMax}`: Turbine outflow limits in m³/s\n  - `travel_time::Union{Nothing, Float64}`: Downstream travel time in hours from reservoir to turbine\n\n### HydroReservoir\n\nKey fields for [`HydroReservoir`](@ref):\n\n  - `storage_level_limits::MinMax`: Storage level limits (in m³, m, or MWh based on `level_data_type`)\n  - `initial_level::Float64`: Initial level as fraction of `storage_level_limits.max`\n  - `inflow::Float64`: Water refilling the reservoir (m³/h or MW)\n  - `outflow::Float64`: Water naturally leaving the reservoir (m³/h or MW)\n  - `spillage_limits::Union{Nothing, MinMax}`: Water spillage limits\n  - `level_targets::Union{Nothing, Float64}`: Target level at simulation end as fraction of max\n  - `intake_elevation::Float64`: Height of intake in meters above sea level\n  - `head_to_volume_factor::ValueCurve`: Head to volume relationship\n  - `upstream_turbines::Vector{HydroUnit}`: Turbines feeding into this reservoir (tail reservoir)\n  - `downstream_turbines::Vector{HydroUnit}`: Turbines fed by this reservoir (head reservoir)\n  - `upstream_reservoirs::Vector{Device}`: Reservoirs feeding spillage into this reservoir\n  - `level_data_type::ReservoirDataType`: Data type (e.g., `ReservoirDataType.USABLE_VOLUME`, `ReservoirDataType.HEAD`, `ReservoirDataType.ENERGY`)\n\n### HydroPumpTurbine\n\nKey fields specific to [`HydroPumpTurbine`](@ref):\n\n  - `active_power_limits::MinMax`: Power limits for turbine (generation) mode\n  - `active_power_limits_pump::MinMax`: Power limits for pump mode\n  - `status::PumpHydroStatus`: Operating status (`PumpHydroStatus.OFF`, `PumpHydroStatus.PUMP`, `PumpHydroStatus.GEN`)\n  - `efficiency::TurbinePump`: Separate efficiencies for turbine and pump modes `(turbine = 0.9, pump = 0.85)`\n  - `transition_time::TurbinePump`: Time to switch modes `(turbine = 0.25, pump = 0.25)`\n  - `minimum_time::TurbinePump`: Minimum operating time in each mode `(turbine = 1.0, pump = 1.0)`\n\n## Helper Functions\n\n### Linking Turbines to Reservoirs\n\n  - `set_downstream_turbine!(reservoir, turbine)`: Link a single turbine as downstream of reservoir\n  - `set_downstream_turbines!(reservoir, turbines)`: Link multiple turbines as downstream\n  - `set_upstream_turbine!(reservoir, turbine)`: Link a single turbine as upstream of reservoir\n  - `set_upstream_turbines!(reservoir, turbines)`: Link multiple turbines as upstream\n\n### Checking Connections\n\n  - `has_downstream_turbine(reservoir)`: Check if any downstream turbines are attached\n  - `has_downstream_turbine(reservoir, turbine)`: Check if specific turbine is downstream\n  - `has_upstream_turbine(reservoir)`: Check if any upstream turbines are attached\n  - `has_upstream_turbine(reservoir, turbine)`: Check if specific turbine is upstream\n\n### Retrieving Connected Components\n\n  - `get_downstream_turbines(reservoir)`: Get vector of downstream turbines\n  - `get_upstream_turbines(reservoir)`: Get vector of upstream turbines\n  - `get_connected_head_reservoirs(sys, turbine)`: Get reservoirs where turbine is downstream\n  - `get_connected_tail_reservoirs(sys, turbine)`: Get reservoirs where turbine is upstream\n  - `get_turbine_head_reservoirs_mapping(sys)`: Get mapping of all turbines to head reservoirs\n  - `get_turbine_tail_reservoirs_mapping(sys)`: Get mapping of all turbines to tail reservoirs\n\n### Removing Connections\n\n  - `remove_turbine!(reservoir, turbine)`: Remove a specific turbine connection\n  - `clear_turbines!(reservoir)`: Remove all turbine connections from reservoir\n"
  },
  {
    "path": "docs/src/how_to/create_system_with_source_import_export_cost.md",
    "content": "# Add costs for imported/exported power\n\nThis how-to guide explains how to add an [`ImportExportCost`](@ref) to a [`Source`](@ref)\ncomponent to model imports and exports with neighboring areas or external grids.\n\nThis guide assumes a [`System`](@ref) is already defined.\n\n```@setup source_ie_cost\nusing PowerSystems\nusing PowerSystemCaseBuilder\nsys = build_system(PSITestSystems, \"c_sys5_uc\")\n```\n\n## Overview\n\nA [`Source`](@ref) component represents an infinite bus with constant voltage output,\ncommonly used to represent:\n\n  - Very large machines on a single bus in dynamics simulations\n  - Import/export connections in operational simulations\n\nThe [`ImportExportCost`](@ref) operating cost allows you to specify:\n\n  - Import offer curves (buy prices for importing power)\n  - Export offer curves (sell prices for exporting power)\n  - Weekly energy limits for imports and exports\n  - Ancillary service offers\n\n## Step 1: Define Import and Export Curves\n\nYou can define import and export curves in several ways, depending on your data format.\n\n### Option A: Simple Single-Price Curves\n\nFor a simple constant price over a power range:\n\n```@repl source_ie_cost\n# Import curve: buy power at $25/MWh up to 200 MW\nimport_curve = make_import_curve(; power = 200.0, price = 25.0)\n\n# Export curve: sell power at $30/MWh up to 200 MW\nexport_curve = make_export_curve(; power = 200.0, price = 30.0)\n```\n\n### Option B: Piecewise Linear Curves\n\nFor more complex pricing with multiple segments:\n\n```@repl source_ie_cost\n# Import curve with increasing prices as more power is imported\nimport_curve = make_import_curve(;\n    power = [0.0, 100.0, 105.0, 120.0, 200.0],\n    price = [5.0, 10.0, 20.0, 40.0],\n)\n\n# Export curve with decreasing prices as more power is exported\nexport_curve = make_export_curve(;\n    power = [0.0, 100.0, 105.0, 120.0, 200.0],\n    price = [40.0, 20.0, 10.0, 5.0],\n)\n```\n\n!!! note\n\n      - Import curves must have non-decreasing (convex) slopes\n      - Export curves must have non-increasing (concave) slopes\n      - Power values must have one more entry than price values\n\n## Step 2: Create the ImportExportCost\n\nUse the curves to create an [`ImportExportCost`](@ref):\n\n```@repl source_ie_cost\nie_cost = ImportExportCost(;\n    import_offer_curves = import_curve,\n    export_offer_curves = export_curve,\n    energy_import_weekly_limit = 10000.0,  # MWh per week (optional)\n    energy_export_weekly_limit = 10000.0,  # MWh per week (optional)\n)\n```\n\n## Step 3: Add the Cost to the Source Component\n\nDefine a [`Source`](@ref) component with the import/export cost, or alternatively use\n[`set_operation_cost!`](@ref) to add the cost to an existing source:\n\n```@repl source_ie_cost\nsource = Source(;\n    name = \"external_grid\",\n    available = true,\n    bus = get_component(ACBus, sys, \"nodeC\"),\n    active_power = 0.0,\n    reactive_power = 0.0,\n    active_power_limits = (min = -200.0, max = 200.0),  # Negative for export\n    reactive_power_limits = (min = -100.0, max = 100.0),\n    R_th = 0.01,\n    X_th = 0.02,\n    internal_voltage = 1.0,\n    internal_angle = 0.0,\n    base_power = 100.0,\n    operation_cost = ie_cost,\n)\n```\n\n!!! tip\n\n    The `active_power_limits` should span negative (for export) to positive (for import)\n    values. Negative power indicates exporting power to the external grid.\n\n## Step 4: Add the Source to the System\n\nAdd the source component to your system:\n\n```@repl source_ie_cost\nadd_component!(sys, source)\n```\n\nVerify the source was added correctly:\n\n```@repl source_ie_cost\nget_component(Source, sys, \"external_grid\")\nget_operation_cost(get_component(Source, sys, \"external_grid\"))\n```\n\n## See Also\n\n  - [`Source`](@ref) - Documentation for the Source component\n  - [`ImportExportCost`](@ref) - Documentation for ImportExportCost\n  - [Adding an Operating Cost](@ref cost_how_to) - General guide for operating costs\n  - [`make_import_curve`](@ref) - Function to create import curves\n  - [`make_export_curve`](@ref) - Function to create export curves\n"
  },
  {
    "path": "docs/src/how_to/handle_3W_transformers.md",
    "content": "# [Handle 3-winding transformer data](@id 3wtdata)\n\nPowerSystems.jl stores the topological data for the [`Transformer3W`](@ref) as the common equivalent circuit in the star (or wye) configuration. In this representation, the series impedances of each winding are transformed into an equivalent star network with a common star bus.\n\n## The \"Starbus\" Representation\n\nThe resulting $Z_{12}, Z_{23},$ and $Z_{13}$ represent the series impedances in a star network. The common point of this star network is the conceptual \"starbus\" or internal neutral node. Each winding's terminal in the power system network is then connected to its corresponding impedance in this equivalent star.\n\n```mermaid\ngraph TD\n    subgraph Equivalent Star Circuit\n        N((Neutral/Starbus))\n        W1 --- Z1 --- N\n        W2 --- Z2 --- N\n        W3 --- Z3 --- N\n    end\n```\n\n## Representing 3-winding transformer PSSe Data in `PowerSystems.jl`\n\nPSS®E represents a [`Transformer3W`](@ref) as a single element with a dedicated data record. This record contains several fields that define the transformer's characteristics and connections. The key information stored includes:\n\n### Bus Connections in Delta configuration\n\n  - From Bus Number (I): The bus number connected to the primary winding.\n  - To Bus Number (J): The bus number connected to the secondary winding.\n  - Third Bus Number (K): The bus number connected to the tertiary winding.\n  - Circuit Identifier (ID): An alphanumeric identifier to distinguish between multiple transformers connected between the same buses.\n  - Impedance Data: PSS®E uses the concept of leakage impedances between the windings to model the transformer.\n\nIt does not explicitly store the equivalent star (wye) impedances. Instead, it stores the following:\n\n  - Positive Sequence Impedance (R1-2, X1-2): Resistance and reactance between winding 1 (primary) and winding 2 (secondary) in per-unit on the transformer's base MVA.\n\n  - Positive Sequence Impedance (R1-3, X1-3): Resistance and reactance between winding 1 (primary) and winding 3 (tertiary) in per-unit on the transformer's base MVA.\n\n  - Positive Sequence Impedance (R2-3, X2-3): Resistance and reactance between winding 2 (secondary) and winding 3 (tertiary) in per-unit on the transformer's base MVA.\n\n  - Star Bus Number: The star bus number is optional and it might be represented or not.\n\n### Magnetizing Admittance\n\n  - Magnetizing Conductance (GMAG1): Core loss conductance in per-unit on the transformer's base MVA, usually referred to the primary winding.\n  - Magnetizing Susceptance (BMAG1): Magnetizing susceptance in per-unit on the transformer's base MVA, usually referred to the primary winding.\n\n### Tap Settings and Phase Shift\n\n  - Winding 1 Tap Ratio (RATIO1): Tap ratio for the primary winding.\n  - Winding 2 Tap Ratio (RATIO2): Tap ratio for the secondary winding.\n  - Winding 3 Tap Ratio (RATIO3): Tap ratio for the tertiary winding.\n  - Phase Shift (ANGLE1, ANGLE2, ANGLE3): Phase shift in degrees applied by each winding.\n\n### Winding Ratings\n\n  - Winding 1 MVA Base (SBASE1): Base apparent power for winding 1.\n  - Winding 2 MVA Base (SBASE2): Base apparent power for winding 2.\n  - Winding 3 MVA Base (SBASE3): Base apparent power for winding 3.\n  - Nominal Voltages (WINDV1, WINDV2, WINDV3): Nominal voltage levels of each winding in kV.\n\n### Control Information (Optional)\n\nFor transformers with on-load tap changers (OLTCs) or phase shifters, additional data related to the control parameters (controlled bus, voltage setpoint, tap limits, etc.) would be included in the relevant control records, not directly within the transformer data record itself.\n\n## Deriving the Equivalent Star Impedances from PSSe\n\nIn `PowerSystems.jl`, we explictly represent and store the [`Transformer3W`](@ref) as an equivalent star (wye) circuit with a common neutral point (often referred to conceptually as a \"starbus\"), we calculate the equivalent series impedance for each winding ($Z_1, Z_2, Z_3$) from the PSS®E Positive Sequence Impedance data (e.g., R1-2, X1-2, etc.) using the following formulas:\n\n$$\\begin{aligned}\nZ_1 &= \\frac{1}{2} (Z_{12} + Z_{13} - Z_{23}) \\\\\nZ_2 &= \\frac{1}{2} (Z_{12} + Z_{23} - Z_{13}) \\\\\nZ_3 &= \\frac{1}{2} (Z_{13} + Z_{23} - Z_{12})\n\\end{aligned}$$\n\nWhere:\n\n  - $Z_1$: Equivalent series impedance of winding 1, connected between its terminal and the neutral point of the equivalent star.\n  - $Z_2$: Equivalent series impedance of winding 2, connected between its terminal and the neutral point of the equivalent star.\n  - $Z_3$: Equivalent series impedance of winding 3, connected between its terminal and the neutral point of the equivalent star.\n\nWe store the data from both representations (Delta and Wye) for completeness as well as the star bus used in the wye representation.\n"
  },
  {
    "path": "docs/src/how_to/improve_ts_performance.md",
    "content": "# Improve Performance with Time Series Data\n\nUse the steps here to improve performance with small or large data sets, but\nparticularly large data sets. These improvements can help handle adding\nlarge numbers of data sets or reduce overhead when accessing time series data\nmultiple times.\n\n## Choosing the Storage Location\n\nBy default, time series data is stored in an HDF5 file in the tmp file system to prevent\nlarge datasets from overwhelming system memory. However, you can change its location.\n\n### Small data sets\n\nIf your dataset will fit in your computer's memory, then you can increase\nperformance by storing it in memory:\n\n```julia\nsys = System(100.0; time_series_in_memory = true)\n```\n\n### Large data sets\n\nIf the system's time series data will be larger than the amount of tmp space available, use\nthe `time_series_directory` parameter to change its location.\n\n```julia\nsys = System(100.0; time_series_directory = \"bigger_directory\")\n```\n\nYou can also override the location by setting the environment\nvariable `SIENNA_TIME_SERIES_DIRECTORY` to another directory.\n\nHDF5 compression is not enabled by default, but you can enable\nit with `enable_compression` to get significant storage savings at the cost of CPU time.\n[`CompressionSettings`](@ref) can be used to customize the HDF5 compression.\n\n```julia\nsys = System(100.0; enable_compression = true)\nsys = System(\n    100.0;\n    compression = CompressionSettings(;\n        enabled = true,\n        type = CompressionTypes.DEFLATE,  # BLOSC is also supported\n        level = 3,\n        shuffle = true,\n    ),\n)\n```\n\n## Adding Timeseries To The System\n\nIn order to optimize the storage of time series data, time series can be shared\nacross devices to avoid duplication. If the same forecast applies to multiple\ncomponents then can call `add_time_series!`, passing the collection of\ncomponents that share the time series data.\nTime series data can also be shared on a component level. Suppose a time series array applies to\nboth the `max_active_power` and `max_reactive_power` attributes of a generator. You can share the\ndata.\n\n```julia\nresolution = Dates.Hour(1)\ndata = Dict(\n    DateTime(\"2020-01-01T00:00:00\") => ones(24),\n    DateTime(\"2020-01-01T01:00:00\") => ones(24),\n)\n# Define a Deterministic for the first attribute\nforecast_max_active_power = Deterministic(\n    \"max_active_power\",\n    data,\n    resolution;\n    scaling_factor_multiplier = get_max_active_power,\n)\nadd_time_series!(sys, generator, forecast_max_active_power)\n# Reuse time series for second attribute\nforecast_max_reactive_power = Deterministic(\n    forecast_max_active_power,\n    \"max_reactive_power\";\n    scaling_factor_multiplier = get_max_reactive_power,\n)\nadd_time_series!(sys, generator, forecast_max_reactive_power)\n```\n\nBy default, the call to [`add_time_series!`](@ref) will open the HDF5 file, write the data to the file,\nand close the file. It will also add a row to an SQLite database. These operations have overhead.\nIf you will add thousands of time series arrays, consider using [`begin_time_series_update`](@ref).\nAll arrays will be written with one file handle. The bulk SQLite operations are much more\nefficient.\n\n```julia\nbegin_time_series_update(sys) do\n    add_time_series!(sys, component1, time_series1)\n    add_time_series!(sys, component2, time_series2)\n    add_time_series!(sys, component3, time_series3)\nend\n```\n\n## Using Forecast Caches for Simulations\n\nEach retrieval of a forecast window from the HDF5 file will involve a small disk read.\nIn the case of production cost modeling or other analyses that access\nforecast windows repeatedly, this can slow down processes significantly, especially if the\nunderlying storage uses spinning disks.\n\nPowerSystems provides an alternate interface -- the forecast cache -- that pre-fetches data\ninto the system memory with large reads in order to mitigate this potential problem.\nIt is highly recommended that you use this interface for modeling implementations. This is\nparticularly relevant for models using large datasets.\nFor example:\n\n```julia\ncache = ForecastCache(Deterministic, component, \"max_active_power\")\nwindow1 = get_next_time_series_array!(cache)\nwindow2 = get_next_time_series_array!(cache)\n# or\nfor window in cache\n    @show window\nend\n```\n\nEach iteration of on the cache object will deliver the next forecast window (see\n[`get_next_time_series_array!`](@ref)).\n"
  },
  {
    "path": "docs/src/how_to/jump.md",
    "content": "# [Modeling with JuMP](@id modeling_with_jump)\n\nThis guide is for users who are interested in writing custom optimization problems directly in [JuMP](https://jump.dev/JuMP.jl/stable/), using data formatted with `PowerSystems.jl`. Check out [`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/stable/) for developing reusable templates for optimization problems within the Sienna platform.\n\nThis page shows a minimal example to develop a Economic Dispatch model. The code shows the stages to develop modeling code:\n\n 1. Make the data set from power flow and time series data,\n 2. Serialize the system data,\n 3. Pass the data and algorithm to the model.\n\nOne of the main uses of `PowerSystems.jl` is not having re-run the data generation for every model execution. The model code shows an example of populating the constraints and cost functions using accessor functions inside the model function. The example concludes by reading the data created earlier and passing the algorithm with the data.\n\nStart by loading required packages:\n\n```@repl using_jump\nusing PowerSystems\nusing JuMP\nusing Ipopt\nusing PowerSystemCaseBuilder\nusing Dates\n```\n\nFor this example, we'll load an existing data set using\n[`PowerSystemCaseBuilder.jl`](https://sienna-platform.github.io/PowerSystemCaseBuilder.jl/stable),\nwhich is a helper library that makes it easier to reproduce examples.\nNormally you would pass your local files to create the system data instead of calling the function `build_system`.\nWe also use [`transform_single_time_series!`](@ref) to format time-series data as forecasts for\nthis problem:\n\n```@repl using_jump\nsystem_data = build_system(PSISystems, \"c_sys5_pjm\")\ntransform_single_time_series!(system_data, Hour(24), Hour(24))\n```\n\nNext, we define the custom optimization problem using [`JuMP`](https://jump.dev/JuMP.jl/stable/)'s syntax.\nThe constraints include each generator's minimum and maximum active power output as well as the system power balance equation, minimizing the operating cost for each step in the 24-hour horizon:\n\n```@repl using_jump\nfunction ed_model(system::System, optimizer, load_scaling_factor::Float64 = 1.0)\n    ed_m = Model(optimizer)\n    time_periods = 1:24\n    thermal_gens_names = get_name.(get_components(ThermalStandard, system))\n    @variable(ed_m, pg[g in thermal_gens_names, t in time_periods] >= 0)\n\n    for g in get_components(ThermalStandard, system), t in time_periods\n        name = get_name(g)\n        @constraint(ed_m, pg[name, t] >= get_active_power_limits(g).min)\n        @constraint(ed_m, pg[name, t] <= get_active_power_limits(g).max)\n    end\n\n    net_load = zeros(length(time_periods))\n    for g in get_components(RenewableGen, system)\n        net_load -=\n            get_time_series_values(SingleTimeSeries, g, \"max_active_power\")[time_periods]\n    end\n\n    for g in get_components(StaticLoad, system)\n        net_load +=\n            get_time_series_values(SingleTimeSeries, g, \"max_active_power\")[time_periods]\n    end\n\n    for t in time_periods\n        @constraint(\n            ed_m,\n            sum(pg[g, t] for g in thermal_gens_names) == load_scaling_factor * net_load[t]\n        )\n    end\n\n    @objective(\n        ed_m,\n        Min,\n        sum(\n            pg[get_name(g), t] *\n            get_proportional_term(get_function_data(get_variable(get_operation_cost(g))))\n            for g in get_components(ThermalGen, system), t in time_periods\n        )\n    )\n    optimize!(ed_m)\n    return ed_m\nend\n```\n\nFinally, the `PowerSystems.jl` data is combined with this economic dispatch model and solved with the open-source [`Ipopt`](https://github.com/jump-dev/Ipopt.jl) solver:\n\n```@repl using_jump\nresults = ed_model(system_data, Ipopt.Optimizer)\n```\n"
  },
  {
    "path": "docs/src/how_to/market_bid_cost.md",
    "content": "# Add a Market Bid\n\nA [`MarketBidCost`](@ref) is an `OperationalCost` data structure that allows the user to run a production\ncost model that is very similar to most US electricity market auctions with bids for energy\nand ancillary services jointly. This page showcases how to create data for this cost function.\n\n## Adding a Single Incremental Energy bids to MarketBidCost\n\n### Construct directly the MarketBidCost using the `make_market_bid_curve` method.\n\nThe `make_market_bid_curve` creates an incremental or decremental offer curve from a vector of `n` power values, a vector of `n-1` marginal costs and single initial input. For example, the following code creates an incremental offer curve:\n\n```@repl market_bid_cost\nusing PowerSystems, Dates\nproposed_offer_curve =\n    make_market_bid_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0], 10.0)\n```\n\nThen a device with MarketBidCost can be directly instantiated using:\n\n```@repl market_bid_cost\nusing PowerSystems, Dates\nbus = ACBus(1, \"nodeE\", true, \"REF\", 0, 1.0, (min = 0.9, max = 1.05), 230, nothing, nothing)\n\ngenerator = ThermalStandard(;\n    name = \"Brighton\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 6.0,\n    reactive_power = 1.50,\n    rating = 0.75,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n    active_power_limits = (min = 0.0, max = 6.0),\n    reactive_power_limits = (min = -4.50, max = 4.50),\n    time_limits = (up = 0.015, down = 0.015),\n    ramp_limits = (up = 5.0, down = 3.0),\n    operation_cost = MarketBidCost(;\n        no_load_cost = 0.0,\n        start_up = (hot = 0.0, warm = 0.0, cold = 0.0),\n        shut_down = 0.0,\n        incremental_offer_curves = proposed_offer_curve,\n    ),\n    base_power = 100.0,\n)\n```\n\nSimilarly, a decremental offer curve can also be created directly using the same helper method:\n\n```@repl market_bid_cost\nusing PowerSystems, Dates\ndecremental_offer =\n    make_market_bid_curve([0.0, 100.0, 105.0, 120.0, 130.0], [30.0, 28.0, 26.0, 25.0], 50.0)\n```\n\nand can be added to a `MarketBidCost` using the field `decremental_offer_curves`.\n\n## Adding Time Series Energy bids to MarketBidCost\n\n### Step 1: Constructing device with MarketBidCost\n\nWhen using [`MarketBidCost`](@ref), the user can add the cost struct to the device specifying\nonly certain elements, at this point the actual energy cost bids don't need to be populated/passed.\n\nThe code below shows an example how we can create a thermal device with MarketBidCost.\n\n```@repl market_bid_cost\nusing PowerSystems, Dates\nbus = ACBus(1, \"nodeE\", true, \"REF\", 0, 1.0, (min = 0.9, max = 1.05), 230, nothing, nothing)\n\ngenerator = ThermalStandard(;\n    name = \"Brighton\",\n    available = true,\n    status = true,\n    bus = bus,\n    active_power = 6.0,\n    reactive_power = 1.50,\n    rating = 0.75,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n    active_power_limits = (min = 0.0, max = 6.0),\n    reactive_power_limits = (min = -4.50, max = 4.50),\n    time_limits = (up = 0.015, down = 0.015),\n    ramp_limits = (up = 5.0, down = 3.0),\n    operation_cost = MarketBidCost(;\n        no_load_cost = 0.0,\n        start_up = (hot = 0.0, warm = 0.0, cold = 0.0),\n        shut_down = 0.0,\n    ),\n    base_power = 100.0,\n)\n```\n\n### Step 2: Creating the `TimeSeriesData` for the Market Bid\n\nThe user is expected to pass the `TimeSeriesData` that holds the energy bid data which can be\nof any type (i.e. `SingleTimeSeries` or `Deterministic`) and data must be `PiecewiseStepData`.\nThis data type is created by specifying a vector of `n` powers, and `n-1` marginal costs.\nThe data must be specified in natural units, that is power in MW and marginal cost in $/MWh\nor it will not be accepted when adding to the system.\nCode below shows an example of how to build a Deterministic TimeSeries.\n\n```@repl market_bid_cost\ninitial_time = Dates.DateTime(\"2020-01-01\")\npsd1 = PiecewiseStepData([5.0, 7.33, 9.67, 12.0], [2.901, 5.8272, 8.941])\npsd2 = PiecewiseStepData([5.0, 7.33, 9.67, 12.0], [3.001, 6.0072, 9.001])\ndata =\n    Dict(\n        initial_time => [\n            psd1,\n            psd2,\n        ],\n    )\ntime_series_data = Deterministic(;\n    name = \"variable_cost\",\n    data = data,\n    resolution = Dates.Hour(1),\n)\n```\n\n### Step 3a: Adding Energy Bid TimeSeriesData to the device\n\nTo add energy market bids time-series to the `MarketBidCost`, use `set_variable_cost!`. The\narguments for `set_variable_cost!` are:\n\n  - `sys::System`: PowerSystem System\n  - `component::StaticInjection`: Static injection device\n  - `time_series_data::TimeSeriesData`: TimeSeriesData\n  - `power_units::UnitSystem`: UnitSystem\n\nCurrently, time series data only supports natural units for time series data, i.e. MW for power and $/MWh for marginal costs.\n\n```@repl market_bid_cost\nsys = System(100.0, [bus], [generator])\nset_variable_cost!(sys, generator, time_series_data, UnitSystem.NATURAL_UNITS)\n```\n\n**Note:** `set_variable_cost!` add curves to the `incremental_offer_curves` in the MarketBidCost.\nSimilarly, `set_incremental_variable_cost!` can be used to add curves to the `incremental_offer_curves`.\nOn the other hand, `set_decremental_variable_cost!` must be used to decremental curves (usually for storage or demand).\nThe creation of the TimeSeriesData is similar to Step 2, using `PiecewiseStepData`\n\n### Step 3b: Adding Service Bid TimeSeriesData to the device\n\nSimilar to adding energy market bids, for adding bids for ancillary services, use\n`set_service_bid!`.\n\n```@repl market_bid_cost\nservice = VariableReserve{ReserveUp}(\"example_reserve\", true, 0.6, 2.0)\nadd_service!(sys, service, get_component(ThermalStandard, sys, \"Brighton\"))\n\npsd3 = PiecewiseStepData([0.0, 10.0], [650.3])\npsd4 = PiecewiseStepData([0.0, 10.0], [750.0])\ndata = Dict(Dates.DateTime(\"2020-01-01\") => [psd3, psd4])\ntime_series_data = Deterministic(;\n    name = get_name(service),\n    data = data,\n    resolution = Dates.Hour(1),\n)\nset_service_bid!(sys, generator, service, time_series_data, UnitSystem.NATURAL_UNITS)\n```\n"
  },
  {
    "path": "docs/src/how_to/migrating_to_psy5.md",
    "content": "# [Migrating from version 4.0 to 5.0](@id psy5_migration)\n\nThis guide outlines the code updates required to upgrade from PowerSystems.jl version 4.0\nto 5.0, which was released in July 2025 and includes breaking changes. Most the changes are related\nto modeling in more detail AC transmission technologies.\n\n!!! warning\n\n    ***PowerSystems v5 is not backwards compatible with PowerSystems v4. The datasets created in PowerSystems v4 need to be converted using a separate script to be loaded\n    in version 5***\n\nThe changes are:\n\n```@contents\nPages = [\"migrating_to_psy5.md\"]\nDepth = 2\n```\n\n## AC Branches Type Hierarchy Change\n\nNew abstract type [`ACTransmission`](@ref) and was created to better distinguish between AC transmission objects connected between [`ACBus`](@ref) the new added [`TwoTerminalHVDC`](@ref) abstract type to caputre HVDC links connected between [`ACBus`](@ref).\n\n## Renamed Types and Parameters\n\nSome `Types` and fields were renamed, which should require a trivial search and replace:\n\nRenamed `Types`:\n\n  - [`TwoTerminalHVDCLine`](@ref) is now named [`TwoTerminalGenericHVDCLine`](@ref) and a method has been included to read old `TwoTerminalHVDCLine` data. See [Deprecated Methods](@ref deprecated)\n  - `TimeSeriesForcedOutage` is now named [`FixedForcedOutage`](@ref) and the method has been removed but the functionality remains.\n\nNew parameters:\n\n  - The [`ACTransmission`](@ref) objects now have rating fields for `b` and `c` ratings to enable modeling security constrained problems. These components now also include a `base_power` field, in situations where the base power for the transformer is not available (e.g., when parsing Matpower), the default behavior is to use the [system base for per-unitization](@ref per_unit).\n\nAffected Types are:\n\n  - [`Line`](@ref)\n  - [`MonitoredLine`](@ref)\n  - [`PhaseShiftingTransformer`](@ref)\n  - [`TapTransformer`](@ref)\n  - [`Transformer2W`](@ref)\n  - [`FuelCurve`](@ref) now has a new field for fuel offtake at the start of a thermal unit. This field defaults to a `LinearCurve(0.0)` value.\n\n## New and Eliminated Types\n\n  - [`Transformer3W`](@ref) (see [Handle 3-winding transformer data](@ref 3wtdata))\n  - [`TwoTerminalLCCLine`](@ref)\n  - [`TwoTerminalVSCLine`](@ref)\n  - [`HydroReservoir`](@ref)\n  - [`HydroTurbine`](@ref)\n  - [`HydroPumpTurbine`](@ref)\n  - [`ShiftablePowerLoad`](@ref)\n  - [`DiscreteControlledACBranch`](@ref)\n  - [`FACTSControlDevice`](@ref)\n  - [`ImpedanceCorrectionData`](@ref)\n  - [`ImportExportCost`](@ref)\n  - [`SynchronousCondenser`](@ref)\n  - [`InterruptibleStandardLoad`](@ref)\n\nThese types are no longer part of PowerSystems.jl:\n\n  - `TwoTerminalVSDCLine`\n  - `HydroPumpedStorage` (see [Updates to Hydro Storage related devices](@ref Hyd_updates))\n  - `HydroEnergyReservoir` (see [Updates to Hydro Storage related devices](@ref Hyd_updates))\n\n## [Updates to hydro storage related devices](@id Hyd_updates)\n\nIn previous versions of `PowerSystems.jl`, hydropower connected to reservoirs was modeled as a single plant connected to a single reservoir. Further, the model just kept track of the total energy in the reservoir. In this version of `PowerSystems.jl`, new structs [`HydroTurbine`](@ref) and [`HydroReservoir`](@ref) have been included to enable individual unit dispatch modeling as well as a shared reservoir.\n\nThe new [`HydroReservoir`](@ref) is also used by the new [`HydroPumpTurbine`](@ref) to model the head and tail reservoirs for Hydro Pump Storage facilities. Check the section [Define Hydro Generators with Reservoirs](@ref hydro_resv)\n\n## Updates to fuel categories\n\nThe fuel categories available in form EIA-923 have been expanded, the old categories are still\nvalid and the expanded list can be explored in the documentation [`ThermalFuels`](@ref tf_list)\n\n## Updates to Transformers\n\nMost of the transformer changes are included to bring PowerSystems.jl closer to the data model employed in PSSe RAW files which tend to be the industry standard. The two notable changes are:\n\n  - All transformers now have additional fields for base quantities needed for the calculation of the impedances in adequate bases. See [`Transformer per unit transformations`](@ref transformers_pu) for more details.\n  - The shunt branch in the transformer now uses a `Complex{Float64}` to model core losses as well as the core inductance.\n  - Shunt allocation in the transformer between the primary and secondary. We now allocate the shunt to the primary following PSSe's convention. See [`this issue`](https://github.com/Sienna-Platform/PowerSystems.jl/issues/1411) for a description of the discrepancy with Matpower. Note that this mostly affect the results reporting between Matpower and PSSe.\n\nWe also added support for [`Transformer3W`](@ref). See [`Handle 3-winding transformer data`](@ref 3wtdata) for more details.\n\nThese changes now provide the capability to obtain the impedance values for the transformer's\ndepending on the [`Per-unit Conventions`](@ref per_unit).\n\n## Updates to ACBuses\n\n[`ACBus`](@ref) has a new field `available` to match the behavior of setting a bus to \"isolated\" in other simulation applications. A detailed explanation on how to handle this new field has been documented in [`Understanding ACBusTypes`](@ref bustypes)\n\n## Updates to parsing PSSe files\n\nWe have implemented new conventions to parsing PSSe files as well as the capability to load PSSe v35 files. See the details in the new documentation section [`Conventions when parsing MATPOWER or PSS/e Files`](@ref parse_conventions)\n"
  },
  {
    "path": "docs/src/how_to/parse_dynamic_data.md",
    "content": "# [Parsing PSS/e dynamic data](@id dyr_data)\n\nA `PowerSystems.jl` system can be created using a .RAW and a .DYR file. For a complete list of supported models in PowerSystems.jl version 5.0, including machine models, AVR models, turbine governors, PSS models, inverter models, and additional models, see the [Supported PSS/e Models](@ref psse_models_ref) reference page.\n\nIn this example we will create a three bus system from these example files:\n\n```@repl raw_dyr_system\nusing PowerSystems\nfile_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"tutorials_data\")\nRAW_dir = joinpath(file_dir, \"ThreeBusNetwork.raw\")\nDYR_dir = joinpath(file_dir, \"TestGENCLS.dyr\")\n```\n\nThe data in the RAW file defines a three bus system with three generators, three loads and\nthree branches:\n\n```raw\n0, 100, 33, 0, 0, 60  / 24-Apr-2020 19:28:39 - MATPOWER 7.0.1-dev\n\n\n     101, 'BUS 1       ',       138, 3,    1,    1, 1,           1.02,        0,  1.1,  0.9,  1.1,  0.9\n     102, 'BUS 2       ',       138, 2,    1,    1, 1,           1.0142,           0,  1.1,  0.9,  1.1,  0.9\n     103, 'BUS 3       ',       138, 2,    1,    1, 1,           1.0059,           0,  1.1,  0.9,  1.1,  0.9\n0 / END OF BUS DATA, BEGIN LOAD DATA\n     101,  1, 1,    1,    1,       100,       20, 0, 0, 0, 0, 1, 1, 0\n     102,  1, 1,    1,    1,       70,       10, 0, 0, 0, 0, 1, 1, 0\n     103,  1, 1,    1,    1,       50,       10, 0, 0, 0, 0, 1, 1, 0\n0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA\n0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA\n     101,  1,       20,         0,       100,      -100,    1.02, 0,     100, 0, 0, 0, 0, 1, 1, 100,       318,         0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1\n     102,  1,       100,         0,       100,      -100,   1.0142, 0,     100, 0, 0.7, 0, 0, 1, 1, 100,       318,         0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1\n     103,  1,       100,         0,       100,      -100,   1.0059, 0,     100, 0, 0.2, 0, 0, 1, 1, 100,       318,         0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1\n0 / END OF GENERATOR DATA, BEGIN BRANCH DATA\n     101,      103, 1,  0.01000,     0.12,      0.0,     250,     250,     250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1\n     101,      102, 1,  0.01000,     0.12,      0.0,     250,     250,     250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1\n     102,      103, 1,  0.01000,     0.12,      0.0,     250,     250,     250, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1\n0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA\n0 / END OF TRANSFORMER DATA, BEGIN AREA DATA\n0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA\n0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA\n0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA\n0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA\n0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA\n0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA\n0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA\n0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA\n0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA\n0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA\n0 / END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA\n0 / END OF GNE DEVICE DATA, BEGIN INDUCTION MACHINE DATA\n0 / END OF INDUCTION MACHINE DATA\nQ\n```\n\nThe dynamic data for the generators is provided in the DYR file:\n\n```raw\n  101 'GENROE' 1   8.000000  0.030000  0.400000  0.050000  6.500000  0.000000  1.800000\n  1.700000  0.300000  0.550000  0.250000  0.200000  0.039200  0.267200  /\n  101 'ESST1A' 1   1  1  0.01  99  -99  1  10  1  1  200  0  4  -4  4  -4  0  0  1  0  3  /\n  102 'GENCLS' 1   0.0   0.0 /\n  103 'GENCLS' 1   3.1   2.0 /\n```\n\nThat assigns a GENROU generator and a ESST1A voltage regulator at the generator located at bus 101, while classic machine models for the generators located at bus 102 and 103.\n\nTo create the `System` in `PowerSystems.jl`, we pass both files directories:\n\n```@repl raw_dyr_system\ndyn_system = System(RAW_dir, DYR_dir; runchecks = false)\n```\n\n# Common Issue: Unique Bus Names\n\nPlease note that while PSS/e does not enforce unique bus names, `PowerSystems.jl` does. To reparse bus names to comply with this requirement the `bus_name_formatter` *kwarg  can be used in `System()` as shown in the example below:\n\n```@repl raw_dyr_system\ndyn_system = System(\n    RAW_dir,\n    DYR_dir;\n    bus_name_formatter = x -> strip(string(x[\"name\"])) * \"-\" * string(x[\"index\"]),\n)\n```\n\nIn this example the anonymous function `x -> strip(string(x[\"name\"])) * \"-\" * string(x[\"index\"])` takes the bus name and index from PSSe and concatenates them to produce the name.\n\n### See also:\n\n  - Parsing [Matpower or PSS/e RAW Files](@ref pm_data)\n  - [Build a `System` from CSV files](@ref system_from_csv)\n  - Parsing [time series](@ref parsing_time_series)\n"
  },
  {
    "path": "docs/src/how_to/parse_matpower_psse.md",
    "content": "# [Parsing MATPOWER or PSS/e Files](@id pm_data)\n\nThe following code will create a System from a MATPOWER .m or PSS/e .raw file:\n\n```@repl m_system\nusing PowerSystems\nfile_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"tutorials_data\")\nsys = System(joinpath(file_dir, \"case5.m\"))\n```\n\nOriginally, the parsing code was copied with permission from\n[`PowerModels.jl`](https://github.com/lanl-ansi/PowerModels.jl) but over the years the code base\nhas had some divergence due to the need to adapt it to for large industrial cases.\n\nThe PSSe parser tries to handle correctly all the gotchas that result from the diverse modeling practices transmission engineers employ. However, it is impossible to anticipate all possible variations.\n\nPowerSystems.jl parsing code has been tested and developed using large cases from North America\nlike the Western Electricity Coordinating Council (WECC) planning case and the Multiregional Modeling Working Group (MMWG) base case models. This parser has also been adapted to load cases in Latin America and the Caribbean and as many of the open data sets available only.\n\n## [Conventions when parsing MATPOWER or PSS/e Files](@id parse_conventions)\n\n!!! Info\n\n    In PowerSystems v5, the parsing conventions changed from those in PowerSystems v4. You might experience different behaviors when loading MATPOWER or PSS/e Files.\n\nPowerSystems.jl utilizes a data model that bridges the gap between operational simulations, such as Production Cost Analysis, and electrical engineering simulations, including power flows. Given the different practices in these domains, there are several discrepancies in how to handle data and we have made changes to make the modeling compatible.\n\nIn PowerSystems v5, we have implemented the following conventions for parsing PSSe files:\n\n  - **BusType correction**: If a bus has a value set to ISOLATED in PSSe, we will confirm that the bus is not entirely disconnected from the network. If the bus is disconnected, it will be set to ISOLATED and set the field available to false. However, if the bus is connected to a generator, we will infer a bus of type PV and set the field 'available' to false. This correction also applies to Matpower. For any other device connected to the bus, we will set it to PQ and set the 'available' field to false. Check [`Understanding ACBusTypes`](@ref bustypes) for a detailed explanation.\n  - **Parsing Synchronous Condensers**: If a generator is connected to a PV Bus with activer power set to 0.0, it will be parsed as a [`SynchronousCondenser`](@ref). This prevents for generators to be modeled as dispatchable [`ThermalStandard`](@ref) when it doesn't apply.\n  - **Reading and Storing Transformer Data**: The transformer data is always stored in the devices\n    ' base. See [`Transformer per unit transformations`](@ref transformers_pu) for additional details.\n  - **Transformer's Susceptance**: When reading from Matpower we split the transformer's susceptance evenly between the `from` and `to` ends to make it a closer approximation to the model in PSSe.\n  - **Tap transformer settings automated fix**: When the tap values in the RAW file are not withing the ranges defined in the same entry, PSSe performs a correction to the data. However, this correction isn't stored back in the file. The tap correction is done internally and is not exported from PSSE. Changes are not reflected in the exported file.PowerSystems.jl will correct the tap setting **and change the field in the transformer struct.**\n  - **Reading and Storing Multi-Section Line Data**: `PowerSystems.jl` does not have a explicit multi-section line object. These devices are parsed as individual lines and the \"dummy buses\" are added to the system. The additional data is stored in the [`Line`](@ref) `ext` field. Further network reductions are performed using [`PowerNetworkMatrices.jl`](https://sienna-platform.github.io/PowerNetworkMatrices.jl/stable/).\n  - **Reading [`GeographicInfo`](@ref) data from substations (PSSe v35 only)**: If the file contains a substation section. The coordinates will be automatically loaded as a [`GeographicInfo`](@ref) attribute and assigned to the relevant buses.\n  - **Use [`InterruptibleStandardLoad`](@ref) (PSSe v35 only)**: In newer versions of PSSe there is a flag for interruptible. Since PowerSystems.jl already has structures to model controllable load like [`InterruptiblePowerLoad`](@ref) and [`ShiftablePowerLoad`](@ref) a new type is used when parsing from PSSe to account of the interruptible behavior in economic modeling.\n  - **Treatment of conforming and non-conforming flags**: See the section [`Conforming and Non-Conforming Loads`](@ref conf_loads). PowerSystems.jl uses an enum to represent this data but it does not implement specific models for this behavior.\n  - **Breakers and Switches**: From the perspective of PowerSystems.jl breakers and switches are modeled as [`DiscreteControlledACBranch`](@ref). We use an enum to separate between the two but from the data structure perspective both use the same object definition.\n  - **Rate data correction**: For rates B and C are set as `nothing` if the value in the file is zero. On the other hand, for rating A, the value gets corrected. If the raw file is zero, then set up the rating to infinite bound first and then reduced according to the voltage values. This proceedure still can produce a large amount of warning for situations where a single line is used to model a double circuit or a whole transmission corridor.\n  - **Motor Loads**: We included a new device for explictly modeling motor loads. However, PSSe doesn't support explicit representations of these loads. The parser will print a warning in the log when we detect conditions commonly associated to motor load representations but won't be able to capture it directly.\n\n### Pending parsing challenges\n\n  - Managing the new format for rate data. In the old PSSe versions, there was Rate A, Rate B and Rate C. However, in newer versions there are 12 possible rates open to intepretation by the modeler. it can still be interpreted as A, B or C rates or a rate per month. PSSe doesn't provide any metada to interpret the rating bands provided.\n  - Detecting motor loads modeled as generators. Same as with the case for the negative loads, motors are known to be modeled as machines with negative injections (i.e., loads) to match modeling them in transient studies as machines.\n  - Automated transformer direction swaping. See [`this issue`](https://github.com/Sienna-Platform/PowerSystems.jl/issues/1423)\n  - Parsing outage data.\n\n### See also:\n\n  - Parsing [PSS/e .dyr Files](@ref dyr_data), which also includes an example of parsing a\n    .raw file\n  - [Build a `System` from CSV files](@ref system_from_csv)\n  - Parsing [time series](@ref parsing_time_series)\n"
  },
  {
    "path": "docs/src/how_to/parse_ts_from_csvs.md",
    "content": "# [Parse Time Series Data from .csv's](@id parsing_time_series)\n\nThis example shows how to parse time series data from .csv files to add to a `System`.\nFor example, a `System` created by [parsing a MATPOWER file](@ref pm_data) doesn't contain\nany time series data, so a user may want to add time series to be able to run a production\ncost model.\n\n```@setup forecasts\nusing PowerSystems\nusing JSON3\n\nfile_dir = joinpath(pkgdir(PowerSystems), \"docs\", \"src\", \"tutorials\", \"tutorials_data\"); #hide\nsys = System(joinpath(file_dir, \"case5_re.m\"));\n```\n\nLet's use a predefined 5-bus [`System`](@ref) with some renewable generators and loads that\nwe want to add time-series data to:\n\n```@repl forecasts\nsys\n```\n\n## Define pointers to time series files\n\n`PowerSystems` requires a metadata file that maps components to their time series\ndata in order to be able to automatically construct time_series from .csv data\nfiles.\n\nFor example, if we want to add a bunch of time series files, say one for each load and one\nfor each renewable generator, we need to define *pointers* to each time series .csv file\nwith the following fields:\n\n  - `simulation`:  User description of simulation\n  - `resolution`:  Resolution of time series in seconds\n  - `module`:  Module that defines the abstract type of the component\n  - `category`:  Type of component. Must map to abstract types defined by the \"module\"\n    entry (Bus, ElectricLoad, Generator, LoadZone, Reserve)\n  - `component_name`:  Name of component\n  - `name`:  User-defined name for the time series data.\n  - `normalization_factor`:  Controls normalization of the data. Use 1.0 for\n    pre-normalized data. Use 'Max' to divide the time series by the max value in the\n    column. Use any float for a custom scaling factor.\n  - `scaling_factor_multiplier_module`:  Module that defines the accessor function for the\n    scaling factor\n  - `scaling_factor_multiplier`:  Accessor function of the scaling factor\n  - `data_file`:  Path to the time series data file\n\nNotes:\n\n  - The `module`, `category`, and `component_name` entries must be valid arguments to retrieve\n    a component using `get_component(${module}.${category}, sys, $name)`.\n  - The `scaling_factor_multiplier_module` and the `scaling_factor_multiplier` entries must\n    be sufficient to return the scaling factor data using\n    `${scaling_factor_multiplier_module}.${scaling_factor_multiplier}(component)`.\n\n`PowerSystems` supports this metadata in either CSV or JSON formats.\n\nIn this example, we will use the JSON format. The example file can be found\n[here](https://github.com/Sienna-Platform/PowerSystemsTestData/blob/master/5-Bus/5bus_ts/timeseries_pointers_da.json),\nand this is what its pointers look like in the required format:\n\n```@repl forecasts\nusing PowerSystemCaseBuilder #hide\nDATA_DIR = PowerSystemCaseBuilder.DATA_DIR #hide\nFORECASTS_DIR = joinpath(DATA_DIR, \"5-Bus\", \"5bus_ts\"); #hide\nfname = joinpath(FORECASTS_DIR, \"timeseries_pointers_da.json\"); # hide\nopen(fname, \"r\") do f # hide\n    JSON3.@pretty JSON3.read(f) # hide\nend #hide\n```\n\n## Read and assign time series to `System` using these parameters.\n\n```@repl forecasts\nfname = joinpath(FORECASTS_DIR, \"timeseries_pointers_da.json\")\nadd_time_series!(sys, fname)\n```\n\nYou can print the `System` to see a new table summarizing the time series data that has been\nadded:\n\n```@repl forecasts\nsys\n```\n\n### See also:\n\n  - [Improve Performance with Time Series Data](@ref)\n  - Parsing [Matpower or PSS/e RAW Files](@ref pm_data)\n  - Parsing [PSS/e DYR Files](@ref dyr_data)\n  - [Build a `System` from CSV files](@ref system_from_csv)\n"
  },
  {
    "path": "docs/src/how_to/reduce_repl_printing.md",
    "content": "# Reduce REPL printing\n\nBy default `PowerSystems.jl` outputs to the REPL all Logging statements, which can be\noverwhelming in some cases.\n\nUse [`configure_logging`](@ref) to create a logger with your preferences for which logging\nstatements should be printed to the console or a log file:\n\n**Example**: Set log output to only see error messages in the console\n\n```julia\nusing PowerSystems\nusing Logging\nconfigure_logging(; console_level = Logging.Error)\n```\n\n**Note:** log messages are not automatically flushed to files. Call\n`flush(logger)` to make this happen.\n\n[Refer to this\npage](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/dev_guide/logging/#Use-Cases)\nfor more logging configuration options. Note that it describes how to enable\ndebug logging for some log messages but not others.\n"
  },
  {
    "path": "docs/src/how_to/serialize_data.md",
    "content": "# Write, View, and Load Data with a JSON\n\n`PowerSystems.jl` provides functionality to serialize an entire [`System`](@ref) to a JSON\nfile and then deserialize it back to a `System`. The main benefit is that\ndeserializing is significantly faster than reconstructing the `System` from raw\ndata files.\n\nThe sections below show how to write data to a JSON, explore the data while it is in\nJSON format, and load Data saved in a JSON back into `PowerSystems.jl`.\n\n## Write data to a JSON\n\nYou can do this to save your own custom `System`, but we'll use an existing\ndataset from\n[`PowerSystemCaseBuilder.jl`](https://github.com/Sienna-Platform/PowerSystemCaseBuilder.jl),\nsimply to illustrate the process.\n\nFirst, load the dependencies and a `System` from `PowerSystemCaseBuilder`:\n\n```@repl serialize_data\nusing PowerSystems\nusing PowerSystemCaseBuilder\nsys = build_system(PSISystems, \"c_sys5_pjm\")\n```\n\nSet up your target path, for example in a \"mysystems\" subfolder:\n\n```@repl serialize_data\nfolder = mkdir(\"mysystems\");\npath = joinpath(folder, \"system.json\")\n```\n\nNow write the system to JSON:\n\n```@repl serialize_data\nto_json(sys, path)\n```\n\nNotice in the `Info` statements that the serialization process stores 3 files:\n\n 1. System data file (`*.json` file)\n 2. Validation data file (`*.json` file)\n 3. Time Series data file (`*.h5` file)\n\n## Viewing `PowerSystems` Data in JSON Format\n\nSome users prefer to view and filter the `PowerSystems.jl` data while it is in JSON format.\nThere are many tools available to browse JSON data.\n\nHere is an example [GUI tool](http://jsonviewer.stack.hu) that is available\nonline in a browser.\n\nThe command line utility [jq](https://stedolan.github.io/jq/) offers even more\nfeatures. Below are some example commands, called from the command line within the\n\"mysystems\" subfolder:\n\nView the entire file pretty-printed:\n\n```zsh\njq . system.json\n```\n\nView the `PowerSystems` component types:\n\n```zsh\njq '.data.components | .[] | .__metadata__ | .type' system.json | sort | uniq\n```\n\nView specific components:\n\n```zsh\njq '.data.components | .[] | select(.__metadata__.type == \"ThermalStandard\")' system.json\n```\n\nGet the count of a component type:\n\n```zsh\n# There is almost certainly a better way.\njq '.data.components | .[] | select(.__metadata__.type == \"ThermalStandard\")' system.json | grep -c ThermalStandard\n```\n\nView specific component by name:\n\n```zsh\njq '.data.components | .[] | select(.__metadata__.type == \"ThermalStandard\" and .name == \"107_CC_1\")' system.json\n```\n\nFilter on a field value:\n\n```zsh\njq '.data.components | .[] | select(.__metadata__.type == \"ThermalStandard\" and .active_power > 2.3)' system.json\n```\n\n## Read the JSON file and create a new `System`\n\nFinally, you can read the file back in, and verify the new system has the same data as above:\n\n```@repl serialize_data\nsys2 = System(path)\nrm(folder; recursive = true); #hide\n```\n\n!!! tip\n\n    PowerSystems generates UUIDs for the `System` and all components in order to have\n    a way to uniquely identify objects. During deserialization it restores the same\n    UUIDs.  If you will modify the `System` or components after deserialization then\n    it is recommended that you set this flag to generate new UUIDs.\n\n    ```julia\n    system2 = System(path; assign_new_uuids = true)\n    ```\n"
  },
  {
    "path": "docs/src/how_to/use_context_managers.md",
    "content": "# Use Context Managers for Efficient Bulk Operations\n\n`PowerSystems.jl` provides several \"context manager\" functions that help you perform bulk\noperations more efficiently and safely. These functions temporarily change system settings or\noptimize batch operations, then automatically restore the original state when complete.\n\nContext managers in PowerSystems follow a pattern similar to `Logging.with_logger` in Julia.\nThey accept a function (typically as a `do` block) that executes with modified settings,\nensuring cleanup even if errors occur.\n\n## Available Context Managers\n\nPowerSystems provides three main context managers:\n\n 1. [`with_units_base`](@ref) - Temporarily change unit system for getting/setting component data\n 2. [`begin_supplemental_attributes_update`](@ref) - Optimize bulk addition/removal of supplemental attributes\n 3. [`begin_time_series_update`](@ref) - Optimize bulk addition of time series data\n\n## Using `with_units_base`\n\nThe [`with_units_base`](@ref) function temporarily changes the [unit system](@ref per_unit)\nfor a `System` or `Component`, executes your code, then automatically restores the original\nunit system. This is useful when you need to retrieve or set values in a specific unit system\nwithout permanently changing the system's configuration.\n\n!!! note\n\n    You can specify the unit system using either the `UnitSystem` enum (e.g.,\n    `UnitSystem.NATURAL_UNITS`) or a string (e.g., `\"NATURAL_UNITS\"`). Both forms are\n    supported and equivalent.\n\n### Example: Getting Component Data in Natural Units\n\n```julia\nusing PowerSystems\nusing PowerSystemCaseBuilder\n\n# Load a system\nsys = build_system(PSISystems, \"c_sys5_pjm\")\ngen = first(get_components(ThermalStandard, sys))\n\n# Get active power in natural units (MW) regardless of system's unit base\nactive_power_mw = with_units_base(sys, UnitSystem.NATURAL_UNITS) do\n    get_active_power(gen)\nend\n\n# The system's unit base is automatically restored after the block\n```\n\n### Example: Setting Multiple Component Values in Natural Units\n\n```julia\n# Temporarily change units to add/modify multiple components in natural units\nwith_units_base(sys, \"NATURAL_UNITS\") do\n    for gen in get_components(ThermalStandard, sys)\n        # Set values in MW, MVA, etc.\n        set_active_power!(gen, 150.0)  # MW\n        set_rating!(gen, 200.0)        # MVA\n    end\nend\n\n# System automatically returns to original unit base\n```\n\n### Component-Level Context Manager\n\nYou can also use `with_units_base` on individual components:\n\n```julia\nactive_power_mw = with_units_base(gen, UnitSystem.NATURAL_UNITS) do\n    get_active_power(gen)\nend\n```\n\n!!! tip\n\n    The `with_units_base` context manager is particularly useful when you need to work with\n    data in natural units (MW, MVA, etc.) while keeping your system configured in per-unit\n    for optimization or simulation purposes.\n\n## Using `begin_supplemental_attributes_update`\n\nThe [`begin_supplemental_attributes_update`](@ref) function optimizes performance when adding\nor removing many supplemental attributes. It batches operations together, reducing overhead\nfrom repeated index updates.\n\nIf an error occurs during the update, all changes are automatically reverted, ensuring data\nconsistency.\n\n### Example: Adding Multiple Supplemental Attributes\n\n```julia\nusing PowerSystems\n\n# Define some supplemental attributes (e.g., outage data)\noutage1 = FixedForcedOutage(;\n    mean_time_to_recovery = 8.0,\n    mean_time_to_failure = 1000.0,\n)\n\noutage2 = FixedForcedOutage(;\n    mean_time_to_recovery = 12.0,\n    mean_time_to_failure = 800.0,\n)\n\n# Get components to attach attributes to\ngen1 = get_component(ThermalStandard, sys, \"322_CT_6\")\ngen2 = get_component(ThermalStandard, sys, \"323_CC_1\")\n\n# Use context manager for efficient bulk addition\nbegin_supplemental_attributes_update(sys) do\n    add_supplemental_attribute!(sys, gen1, outage1)\n    add_supplemental_attribute!(sys, gen2, outage2)\n    # Add many more attributes...\nend\n```\n\n### Example: Bulk Operations with Error Handling\n\n```julia\n# If an error occurs, all changes are automatically reverted\ntry\n    begin_supplemental_attributes_update(sys) do\n        add_supplemental_attribute!(sys, component1, attribute1)\n        add_supplemental_attribute!(sys, component2, attribute2)\n        # ... more operations ...\n        error(\"Something went wrong!\")  # All changes will be reverted\n    end\ncatch e\n    @warn \"Operation failed, changes were reverted\" exception=e\nend\n```\n\n!!! note\n\n    Without using this context manager, each individual call to\n    `add_supplemental_attribute!` updates internal indexes separately, which can be slow\n    when adding many attributes. The context manager batches all updates together for\n    better performance.\n\n## Using `begin_time_series_update`\n\nThe [`begin_time_series_update`](@ref) function optimizes performance when adding many time\nseries arrays by keeping the HDF5 file open and batching SQLite database operations. This\nreduces the overhead of repeatedly opening/closing files and performing individual database\ntransactions.\n\nIf an error occurs during the update, changes are automatically reverted.\n\n!!! note\n\n    This context manager is not necessary for in-memory time series stores, only for\n    HDF5-backed storage.\n\n### Example: Adding Multiple Time Series\n\n```julia\nusing PowerSystems\nusing Dates\n\n# Create time series data\nresolution = Dates.Hour(1)\ndata = Dict(\n    DateTime(\"2020-01-01T00:00:00\") => ones(24),\n    DateTime(\"2020-01-02T00:00:00\") => ones(24) * 1.1,\n)\n\n# Get components\ngenerators = collect(get_components(ThermalStandard, sys))\n\n# Use context manager for efficient bulk addition\nbegin_time_series_update(sys) do\n    for (i, gen) in enumerate(generators)\n        forecast = Deterministic(\n            \"max_active_power\",\n            data,\n            resolution;\n            scaling_factor_multiplier = get_max_active_power,\n        )\n        add_time_series!(sys, gen, forecast)\n    end\nend\n```\n\n### Example: Adding Time Series from Multiple Sources\n\n```julia\n# When you have time series data from multiple sources\nbegin_time_series_update(sys) do\n    for component in get_components(Generator, sys)\n        # Create time series data specific to each component\n        # (In practice, this might come from CSV files, databases, or other sources)\n        component_data = Dict(\n            DateTime(\"2020-01-01T00:00:00\") => rand(24),\n            DateTime(\"2020-01-02T00:00:00\") => rand(24),\n        )\n\n        forecast = Deterministic(\n            \"max_active_power\",\n            component_data,\n            resolution;\n            scaling_factor_multiplier = get_max_active_power,\n        )\n        add_time_series!(sys, component, forecast)\n    end\nend\n```\n\n!!! tip\n\n    When adding thousands of time series arrays, using `begin_time_series_update` can\n    provide significant performance improvements by reducing file I/O and database\n    transaction overhead.\n\n## Best Practices\n\n 1. **Always use context managers for bulk operations**: When adding multiple supplemental\n    attributes or time series, use the appropriate context manager to improve performance.\n\n 2. **Automatic cleanup**: Context managers ensure cleanup happens even if errors occur, so\n    your system state remains consistent.\n\n 3. **Nested context managers**: You can nest context managers if needed:\n\n    ```julia\n    with_units_base(sys, \"NATURAL_UNITS\") do\n        begin_time_series_update(sys) do\n            # Add time series with natural unit scaling factors\n            for gen in get_components(Generator, sys)\n                # ... add time series ...\n            end\n        end\n    end\n    ```\n\n 4. **Error handling**: The context managers automatically handle cleanup, but you can still\n    use `try-catch` blocks for application-specific error handling:\n\n    ```julia\n    try\n        begin_time_series_update(sys) do\n            # ... operations ...\n        end\n    catch e\n        @error \"Time series update failed\" exception=e\n        # Handle application-specific recovery\n    end\n    ```\n\n## See Also\n\n  - [Per-unit Conventions](@ref per_unit) - Learn more about unit systems\n  - [Supplemental Attributes](@ref supplemental_attributes) - Details on supplemental attribute usage\n  - [Working with Time Series Data](@ref tutorial_time_series) - Tutorial on time series handling\n  - [Improve Performance with Time Series Data](@ref) - Additional time series performance tips\n"
  },
  {
    "path": "docs/src/index.md",
    "content": "# Welcome to PowerSystems.jl\n\n```@meta\nCurrentModule = PowerSystems\n```\n\n!!! tip \"Announcement\"\n\n    PowerSystems.jl upgraded to version 5.0 in November 2025, which included breaking changes.\n    Visit the [v5.0 migration guide](@ref psy5_migration) for information on\n    how to update your existing code from version 4.0.\n\n## About\n\n`PowerSystems.jl` is part of the National Laboratory of the Rockies'\n[Sienna ecosystem](https://www.nlr.gov/analysis/sienna.html), an open source framework for\nscheduling problems and dynamic simulations for power systems. The Sienna ecosystem can be\n[found on github](https://github.com/Sienna-Platform/Sienna). It contains three applications:\n\n  - [Sienna\\Data](https://github.com/Sienna-Platform/Sienna?tab=readme-ov-file#siennadata) enables\n    efficient data input, analysis, and transformation\n  - [Sienna\\Ops](https://github.com/Sienna-Platform/Sienna?tab=readme-ov-file#siennaops) enables\n    enables system scheduling simulations by formulating and solving optimization problems\n  - [Sienna\\Dyn](https://github.com/Sienna-Platform/Sienna?tab=readme-ov-file#siennadyn) enables\n    system transient analysis including small signal stability and full system dynamic\n    simulations\n\nEach application uses multiple packages in the [`Julia`](http://www.julialang.org)\nprogramming language.\n\n`PowerSystems.jl` is the foundation of Sienna\\Data, and it is used with all three\napplications. It provides a rigorous\ndata model using Julia structures to enable power systems modeling. `PowerSystems.jl` is\nagnostic to a specific mathematical model and can be used for many model categories.\n\n`PowerSystems.jl` provides tools to prepare and process data useful\nfor electric energy systems modeling. This package serves two purposes:\n\n 1. It facilitates the development and open sharing of large data sets for Power Systems modeling\n 2. It provides a data model that imposes discipline on model specification, addressing the challenge of design and terminology choices when sharing code and data.\n\nThe main features include:\n\n  - Comprehensive and extensible library of data structures for electric systems modeling.\n  - Large scale data set development tools based on common text based data formats\n    (PSS/e `.raw` and `.dyr`, and `MATPOWER`) and configurable tabular data (e.g. CSV)\n    parsing capabilities.\n  - Optimized container for component data and time series supporting serialization to\n    portable file formats and configurable validation routines.\n\n## How To Use This Documentation\n\nThere are five main sections containing different information:\n\n  - **Tutorials** - Detailed walk-throughs to help you *learn* how to use\n    `PowerSystems.jl`\n  - **How to...** - Directions to help *guide* your work for a particular task\n  - **Explanation** - Additional details and background information to help you *understand*\n    `PowerSystems.jl`, its structure, and how it works behind the scenes\n  - **Reference** - Technical references and API for a quick *look-up* during your work\n  - **Model Library** - Technical references of the data types and their functions that\n    `PowerSystems.jl` uses to model power system components\n\n`PowerSystems.jl` strives to follow the [Diataxis](https://diataxis.fr/) documentation\nframework.\n\n## Installation and Quick Links\n\n  - [Sienna installation page](https://sienna-platform.github.io/Sienna/SiennaDocs/docs/build/how-to/install/):\n    Instructions to install `PowerSystems.jl` and other Sienna packages\n\n!!! note\n\n    `PowerSystems.jl` uses [`InfrastructureSystems.jl`](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/) as a utility library. Many methods are re-exported from `InfrastructureSystems.jl`.\n    For most users there is no need to import `InfrastructureSystems.jl`.\n\n  - [Sienna Documentation Hub](https://sienna-platform.github.io/Sienna/SiennaDocs/docs/build/index.html):\n    Links to other Sienna packages' documentation\n"
  },
  {
    "path": "docs/src/model_library/dynamic_branch.md",
    "content": "# Dynamic Branch\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"models/dynamic_branch.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/dynamic_generator.md",
    "content": "# DynamicGenerator\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"dynamic_generator.jl\"]\nOrder = [:type, :function]\nPublic = true\n```\n"
  },
  {
    "path": "docs/src/model_library/dynamic_inverter.md",
    "content": "# DynamicInverter\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"dynamic_inverter.jl\"]\nOrder = [:type, :function]\nPublic = true\n```\n"
  },
  {
    "path": "docs/src/model_library/hybrid_system.md",
    "content": "### Hybrid System\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"HybridSystem.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/hydro_generation_cost.md",
    "content": "# HydroGenerationCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/HydroGenerationCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/hydro_reservoir.md",
    "content": "### `HydroReservoir`\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"HydroReservoir.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/hydro_reservoir_cost.md",
    "content": "### `HydroReservoirCost`\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/HydroReservoirCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/import_export_cost.md",
    "content": "# ImportExportCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/ImportExportCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/load_cost.md",
    "content": "# LoadCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/LoadCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/market_bid_cost.md",
    "content": "# MarketBidCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/MarketBidCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/offer_curve_cost.md",
    "content": "# OfferCurveCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/OfferCurveCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/outer_control.md",
    "content": "# OuterControl\n\nThe outer control is composed by the ReactivePowerControl and the ActivePowerControl types.\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"/OuterControl.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n## Active Power Controllers\n\n### Virtual Inertia\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/VirtualInertia.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Active Power Droop\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ActivePowerDroop.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Active Power PI\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ActivePowerPI.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Active Virtual Oscillator\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ActiveVirtualOscillator.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Active Renewable Controller Type AB\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ActiveRenewableControllerAB.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n## Reactive Power Controllers\n\n### Reactive Power Droop\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ReactivePowerDroop.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Reactive Power PI\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ReactivePowerPI.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Reactive Virtual Oscillator\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ReactiveVirtualOscillator.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n\n### Reactive Renewable Controller Type AB\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ReactiveRenewableControllerAB.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/renewable_generation_cost.md",
    "content": "# RenewableGenerationCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/RenewableGenerationCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/reserves.md",
    "content": "# Reserves\n\n## Constant Reserve\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ConstantReserve.jl\"]\nPublic = true\nPrivate = false\n```\n\n## Constant Reserve Group\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ConstantReserveGroup.jl\"]\nPublic = true\nPrivate = false\n```\n\n## Variable Reserve\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/VariableReserve.jl\"]\nPublic = true\nPrivate = false\n```\n\n## Reserve Demand Curve\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"generated/ReserveDemandCurve.jl\"]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/storage_cost.md",
    "content": "# StorageCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/StorageCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/model_library/thermal_generation_cost.md",
    "content": "# ThermalGenerationCost\n\n```@autodocs\nModules = [PowerSystems]\nPages   = [\"cost_functions/ThermalGenerationCost.jl\"]\nOrder = [:type, :function]\nPublic = true\nPrivate = false\n```\n"
  },
  {
    "path": "docs/src/tutorials/add_dynamic_data.jl",
    "content": "# # Adding Data for Dynamic Simulations\n# In this tutorial, we are going to add dynamic data to a power [`System`](@ref), including\n# a dynamic generator suitable for phasor-type simulations, as well as a dynamic inverter\n# and dynamic lines necessary for more complex EMT (electro-magnetic transient)\n# simulations.\n# To run a dynamic simulation in Sienna\\Dyn using\n# [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/),\n# two data layers are required:\n#  1. A base layer of [static](@ref S) components, which includes the data needed to run a\n#     power flow problem\n#  2. An additional layer of [dynamic](@ref D) components, which define differential equations\n#     to run a transient simulation\n# We'll define these two layers sequentially.\n\n# ## Defining the Static Data Layer\n# Instead of defining the static data in the [`System`](@ref) manually, we will load an existing three-bus system using\n# [`PowerSystemCaseBuilder.jl`](https://github.com/Sienna-Platform/PowerSystemCaseBuilder.jl)\n# to use as a starting point.\n# Start by importing these packages:\n\nusing PowerSystems\nusing PowerSystemCaseBuilder\nimport PowerSystems as PSY;\n\n# To create the system, load pre-existing data for a 3-bus system using\n# `PowerSystemCaseBuilder.jl`:\n\nthreebus_sys = build_system(PSIDSystems, \"3 Bus Inverter Base\")\n\n# See that there is a table of \"[Static](@ref S) Components\", which contains the\n# steady state data needed for power flow analysis, but no \"[Dynamic](@ref D)\" data\n# yet to define the differential equations for transient simulations.\n# Let's view the generators in the system with [`show_components`](@ref),\n# including which bus they are connected at:\n\nshow_components(ThermalStandard, threebus_sys, [:bus])\n\n# Notice that there are generators connected at Buses 2 and 3, but not Bus 1.\n# Now, we are going to add the data needed to run an EMT simulation.\n# We will add an infinite voltage source to Bus 1, which is the last component we\n# need to complete the static data layer. Then, we will add a dynamic\n# generator or inverter model to the two generators, as well as adding dynamic lines.\n\n# ## Add an Infinite Voltage Source\n# Add a infinite voltage source with small impedance to Bus 1 (the reference bus).\n# First, retrieve the reference bus using [`get_components`](@ref):\n\nslack_bus = first(get_components(x -> get_bustype(x) == ACBusTypes.REF, Bus, threebus_sys))\n\n# Notice we filtered by the [bus type](@ref acbustypes_list) to get the bus(es) we wanted.\n# Next, manually define a [`Source`](@ref):\n\ninf_source = Source(;\n    name = \"InfBus\", #name\n    available = true, #availability\n    active_power = 0.0,\n    reactive_power = 0.0,\n    bus = slack_bus, #bus\n    R_th = 0.0, #Rth\n    X_th = 5e-6, #Xth\n);\n\n# And add it to the system:\n\nadd_component!(threebus_sys, inf_source)\n\n# This completes the first layer of [static](@ref S) data, using components similar to those\n# we added manually in the [Create and Explore a Power `System`](@ref) tutorial.\n\n# ## Adding a Dynamic Generator\n# Now, we will connect a classic machine model to the generator at bus 102.\n# Dynamic generator devices\n# are composed by 5 components: a [Machine](@ref Machine),\n# [Shaft](@ref Shaft), [Automatic Voltage Regulator](@ref AVR) (AVR),\n# [Power System Stabilizer](@ref PSS) (PSS), and\n# [Prime Mover and Turbine Governor](@ref TurbineGov).\n# For each of those 5 components, we will select a specific model that defines the data and\n# differential equations for that component,\n# and then use those 5 components to define the complete dynamic generator.\n# ```@raw html\n# <img src=\"../../assets/gen_metamodel.png\" width=\"75%\"/>\n# ```\n# !!! note\n#     When defining dynamic data, by convention `PowerSystems.jl` assumes that all data is\n#     in [`DEVICE_BASE`](@ref per_unit).\n# First, define a [Machine](@ref Machine) that describes the stator electro-magnetic dynamics:\n\nmachine_oneDoneQ = OneDOneQMachine(;\n    R = 0.0,\n    Xd = 1.3125,\n    Xq = 1.2578,\n    Xd_p = 0.1813,\n    Xq_p = 0.25,\n    Td0_p = 5.89,\n    Tq0_p = 0.6,\n)\n\n# Notice that we selected a specific model, [`OneDOneQMachine`](@ref), with the parameters\n# tailored to a One-d-one-q dynamic machine model.\n# Next, define a specific [Shaft](@ref Shaft) model, [`SingleMass`](@ref) that describes the\n# rotor electro-mechanical dynamics:\n\nshaft_no_damping = SingleMass(;\n    H = 3.01, #(M = 6.02 -> H = M/2)\n    D = 0.0,\n)\n\n# Represent the electromotive dynamics of the AVR controller using a specific\n# [Automatic Voltage Regulator](@ref AVR) model, [`AVRTypeI`](@ref):\n\navr_type1 = AVRTypeI(; # Type I: Resembles a DC1 AVR\n    Ka = 20.0,\n    Ke = 0.01,\n    Kf = 0.063,\n    Ta = 0.2,\n    Te = 0.314,\n    Tf = 0.35,\n    Tr = 0.001,\n    Va_lim = (min = -5.0, max = 5.0),\n    Ae = 0.0039, #1st ceiling coefficient\n    Be = 1.555, #2nd ceiling coefficient\n)\n\n# Define a fixed efficiency [Prime Mover and Turbine Governor](@ref TurbineGov) with\n# [`TGFixed`](@ref):\n\ntg_none = TGFixed(; efficiency = 1.0) # No Turbine Governor\n\n# See that we are modeling a machine that does not include a Turbine Governor\n# (or PSS below), but you must define components for them to build a\n# complete machine model.\n# Similarly, define a PSS using [`PSSFixed`](@ref), which is used to describe the stabilization\n# signal for the AVR:\n\npss_none = PSSFixed(; V_pss = 0.0) # No PSS\n\n# Now, we are ready to add a dynamic generator to the static\n# generator at bus 102. First, let's get that static generator:\n\nstatic_gen = get_component(Generator, threebus_sys, \"generator-102-1\")\n\n# Notice that its `dynamic_injector` field is currently `nothing`.\n# Use its name and the 5 components above to define its [`DynamicGenerator`](@ref) model:\n\ndynamic_gen = DynamicGenerator(;\n    name = get_name(static_gen),\n    ω_ref = 1.0, # frequency reference set-point\n    machine = machine_oneDoneQ,\n    shaft = shaft_no_damping,\n    avr = avr_type1,\n    prime_mover = tg_none,\n    pss = pss_none,\n)\n\n# See that the specific component models that we selected and defined above were used to\n# specify the states needed to model this generator in a dynamic simulation.\n# Finally, use the dynamic version of [`add_component!`](@ref add_component!(\n# sys::System,\n# dyn_injector::DynamicInjection,\n# static_injector::StaticInjection;\n# kwargs...,\n# )) to add this data to the [`System`](@ref):\n\nadd_component!(threebus_sys, dynamic_gen, static_gen)\n\n# Notice that unlike static components, which are just added to the [`System`](@ref),\n# this dynamic component is added to a specific static component within the [`System`](@ref).\n# !!! tip\n#     To define identical dynamic devices for multiple generators at once, define the pieces of the\n#     generator model as *functions*, such as:\n#     ```\n#     avr_type1() = AVRTypeI(...\n#     ```\n#     When called in the [`DynamicGenerator`](@ref) constructor, this will create a new AVR for each generator, so\n#     they are different in memory. Later, if you decide to modify the AVR parameters for\n#     a specific generator, it will not modify the AVR in another generator.\n# Recall that you can print the system to see a summary of its data:\n\nthreebus_sys\n\n# See that a new table has been added: \"Dynamic Components.\"\n# Also, print the static generator to double-check the dynamic layer has been added:\n\nstatic_gen\n\n# Verify that `dynamic_injector` now contains our dynamic generator model.\n# Up to this point, you have added the dynamic data necessary to do a phaser-type simulation,\n# which focuses on machine behavior. Now we will also add dynamic inverters and lines to enable\n# EMT simulations.\n\n# ## Adding a Dynamic Inverter\n# Next we will connect a Virtual Synchronous Generator Inverter at bus 103.\n# An inverter is composed of [Converter](@ref), [OuterControl](@ref), [InnerControl](@ref),\n# [DCSource](@ref), [FrequencyEstimator](@ref), and [Filter](@ref) components:\n# ```@raw html\n# <img src=\"../../assets/inv_metamodel.png\" width=\"75%\"/>\n# ```\n# As we did for the generator, we will define each of these six components with a specific\n# model, which defines its differential equations.\n# First, define an [`AverageConverter`](@ref) as the specific model for the [Converter](@ref)\n# component:\n\nconverter_high_power() = AverageConverter(;\n    rated_voltage = 138.0,\n    rated_current = 100.0,\n)\n\n# Recall from the tip above that we can define these components as *functions* instead of\n# objects for reusability across multiple generators, and notice that that is what we have\n# done here.\n# Define [OuterControl](@ref) using [Virtual Inertia](@ref) for the active power control and\n# [ReactivePowerDroop](@ref) for the reactive power control:\n\nouter_control() = OuterControl(\n    VirtualInertia(; Ta = 2.0, kd = 400.0, kω = 20.0),\n    ReactivePowerDroop(; kq = 0.2, ωf = 1000.0),\n)\n\n# Define an [InnerControl](@ref) as a Voltage+Current Controller with Virtual Impedance,\n# using [`VoltageModeControl`](@ref):\n\ninner_control() = VoltageModeControl(;\n    kpv = 0.59,     #Voltage controller proportional gain\n    kiv = 736.0,    #Voltage controller integral gain\n    kffv = 0.0,     #Binary variable enabling voltage feed-forward in current controllers\n    rv = 0.0,       #Virtual resistance in pu\n    lv = 0.2,       #Virtual inductance in pu\n    kpc = 1.27,     #Current controller proportional gain\n    kic = 14.3,     #Current controller integral gain\n    kffi = 0.0,     #Binary variable enabling the current feed-forward in output of current controllers\n    ωad = 50.0,     #Active damping low pass filter cut-off frequency\n    kad = 0.2,      #Active damping gain\n)\n\n# Define a [`FixedDCSource`](@ref) for the [DCSource](@ref):\n\ndc_source_lv() = FixedDCSource(; voltage = 600.0)\n\n# Define a [FrequencyEstimator](@ref) as a phase-locked loop (PLL) using [`KauraPLL`](@ref):\n\npll() = KauraPLL(;\n    ω_lp = 500.0, #Cut-off frequency for LowPass filter of PLL filter.\n    kp_pll = 0.084,  #PLL proportional gain\n    ki_pll = 4.69,   #PLL integral gain\n)\n\n# Finally, define an [`LCLFilter`](@ref) for the [Filter](@ref):\n\nfilt() = LCLFilter(;\n    lf = 0.08,\n    rf = 0.003,\n    cf = 0.074,\n    lg = 0.2,\n    rg = 0.01,\n)\n\n# Now, use those six functions to define a complete dynamic inverter\n# by getting the static component at bus 103:\n\ngen_103 = get_component(Generator, threebus_sys, \"generator-103-1\");\n\n# using it and our six functions to define a [`DynamicInverter`](@ref):\n\ndynamic_inv = DynamicInverter(;\n    name = get_name(gen_103),\n    ω_ref = 1.0, # frequency reference set-point\n    converter = converter_high_power(),\n    outer_control = outer_control(),\n    inner_control = inner_control(),\n    dc_source = dc_source_lv(),\n    freq_estimator = pll(),\n    filter = filt(),\n)\n\n# and adding it to the [`System`](@ref):\n\nadd_component!(threebus_sys, dynamic_inv, gen_103)\n\n# Both generators have now been updated with dynamic data. Let's complete the [`System`](@ref)\n# updates by adding dynamic lines.\n\n# ## Adding Dynamic Lines\n# !!! warning\n#     A [`System`](@ref) must have at least two buses and one branch to run a dynamic simulation in\n#     [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/).\n# Let's review the AC branches currently in the system:\n\nget_components(ACBranch, threebus_sys)\n\n# Notice that we have three static [`Line`](@ref) components.\n# Let's also print the first line to review its format:\n\nfirst(get_components(Line, threebus_sys))\n\n# See that these components do not have the fields for dynamic modeling, such as fields for\n# different [states](@ref S).\n# Let's update that by cycling through these lines and using [`DynamicBranch`](@ref) to extend\n# each static line with the necessary fields:\n\nfor l in get_components(Line, threebus_sys)\n    ## create a dynamic branch\n    dyn_branch = DynamicBranch(l)\n    ## add dynamic branch to the system, replacing the static branch\n    add_component!(threebus_sys, dyn_branch)\nend\n\n# Take a look at the AC branches in the system again:\n\nbranches = get_components(ACBranch, threebus_sys)\n\n# Notice that now there are 3 [`DynamicBranch`](@ref) components instead of the `Line` components.\n# Let's take a look by printing the first one:\n\nfirst(branches)\n\n# Observe that this is a wrapper around the static data, with the additional states\n# data for dynamic modeling.\n# Finally, let's print the [`System`](@ref) again to summarize our additions:\n\nthreebus_sys\n\n# Verify that the additions were successful, with an added voltage [`Source`](@ref), [`DynamicBranch`](@ref)es\n# replacing the static [`Line`](@ref), and two new dynamic components with the generator and inverter models.\n\n# ## Next Steps\n# In this tutorial, you have updated a static system with a second dynamic data layer.\n# The data you added can enable a phasor-based simulation using the dynamic generator, or\n# a more complex EMT simulation with the additional dynamic inverter and dynamic lines.\n# Next, you might like to:\n#   - Read more about the static and dynamic data layers and the dynamic data format in\n#     [Dynamic Devices](@ref).\n#   - Review the specific subsystem models available in `PowerSystems.jl` for [Machine](@ref),\n#     [Shaft](@ref), [AVR](@ref), [PSS](@ref),\n#     [Prime Mover and Turbine Governor](@ref TurbineGov), [Converter](@ref),\n#     [OuterControl](@ref), [InnerControl](@ref), [DCSource](@ref),\n#     [FrequencyEstimator](@ref), and [Filter](@ref) components\n#   - Explore [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/)\n#     for dynamics modeling in Sienna\\Dyn\n"
  },
  {
    "path": "docs/src/tutorials/creating_system.jl",
    "content": "# # Create and Explore a Power `System`\n# Welcome to PowerSystems.jl!\n# In this tutorial, we will create a power system and add some components to it,\n# including some nodes, a transmission line, load, and both renewable\n# and fossil fuel generators. Then we will retrieve data from the system and explore the\n# system settings.\n\n# ## Setup\n# To get started, ensure you have followed the\n# [installation instructions](https://sienna-platform.github.io/Sienna/SiennaDocs/docs/build/how-to/install/).\n# Start Julia from the command line if you haven't already:\n# ```\n# $ julia\n# ```\n# Load the PowerSystems.jl package:\n\nusing PowerSystems\n\n# ## Creating a Power [`System`](@ref)\n# In PowerSystems.jl, data is held in a [`System`](@ref) that holds all of the individual components\n# along with some metadata about the power system itself.\n# There are many ways to define a [`System`](@ref), but let's start with an empty system.\n# All we need to define is a base power of 100 MVA for [per-unitization](@ref per_unit).\n\nsys = System(100.0)\n\n# Notice that this system is a 60 Hz system with a base power of 100 MVA.\n# Now, let's add some components to our system.\n\n# ## Adding Buses\n# We'll start by creating some buses. By referring to the documentation for\n# [ACBus](@ref), notice that we need define some basic data, including the bus's\n# unique identifier and name, base voltage, and whether it's a [load, generator,\n# or reference bus](@ref acbustypes_list).\n# Let's start with a reference bus:\n\nbus1 = ACBus(;\n    number = 1,\n    name = \"bus1\",\n    available = true,\n    bustype = ACBusTypes.REF,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.05),\n    base_voltage = 230.0,\n);\n\n# This bus is on a 230 kV AC transmission network, with an allowable voltage range of\n# 0.9 to 1.05 p.u. We are assuming it is currently operating at 1.0 p.u. voltage and\n# an angle of 0 radians. Notice that we've defined this bus as [reference bus or slack\n# bus](@ref acbustypes_list), where it will be used for balancing power flow in power\n# flow studies.\n# Let's add this bus to our [`System`](@ref) with [`add_component!`](@ref add_component!(sys::System, component::Component; kwargs...)):\n\nadd_component!(sys, bus1)\n\n# We can see the impact this has on the [`System`](@ref) simply by printing it:\n\nsys\n\n# Notice that [`System`](@ref) now shows a summary of components in the system. The table shows\n# \"[Static](@ref S) Components\", which refers to steady state data used for power\n# flow analysis or production cost modeling, as opposed to [Dynamic](@ref D) components\n# which that can be used to define differential equations for transient simulations.\n# Let's create a second bus:\n\nbus2 = ACBus(;\n    number = 2,\n    name = \"bus2\",\n    available = true,\n    bustype = ACBusTypes.PV,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.05),\n    base_voltage = 230.0,\n);\n\n# Notice that we've defined this bus with [power and voltage variables](@ref acbustypes_list),\n# suitable for power flow studies.\n# Let's also add this to our [`System`](@ref):\n\nadd_component!(sys, bus2)\n\n# Now, let's use [`show_components`](@ref) to quickly see some basic information about the buses:\n\nshow_components(sys, ACBus)\n\n# ## Adding a Transmission Line\n# Let's connect our buses. We'll add a transmission [`Line`](@ref) between `bus1` and `bus2`.\n# !!! warning\n#     When defining a line that isn't attached to a [`System`](@ref) yet, you must define the\n#     thermal rating of the transmission line in per-unit using the base power of the\n#     [`System`](@ref) you plan to connect it to -- in this case, 100 MVA.\n\nline = Line(;\n    name = \"line1\",\n    available = true,\n    active_power_flow = 0.0,\n    reactive_power_flow = 0.0,\n    arc = Arc(; from = bus1, to = bus2),\n    r = 0.00281, # Per-unit\n    x = 0.0281, # Per-unit\n    b = (from = 0.00356, to = 0.00356), # Per-unit\n    rating = 2.0, # Line rating of 200 MVA / System base of 100 MVA\n    angle_limits = (min = -0.7, max = 0.7),\n);\n\n# Note that we also had to define an [`Arc`](@ref) in the process to define the connection between\n# the two buses.\n# Let's also add this to our [`System`](@ref):\n\nadd_component!(sys, line)\n\n# Finally, let's check our [`System`](@ref) summary to see all the network topology components we have added\n# are attached:\n\nsys\n\n# ## Adding Loads and Generators\n# Now that our network topology is complete, we'll start adding components that [inject](@ref I) or\n# withdraw power from the network.\n# !!! warning\n#     When you define components that aren't attached to a [`System`](@ref) yet, you must define\n#     all fields related to power (with units such as MW, MVA, MVAR, or MW/min) in\n#     per-unit using the `base_power` of the component (with the exception of `base_power`\n#     itself, which is in MVA).\n# We'll start with defining a 10 MW [load](@ref PowerLoad) to `bus2`:\n\nload = PowerLoad(;\n    name = \"load1\",\n    available = true,\n    bus = bus2,\n    active_power = 0.5, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    base_power = 10.0, # MVA\n    max_active_power = 1.0, # 10 MW per-unitized by device base_power\n    max_reactive_power = 0.0,\n);\n\n# Notice that we defined the `max_active_power`, which is 10 MW, as 1.0 in per-unit using the\n# `base_power` of 10 MVA. We've also used the `bus2` component itself to define where this\n# load is located in the network.\n# Now add the load to the system:\n\nadd_component!(sys, load)\n\n# Finally, we'll add two generators: one renewable and one thermal.\n# We'll add a 5 MW solar power plant to `bus2`:\n\nsolar = RenewableDispatch(;\n    name = \"solar1\",\n    available = true,\n    bus = bus2,\n    active_power = 0.2, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    rating = 1.0, # 5 MW per-unitized by device base_power\n    prime_mover_type = PrimeMovers.PVe,\n    reactive_power_limits = (min = 0.0, max = 0.05), # 0 MVAR to 0.25 MVAR per-unitized by device base_power\n    power_factor = 1.0,\n    operation_cost = RenewableGenerationCost(nothing),\n    base_power = 5.0, # MVA\n);\n\n# Note that we've used a generic [renewable generator](@ref RenewableDispatch) to model\n# solar, but we can specify that it is solar through the [prime mover](@ref pm_list).\n# Finally, we'll also add a 30 MW gas [thermal generator](@ref ThermalStandard) to `bus1`\n# because a slack bus require a controllable generator component:\n\ngas = ThermalStandard(;\n    name = \"gas1\",\n    available = true,\n    status = true,\n    bus = bus1,\n    active_power = 0.0, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    rating = 1.0, # 30 MW per-unitized by device base_power\n    active_power_limits = (min = 0.2, max = 1.0), # 6 MW to 30 MW per-unitized by device base_power\n    reactive_power_limits = nothing, # Per-unitized by device base_power\n    ramp_limits = (up = 0.2, down = 0.2), # 6 MW/min up or down, per-unitized by device base_power\n    operation_cost = ThermalGenerationCost(nothing),\n    base_power = 30.0, # MVA\n    time_limits = (up = 8.0, down = 8.0), # Hours\n    must_run = false,\n    prime_mover_type = PrimeMovers.CC,\n    fuel = ThermalFuels.NATURAL_GAS,\n);\n\n# This time, let's add these components to our [`System`](@ref) using [`add_components!`](@ref)\n# to add them both at the same time:\n\nadd_components!(sys, [solar, gas])\n\n# ## Explore the System and its Components\n# Congratulations! You have built a power system including buses, a transmission line, a\n# load, and different types of generators. Now let's take a look around.\n# Remember that we can see a summary of our [`System`](@ref) using the print statement:\n\nsys\n\n# Now, let's double-check some of our data by retrieving it from the [`System`](@ref).\n# Let's use [`show_components`](@ref) again to get an overview of our renewable generators:\n\nshow_components(sys, RenewableDispatch)\n\n# We just have the one renewable generator named `solar1`. Use `get_component` to\n# retrieve it by name:\n\nretrieved_component = get_component(RenewableDispatch, sys, \"solar1\");\n\n# Let's double-check what type of renewable generator this is using a `get_` function:\n\nget_prime_mover_type(retrieved_component)\n\n# Verify that this a `PVe`, or solar photovoltaic, generator.\n# Let's also use a `get_` function to double-check where this generator is connected in the\n# transmission network:\n\nget_bus(retrieved_component)\n\n# See that the generator's bus is linked to the actual `bus2` component in our [`System`](@ref).\n# These \"getter\" functions are available for all the data fields in a component.\n# !!! tip\n#     **Always use the `get_*` functions to retrieve the data within a component.**\n#     While in Julia a user can use `.` to access the fields of a component, we make no\n#     guarantees on the stability of field names and locations. We do however promise to\n#     keep the getter functions stable. PowerSystems.jl also does many internal data\n#     calculations that the getter functions will properly handle for you, as you'll see\n#     below.\n\n# ## Changing [`System`](@ref) Per-Unit Settings\n# Now, let's use a getter function to look up the solar generator's `rating`:\n\nget_rating(retrieved_component)\n\n# !!! tip \"Important\"\n#     When we defined the solar generator, we defined the rating\n#     as 1.0 per-unit with a device `base_power` of 5.0 MVA. Notice that the rating now reads\n#     0.05. After we attached this component to our [`System`](@ref), its power data is being\n#     returned to us in the [`System`](@ref)'s units base.\n# Let's double-check the [`System`](@ref)'s units base:\n\nget_units_base(sys)\n\n# `SYSTEM_BASE` means all power-related (MW, MVA, MVAR, MW/min) component data in\n# the [`System`](@ref), except for each component's `base_power`, is per-unitized by the\n# system base power for consistency.\n# Check the [`System`](@ref)'s base_power again:\n\nget_base_power(sys)\n\n# Notice that when we called `get_rating` above, the solar generator's rating, 5.0 MW,\n# is being returned as 0.05 = (5 MVA)/(100 MVA) using the system base power.\n# Instead of using the [`System`](@ref) base power, let's view everything in MW or MVA -- or what we\n# call \"NATURAL_UNITS\" in PowerSystems.\n# Change the [`System`](@ref)'s unit system:\n\nset_units_base_system!(sys, \"NATURAL_UNITS\")\n\n# Now retrieve the solar generator's rating again:\n\nget_rating(retrieved_component)\n\n# Notice that the value is now its \"natural\" value, 5.0 MVA.\n# Finally, let's change the [`System`](@ref)'s unit system to the final option, \"DEVICE_BASE\":\n\nset_units_base_system!(sys, \"DEVICE_BASE\")\n\n# And retrieve the solar generator's rating once more:\n\nget_rating(retrieved_component)\n\n# See that now the data is now 1.0 (5.0 MVA per-unitized by the generator (i.e., the device's)\n# `base_power` of 5.0 MVA), which is the format we used to originally define the device.\n# As a shortcut to temporarily set the [`System`](@ref)'s unit system to a particular value, perform\n# some action, and then automatically set it back to what it was before, we can use\n# `with_units_base` and a [`do` block](https://docs.julialang.org/en/v1/manual/functions/#Do-Block-Syntax-for-Function-Arguments):\n\nwith_units_base(sys, \"NATURAL_UNITS\") do\n    ## Everything inside this block will run as if the unit system were NATURAL_UNITS\n    get_rating(retrieved_component)\nend\nget_units_base(sys)  # Unit system goes back to previous value when the block ends\n\n# Recall that if you ever need to check a [`System`](@ref)'s settings, including the unit system being\n# used by all the getter functions, you can always just print the [`System`](@ref):\n\nsys\n\n# See the units base is printed as one of the [`System`](@ref) properties.\n\n# ## Next Steps\n# In this tutorial, you manually created a power [`System`](@ref), added and then retrieved its components,\n# and modified the [`System`](@ref) per-unit settings.\n# Next, you might want to:\n#   - [Add time series data to components in the `System`](@ref tutorial_time_series)\n#   - [Add necessary data for dynamic simulations](@ref \"Adding Data for Dynamic Simulations\")\n#   - Import a [`System`](@ref) [from an existing Matpower or PSSE file](@ref pm_data) or\n#     [with PSSE dynamic data](@ref dyr_data) instead of creating it manually\n#   - [Create your own `System` from .csv files instead of creating it manually](@ref system_from_csv)\n#   - [Read more to understand per-unitization in PowerSystems.jl](@ref per_unit)\n#   - See a workaround for how to [Add a Component in Natural Units](@ref)\n"
  },
  {
    "path": "docs/src/tutorials/manipulating_datasets.jl",
    "content": "# # Manipulating Datasets\n# `PowerSystems` provides function interfaces to all data, and in this tutorial we will explore how to do this using the [`show_components`](@ref),\n# [`get_component`](@ref get_component(::Type{T}, sys::System, name::AbstractString) where {T <: Component})/\n# [`get_components`](@ref), and getter (`get_*`) and setter (`set_*`) functions for component fields.\n\n# ## Viewing Components in the System\n# We are going to begin by loading in a test case [`System`](@ref) from [`PowerSystemCaseBuilder.jl`](https://sienna-platform.github.io/PowerSystemCaseBuilder.jl/stable/):\n\nusing PowerSystems;\nusing PowerSystemCaseBuilder;\nsys = build_system(PSISystems, \"c_sys5_pjm\")\n\n# Notice that the print statement for the [`System`](@ref) already includes a basic\n# summary of the components, including 5 [`ThermalStandard`](@ref) components.\n# We can use the [`show_components`](@ref) function to get more details:\n\nshow_components(ThermalStandard, sys)\n\n# We can see the names and availability are the standard fields returned when using [`show_components`](@ref).\n# We can also view specific fields within components using the [`show_components`](@ref)\n# function. For example, we can view the type of `fuel` the thermal generators are using,\n# and their current `active_power` and `reactive_power` for a power flow case:\n\nshow_components(ThermalStandard, sys, [:fuel, :active_power, :reactive_power])\n\n# Notice all our thermal generators are currently fueled by coal.\n\n# ## Accessing and Updating a Component in a System\n# We can access a component in our system using the\n# [`get_component`](@ref get_component(::Type{T}, sys::System, name::AbstractString) where {T <: Component})\n# function. For example, if we are interested in accessing a [`ThermalStandard`](@ref) component we can\n# do so using the component's name and `Type` from `PowerSystems.jl`'s [Type Tree](@ref).\n# From above we know the names of the thermal generators.\n\nsolitude = get_component(ThermalStandard, sys, \"Solitude\")\n\n# Notice that all of Solitude's fields are pretty-printed with the return statement for\n# quick reference. However, what is returned is a [`ThermalStandard`](@ref) object we can\n# manipulate:\n\ntypeof(solitude)\n\n# If we are interested in accessing a particular field, we can use a `get_*` function, also known as a getter,\n# on this object. For example, if we are interested in the `fuel` we can use [`get_fuel`](@ref get_fuel(value::ThermalStandard)):\n\nget_fuel(solitude)\n\n# You can see a [`ThermalFuels`](@ref tf_list) option returned.\n# To recap, [`get_component`](@ref) will return a component object, but we can use a specific `get_*` function to return the data in a particular field.\n# !!! warning\n#     Using the \"dot\" access to get a field value from a component is actively discouraged, use `get_*` functions instead.\n#     Julia syntax enables access to this data using the \"dot\" access (e.g., `solitude.fuel`), however this is discouraged for two reasons:\n#      1. We make no guarantees on the stability of component structure definitions. We will maintain version stability on the accessor methods.\n#      2. Per-unit conversions are made in the return of data from the accessor functions. (see the [per-unit](https://sienna-platform.github.io/PowerSystems.jl/stable/explanation/per_unit/#per_unit) section for more details)\n# To update a field we can use a specific `set_*`, or setter function, which are defined for each component field.\n# We can use [`set_fuel!`](@ref set_fuel!(value::ThermalStandard, val)) to update the `fuel` field of Solitude to natural gas.\n\nset_fuel!(solitude, ThermalFuels.NATURAL_GAS)\n\n# We can use [`show_components`](@ref) again to check that the `Solitude` `fuel` has been\n# updated to [`ThermalFuels.NATURAL_GAS`](@ref tf_list):\n\nshow_components(ThermalStandard, sys, [:fuel])\n\n# Similarly, you can updated the `active_power` field using its specific `get_*` and `set_*` functions.\n# We can access this field by using [`get_active_power`](@ref get_active_power(value::ThermalStandard)):\n\nget_active_power(solitude)\n\n# We can then update it using [`set_active_power!`](@ref set_active_power!(value::ThermalStandard, val)):\n\nset_active_power!(solitude, 4.0)\n\n# We can see that our `active_power` field has been updated to 4.0.\n\n# ## Accessing and Updating Multiple Components in the System at Once\n# We can also update more than one component at a time using the [`get_components`](@ref get_components(\n# ::Type{T},\n# sys::System;\n# subsystem_name = nothing,\n# ) where {T <: Component}) and `set_*` functions.\n# Let's say we were interested in updating the `base_voltage` field for all of the [`ACBus`](@ref).\n# We can see that currently the `base_voltages` are:\n\nshow_components(ACBus, sys, [:base_voltage])\n\n# But what if we are looking to correct them to 250.0 kV?\n# Let's start by getting an iterator for all the buses using [`get_components`](@ref get_components(\n# ::Type{T},\n# sys::System;\n# subsystem_name = nothing,\n# ) where {T <: Component}):\n\nbuses = get_components(ACBus, sys)\n\n# See that the pretty-print summarizes this set of components, but let's check what was actually returned:\n\ntypeof(buses)\n\n# !!! tip\n#     Notice that [`get_components`](@ref get_components(\n#     ::Type{T},\n#     sys::System;\n#     subsystem_name = nothing,\n#     ) where {T <: Component}) and similar functions return Julia iterators, which allows you to\n#     access and manipulate data without a large memory allocation that might occur for very\n#     large data sets.\n#     Use [`collect`](https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple%7BAny%7D)\n#     to gather the data to a vector instead, but be aware of your dataset size.\n# Now using the [`set_base_voltage!`](@ref) function and a `for` loop we can update the voltage:\n\nfor i in buses\n    set_base_voltage!(i, 250.0)\nend\n\n# We could use [`show_components`](@ref) to verify the results, but this time let's use a\n# `get_*` function and Julia's dot notation over our bus iterator to get the data for\n# a specific field from multiple components:\n\nget_base_voltage.(buses)\n\n# We can see that all of the buses now have a `base_voltage` of 250.0 kV.\n# If we are interested in updating the `fuel` in all the thermal generators, we would use a similar approach. We begin by grabbing an iterator for all the components in [`ThermalStandard`](@ref).\n\nthermal_gens = get_components(ThermalStandard, sys)\n\n# Now, using the [`set_fuel!`](@ref set_fuel!(value::ThermalStandard)) and a `for` loop, we will update the `fuel` to `NATURAL_GAS`.\n\nfor i in thermal_gens\n    set_fuel!(i, ThermalFuels.NATURAL_GAS)\nend\n\n# We can verify that the `fuel` types for all the thermal generators has been updated,\n# using dot notation again to access the `fuel` fields:\n\nget_fuel.(get_components(ThermalStandard, sys))\n\n# See that we linked two functions here with Julia's dot notation -- this is a very convenient way of quickly getting the data you need.\n\n# ## Filtering Specific Data\n# We have seen how to update a single component, and all the components of a specific type, but what if we are interested in updating only particular components? We can do this using filter functions.\n# For example, let's say we are interested in updating all the `active_power` values of the thermal generators except `Solitude`.\n# Let's start by seeing the current `active_power` values.\n\nshow_components(ThermalStandard, sys, [:active_power])\n\n# Let's grab an iterator for the all the thermal generators except `Solitude` by adding a filter function\n# in another version of the [`get_components`](@ref get_components(\n# filter_func::Function,\n# ::Type{T},\n# sys::System;\n# subsystem_name = nothing,\n# ) where {T <: Component}) function defined with Julia's multiple dispatch:\n\nthermal_not_solitude = get_components(x -> get_name(x) != \"Solitude\", ThermalStandard, sys)\n\n# We can see that only four [`ThermalStandard`](@ref) components are returned, as expected.\n# Now let's update the `active_power` field of these four thermal generators using the [`set_active_power!`](@ref) function.\n\nfor i in thermal_not_solitude\n    set_active_power!(i, 0.0)\nend\n\n# Let's check the update using [`show_components`](@ref):\n\nshow_components(ThermalStandard, sys, [:active_power])\n\n# We can see that all the `active_power` values are 0.0, except `Solitude`.\n# We can filter on any component field. Similarly, let's filter all of the thermal generators\n# that now have an `active_power` of 0.0, and also set their availability to false.\n\nfor i in get_components(x -> get_active_power(x) == 0.0, ThermalStandard, sys)\n    set_available!(i, 0)\nend\n\n# ## Getting Available Components\n# The [`get_available_components`](@ref) function is a useful short-hand function with a\n# built-in filter for grabbing all the components of a particular type that are available.\n# For example, if we are interested in grabbing all the available [`ThermalStandard`](@ref):\n\nget_available_components(ThermalStandard, sys)\n\n# We only retrieved one component, because we just set the rest to unavailable above:\n\nshow_components(ThermalStandard, sys)\n\n# ## Getting Buses\n# We can retrieve the [`ACBus`](@ref) components using\n# [`get_buses`](@ref get_buses(sys::System, bus_numbers::Set{Int})),\n# by [ID number](@ref get_buses(sys::System, bus_numbers::Set{Int})) or\n# [`Area` or `LoadZone`](@ref get_buses(sys::System, aggregator::AggregationTopology)).\n# Let's begin by accessing the ID numbers associated with the [`ACBus`](@ref)\n# components using the [`get_bus_numbers`](@ref) function.\n\nget_bus_numbers(sys)\n\n# We can see that these bus IDs are numbered 1 through 5.\n# Now let's specifically grab buses 2 and 3 using the [`get_buses`](@ref) function:\n\nhigh_voltage_buses = get_buses(sys, Set(2:3))\n\n# and update their base voltage to 330 kV:\n\nfor i in high_voltage_buses\n    set_base_voltage!(i, 330.0)\nend\n\n# As usual, we can review the updated data with [`show_components`](@ref):\n\nshow_components(ACBus, sys, [:number, :base_voltage])\n\n# ## Updating Component Names\n# We can also access and update the component name field using the\n# [`get_name`](@ref get_name(value::ThermalStandard)) and\n# [set_name!](@ref set_name!(value::ThermalStandard, name::AbstractString)) functions.\n# Recall that we created an iterator called `thermal_gens` for all the thermal generators.\n# We can use the [`get_name`](@ref get_name(value::ThermalStandard)) function to access\n# the `name` field for these components with dot notation:\n\nget_name.(thermal_gens)\n\n# To update the names we will use the\n# [set_name!](@ref set_name!(value::ThermalStandard, name::AbstractString)) function.\n# !!! warning\n#     Specifically when using [set_name!](@ref set_name!(value::ThermalStandard, name::AbstractString))\n#     to modify multiple components accessed through an iterator, it is important to note that this\n#     not only changes the field `name`, but also changes the iterator itself\n#     as you are iterating over it, which will result in unexpected outcomes and errors.\n# Therefore, rather than using [set_name!](@ref set_name!(value::ThermalStandard, name::AbstractString))\n# on an iterator, only use it after first\n# calling [`collect`](https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple%7BAny%7D)\n# on the iterator to get a vector of the components:\n\nfor thermal_gen in collect(get_components(ThermalStandard, sys))\n    set_name!(sys, thermal_gen, get_name(thermal_gen) * \"-renamed\")\nend\n\n# Now we can check the names using the [`get_name`](@ref) function again.\n\nget_name.(get_components(ThermalStandard, sys))\n\n# Be aware again that accessing components through a vector using\n# [`collect`](https://docs.julialang.org/en/v1/base/collections/#Base.collect-Tuple%7BAny%7D)\n# might cause large memory allocations, based on your dataset size.\n\n# ## Next Steps & Links\n# In this tutorial, we explored a dataset using [`show_components`](@ref) to summarize data\n# and accessed particular groups of components with [`get_components`](@ref get_components(\n# ::Type{T},\n# sys::System;\n# subsystem_name = nothing,\n# ) where {T <: Component}), [`get_buses`](@ref get_buses(sys::System, bus_numbers::Set{Int})),\n# and [`get_available_components`](@ref).\n# We used specific `get_*` functions and `set_*` functions to see and update the fields in\n# [`ThermalStandard`](@ref) and [`ACBus`](@ref) components, but remember that these getters\n# and setters are available for each data field for components of all Types in `PowerSystems.jl`.\n# Follow the next tutorials to learn how to [work with time series](@ref tutorial_time_series).\n"
  },
  {
    "path": "docs/src/tutorials/tutorials_data/RTS-GMLC.RAW",
    "content": " 0,    100.00, 33, 0, 0, 60.00       / November 07, 2017 19:41:38; Simulator Version 19; BuildDate 2017_9_5\n\n\n  101,'ABEL        ', 138.0000,2,   1,  11,   1,1.04777002,  -7.741520, 1.10000, 0.90000, 1.10000, 0.90000\n  102,'ADAMS       ', 138.0000,2,   1,  12,   1,1.04782999,  -7.817840, 1.10000, 0.90000, 1.10000, 0.90000\n  103,'ADLER       ', 138.0000,2,   1,  11,   1,1.01084995,  -7.210900, 1.10000, 0.90000, 1.10000, 0.90000\n  104,'AGRICOLA    ', 138.0000,2,   1,  11,   1,1.01765001, -10.566140, 1.10000, 0.90000, 1.10000, 0.90000\n  105,'AIKEN       ', 138.0000,1,   1,  11,   1,1.03568006, -10.708870, 1.10000, 0.90000, 1.10000, 0.90000\n  106,'ALBER       ', 138.0000,1,   1,  12,   1,1.03242004, -13.279440, 1.10000, 0.90000, 1.10000, 0.90000\n  107,'ALDER       ', 138.0000,2,   1,  12,   1,1.03744996, -11.276730, 1.10000, 0.90000, 1.10000, 0.90000\n  108,'ALGER       ', 138.0000,1,   1,  12,   1,1.01023996, -13.749670, 1.10000, 0.90000, 1.10000, 0.90000\n  109,'ALI         ', 138.0000,1,   1,  13,   1,1.02610004,  -8.815240, 1.10000, 0.90000, 1.10000, 0.90000\n  110,'ALLEN       ', 138.0000,1,   1,  13,   1,1.04999995, -10.620630, 1.10000, 0.90000, 1.10000, 0.90000\n  111,'ANNA        ', 230.0000,1,   1,  13,   1,1.02763999,  -3.916740, 1.10000, 0.90000, 1.10000, 0.90000\n  112,'ARCHER      ', 230.0000,1,   1,  13,   1,1.02023995,  -2.424240, 1.10000, 0.90000, 1.10000, 0.90000\n  113,'ARNE        ', 230.0000,3,   1,  14,   1,1.03470004,   0.000000, 1.10000, 0.90000, 1.10000, 0.90000\n  114,'ARNOLD      ', 230.0000,2,   1,  16,   1,1.04401004,  -1.730560, 1.10000, 0.90000, 1.10000, 0.90000\n  115,'ARTHUR      ', 230.0000,2,   1,  16,   1,1.04334998,   7.959700, 1.10000, 0.90000, 1.10000, 0.90000\n  116,'ASSER       ', 230.0000,2,   1,  16,   1,1.04565001,   7.569290, 1.10000, 0.90000, 1.10000, 0.90000\n  117,'ASTON       ', 230.0000,1,   1,  17,   1,1.04782999,  11.434170, 1.10000, 0.90000, 1.10000, 0.90000\n  118,'ASTOR       ', 230.0000,2,   1,  17,   1,1.04999995,  12.524570, 1.10000, 0.90000, 1.10000, 0.90000\n  119,'ATTAR       ', 230.0000,2,   1,  15,   1,1.03962004,   6.657770, 1.10000, 0.90000, 1.10000, 0.90000\n  120,'ATTILA      ', 230.0000,1,   1,  15,   1,1.04399002,   7.740600, 1.10000, 0.90000, 1.10000, 0.90000\n  121,'ATTLEE      ', 230.0000,2,   1,  17,   1,1.04999995,  13.086530, 1.10000, 0.90000, 1.10000, 0.90000\n  122,'AUBREY      ', 230.0000,2,   1,  17,   1,1.04999995,  18.949779, 1.10000, 0.90000, 1.10000, 0.90000\n  123,'AUSTEN      ', 230.0000,2,   1,  15,   1,1.04999995,   9.056170, 1.10000, 0.90000, 1.10000, 0.90000\n  124,'AVERY       ', 230.0000,1,   1,  16,   1,1.01154995,   2.383390, 1.10000, 0.90000, 1.10000, 0.90000\n  201,'BACH        ', 138.0000,2,   2,  21,   1,1.04841006, -10.689730, 1.10000, 0.90000, 1.10000, 0.90000\n  202,'BACON       ', 138.0000,2,   2,  22,   1,1.04843998, -10.759060, 1.10000, 0.90000, 1.10000, 0.90000\n  203,'BAFFIN      ', 138.0000,1,   2,  21,   1,1.01885998, -10.474530, 1.10000, 0.90000, 1.10000, 0.90000\n  204,'BAILEY      ', 138.0000,1,   2,  21,   1,1.01890004, -13.484790, 1.10000, 0.90000, 1.10000, 0.90000\n  205,'BAIN        ', 138.0000,1,   2,  21,   1,1.03603005, -13.611870, 1.10000, 0.90000, 1.10000, 0.90000\n  206,'BAJER       ', 138.0000,1,   2,  22,   1,1.03259003, -16.156720, 1.10000, 0.90000, 1.10000, 0.90000\n  207,'BAKER       ', 138.0000,2,   2,  22,   1,1.03972995, -13.466060, 1.10000, 0.90000, 1.10000, 0.90000\n  208,'BALCH       ', 138.0000,1,   2,  22,   1,1.01203001, -16.223590, 1.10000, 0.90000, 1.10000, 0.90000\n  209,'BALZAC      ', 138.0000,1,   2,  23,   1,1.02780998, -11.724090, 1.10000, 0.90000, 1.10000, 0.90000\n  210,'BANKS       ', 138.0000,1,   2,  23,   1,1.04999995, -13.479860, 1.10000, 0.90000, 1.10000, 0.90000\n  211,'BARDEEN     ', 230.0000,1,   2,  23,   1,1.02734995,  -6.933360, 1.10000, 0.90000, 1.10000, 0.90000\n  212,'BARKLA      ', 230.0000,2,   2,  23,   1,1.01920998,  -5.253340, 1.10000, 0.90000, 1.10000, 0.90000\n  213,'BARLOW      ', 230.0000,2,   2,  24,   1,1.03752005,  -3.215100, 1.10000, 0.90000, 1.10000, 0.90000\n  214,'BARRY       ', 230.0000,2,   2,  26,   1,1.04334998,  -4.685190, 1.10000, 0.90000, 1.10000, 0.90000\n  215,'BARTON      ', 230.0000,2,   2,  26,   1,1.04326999,   4.633510, 1.10000, 0.90000, 1.10000, 0.90000\n  216,'BASOV       ', 230.0000,2,   2,  26,   1,1.04556000,   4.700090, 1.10000, 0.90000, 1.10000, 0.90000\n  217,'BATES       ', 230.0000,1,   2,  27,   1,1.04847002,   8.818390, 1.10000, 0.90000, 1.10000, 0.90000\n  218,'BAYLE       ', 230.0000,2,   2,  27,   1,1.04999995,   9.994730, 1.10000, 0.90000, 1.10000, 0.90000\n  219,'BEDE        ', 230.0000,1,   2,  25,   1,1.03945994,   4.212330, 1.10000, 0.90000, 1.10000, 0.90000\n  220,'BEETHOVEN   ', 230.0000,1,   2,  25,   1,1.04380000,   5.664490, 1.10000, 0.90000, 1.10000, 0.90000\n  221,'BEHRING     ', 230.0000,2,   2,  27,   1,1.04999995,  10.632090, 1.10000, 0.90000, 1.10000, 0.90000\n  222,'BELL        ', 230.0000,2,   2,  27,   1,1.04999995,  16.432030, 1.10000, 0.90000, 1.10000, 0.90000\n  223,'BLOCH       ', 230.0000,2,   2,  25,   1,1.04999995,   7.181510, 1.10000, 0.90000, 1.10000, 0.90000\n  224,'BORDET      ', 230.0000,1,   2,  26,   1,1.01455998,  -0.960050, 1.10000, 0.90000, 1.10000, 0.90000\n  301,'CABELL      ', 138.0000,2,   3,  31,   1,1.04859996,  -9.348210, 1.10000, 0.90000, 1.10000, 0.90000\n  302,'CABOT       ', 138.0000,2,   3,  32,   1,1.04864001,  -9.431000, 1.10000, 0.90000, 1.10000, 0.90000\n  303,'CAESAR      ', 138.0000,2,   3,  31,   1,1.01045001,  -8.576890, 1.10000, 0.90000, 1.10000, 0.90000\n  304,'CAINE       ', 138.0000,1,   3,  31,   1,1.01785004, -12.187840, 1.10000, 0.90000, 1.10000, 0.90000\n  305,'CALVIN      ', 138.0000,1,   3,  31,   1,1.03609002, -12.350050, 1.10000, 0.90000, 1.10000, 0.90000\n  306,'CAMUS       ', 138.0000,1,   3,  32,   1,1.03260005, -14.942050, 1.10000, 0.90000, 1.10000, 0.90000\n  307,'CAREW       ', 138.0000,2,   3,  32,   1,1.03804004, -12.547950, 1.10000, 0.90000, 1.10000, 0.90000\n  308,'CARREL      ', 138.0000,2,   3,  32,   1,1.01056004, -15.182870, 1.10000, 0.90000, 1.10000, 0.90000\n  309,'CARTER      ', 138.0000,2,   3,  33,   1,1.02578998, -10.446170, 1.10000, 0.90000, 1.10000, 0.90000\n  310,'CARUSO      ', 138.0000,2,   3,  33,   1,1.04999995, -12.301170, 1.10000, 0.90000, 1.10000, 0.90000\n  311,'CARY        ', 230.0000,1,   3,  33,   1,1.02830005,  -5.740690, 1.10000, 0.90000, 1.10000, 0.90000\n  312,'CAXTON      ', 230.0000,2,   3,  33,   1,1.01900005,  -4.146040, 1.10000, 0.90000, 1.10000, 0.90000\n  313,'CECIL       ', 230.0000,2,   3,  34,   1,1.03802001,  -2.415130, 1.10000, 0.90000, 1.10000, 0.90000\n  314,'CHAIN       ', 230.0000,2,   3,  36,   1,1.04630995,  -3.207930, 1.10000, 0.90000, 1.10000, 0.90000\n  315,'CHASE       ', 230.0000,2,   3,  36,   1,1.04299998,   7.050880, 1.10000, 0.90000, 1.10000, 0.90000\n  316,'CHIFA       ', 230.0000,2,   3,  36,   1,1.04558003,   6.598750, 1.10000, 0.90000, 1.10000, 0.90000\n  317,'CHUHSI      ', 230.0000,2,   3,  37,   1,1.04785001,  10.344180, 1.10000, 0.90000, 1.10000, 0.90000\n  318,'CLARK       ', 230.0000,2,   3,  37,   1,1.04999995,  11.342620, 1.10000, 0.90000, 1.10000, 0.90000\n  319,'CLAY        ', 230.0000,2,   3,  35,   1,1.03953004,   5.915390, 1.10000, 0.90000, 1.10000, 0.90000\n  320,'CLIVE       ', 230.0000,2,   3,  35,   1,1.04389000,   7.197090, 1.10000, 0.90000, 1.10000, 0.90000\n  321,'COBB        ', 230.0000,2,   3,  37,   1,1.04999995,  12.341220, 1.10000, 0.90000, 1.10000, 0.90000\n  322,'COLE        ', 230.0000,2,   3,  37,   1,1.04999995,  18.069141, 1.10000, 0.90000, 1.10000, 0.90000\n  323,'COMTE       ', 230.0000,2,   3,  35,   1,1.04999995,   8.621120, 1.10000, 0.90000, 1.10000, 0.90000\n  324,'CURIE       ', 230.0000,2,   3,  36,   1,1.01046002,   1.306060, 1.10000, 0.90000, 1.10000, 0.90000\n  325,'CURTISS     ', 230.0000,1,   3,  35,   1,1.04986000,   8.993320, 1.10000, 0.90000, 1.10000, 0.90000\n0 / END OF BUS DATA, BEGIN LOAD DATA\n  101,'1 ',1,   1,   1,   108.000,    22.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  102,'1 ',1,   1,   1,    97.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  103,'1 ',1,   1,   1,   180.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  104,'1 ',1,   1,   1,    74.000,    15.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  105,'1 ',1,   1,   1,    71.000,    14.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  106,'1 ',1,   1,   1,   136.000,    28.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  107,'1 ',1,   1,   1,   125.000,    25.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  108,'1 ',1,   1,   1,   171.000,    35.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  109,'1 ',1,   1,   1,   175.000,    36.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  110,'1 ',1,   1,   1,   195.000,    40.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  113,'1 ',1,   1,   1,   265.000,    54.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  114,'1 ',1,   1,   1,   194.000,    39.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  115,'1 ',1,   1,   1,   317.000,    64.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  116,'1 ',1,   1,   1,   100.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  118,'1 ',1,   1,   1,   333.000,    68.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  119,'1 ',1,   1,   1,   181.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  120,'1 ',1,   1,   1,   128.000,    26.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  201,'1 ',1,   2,   1,   108.000,    22.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  202,'1 ',1,   2,   1,    97.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  203,'1 ',1,   2,   1,   180.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  204,'1 ',1,   2,   1,    74.000,    15.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  205,'1 ',1,   2,   1,    71.000,    14.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  206,'1 ',1,   2,   1,   136.000,    28.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  207,'1 ',1,   2,   1,   125.000,    25.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  208,'1 ',1,   2,   1,   171.000,    35.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  209,'1 ',1,   2,   1,   175.000,    36.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  210,'1 ',1,   2,   1,   195.000,    40.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  213,'1 ',1,   2,   1,   265.000,    54.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  214,'1 ',1,   2,   1,   194.000,    39.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  215,'1 ',1,   2,   1,   317.000,    64.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  216,'1 ',1,   2,   1,   100.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  218,'1 ',1,   2,   1,   333.000,    68.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  219,'1 ',1,   2,   1,   181.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  220,'1 ',1,   2,   1,   128.000,    26.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  301,'1 ',1,   3,   1,   108.000,    22.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  302,'1 ',1,   3,   1,    97.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  303,'1 ',1,   3,   1,   180.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  304,'1 ',1,   3,   1,    74.000,    15.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  305,'1 ',1,   3,   1,    71.000,    14.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  306,'1 ',1,   3,   1,   136.000,    28.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  307,'1 ',1,   3,   1,   125.000,    25.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  308,'1 ',1,   3,   1,   171.000,    35.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  309,'1 ',1,   3,   1,   175.000,    36.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  310,'1 ',1,   3,   1,   195.000,    40.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  313,'1 ',1,   3,   1,   265.000,    54.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  314,'1 ',1,   3,   1,   194.000,    39.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  315,'1 ',1,   3,   1,   317.000,    64.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  316,'1 ',1,   3,   1,   100.000,    20.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  318,'1 ',1,   3,   1,   333.000,    68.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  319,'1 ',1,   3,   1,   181.000,    37.000,     0.000,     0.000,     0.000,     0.000,   1,1\n  320,'1 ',1,   3,   1,   128.000,    26.000,     0.000,     0.000,     0.000,     0.000,   1,1\n0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA\n0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA\n  101,'1 ',     8.000,     4.960,    10.000,     0.000,1.04680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'2 ',     8.000,     4.960,    10.000,     0.000,1.04680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'3 ',    76.000,     0.140,    30.000,   -25.000,1.04680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'4 ',    76.000,     0.140,    30.000,   -25.000,1.04680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    25.900,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    26.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'7 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    26.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  101,'8 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    25.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'1 ',     8.000,     4.880,    10.000,     0.000,1.04670,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'2 ',     8.000,     4.880,    10.000,     0.000,1.04670,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'3 ',    76.000,    -2.310,    30.000,   -25.000,1.04670,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'4 ',    76.000,    -2.310,    30.000,   -25.000,1.04670,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    25.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  102,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    25.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  103,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    61.500,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  104,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    26.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  107,'1 ',   355.000,    49.510,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'1 ',    55.000,    19.000,    19.000,   -15.000,1.03470,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'2 ',    55.000,    19.000,    19.000,   -15.000,1.03470,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'3 ',    55.000,    19.000,    19.000,   -15.000,1.03470,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'4 ',    55.000,    19.000,    19.000,   -15.000,1.03470,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    93.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  113,'DC',     0.000,     0.000,     0.000,     0.000,1.03470,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,     0.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  114,'1 ',     0.000,   103.320,   200.000,   -50.000,1.04410,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,     0.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  115,'1 ',     5.000,     6.000,     6.000,     0.000,1.04280,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  115,'2 ',     5.000,     6.000,     6.000,     0.000,1.04280,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  115,'3 ',   155.000,    80.000,    80.000,   -50.000,1.04280,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  116,'1 ',   155.000,    80.000,    80.000,   -50.000,1.04610,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'1 ',   355.000,    68.430,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'3 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'4 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.400,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'7 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'8 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    11.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'9 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    11.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'A ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    10.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  118,'B ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     4.500,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  119,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    66.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  121,'1 ',   400.000,   -21.870,   200.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   400.000,   396.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'1 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'2 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'3 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'4 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'5 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'6 ',    50.000,    -6.790,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  122,'7 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   713.500,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  123,'1 ',   155.000,    -5.190,    80.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  123,'2 ',   350.000,    28.410,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   350.000,   140.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  123,'3 ',    55.000,     0.620,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  123,'4 ',    55.000,     0.620,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  123,'5 ',    55.000,     0.620,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  201,'1 ',     8.000,     5.290,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  201,'2 ',     8.000,     5.290,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  201,'3 ',    76.000,     6.990,    30.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  201,'4 ',    50.000,     4.150,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  202,'1 ',     8.000,     5.130,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  202,'2 ',     8.000,     5.130,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  202,'3 ',    76.000,     2.010,    30.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  202,'4 ',    76.000,     2.010,    30.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    76.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  207,'1 ',    55.000,    19.000,    19.000,   -15.000,0.96990,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  207,'2 ',    55.000,    19.000,    19.000,   -15.000,0.96990,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  212,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   200.000,    30.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  213,'1 ',   355.000,   135.800,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  213,'2 ',    55.000,     9.230,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  213,'3 ',    55.000,     9.230,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  213,'4 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    13.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  214,'1 ',     0.000,   125.280,   200.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,     0.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'1 ',    55.000,    19.000,    19.000,   -15.000,1.04370,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'2 ',    55.000,    19.000,    19.000,   -15.000,1.04370,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'3 ',    50.000,    16.000,    16.000,   -10.000,1.04370,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'4 ',    50.000,    16.000,    16.000,   -10.000,1.04370,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'5 ',    50.000,    16.000,    16.000,   -10.000,1.04370,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  215,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   125.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  216,'1 ',   155.000,    80.000,    80.000,   -50.000,1.04730,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  218,'1 ',   355.000,    60.300,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  221,'1 ',   296.970,    -7.520,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'1 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'2 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'3 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'4 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'5 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  222,'6 ',    50.000,    -6.970,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'1 ',   155.000,   -10.310,    80.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'2 ',   155.000,   -10.310,    80.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'3 ',   350.000,    20.590,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   350.000,   140.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'4 ',    22.000,     0.240,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'5 ',    22.000,     0.240,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  223,'6 ',    22.000,     0.240,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  301,'1 ',     8.000,     7.950,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  301,'2 ',     8.000,     7.950,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  301,'3 ',    44.000,    16.530,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  301,'4 ',    44.000,    16.530,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  302,'1 ',     8.000,     6.160,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  302,'2 ',     8.000,     6.160,    10.000,     0.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    20.000,     8.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  302,'3 ',    55.000,    10.990,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  302,'4 ',    55.000,    10.990,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  303,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   847.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  307,'1 ',    55.000,    19.000,    19.000,   -15.000,0.95680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  307,'2 ',    55.000,    19.000,    19.000,   -15.000,0.95680,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  308,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   100.900,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  309,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   148.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  310,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  310,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  312,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    94.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'1 ',   355.000,   150.000,   150.000,   -25.000,1.03500,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    95.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'3 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    93.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'4 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   101.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    63.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    65.400,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'7 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    67.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'8 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    64.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'9 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    63.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'A ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    64.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'B ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    66.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'C ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    62.400,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'D ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    66.900,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'E ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    65.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'F ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    27.800,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'G ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    27.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  313,'H ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  314,'1 ',     0.000,   166.630,   200.000,   -50.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,     0.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  314,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  314,'3 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  314,'4 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    92.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  314,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'1 ',     5.000,     6.000,     6.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'2 ',     5.000,     6.000,     6.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'3 ',     5.000,     6.000,     6.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'4 ',     5.000,     6.000,     6.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'5 ',     5.000,     6.000,     6.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    12.000,     5.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'6 ',    55.000,    19.000,    19.000,   -15.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'7 ',    55.000,    19.000,    19.000,   -15.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  315,'8 ',    55.000,    60.000,    60.000,     0.000,1.04220,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  316,'1 ',   155.000,    80.000,    80.000,   -50.000,1.04490,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   155.000,    62.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  316,'DC',     0.000,     0.000,     0.000,     0.000,1.04490,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,     0.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  317,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   799.100,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  318,'1 ',   355.000,    63.120,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  319,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,   188.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    27.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'3 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    27.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'4 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    28.300,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'5 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    27.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'6 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    28.200,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  320,'7 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,     9.400,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  321,'1 ',   355.000,    -3.340,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'1 ',    55.000,    -9.730,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'2 ',    55.000,    -9.730,    19.000,   -15.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    55.000,    22.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'3 ',    50.000,    -5.130,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'4 ',    50.000,    -5.130,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'5 ',    50.000,    -5.130,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  322,'6 ',    50.000,    -5.130,    16.000,   -10.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,    50.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  323,'1 ',   355.000,    37.410,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  323,'2 ',   355.000,    37.410,   150.000,   -25.000,1.05000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,1,  100.0,   355.000,   170.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  324,'1 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    49.700,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  324,'2 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.600,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n  324,'3 ',     0.000,     0.000,     0.000,     0.000,1.00000,    0,   100.000,   0.00000,   1.00000,   0.00000,   0.00000,1.00000,0,  100.0,    51.000,     0.000,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,0, 1.0000\n0 / END OF GENERATOR DATA, BEGIN BRANCH DATA\n   101,   102,'1 ',3.00000E-3,1.40000E-2,4.61000E-1, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1,  3.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   101,   103,'1 ',5.50000E-2,2.11000E-1,5.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 55.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   101,   105,'1 ',2.20000E-2,8.50000E-2,2.30000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 22.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   102,   104,'1 ',3.30000E-2,1.27000E-1,3.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   102,   106,'1 ',5.00000E-2,1.92000E-1,5.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 50.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   103,   109,'1 ',3.10000E-2,1.19000E-1,3.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 31.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   104,   109,'1 ',2.70000E-2,1.04000E-1,2.80000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   105,   110,'1 ',2.30000E-2,8.80000E-2,2.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 23.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   106,   110,'1 ',1.40000E-2,6.10000E-2,2.45900E-0, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   107,   108,'1 ',1.60000E-2,6.10000E-2,1.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   107,   203,'1 ',4.20000E-2,1.61000E-1,4.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 42.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   108,   109,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   108,   110,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   111,   113,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   111,   114,'1 ',5.00000E-3,4.20000E-2,8.80000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 29.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   112,   113,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   112,   123,'1 ',1.20000E-2,9.70000E-2,2.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 67.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   113,   123,'1 ',1.10000E-2,8.70000E-2,1.82000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 60.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   113,   215,'1 ',1.00000E-2,7.50000E-2,1.58000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 52.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   114,   116,'1 ',5.00000E-3,5.90000E-2,8.20000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   115,   116,'1 ',2.00000E-3,1.70000E-2,3.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 12.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   115,   121,'1 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   115,   121,'2 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   115,   124,'1 ',7.00000E-3,5.20000E-2,1.09000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 36.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   116,   117,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   116,   119,'1 ',3.00000E-3,2.30000E-2,4.90000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   117,   118,'1 ',2.00000E-3,1.40000E-2,3.00000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 10.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   117,   122,'1 ',1.40000E-2,1.05000E-1,2.21000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 73.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   118,   121,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   118,   121,'2 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   119,   120,'1 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   119,   120,'2 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   120,   123,'1 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   120,   123,'2 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   121,   122,'1 ',9.00000E-3,6.80000E-2,1.42000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 47.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   123,   217,'1 ',1.00000E-2,7.40000E-2,1.55000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 51.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   201,   202,'1 ',3.00000E-3,1.40000E-2,4.61000E-1, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1,  3.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   201,   203,'1 ',5.50000E-2,2.11000E-1,5.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 55.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   201,   205,'1 ',2.20000E-2,8.50000E-2,2.30000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 22.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   202,   204,'1 ',3.30000E-2,1.27000E-1,3.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   202,   206,'1 ',5.00000E-2,1.92000E-1,5.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 50.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   203,   209,'1 ',3.10000E-2,1.19000E-1,3.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 31.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   204,   209,'1 ',2.70000E-2,1.04000E-1,2.80000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   205,   210,'1 ',2.30000E-2,8.80000E-2,2.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 23.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   206,   210,'1 ',1.40000E-2,6.10000E-2,2.45900E-0, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   207,   208,'1 ',1.60000E-2,6.10000E-2,1.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   208,   209,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   208,   210,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   211,   213,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   211,   214,'1 ',5.00000E-3,4.20000E-2,8.80000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 29.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   212,   213,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   212,   223,'1 ',1.20000E-2,9.70000E-2,2.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 67.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   213,   223,'1 ',1.10000E-2,8.70000E-2,1.82000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 60.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   214,   216,'1 ',5.00000E-3,5.90000E-2,8.20000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   215,   216,'1 ',2.00000E-3,1.70000E-2,3.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 12.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   215,   221,'1 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   215,   221,'2 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   215,   224,'1 ',7.00000E-3,5.20000E-2,1.09000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 36.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   216,   217,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   216,   219,'1 ',3.00000E-3,2.30000E-2,4.90000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   217,   218,'1 ',2.00000E-3,1.40000E-2,3.00000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 10.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   217,   222,'1 ',1.40000E-2,1.05000E-1,2.21000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 73.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   218,   221,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   218,   221,'2 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   219,   220,'1 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   219,   220,'2 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   220,   223,'1 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   220,   223,'2 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   221,   222,'1 ',9.00000E-3,6.80000E-2,1.42000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 47.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   301,   302,'1 ',3.00000E-3,1.40000E-2,4.61000E-1, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1,  3.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   301,   303,'1 ',5.50000E-2,2.11000E-1,5.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 55.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   301,   305,'1 ',2.20000E-2,8.50000E-2,2.30000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 22.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   302,   304,'1 ',3.30000E-2,1.27000E-1,3.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   302,   306,'1 ',5.00000E-2,1.92000E-1,5.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 50.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   303,   309,'1 ',3.10000E-2,1.19000E-1,3.20000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 31.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   304,   309,'1 ',2.70000E-2,1.04000E-1,2.80000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   305,   310,'1 ',2.30000E-2,8.80000E-2,2.40000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 23.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   306,   310,'1 ',1.40000E-2,6.10000E-2,2.45900E-0, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   307,   308,'1 ',1.60000E-2,6.10000E-2,1.70000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   308,   309,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   308,   310,'1 ',4.30000E-2,1.65000E-1,4.50000E-2, 175.00, 175.00, 175.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 43.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   311,   313,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   311,   314,'1 ',5.00000E-3,4.20000E-2,8.80000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 29.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   312,   313,'1 ',6.00000E-3,4.80000E-2,1.00000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 33.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   312,   323,'1 ',1.20000E-2,9.70000E-2,2.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 67.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   313,   323,'1 ',1.10000E-2,8.70000E-2,1.82000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 60.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   314,   316,'1 ',5.00000E-3,5.90000E-2,8.20000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   315,   316,'1 ',2.00000E-3,1.70000E-2,3.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 12.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   315,   321,'1 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   315,   321,'2 ',6.00000E-3,4.90000E-2,1.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 34.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   315,   324,'1 ',7.00000E-3,5.20000E-2,1.09000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 36.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   316,   317,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   316,   319,'1 ',3.00000E-3,2.30000E-2,4.90000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 16.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   317,   318,'1 ',2.00000E-3,1.40000E-2,3.00000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 10.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   317,   322,'1 ',1.40000E-2,1.05000E-1,2.21000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 73.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   318,   223,'1 ',1.30000E-2,1.04000E-1,2.18000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 72.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   318,   321,'1 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   318,   321,'2 ',3.00000E-3,2.60000E-2,5.50000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 18.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   319,   320,'1 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   319,   320,'2 ',5.00000E-3,4.00000E-2,8.30000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 27.50,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   320,   323,'1 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   320,   323,'2 ',3.00000E-3,2.20000E-2,4.60000E-2, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 15.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   321,   322,'1 ',9.00000E-3,6.80000E-2,1.42000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 47.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   323,   325,'1 ',1.00000E-7,9.00000E-3,0.00000E-0, 722.00, 722.00, 722.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1,  0.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n   325,   121,'1 ',1.20000E-2,9.70000E-2,2.03000E-1, 500.00, 500.00, 500.00,  0.00000,  0.00000,  0.00000,  0.00000,1,1, 67.00,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000\n0 / END OF BRANCH DATA, BEGIN TRANSFORMER DATA\n   103,   124,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   109,   111,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   109,   112,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   110,   111,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   110,   112,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   203,   224,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   209,   211,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   209,   212,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   210,   211,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   210,   212,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   303,   324,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   309,   311,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   309,   312,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.030000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   310,   311,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n   310,   312,    0,'1 ',1,1,1,0.00000E0,0.00000E0,2,'            ',1,   1,1.0000,   0,1.0000,   0,1.0000,   0,1.0000,'            '\n2.00000E-3,8.40000E-2, 100.00\n1.015000,138.000,   0.000, 400.00, 400.00, 400.00,-1,     0,1.500000,0.510000,1.500000,0.510000,159, 0, 0.00000, 0.00000,  0.000\n1.000000,230.000\n0 / END OF TRANSFORMER DATA, BEGIN AREA DATA\n   1,    0,     0.000,     1.000,'1           '\n   2,    0,     0.000,     1.000,'2           '\n   3,    0,     0.000,     1.000,'3           '\n0 / END OF AREA DATA, BEGIN TWO-TERMINAL DC DATA\n0 / END OF TWO-TERMINAL DC DATA, BEGIN VOLTAGE SOURCE CONVERTER DATA\n0 / END OF VOLTAGE SOURCE CONVERTER DATA, BEGIN IMPEDANCE CORRECTION DATA\n0 / END OF IMPEDANCE CORRECTION DATA, BEGIN MULTI-TERMINAL DC DATA\n0 / END OF MULTI-TERMINAL DC DATA, BEGIN MULTI-SECTION LINE DATA\n0 / END OF MULTI-SECTION LINE DATA, BEGIN ZONE DATA\n   1,'1       '\n  11,'11      '\n  12,'12      '\n  13,'13      '\n  14,'14      '\n  15,'15      '\n  16,'16      '\n  17,'17      '\n  21,'21      '\n  22,'22      '\n  23,'23      '\n  24,'24      '\n  25,'25      '\n  26,'26      '\n  27,'27      '\n  31,'31      '\n  32,'32      '\n  33,'33      '\n  34,'34      '\n  35,'35      '\n  36,'36      '\n  37,'37      '\n0 / END OF ZONE DATA, BEGIN INTER-AREA TRANSFER DATA\n0 / END OF INTER-AREA TRANSFER DATA, BEGIN OWNER DATA\n    1,'1'\n0 / END OF OWNER DATA, BEGIN FACTS CONTROL DEVICE DATA\n0 / END OF FACTS CONTROL DEVICE DATA, BEGIN SWITCHED SHUNT DATA\n  106,0,0,1,1.05000,0.95000,    0,100.0,'        ', -100.00, 1,-100.00\n  206,0,0,1,1.05000,0.95000,    0,100.0,'        ', -100.00, 1,-100.00\n  306,0,0,1,1.05000,0.95000,    0,100.0,'        ', -100.00, 1,-100.00\n0 /END OF SWITCHED SHUNT DATA, BEGIN GNE DEVICE DATA\n0 /END OF GNE DEVICE DATA\nQ"
  },
  {
    "path": "docs/src/tutorials/tutorials_data/RTS_GMLC.m",
    "content": "function mpc = RTS_GMLC\n\n    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% RTS-GMLC Test Case %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n    %%%%%%%%%%%%%%% By: Clayton Barrows, Ali Ehlen, Matt O Connell, %%%%%%%%%%%%%%%%\n    %%%%%%%%%% Dheepak Krishnamurthy, Brendan McBennett, and Aaron Bloom %%%%%%%%%%%\n    %%%%%%%%%%%%%%%%%%% National Renewable Energy Lab, Golden CO %%%%%%%%%%%%%%%%%%%\n    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n    \n    %% MATPOWER Case Format : Version 2\n    mpc.version = '2';\n    \n    %%-----  Power Flow Data  -----%%\n    %% system MVA base\n    mpc.baseMVA = 100.0;\n    \n    %% area data\n    % area refbus\n    mpc.areas = [\n            1    101;\n            2    201;\n            3    301;\n                ];\n    \n    %% bus data\n    %\tbus_i\ttype\tPd\tQd\tGs\tBs\tarea\tVm\tVa\tbaseKV\tzone\tVmax\tVmin\n    mpc.bus = [\n        101\t2\t108.0\t22.0\t0.0\t0.0\t1\t1.04777\t-7.74152\t138.0\t11\t1.05\t0.95\n        102\t2\t97.0\t20.0\t0.0\t0.0\t1\t1.04783\t-7.81784\t138.0\t12\t1.05\t0.95\n        103\t1\t180.0\t37.0\t0.0\t0.0\t1\t1.01085\t-7.21090\t138.0\t11\t1.05\t0.95\n        104\t1\t74.0\t15.0\t0.0\t0.0\t1\t1.01765\t-10.56614\t138.0\t11\t1.05\t0.95\n        105\t1\t71.0\t14.0\t0.0\t0.0\t1\t1.03568\t-10.70887\t138.0\t11\t1.05\t0.95\n        106\t1\t136.0\t28.0\t0.0\t-100.0\t1\t1.03242\t-13.27944\t138.0\t12\t1.05\t0.95\n        107\t2\t125.0\t25.0\t0.0\t0.0\t1\t1.03745\t-11.27673\t138.0\t12\t1.05\t0.95\n        108\t1\t171.0\t35.0\t0.0\t0.0\t1\t1.01024\t-13.74967\t138.0\t12\t1.05\t0.95\n        109\t1\t175.0\t36.0\t0.0\t0.0\t1\t1.02610\t-8.81524\t138.0\t13\t1.05\t0.95\n        110\t1\t195.0\t40.0\t0.0\t0.0\t1\t1.05000\t-10.62063\t138.0\t13\t1.05\t0.95\n        111\t1\t0.0\t0.0\t0.0\t0.0\t1\t1.02764\t-3.91674\t230.0\t13\t1.05\t0.95\n        112\t1\t0.0\t0.0\t0.0\t0.0\t1\t1.02024\t-2.42424\t230.0\t13\t1.05\t0.95\n        113\t3\t265.0\t54.0\t0.0\t0.0\t1\t1.03943\t0.00000\t230.0\t14\t1.05\t0.95\n        114\t2\t194.0\t39.0\t0.0\t0.0\t1\t1.04401\t-1.73056\t230.0\t16\t1.05\t0.95\n        115\t2\t317.0\t64.0\t0.0\t0.0\t1\t1.04335\t7.95970\t230.0\t16\t1.05\t0.95\n        116\t2\t100.0\t20.0\t0.0\t0.0\t1\t1.04565\t7.56929\t230.0\t16\t1.05\t0.95\n        117\t1\t0.0\t0.0\t0.0\t0.0\t1\t1.04783\t11.43417\t230.0\t17\t1.05\t0.95\n        118\t2\t333.0\t68.0\t0.0\t0.0\t1\t1.05000\t12.52457\t230.0\t17\t1.05\t0.95\n        119\t1\t181.0\t37.0\t0.0\t0.0\t1\t1.03962\t6.65777\t230.0\t15\t1.05\t0.95\n        120\t1\t128.0\t26.0\t0.0\t0.0\t1\t1.04399\t7.74060\t230.0\t15\t1.05\t0.95\n        121\t2\t0.0\t0.0\t0.0\t0.0\t1\t1.05000\t13.08653\t230.0\t17\t1.05\t0.95\n        122\t2\t0.0\t0.0\t0.0\t0.0\t1\t1.05000\t18.94978\t230.0\t17\t1.05\t0.95\n        123\t2\t0.0\t0.0\t0.0\t0.0\t1\t1.05000\t9.05617\t230.0\t15\t1.05\t0.95\n        124\t1\t0.0\t0.0\t0.0\t0.0\t1\t1.01155\t2.38339\t230.0\t16\t1.05\t0.95\n        201\t2\t108.0\t22.0\t0.0\t0.0\t2\t1.04841\t-10.68973\t138.0\t21\t1.05\t0.95\n        202\t2\t97.0\t20.0\t0.0\t0.0\t2\t1.04844\t-10.75906\t138.0\t22\t1.05\t0.95\n        203\t1\t180.0\t37.0\t0.0\t0.0\t2\t1.01886\t-10.47453\t138.0\t21\t1.05\t0.95\n        204\t1\t74.0\t15.0\t0.0\t0.0\t2\t1.01890\t-13.48479\t138.0\t21\t1.05\t0.95\n        205\t1\t71.0\t14.0\t0.0\t0.0\t2\t1.03603\t-13.61187\t138.0\t21\t1.05\t0.95\n        206\t1\t136.0\t28.0\t0.0\t-100.0\t2\t1.03259\t-16.15672\t138.0\t22\t1.05\t0.95\n        207\t2\t125.0\t25.0\t0.0\t0.0\t2\t1.03973\t-13.46606\t138.0\t22\t1.05\t0.95\n        208\t1\t171.0\t35.0\t0.0\t0.0\t2\t1.01203\t-16.22359\t138.0\t22\t1.05\t0.95\n        209\t1\t175.0\t36.0\t0.0\t0.0\t2\t1.02781\t-11.72409\t138.0\t23\t1.05\t0.95\n        210\t1\t195.0\t40.0\t0.0\t0.0\t2\t1.05000\t-13.47986\t138.0\t23\t1.05\t0.95\n        211\t1\t0.0\t0.0\t0.0\t0.0\t2\t1.02735\t-6.93336\t230.0\t23\t1.05\t0.95\n        212\t1\t0.0\t0.0\t0.0\t0.0\t2\t1.01921\t-5.25334\t230.0\t23\t1.05\t0.95\n        213\t2\t265.0\t54.0\t0.0\t0.0\t2\t1.03752\t-3.21510\t230.0\t24\t1.05\t0.95\n        214\t2\t194.0\t39.0\t0.0\t0.0\t2\t1.04335\t-4.68519\t230.0\t26\t1.05\t0.95\n        215\t2\t317.0\t64.0\t0.0\t0.0\t2\t1.04327\t4.63351\t230.0\t26\t1.05\t0.95\n        216\t2\t100.0\t20.0\t0.0\t0.0\t2\t1.04556\t4.70009\t230.0\t26\t1.05\t0.95\n        217\t1\t0.0\t0.0\t0.0\t0.0\t2\t1.04847\t8.81839\t230.0\t27\t1.05\t0.95\n        218\t2\t333.0\t68.0\t0.0\t0.0\t2\t1.05000\t9.99473\t230.0\t27\t1.05\t0.95\n        219\t1\t181.0\t37.0\t0.0\t0.0\t2\t1.03946\t4.21233\t230.0\t25\t1.05\t0.95\n        220\t1\t128.0\t26.0\t0.0\t0.0\t2\t1.04380\t5.66449\t230.0\t25\t1.05\t0.95\n        221\t2\t0.0\t0.0\t0.0\t0.0\t2\t1.05000\t10.63209\t230.0\t27\t1.05\t0.95\n        222\t2\t0.0\t0.0\t0.0\t0.0\t2\t1.05000\t16.43203\t230.0\t27\t1.05\t0.95\n        223\t2\t0.0\t0.0\t0.0\t0.0\t2\t1.05000\t7.18151\t230.0\t25\t1.05\t0.95\n        224\t1\t0.0\t0.0\t0.0\t0.0\t2\t1.01456\t-0.96005\t230.0\t26\t1.05\t0.95\n        301\t2\t108.0\t22.0\t0.0\t0.0\t3\t1.04860\t-9.34821\t138.0\t31\t1.05\t0.95\n        302\t2\t97.0\t20.0\t0.0\t0.0\t3\t1.04864\t-9.43100\t138.0\t32\t1.05\t0.95\n        303\t1\t180.0\t37.0\t0.0\t0.0\t3\t1.01045\t-8.57689\t138.0\t31\t1.05\t0.95\n        304\t1\t74.0\t15.0\t0.0\t0.0\t3\t1.01785\t-12.18784\t138.0\t31\t1.05\t0.95\n        305\t1\t71.0\t14.0\t0.0\t0.0\t3\t1.03609\t-12.35005\t138.0\t31\t1.05\t0.95\n        306\t1\t136.0\t28.0\t0.0\t-100.0\t3\t1.03260\t-14.94205\t138.0\t32\t1.05\t0.95\n        307\t2\t125.0\t25.0\t0.0\t0.0\t3\t1.03804\t-12.54795\t138.0\t32\t1.05\t0.95\n        308\t1\t171.0\t35.0\t0.0\t0.0\t3\t1.01056\t-15.18287\t138.0\t32\t1.05\t0.95\n        309\t1\t175.0\t36.0\t0.0\t0.0\t3\t1.02579\t-10.44617\t138.0\t33\t1.05\t0.95\n        310\t1\t195.0\t40.0\t0.0\t0.0\t3\t1.05000\t-12.30117\t138.0\t33\t1.05\t0.95\n        311\t1\t0.0\t0.0\t0.0\t0.0\t3\t1.02830\t-5.74069\t230.0\t33\t1.05\t0.95\n        312\t1\t0.0\t0.0\t0.0\t0.0\t3\t1.01900\t-4.14604\t230.0\t33\t1.05\t0.95\n        313\t2\t265.0\t54.0\t0.0\t0.0\t3\t1.03802\t-2.41513\t230.0\t34\t1.05\t0.95\n        314\t2\t194.0\t39.0\t0.0\t0.0\t3\t1.04631\t-3.20793\t230.0\t36\t1.05\t0.95\n        315\t2\t317.0\t64.0\t0.0\t0.0\t3\t1.04300\t7.05088\t230.0\t36\t1.05\t0.95\n        316\t2\t100.0\t20.0\t0.0\t0.0\t3\t1.04558\t6.59875\t230.0\t36\t1.05\t0.95\n        317\t1\t0.0\t0.0\t0.0\t0.0\t3\t1.04785\t10.34418\t230.0\t37\t1.05\t0.95\n        318\t2\t333.0\t68.0\t0.0\t0.0\t3\t1.05000\t11.34262\t230.0\t37\t1.05\t0.95\n        319\t1\t181.0\t37.0\t0.0\t0.0\t3\t1.03953\t5.91539\t230.0\t35\t1.05\t0.95\n        320\t1\t128.0\t26.0\t0.0\t0.0\t3\t1.04389\t7.19709\t230.0\t35\t1.05\t0.95\n        321\t2\t0.0\t0.0\t0.0\t0.0\t3\t1.05000\t12.34122\t230.0\t37\t1.05\t0.95\n        322\t2\t0.0\t0.0\t0.0\t0.0\t3\t1.05000\t18.06914\t230.0\t37\t1.05\t0.95\n        323\t2\t0.0\t0.0\t0.0\t0.0\t3\t1.05000\t8.62112\t230.0\t35\t1.05\t0.95\n        324\t1\t0.0\t0.0\t0.0\t0.0\t3\t1.01046\t1.30606\t230.0\t36\t1.05\t0.95\n        325\t1\t0.0\t0.0\t0.0\t0.0\t3\t1.04986\t8.99332\t230.0\t35\t1.05\t0.95\n    ];\n    \n    %% generator data\n    %\tbus\tPg\tQg\tQmax\tQmin\tVg\tmBase\tstatus\tPmax\tPmin\tPc1\tPc2\tQc1min\tQc1max\tQc2min\tQc2max\tramp_agc\tramp_10\tramp_30\tramp_q\tapf\n    mpc.gen = [\n        101\t8.0\t4.96\t10\t0\t1.04680\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        101\t8.0\t4.96\t10\t0\t1.04680\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        101\t76.0\t0.14\t30\t-25\t1.04680\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        101\t76.0\t0.14\t30\t-25\t1.04680\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        102\t8.0\t4.88\t10\t0\t1.04670\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        102\t8.0\t4.88\t10\t0\t1.04670\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        102\t76.0\t-2.31\t30\t-25\t1.04670\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        102\t76.0\t-2.31\t30\t-25\t1.04670\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        107\t355.0\t49.51\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        113\t55.0\t19.0\t19\t-15\t1.03470\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        113\t55.0\t19.0\t19\t-15\t1.03470\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        113\t55.0\t19.0\t19\t-15\t1.03470\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        113\t55.0\t19.0\t19\t-15\t1.03470\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        115\t5.0\t6.0\t6\t0\t1.04280\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        115\t5.0\t6.0\t6\t0\t1.04280\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        115\t155.0\t80.0\t80\t-50\t1.04280\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        116\t155.0\t80.0\t80\t-50\t1.04610\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        118\t355.0\t68.43\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        123\t155.0\t-5.19\t80\t-50\t1.05000\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        123\t350.0\t28.41\t150\t-25\t1.05000\t100.0\t1\t350.0\t140\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.0\t4.0\t4.0\t4.0\t0.0\n        123\t55.0\t0.62\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        123\t55.0\t0.62\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        123\t55.0\t0.62\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        201\t8.0\t5.29\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        201\t8.0\t5.29\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        201\t76.0\t6.99\t30\t-25\t1.05000\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        202\t8.0\t5.13\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        202\t8.0\t5.13\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        202\t76.0\t2.01\t30\t-25\t1.05000\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        202\t76.0\t2.01\t30\t-25\t1.05000\t100.0\t1\t76.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t2.0\t2.0\t2.0\t2.0\t0.0\n        207\t55.0\t19.0\t19\t-15\t0.96990\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        207\t55.0\t19.0\t19\t-15\t0.96990\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        213\t355.0\t135.8\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        213\t55.0\t9.23\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        213\t55.0\t9.23\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        215\t55.0\t19.0\t19\t-15\t1.04370\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        215\t55.0\t19.0\t19\t-15\t1.04370\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        216\t155.0\t80.0\t80\t-50\t1.04730\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        218\t355.0\t60.3\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        221\t296.97\t-7.52\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        223\t155.0\t-10.31\t80\t-50\t1.05000\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        223\t155.0\t-10.31\t80\t-50\t1.05000\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        223\t350.0\t20.59\t150\t-25\t1.05000\t100.0\t1\t350.0\t140\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.0\t4.0\t4.0\t4.0\t0.0\n        223\t22.0\t0.24\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        223\t22.0\t0.24\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        223\t22.0\t0.24\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        301\t8.0\t7.95\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        301\t8.0\t7.95\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        301\t44.0\t16.53\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        301\t44.0\t16.53\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        302\t8.0\t6.16\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        302\t8.0\t6.16\t10\t0\t1.05000\t100.0\t1\t20.0\t8\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        302\t55.0\t10.99\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        302\t55.0\t10.99\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        307\t55.0\t19.0\t19\t-15\t0.95680\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        307\t55.0\t19.0\t19\t-15\t0.95680\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        313\t355.0\t150.0\t150\t-25\t1.00000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        315\t5.0\t6.0\t6\t0\t1.04220\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        315\t5.0\t6.0\t6\t0\t1.04220\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        315\t5.0\t6.0\t6\t0\t1.04220\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        315\t5.0\t6.0\t6\t0\t1.04220\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        315\t5.0\t6.0\t6\t0\t1.04220\t100.0\t1\t12.0\t5\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t1.0\t1.0\t1.0\t1.0\t0.0\n        315\t55.0\t19.0\t19\t-15\t1.04220\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        315\t55.0\t19.0\t19\t-15\t1.04220\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        315\t55.0\t60.0\t60\t0\t1.04220\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        316\t155.0\t80.0\t80\t-50\t1.04490\t100.0\t1\t155.0\t62\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.0\t3.0\t3.0\t3.0\t0.0\n        318\t355.0\t63.12\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        321\t355.0\t-3.34\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        322\t55.0\t-9.73\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        322\t55.0\t-9.73\t19\t-15\t1.05000\t100.0\t1\t55.0\t22\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t3.7\t3.7\t3.7\t3.7\t0.0\n        323\t355.0\t37.41\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        323\t355.0\t37.41\t150\t-25\t1.05000\t100.0\t1\t355.0\t170\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.14\t4.14\t4.14\t4.14\t0.0\n        114\t0.0\t103.32\t200\t-50\t1.04410\t100.0\t1\t0.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n        121\t400.0\t-21.87\t200\t-50\t1.05000\t100.0\t1\t400.0\t396\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t20.0\t20.0\t20.0\t20.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        122\t50.0\t-6.79\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        201\t50.0\t4.15\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        214\t0.0\t125.28\t200\t-50\t1.05000\t100.0\t1\t0.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n        215\t50.0\t16.0\t16\t-10\t1.04370\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        215\t50.0\t16.0\t16\t-10\t1.04370\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        215\t50.0\t16.0\t16\t-10\t1.04370\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        222\t50.0\t-6.97\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        314\t0.0\t166.63\t200\t-50\t1.00000\t100.0\t1\t0.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\n        322\t50.0\t-5.13\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        322\t50.0\t-5.13\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        322\t50.0\t-5.13\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        322\t50.0\t-5.13\t16\t-10\t1.05000\t100.0\t1\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        314\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        314\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t95.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t95.1\t95.1\t95.1\t95.1\t0.0\n        314\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t92.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t92.7\t92.7\t92.7\t92.7\t0.0\n        314\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t93.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t93.3\t93.3\t93.3\t93.3\t0.0\n        310\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.7\t51.7\t51.7\t51.7\t0.0\n        324\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t49.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t49.7\t49.7\t49.7\t49.7\t0.0\n        312\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t94.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t94.1\t94.1\t94.1\t94.1\t0.0\n        310\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        324\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.6\t51.6\t51.6\t51.6\t0.0\n        324\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t51.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t51.0\t51.0\t51.0\t51.0\t0.0\n        113\t0.0\t0.0\t0\t0\t1.03470\t100.0\t0\t93.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t93.6\t93.6\t93.6\t93.6\t0.0\n        319\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t188.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t188.2\t188.2\t188.2\t188.2\t0.0\n        215\t0.0\t0.0\t0\t0\t1.04370 100.0\t0\t125.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t125.1\t125.1\t125.1\t125.1\t0.0\n        102\t0.0\t0.0\t0\t0\t1.04670\t100.0\t0\t25.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t25.6\t25.6\t25.6\t25.6\t0.0\n        101\t0.0\t0.0\t0\t0\t1.04680\t100.0\t0\t25.9\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t25.9\t25.9\t25.9\t25.9\t0.0\n        102\t0.0\t0.0\t0\t0\t1.04670\t100.0\t0\t25.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t25.3\t25.3\t25.3\t25.3\t0.0\n        104\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t26.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t26.8\t26.8\t26.8\t26.8\t0.0\n        212\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t200.0\t30\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t20.0\t20.0\t20.0\t20.0\t0.0\n        101\t0.0\t0.0\t0\t0\t1.04680\t100.0\t0\t26.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t26.7\t26.7\t26.7\t26.7\t0.0\n        101\t0.0\t0.0\t0\t0\t1.04680\t100.0\t0\t26.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t26.2\t26.2\t26.2\t26.2\t0.0\n        101\t0.0\t0.0\t0\t0\t1.04680\t100.0\t0\t25.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t25.8\t25.8\t25.8\t25.8\t0.0\n        103\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t61.5\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t61.5\t61.5\t61.5\t61.5\t0.0\n        119\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t66.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t66.6\t66.6\t66.6\t66.6\t0.0\n        308\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t100.9\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t100.9\t100.9\t100.9\t100.9\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t101.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t101.7\t101.7\t101.7\t101.7\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t63.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t63.1\t63.1\t63.1\t63.1\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t65.4\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t65.4\t65.4\t65.4\t65.4\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t67.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t67.0\t67.0\t67.0\t67.0\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t64.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t64.8\t64.8\t64.8\t64.8\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t63.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t63.8\t63.8\t63.8\t63.8\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t64.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t64.1\t64.1\t64.1\t64.1\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t66.6\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t66.6\t66.6\t66.6\t66.6\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t62.4\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t62.4\t62.4\t62.4\t62.4\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t66.9\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t66.9\t66.9\t66.9\t66.9\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t65.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t65.2\t65.2\t65.2\t65.2\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t27.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t27.8\t27.8\t27.8\t27.8\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t27.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t27.3\t27.3\t27.3\t27.3\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t27.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t27.0\t27.0\t27.0\t27.0\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t28.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t28.3\t28.3\t28.3\t28.3\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t27.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t27.2\t27.2\t27.2\t27.2\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t27.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t27.0\t27.0\t27.0\t27.0\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t28.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t28.2\t28.2\t28.2\t28.2\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.3\t9.3\t9.3\t9.3\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.7\t9.7\t9.7\t9.7\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.4\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.4\t9.4\t9.4\t9.4\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.1\t9.1\t9.1\t9.1\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.1\t9.1\t9.1\t9.1\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.7\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.7\t9.7\t9.7\t9.7\t0.0\n        320\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t9.4\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t9.4\t9.4\t9.4\t9.4\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t11.8\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t11.8\t11.8\t11.8\t11.8\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t11.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t11.2\t11.2\t11.2\t11.2\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t10.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t10.3\t10.3\t10.3\t10.3\t0.0\n        118\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t4.5\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t4.5\t4.5\t4.5\t4.5\t0.0\n        213\t0.0\t0.0\t0\t0\t1.05000\t100.0\t0\t13.2\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t13.2\t13.2\t13.2\t13.2\t0.0\n        309\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t148.3\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t148.3\t148.3\t148.3\t148.3\t0.0\n        317\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t799.1\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t799.1\t799.1\t799.1\t799.1\t0.0\n        303\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t847.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t847.0\t847.0\t847.0\t847.0\t0.0\n        122\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t713.5\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t713.5\t713.5\t713.5\t713.5\t0.0\n        313\t0.0\t0.0\t0\t0\t1.00000\t100.0\t0\t50.0\t0\t0.0\t0.0\t0.0\t0.0\t0.0\t0.0\t50.0\t50.0\t50.0\t50.0\t0.0\n    ];\n    \n    %% branch data\n    %\tfbus\ttbus\tr\tx\tb\trateA\trateB\trateC\tratio\tangle\tstatus\tangmin\tangmax\n    mpc.branch = [\n        101\t102\t0.00300\t0.01400\t0.46100\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        101\t103\t0.05500\t0.21100\t0.05700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        101\t105\t0.02200\t0.08500\t0.02300\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        102\t104\t0.03300\t0.12700\t0.03400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        102\t106\t0.05000\t0.19200\t0.05200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        103\t109\t0.03100\t0.11900\t0.03200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        103\t124\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        104\t109\t0.02700\t0.10400\t0.02800\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        105\t110\t0.02300\t0.08800\t0.02400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        106\t110\t0.01400\t0.06100\t2.45900\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        107\t108\t0.01600\t0.06100\t0.01700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        107\t203\t0.04200\t0.16100\t0.04400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        108\t109\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        108\t110\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        109\t111\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        109\t112\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        110\t111\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        110\t112\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        111\t113\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        111\t114\t0.00500\t0.04200\t0.08800\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        112\t113\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        112\t123\t0.01200\t0.09700\t0.20300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        113\t123\t0.01100\t0.08700\t0.18200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        113\t215\t0.01000\t0.07500\t0.15800\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        114\t116\t0.00500\t0.05900\t0.08200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        115\t116\t0.00200\t0.01700\t0.03600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        115\t121\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        115\t121\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        115\t124\t0.00700\t0.05200\t0.10900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        116\t117\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        116\t119\t0.00300\t0.02300\t0.04900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        117\t118\t0.00200\t0.01400\t0.03000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        117\t122\t0.01400\t0.10500\t0.22100\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        118\t121\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        118\t121\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        119\t120\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        119\t120\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        120\t123\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        120\t123\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        121\t122\t0.00900\t0.06800\t0.14200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        123\t217\t0.01000\t0.07400\t0.15500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        201\t202\t0.00300\t0.01400\t0.46100\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        201\t203\t0.05500\t0.21100\t0.05700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        201\t205\t0.02200\t0.08500\t0.02300\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        202\t204\t0.03300\t0.12700\t0.03400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        202\t206\t0.05000\t0.19200\t0.05200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        203\t209\t0.03100\t0.11900\t0.03200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        203\t224\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        204\t209\t0.02700\t0.10400\t0.02800\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        205\t210\t0.02300\t0.08800\t0.02400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        206\t210\t0.01400\t0.06100\t2.45900\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        207\t208\t0.01600\t0.06100\t0.01700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        208\t209\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        208\t210\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        209\t211\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        209\t212\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        210\t211\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        210\t212\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        211\t213\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        211\t214\t0.00500\t0.04200\t0.08800\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        212\t213\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        212\t223\t0.01200\t0.09700\t0.20300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        213\t223\t0.01100\t0.08700\t0.18200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        214\t216\t0.00500\t0.05900\t0.08200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        215\t216\t0.00200\t0.01700\t0.03600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        215\t221\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        215\t221\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        215\t224\t0.00700\t0.05200\t0.10900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        216\t217\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        216\t219\t0.00300\t0.02300\t0.04900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        217\t218\t0.00200\t0.01400\t0.03000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        217\t222\t0.01400\t0.10500\t0.22100\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        218\t221\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        218\t221\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        219\t220\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        219\t220\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        220\t223\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        220\t223\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        221\t222\t0.00900\t0.06800\t0.14200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        301\t302\t0.00300\t0.01400\t0.46100\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        301\t303\t0.05500\t0.21100\t0.05700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        301\t305\t0.02200\t0.08500\t0.02300\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        302\t304\t0.03300\t0.12700\t0.03400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        302\t306\t0.05000\t0.19200\t0.05200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        303\t309\t0.03100\t0.11900\t0.03200\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        303\t324\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        304\t309\t0.02700\t0.10400\t0.02800\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        305\t310\t0.02300\t0.08800\t0.02400\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        306\t310\t0.01400\t0.06100\t2.45900\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        307\t308\t0.01600\t0.06100\t0.01700\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        308\t309\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        308\t310\t0.04300\t0.16500\t0.04500\t175\t175\t175\t0.0\t0.0\t1\t-90\t90\n        309\t311\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        309\t312\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.03\t0.0\t1\t-90\t90\n        310\t311\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        310\t312\t0.00200\t0.08400\t0.00000\t400\t400\t400\t1.015\t0.0\t1\t-90\t90\n        311\t313\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        311\t314\t0.00500\t0.04200\t0.08800\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        312\t313\t0.00600\t0.04800\t0.10000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        312\t323\t0.01200\t0.09700\t0.20300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        313\t323\t0.01100\t0.08700\t0.18200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        314\t316\t0.00500\t0.05900\t0.08200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        315\t316\t0.00200\t0.01700\t0.03600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        315\t321\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        315\t321\t0.00600\t0.04900\t0.10300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        315\t324\t0.00700\t0.05200\t0.10900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        316\t317\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        316\t319\t0.00300\t0.02300\t0.04900\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        317\t318\t0.00200\t0.01400\t0.03000\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        317\t322\t0.01400\t0.10500\t0.22100\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        318\t321\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        318\t321\t0.00300\t0.02600\t0.05500\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        319\t320\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        319\t320\t0.00500\t0.04000\t0.08300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        320\t323\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        320\t323\t0.00300\t0.02200\t0.04600\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        321\t322\t0.00900\t0.06800\t0.14200\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        325\t121\t0.01200\t0.09700\t0.20300\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        318\t223\t0.01300\t0.10400\t0.21800\t500\t500\t500\t0.0\t0.0\t1\t-90\t90\n        323\t325\t0.00000\t0.00900\t0.00000\t722\t722\t722\t1.0\t0.0\t1\t-90\t90\n    ];\n    \n    %%-----  OPF Data  -----%%\n    %% generator cost data\n    %   1   startup shutdown    n   x1  y1  ... xn  yn\n    %   2   startup shutdown    n   c(n-1)  ... c0\n    mpc.gencost = [\n        1\t51.74700\t51.74700\t4\t8.00000\t1085.77625\t12.00000\t1477.23196\t16.00000\t1869.51562\t20.00000\t2298.06357\n        1\t51.74700\t51.74700\t4\t8.00000\t1085.77625\t12.00000\t1477.23196\t16.00000\t1869.51562\t20.00000\t2298.06357\n        1\t11172.01435\t11172.01435\t4\t30.00000\t841.57942\t45.33333\t1059.17805\t60.66667\t1319.40176\t76.00000\t1596.51343\n        1\t11172.01435\t11172.01435\t4\t30.00000\t841.57942\t45.33333\t1059.17805\t60.66667\t1319.40176\t76.00000\t1596.51343\n        1\t51.74700\t51.74700\t4\t8.00000\t1212.03893\t12.00000\t1567.93410\t16.00000\t1946.59795\t20.00000\t2344.92565\n        1\t51.74700\t51.74700\t4\t8.00000\t1212.03893\t12.00000\t1567.93410\t16.00000\t1946.59795\t20.00000\t2344.92565\n        1\t11172.01435\t11172.01435\t4\t30.00000\t735.09774\t45.33333\t1018.20610\t60.66667\t1337.84562\t76.00000\t1683.09260\n        1\t11172.01435\t11172.01435\t4\t30.00000\t735.09774\t45.33333\t1018.20610\t60.66667\t1337.84562\t76.00000\t1683.09260\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4772.49548\t231.66667\t6203.57553\t293.33333\t7855.66994\t355.00000\t9738.36720\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t703.75920\t703.75920\t4\t5.00000\t897.29298\t7.33333\t1187.80064\t9.66667\t1479.58817\t12.00000\t1791.41904\n        1\t703.75920\t703.75920\t4\t5.00000\t897.29298\t7.33333\t1187.80064\t9.66667\t1479.58817\t12.00000\t1791.41904\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1500.19723\t93.00000\t2132.59734\t124.00000\t2829.87580\t155.00000\t3668.44490\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1735.06998\t93.00000\t2345.31970\t124.00000\t3011.01092\t155.00000\t3751.14842\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4795.62444\t231.66667\t6187.87116\t293.33333\t7899.41412\t355.00000\t9901.24820\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1437.41596\t93.00000\t2039.73610\t124.00000\t2751.75964\t155.00000\t3775.85462\n        1\t36749.81356\t36749.81356\t4\t140.00000\t3582.87481\t210.00000\t4981.72313\t280.00000\t6497.03117\t350.00000\t8137.67767\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1088.22724\t33.00000\t1377.15264\t44.00000\t1704.98911\t55.00000\t2046.97895\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1088.22724\t33.00000\t1377.15264\t44.00000\t1704.98911\t55.00000\t2046.97895\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1088.22724\t33.00000\t1377.15264\t44.00000\t1704.98911\t55.00000\t2046.97895\n        1\t51.74700\t51.74700\t4\t8.00000\t1157.22851\t12.00000\t1487.12598\t16.00000\t1822.73633\t20.00000\t2269.08525\n        1\t51.74700\t51.74700\t4\t8.00000\t1157.22851\t12.00000\t1487.12598\t16.00000\t1822.73633\t20.00000\t2269.08525\n        1\t11172.01435\t11172.01435\t4\t30.00000\t823.75848\t45.33333\t1163.94880\t60.66667\t1523.42575\t76.00000\t1918.39660\n        1\t51.74700\t51.74700\t4\t8.00000\t1131.23082\t12.00000\t1455.62241\t16.00000\t1805.10095\t20.00000\t2196.47386\n        1\t51.74700\t51.74700\t4\t8.00000\t1131.23082\t12.00000\t1455.62241\t16.00000\t1805.10095\t20.00000\t2196.47386\n        1\t11172.01435\t11172.01435\t4\t30.00000\t751.26977\t45.33333\t1075.05834\t60.66667\t1401.47249\t76.00000\t1819.68454\n        1\t11172.01435\t11172.01435\t4\t30.00000\t751.26977\t45.33333\t1075.05834\t60.66667\t1401.47249\t76.00000\t1819.68454\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1116.10638\t33.00000\t1492.56031\t44.00000\t1897.96238\t55.00000\t2366.39182\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1116.10638\t33.00000\t1492.56031\t44.00000\t1897.96238\t55.00000\t2366.39182\n        1\t28046.68102\t28046.68102\t4\t170.00000\t5170.31357\t231.66667\t6688.64875\t293.33333\t8361.59810\t355.00000\t10458.83751\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1122.43477\t33.00000\t1417.43201\t44.00000\t1742.48912\t55.00000\t2075.88432\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1216.84757\t33.00000\t1501.96739\t44.00000\t1800.72745\t55.00000\t2160.80453\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1216.84757\t33.00000\t1501.96739\t44.00000\t1800.72745\t55.00000\t2160.80453\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1426.14416\t93.00000\t2001.92316\t124.00000\t2679.08278\t155.00000\t3412.47031\n        1\t28046.68102\t28046.68102\t4\t170.00000\t7523.51994\t231.66667\t8815.08767\t293.33333\t10151.48151\t355.00000\t11987.19523\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4551.11830\t231.66667\t5977.40411\t293.33333\t7600.73310\t355.00000\t9828.37578\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1422.99854\t93.00000\t2013.06389\t124.00000\t2623.44468\t155.00000\t3256.43459\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1422.99854\t93.00000\t2013.06389\t124.00000\t2623.44468\t155.00000\t3256.43459\n        1\t36749.81356\t36749.81356\t4\t140.00000\t3323.31912\t210.00000\t4643.59043\t280.00000\t6258.48853\t350.00000\t7981.70748\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1692.75992\t33.00000\t2103.03655\t44.00000\t2540.25162\t55.00000\t2996.75119\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1692.75992\t33.00000\t2103.03655\t44.00000\t2540.25162\t55.00000\t2996.75119\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1692.75992\t33.00000\t2103.03655\t44.00000\t2540.25162\t55.00000\t2996.75119\n        1\t51.74700\t51.74700\t4\t8.00000\t1208.23035\t12.00000\t1557.25352\t16.00000\t1956.03660\t20.00000\t2377.50557\n        1\t51.74700\t51.74700\t4\t8.00000\t1208.23035\t12.00000\t1557.25352\t16.00000\t1956.03660\t20.00000\t2377.50557\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1119.44162\t33.00000\t1432.61161\t44.00000\t1754.76108\t55.00000\t2235.93283\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1119.44162\t33.00000\t1432.61161\t44.00000\t1754.76108\t55.00000\t2235.93283\n        1\t51.74700\t51.74700\t4\t8.00000\t1208.23035\t12.00000\t1557.25352\t16.00000\t1956.03660\t20.00000\t2377.50557\n        1\t51.74700\t51.74700\t4\t8.00000\t1208.23035\t12.00000\t1557.25352\t16.00000\t1956.03660\t20.00000\t2377.50557\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1316.56254\t33.00000\t1688.27018\t44.00000\t2110.47669\t55.00000\t2535.46257\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1316.56254\t33.00000\t1688.27018\t44.00000\t2110.47669\t55.00000\t2535.46257\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1141.93307\t33.00000\t1448.77467\t44.00000\t1770.19723\t55.00000\t2160.41970\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1141.93307\t33.00000\t1448.77467\t44.00000\t1770.19723\t55.00000\t2160.41970\n        1\t28046.68102\t28046.68102\t4\t170.00000\t5243.00459\t231.66667\t6213.11865\t293.33333\t7863.05566\t355.00000\t9944.47408\n        1\t703.75920\t703.75920\t4\t5.00000\t745.67427\t7.33333\t921.69342\t9.66667\t1155.95898\t12.00000\t1445.52485\n        1\t703.75920\t703.75920\t4\t5.00000\t745.67427\t7.33333\t921.69342\t9.66667\t1155.95898\t12.00000\t1445.52485\n        1\t703.75920\t703.75920\t4\t5.00000\t745.67427\t7.33333\t921.69342\t9.66667\t1155.95898\t12.00000\t1445.52485\n        1\t703.75920\t703.75920\t4\t5.00000\t745.67427\t7.33333\t921.69342\t9.66667\t1155.95898\t12.00000\t1445.52485\n        1\t703.75920\t703.75920\t4\t5.00000\t745.67427\t7.33333\t921.69342\t9.66667\t1155.95898\t12.00000\t1445.52485\n        1\t5665.23443\t5665.23443\t4\t22.00000\t884.43584\t33.00000\t1174.85782\t44.00000\t1470.71025\t55.00000\t1821.12370\n        1\t5665.23443\t5665.23443\t4\t22.00000\t884.43584\t33.00000\t1174.85782\t44.00000\t1470.71025\t55.00000\t1821.12370\n        1\t5665.23443\t5665.23443\t4\t22.00000\t884.43584\t33.00000\t1174.85782\t44.00000\t1470.71025\t55.00000\t1821.12370\n        1\t22784.79562\t22784.79562\t4\t62.00000\t1552.62418\t93.00000\t2207.24021\t124.00000\t2867.16447\t155.00000\t3712.68014\n        1\t28046.68102\t28046.68102\t4\t170.00000\t5254.89948\t231.66667\t6910.34987\t293.33333\t8592.40827\t355.00000\t10536.71149\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4775.79962\t231.66667\t6177.63481\t293.33333\t7775.31462\t355.00000\t9868.71865\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1031.69929\t33.00000\t1288.38408\t44.00000\t1579.87505\t55.00000\t1886.71665\n        1\t5665.23443\t5665.23443\t4\t22.00000\t1031.69929\t33.00000\t1288.38408\t44.00000\t1579.87505\t55.00000\t1886.71665\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4877.56703\t231.66667\t6507.36825\t293.33333\t8374.48424\t355.00000\t10331.01276\n        1\t28046.68102\t28046.68102\t4\t170.00000\t4877.56703\t231.66667\t6507.36825\t293.33333\t8374.48424\t355.00000\t10331.01276\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t0.33333\t\t0\t\t0.66667\t\t0\t\t1.00000\t\t0\n        1\t63999.82230\t63999.82230\t4\t396.00000\t3208.98600\t397.33333\t3219.79067\t398.66667\t3230.59533\t400.00000\t3241.40000\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t0.33333\t\t0\t\t0.66667\t\t0\t\t1.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t0.33333\t\t0\t\t0.66667\t\t0\t\t1.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t31.70000\t\t0\t\t63.40000\t\t0\t\t95.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t30.90000\t\t0\t\t61.80000\t\t0\t\t92.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t31.10000\t\t0\t\t62.20000\t\t0\t\t93.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.23333\t\t0\t\t34.46667\t\t0\t\t51.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.56667\t\t0\t\t33.13333\t\t0\t\t49.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t31.36667\t\t0\t\t62.73333\t\t0\t\t94.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.20000\t\t0\t\t34.40000\t\t0\t\t51.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t17.00000\t\t0\t\t34.00000\t\t0\t\t51.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t31.20000\t\t0\t\t62.40000\t\t0\t\t93.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t62.73333\t\t0\t\t125.46667\t\t0\t\t188.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t41.70000\t\t0\t\t83.40000\t\t0\t\t125.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.53333\t\t0\t\t17.06667\t\t0\t\t25.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.63333\t\t0\t\t17.26667\t\t0\t\t25.90000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.43333\t\t0\t\t16.86667\t\t0\t\t25.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.93333\t\t0\t\t17.86667\t\t0\t\t26.80000\t\t0\n        1\t10000.00000\t0.00000\t4\t30.00000\t0.00000\t66.00000\t0.00000\t120.00000\t0.00000\t160.00000\t0.00000\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.90000\t\t0\t\t17.80000\t\t0\t\t26.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.73333\t\t0\t\t17.46667\t\t0\t\t26.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t8.60000\t\t0\t\t17.20000\t\t0\t\t25.80000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t20.50000\t\t0\t\t41.00000\t\t0\t\t61.50000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t22.20000\t\t0\t\t44.40000\t\t0\t\t66.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t33.63333\t\t0\t\t67.26667\t\t0\t\t100.90000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t33.90000\t\t0\t\t67.80000\t\t0\t\t101.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.03333\t\t0\t\t42.06667\t\t0\t\t63.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.80000\t\t0\t\t43.60000\t\t0\t\t65.40000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t22.33333\t\t0\t\t44.66667\t\t0\t\t67.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.60000\t\t0\t\t43.20000\t\t0\t\t64.80000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.26667\t\t0\t\t42.53333\t\t0\t\t63.80000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.36667\t\t0\t\t42.73333\t\t0\t\t64.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t22.20000\t\t0\t\t44.40000\t\t0\t\t66.60000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t20.80000\t\t0\t\t41.60000\t\t0\t\t62.40000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t22.30000\t\t0\t\t44.60000\t\t0\t\t66.90000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t21.73333\t\t0\t\t43.46667\t\t0\t\t65.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.26667\t\t0\t\t18.53333\t\t0\t\t27.80000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.10000\t\t0\t\t18.20000\t\t0\t\t27.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.00000\t\t0\t\t18.00000\t\t0\t\t27.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.43333\t\t0\t\t18.86667\t\t0\t\t28.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.06667\t\t0\t\t18.13333\t\t0\t\t27.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.00000\t\t0\t\t18.00000\t\t0\t\t27.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t9.40000\t\t0\t\t18.80000\t\t0\t\t28.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.10000\t\t0\t\t6.20000\t\t0\t\t9.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.23333\t\t0\t\t6.46667\t\t0\t\t9.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.13333\t\t0\t\t6.26667\t\t0\t\t9.40000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.03333\t\t0\t\t6.06667\t\t0\t\t9.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.03333\t\t0\t\t6.06667\t\t0\t\t9.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.23333\t\t0\t\t6.46667\t\t0\t\t9.70000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.13333\t\t0\t\t6.26667\t\t0\t\t9.40000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.93333\t\t0\t\t7.86667\t\t0\t\t11.80000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.73333\t\t0\t\t7.46667\t\t0\t\t11.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t3.43333\t\t0\t\t6.86667\t\t0\t\t10.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t1.50000\t\t0\t\t3.00000\t\t0\t\t4.50000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t4.40000\t\t0\t\t8.80000\t\t0\t\t13.20000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t49.43333\t\t0\t\t98.86667\t\t0\t\t148.30000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t266.36667\t\t0\t\t532.73333\t\t0\t\t799.10000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t282.33333\t\t0\t\t564.66667\t\t0\t\t847.00000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t237.83333\t\t0\t\t475.66667\t\t0\t\t713.50000\t\t0\n        1\t0.00000\t0.00000\t4\t0.00000\t\t0\t\t16.66667\t\t0\t\t33.33333\t\t0\t\t50.00000\t\t0\n    ];\n    \n    \n    % bus names\n    %column_names%\tname\n    mpc.bus_name = {\n        'ABEL';\n        'ADAMS';\n        'ADLER';\n        'AGRICOLA';\n        'AIKEN';\n        'ALBER';\n        'ALDER';\n        'ALGER';\n        'ALI';\n        'ALLEN';\n        'ANNA';\n        'ARCHER';\n        'ARNE';\n        'ARNOLD';\n        'ARTHUR';\n        'ASSER';\n        'ASTON';\n        'ASTOR';\n        'ATTAR';\n        'ATTILA';\n        'ATTLEE';\n        'AUBREY';\n        'AUSTEN';\n        'AVERY';\n        'BACH';\n        'BACON';\n        'BAFFIN';\n        'BAILEY';\n        'BAIN';\n        'BAJER';\n        'BAKER';\n        'BALCH';\n        'BALZAC';\n        'BANKS';\n        'BARDEEN';\n        'BARKLA';\n        'BARLOW';\n        'BARRY';\n        'BARTON';\n        'BASOV';\n        'BATES';\n        'BAYLE';\n        'BEDE';\n        'BEETHOVEN';\n        'BEHRING';\n        'BELL';\n        'BLOCH';\n        'BORDET';\n        'CABELL';\n        'CABOT';\n        'CAESAR';\n        'CAINE';\n        'CALVIN';\n        'CAMUS';\n        'CAREW';\n        'CARREL';\n        'CARTER';\n        'CARUSO';\n        'CARY';\n        'CAXTON';\n        'CECIL';\n        'CHAIN';\n        'CHASE';\n        'CHIFA';\n        'CHUHSI';\n        'CLARK';\n        'CLAY';\n        'CLIVE';\n        'COBB';\n        'COLE';\n        'COMTE';\n        'CURIE';\n        'CURTISS';\n    };\n    \n    \n    % generator names types and fuels\n    %column_names%\tname    type    fuel\n    mpc.gen_name = {\n        '101_CT_1'\t'CT'\t'Oil';\n        '101_CT_2'\t'CT'\t'Oil';\n        '101_STEAM_3'\t'STEAM'\t'Coal';\n        '101_STEAM_4'\t'STEAM'\t'Coal';\n        '102_CT_1'\t'CT'\t'Oil';\n        '102_CT_2'\t'CT'\t'Oil';\n        '102_STEAM_3'\t'STEAM'\t'Coal';\n        '102_STEAM_4'\t'STEAM'\t'Coal';\n        '107_CC_1'\t'CC'\t'NG';\n        '113_CT_1'\t'CT'\t'NG';\n        '113_CT_2'\t'CT'\t'NG';\n        '113_CT_3'\t'CT'\t'NG';\n        '113_CT_4'\t'CT'\t'NG';\n        '115_STEAM_1'\t'STEAM'\t'Oil';\n        '115_STEAM_2'\t'STEAM'\t'Oil';\n        '115_STEAM_3'\t'STEAM'\t'Coal';\n        '116_STEAM_1'\t'STEAM'\t'Coal';\n        '118_CC_1'\t'CC'\t'NG';\n        '123_STEAM_2'\t'STEAM'\t'Coal';\n        '123_STEAM_3'\t'STEAM'\t'Coal';\n        '123_CT_1'\t'CT'\t'NG';\n        '123_CT_4'\t'CT'\t'NG';\n        '123_CT_5'\t'CT'\t'NG';\n        '201_CT_1'\t'CT'\t'Oil';\n        '201_CT_2'\t'CT'\t'Oil';\n        '201_STEAM_3'\t'STEAM'\t'Coal';\n        '202_CT_1'\t'CT'\t'Oil';\n        '202_CT_2'\t'CT'\t'Oil';\n        '202_STEAM_3'\t'STEAM'\t'Coal';\n        '202_STEAM_4'\t'STEAM'\t'Coal';\n        '207_CT_1'\t'CT'\t'NG';\n        '207_CT_2'\t'CT'\t'NG';\n        '213_CC_3'\t'CC'\t'NG';\n        '213_CT_1'\t'CT'\t'NG';\n        '213_CT_2'\t'CT'\t'NG';\n        '215_CT_4'\t'CT'\t'NG';\n        '215_CT_5'\t'CT'\t'NG';\n        '216_STEAM_1'\t'STEAM'\t'Coal';\n        '218_CC_1'\t'CC'\t'NG';\n        '221_CC_1'\t'CC'\t'NG';\n        '223_STEAM_1'\t'STEAM'\t'Coal';\n        '223_STEAM_2'\t'STEAM'\t'Coal';\n        '223_STEAM_3'\t'STEAM'\t'Coal';\n        '223_CT_4'\t'CT'\t'NG';\n        '223_CT_5'\t'CT'\t'NG';\n        '223_CT_6'\t'CT'\t'NG';\n        '301_CT_1'\t'CT'\t'Oil';\n        '301_CT_2'\t'CT'\t'Oil';\n        '301_CT_3'\t'CT'\t'NG';\n        '301_CT_4'\t'CT'\t'NG';\n        '302_CT_1'\t'CT'\t'Oil';\n        '302_CT_2'\t'CT'\t'Oil';\n        '302_CT_3'\t'CT'\t'NG';\n        '302_CT_4'\t'CT'\t'NG';\n        '307_CT_1'\t'CT'\t'NG';\n        '307_CT_2'\t'CT'\t'NG';\n        '313_CC_1'\t'CC'\t'NG';\n        '315_STEAM_1'\t'STEAM'\t'Oil';\n        '315_STEAM_2'\t'STEAM'\t'Oil';\n        '315_STEAM_3'\t'STEAM'\t'Oil';\n        '315_STEAM_4'\t'STEAM'\t'Oil';\n        '315_STEAM_5'\t'STEAM'\t'Oil';\n        '315_CT_6'\t'CT'\t'NG';\n        '315_CT_7'\t'CT'\t'NG';\n        '315_CT_8'\t'CT'\t'NG';\n        '316_STEAM_1'\t'STEAM'\t'Coal';\n        '318_CC_1'\t'CC'\t'NG';\n        '321_CC_1'\t'CC'\t'NG';\n        '322_CT_5'\t'CT'\t'NG';\n        '322_CT_6'\t'CT'\t'NG';\n        '323_CC_1'\t'CC'\t'NG';\n        '323_CC_2'\t'CC'\t'NG';\n        '114_SYNC_COND_1'\t'SYNC_COND'\t'Sync_Cond';\n        '121_NUCLEAR_1'\t'NUCLEAR'\t'Nuclear';\n        '122_HYDRO_1'\t'HYDRO'\t'Hydro';\n        '122_HYDRO_2'\t'HYDRO'\t'Hydro';\n        '122_HYDRO_3'\t'HYDRO'\t'Hydro';\n        '122_HYDRO_4'\t'HYDRO'\t'Hydro';\n        '122_HYDRO_5'\t'HYDRO'\t'Hydro';\n        '122_HYDRO_6'\t'HYDRO'\t'Hydro';\n        '201_HYDRO_4'\t'HYDRO'\t'Hydro';\n        '214_SYNC_COND_1'\t'SYNC_COND'\t'Sync_Cond';\n        '215_HYDRO_1'\t'HYDRO'\t'Hydro';\n        '215_HYDRO_2'\t'HYDRO'\t'Hydro';\n        '215_HYDRO_3'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_1'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_2'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_3'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_4'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_5'\t'HYDRO'\t'Hydro';\n        '222_HYDRO_6'\t'HYDRO'\t'Hydro';\n        '314_SYNC_COND_1'\t'SYNC_COND'\t'Sync_Cond';\n        '322_HYDRO_1'\t'HYDRO'\t'Hydro';\n        '322_HYDRO_2'\t'HYDRO'\t'Hydro';\n        '322_HYDRO_3'\t'HYDRO'\t'Hydro';\n        '322_HYDRO_4'\t'HYDRO'\t'Hydro';\n        '320_PV_1'\t'PV'\t'Solar';\n        '314_PV_1'\t'PV'\t'Solar';\n        '314_PV_2'\t'PV'\t'Solar';\n        '313_PV_1'\t'PV'\t'Solar';\n        '314_PV_3'\t'PV'\t'Solar';\n        '314_PV_4'\t'PV'\t'Solar';\n        '313_PV_2'\t'PV'\t'Solar';\n        '310_PV_1'\t'PV'\t'Solar';\n        '324_PV_1'\t'PV'\t'Solar';\n        '312_PV_1'\t'PV'\t'Solar';\n        '310_PV_2'\t'PV'\t'Solar';\n        '324_PV_2'\t'PV'\t'Solar';\n        '324_PV_3'\t'PV'\t'Solar';\n        '113_PV_1'\t'PV'\t'Solar';\n        '319_PV_1'\t'PV'\t'Solar';\n        '215_PV_1'\t'PV'\t'Solar';\n        '102_PV_1'\t'PV'\t'Solar';\n        '101_PV_1'\t'PV'\t'Solar';\n        '102_PV_2'\t'PV'\t'Solar';\n        '104_PV_1'\t'PV'\t'Solar';\n        '212_CSP_1'\t'CSP'\t'Solar';\n        '101_PV_2'\t'PV'\t'Solar';\n        '101_PV_3'\t'PV'\t'Solar';\n        '101_PV_4'\t'PV'\t'Solar';\n        '103_PV_1'\t'PV'\t'Solar';\n        '119_PV_1'\t'PV'\t'Solar';\n        '308_RTPV_1'\t'RTPV'\t'Solar';\n        '313_RTPV_1'\t'RTPV'\t'Solar';\n        '313_RTPV_2'\t'RTPV'\t'Solar';\n        '313_RTPV_3'\t'RTPV'\t'Solar';\n        '313_RTPV_4'\t'RTPV'\t'Solar';\n        '313_RTPV_5'\t'RTPV'\t'Solar';\n        '313_RTPV_6'\t'RTPV'\t'Solar';\n        '313_RTPV_7'\t'RTPV'\t'Solar';\n        '313_RTPV_8'\t'RTPV'\t'Solar';\n        '313_RTPV_9'\t'RTPV'\t'Solar';\n        '313_RTPV_10'\t'RTPV'\t'Solar';\n        '313_RTPV_11'\t'RTPV'\t'Solar';\n        '313_RTPV_12'\t'RTPV'\t'Solar';\n        '320_RTPV_1'\t'RTPV'\t'Solar';\n        '320_RTPV_2'\t'RTPV'\t'Solar';\n        '320_RTPV_3'\t'RTPV'\t'Solar';\n        '313_RTPV_13'\t'RTPV'\t'Solar';\n        '320_RTPV_4'\t'RTPV'\t'Solar';\n        '320_RTPV_5'\t'RTPV'\t'Solar';\n        '118_RTPV_1'\t'RTPV'\t'Solar';\n        '118_RTPV_2'\t'RTPV'\t'Solar';\n        '118_RTPV_3'\t'RTPV'\t'Solar';\n        '118_RTPV_4'\t'RTPV'\t'Solar';\n        '118_RTPV_5'\t'RTPV'\t'Solar';\n        '118_RTPV_6'\t'RTPV'\t'Solar';\n        '320_RTPV_6'\t'RTPV'\t'Solar';\n        '118_RTPV_7'\t'RTPV'\t'Solar';\n        '118_RTPV_8'\t'RTPV'\t'Solar';\n        '118_RTPV_9'\t'RTPV'\t'Solar';\n        '118_RTPV_10'\t'RTPV'\t'Solar';\n        '213_RTPV_1'\t'RTPV'\t'Solar';\n        '309_WIND_1'\t'WIND'\t'Wind';\n        '317_WIND_1'\t'WIND'\t'Wind';\n        '303_WIND_1'\t'WIND'\t'Wind';\n        '122_WIND_1'\t'WIND'\t'Wind';\n        '313_STORAGE_1'\t'STORAGE'\t'Storage';\n    };\n    \n    %%-----  DC Line Data  -----%%\n    % F_BUS T_BUS BR_STATUS PF PT QF QT VF VT PMIN PMAX QMINF QMAXF QMINT QMAXT LOSS0 LOSS1 MU_PMIN MU_PMAX MU_QMINF MU_QMAXF MU_QMINT MU_QMAXT\n    mpc.dcline = [\n        113 316 1 0 0 0 0 1 1 -100 100 -9999 9999 -9999 9999 0 0 0 0 0 0 0 0\n    ];"
  },
  {
    "path": "docs/src/tutorials/tutorials_data/TestGENCLS.dyr",
    "content": "  101 'GENROE' 1   8.000000  0.030000  0.400000  0.050000  6.500000  0.000000  1.800000\n  1.700000  0.300000  0.550000  0.250000  0.200000  0.039200  0.267200  /\n  101 'ESST1A' 1   1  1  0.01  99  -99  1  10  1  1  200  0  4  -4  4  -4  0  0  1  0  3  /\n  102 'GENCLS' 1   0.0   0.0 /\n  103 'GENCLS' 1   3.1   2.0 /"
  },
  {
    "path": "docs/src/tutorials/tutorials_data/case5.m",
    "content": "% NESTA v0.6.0\n% used in tests of,\n% - non-contiguous bus ids\n% - tranformer orentation swapping\n% - dual values\n%\n\nfunction mpc = nesta_case5_pjm\n    mpc.version = '2';\n    mpc.baseMVA = 100.0;\n    \n    %% area data\n    %\tarea\trefbus\n    mpc.areas = [\n        1\t 4;\n    ];\n    \n    %% bus data\n    %\tbus_i\ttype\tPd\tQd\tGs\tBs\tarea\tVm\tVa\tbaseKV\tzone\tVmax\tVmin\n    mpc.bus = [\n        1\t 2\t 0.0\t 0.0\t 0.0\t 0.0\t 1\t    1.00000\t    2.80377\t 230.0\t 1\t    1.10000\t    0.90000;\n        2\t 1\t 300.0\t 98.61\t 0.0\t 0.0\t 1\t    1.08407\t   -0.73465\t 230.0\t 1\t    1.10000\t    0.90000;\n        3\t 2\t 300.0\t 98.61\t 0.0\t 0.0\t 1\t    1.00000\t   -0.55972\t 230.0\t 1\t    1.10000\t    0.90000;\n        4\t 3\t 400.0\t 131.47\t 0.0\t 0.0\t 1\t    1.00000\t    0.00000\t 230.0\t 1\t    1.10000\t    0.90000;\n        10\t 2\t 0.0\t 0.0\t 0.0\t 0.0\t 1\t    1.00000\t    3.59033\t 230.0\t 1\t    1.10000\t    0.90000;\n    ];\n    \n    %% generator data\n    %\tbus\tPg\tQg\tQmax\tQmin\tVg\tmBase\tstatus\tPmax\tPmin\tPc1\tPc2\tQc1min\tQc1max\tQc2min\tQc2max\tramp_agc\tramp_10\tramp_30\tramp_q\tapf\n    mpc.gen = [\n        1\t 40.0\t 30.0\t 30.0\t -30.0\t 1.07762\t 100.0\t 1\t 40.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        1\t 170.0\t 127.5\t 127.5\t -127.5\t 1.07762\t 100.0\t 1\t 170.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        3\t 324.498\t 390.0\t 390.0\t -390.0\t 1.1\t 100.0\t 1\t 520.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        4\t 0.0\t -10.802\t 150.0\t -150.0\t 1.06414\t 100.0\t 1\t 200.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        10\t 470.694\t -165.039\t 450.0\t -450.0\t 1.06907\t 100.0\t 1\t 600.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n    ];\n    \n    %% generator cost data\n    %\t2\tstartup\tshutdown\tn\tc(n-1)\t...\tc0\n    mpc.gencost = [\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  14.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  15.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  30.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  40.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  10.000000\t   0.000000;\n    ];\n    \n    %% branch data\n    %\tfbus\ttbus\tr\tx\tb\trateA\trateB\trateC\tratio\tangle\tstatus\tangmin\tangmax\n    mpc.branch = [\n        1\t 2\t 0.00281\t 0.0281\t 0.00712\t 400.0\t 400.0\t 400.0\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        1\t 4\t 0.00304\t 0.0304\t 0.00658\t 426\t 426\t 426\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        1\t 10\t 0.00064\t 0.0064\t 0.03126\t 426\t 426\t 426\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        2\t 3\t 0.00108\t 0.0108\t 0.01852\t 426\t 426\t 426\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        3\t 4\t 0.00297\t 0.0297\t 0.00674\t 426\t 426\t 426\t 1.05\t  1.0\t 1\t -30.0\t 30.0;\n        4\t 3\t 0.00297\t 0.0297\t 0.00674\t 426\t 426\t 426\t 1.05\t -1.0\t 1\t -30.0\t 30.0;\n        4\t 10\t 0.00297\t 0.0297\t 0.00674\t 240.0\t 240.0\t 240.0\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n    ];\n    "
  },
  {
    "path": "docs/src/tutorials/tutorials_data/case5_re.m",
    "content": "% NESTA v0.6.0\n% extended to include renewable generators\n% used in tests of,\n% - non-contiguous bus ids\n% - tranformer orentation swapping\n% - dual values\n%\n\nfunction mpc = nesta_case5_pjm\n    mpc.version = '2';\n    mpc.baseMVA = 100.0;\n    \n    %% area data\n    %\tarea\trefbus\n    mpc.areas = [\n        1\t 4;\n    ];\n    \n    %% bus data\n    %\tbus_i\ttype\tPd\tQd\tGs\tBs\tarea\tVm\tVa\tbaseKV\tzone\tVmax\tVmin\n    mpc.bus = [\n        1\t 2\t 0.0\t 0.0\t 0.0\t 0.0\t 1\t    1.00000\t    2.80377\t 230.0\t 1\t    1.10000\t    0.90000;\n        2\t 1\t 300.0\t 98.61\t 0.0\t 0.0\t 1\t    1.08407\t   -0.73465\t 230.0\t 1\t    1.10000\t    0.90000;\n        3\t 2\t 300.0\t 98.61\t 0.0\t 0.0\t 1\t    1.00000\t   -0.55972\t 230.0\t 1\t    1.10000\t    0.90000;\n        4\t 3\t 400.0\t 131.47\t 0.0\t 0.0\t 1\t    1.00000\t    0.00000\t 230.0\t 1\t    1.10000\t    0.90000;\n        10\t 2\t 0.0\t 0.0\t 0.0\t 0.0\t 1\t    1.00000\t    3.59033\t 230.0\t 1\t    1.10000\t    0.90000;\n    ];\n    \n    %% generator data\n    %\tbus\tPg\tQg\tQmax\tQmin\tVg\tmBase\tstatus\tPmax\tPmin\tPc1\tPc2\tQc1min\tQc1max\tQc2min\tQc2max\tramp_agc\tramp_10\tramp_30\tramp_q\tapf\n    mpc.gen = [\n        1\t 40.0\t 30.0\t 30.0\t -30.0\t 1.07762\t 100.0\t 1\t 40.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        1\t 170.0\t 127.5\t 127.5\t -127.5\t 1.07762\t 100.0\t 1\t 170.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        3\t 324.498\t 390.0\t 390.0\t -390.0\t 1.1\t 100.0\t 1\t 520.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        4\t 0.0\t -10.802\t 150.0\t -150.0\t 1.06414\t 100.0\t 1\t 200.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        10\t 470.694\t -165.039\t 450.0\t -450.0\t 1.06907\t 100.0\t 1\t 600.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        3\t 0\t 0\t 0\t 0\t 1.1\t 100.0\t 1\t 60\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n        10\t 0\t 0\t 0\t 0\t 1.06907\t 100.0\t 1\t 60\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0\t 0.0;\n    ];\n    \n    %% generator cost data\n    %\t2\tstartup\tshutdown\tn\tc(n-1)\t...\tc0\n    mpc.gencost = [\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  14.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  15.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  30.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  40.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  10.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  0.000000\t   0.000000;\n        2\t 0.0\t 0.0\t 3\t   0.000000\t  0.000000\t   0.000000;\n    ];\n    \n    %% branch data\n    %\tfbus\ttbus\tr\tx\tb\trateA\trateB\trateC\tratio\tangle\tstatus\tangmin\tangmax\n    mpc.branch = [\n        1\t 2\t 0.00281\t 0.0281\t 0.00712\t 200.0\t 200.0\t 200.0\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        1\t 4\t 0.00304\t 0.0304\t 0.00658\t 200\t 200\t 200\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        1\t 10\t 0.00064\t 0.0064\t 0.03126\t 1000\t 1000\t 1000\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        2\t 3\t 0.00108\t 0.0108\t 0.01852\t 1200\t 1200\t 1200\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n        3\t 4\t 0.00297\t 0.0297\t 0.00674\t 1000\t 1000\t 1000\t 1.05\t  1.0\t 1\t -30.0\t 30.0;\n        4\t 3\t 0.00297\t 0.0297\t 0.00674\t 426\t 426\t 426\t 1.05\t -1.0\t 1\t -30.0\t 30.0;\n        4\t 10\t 0.00297\t 0.0297\t 0.00674\t 200.0\t 200.0\t 200.0\t 0.0\t  0.0\t 1\t -30.0\t 30.0;\n    ];\n    \n    % generator names types and fuels\n    %column_names%\tname    type    fuel\n    mpc.gen_name = {\n        'Alta'\t'CT'\t'Gas';\n        'Park City'\t'CC'\t'Gas';\n        'Solitude'\t'ST'\t'Nuc';\n        'Sundance'\t'CC'\t'Gas';\n        'Brighton'\t'ST'\t'Coal';\n        'SolarBusC'\t'PV'\t'Solar';\n        'WindBusA'\t'WIND'\t'Wind';\n    };\n    \n    % bus names\n    %column_names%\tname\n    mpc.bus_name = {\n        'bus1';\n        'bus2';\n        'bus3';\n        'bus4';\n        'bus5';\n    };"
  },
  {
    "path": "docs/src/tutorials/utils/docs_utils.jl",
    "content": "\"\"\"\n`print_struct()`\n\nPrints the definition of a struct.\n\"\"\"\nfunction print_struct(type)\n    mutable = ismutable(type) ? \"mutable\" : \"\"\n    println(\"$mutable struct $type\")\n    for (fn, ft) in zip(fieldnames(type), fieldtypes(type))\n        println(\"    $fn::$ft\")\n    end\n    println(\"end\")\nend\n"
  },
  {
    "path": "docs/src/tutorials/working_with_time_series.jl",
    "content": "# # [Working with Time Series Data](@id tutorial_time_series)\n# In this tutorial, we will manually add, retrieve, and inspect time-series data in\n# different formats, including identifying which components in a power [`System`](@ref) have time\n# series data. Along the way, we will also use workarounds for missing forecast data and\n# reuse identical time series profiles to avoid unnecessary memory usage.\n\n# ## Example Data and Setup\n# We will make an example [`System`](@ref) with a wind generator and two loads, and\n# add the time series needed to model, for example, the impacts of wind forecast uncertainty.\n# Here is the available data:\n# ```@raw html\n# <img src=\"../../assets/time_series_tutorial.png\" width=\"100%\"/>\n# ```\n# For the wind generator, we have the historical point (deterministic) forecasts of power\n# output. The forecasts were generated every 30 minutes with a 5-minute [resolution](@ref R)\n# and 1-hour [horizon](@ref H). We also have\n# measurements of what actually happened at 5-minute resolution over the 2 hours.\n# For the loads, note that the forecast data is missing. We only have the historical\n# measurements of total load for the system, which is normalized to the system's peak load.\n# Load the `PowerSystems`, `Dates`, and `TimeSeries` packages to get started:\n\nusing PowerSystems\nusing Dates\nusing TimeSeries\n\n# As usual, we need to define a power [`System`](@ref) that holds all our data. Let's define\n# a simple system with a bus, a wind generator, and two loads:\n\nsystem = System(100.0); # 100 MVA base power\nbus1 = ACBus(;\n    number = 1,\n    name = \"bus1\",\n    available = true,\n    bustype = ACBusTypes.REF,\n    angle = 0.0,\n    magnitude = 1.0,\n    voltage_limits = (min = 0.9, max = 1.05),\n    base_voltage = 230.0,\n);\nwind1 = RenewableDispatch(;\n    name = \"wind1\",\n    available = true,\n    bus = bus1,\n    active_power = 0.0, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    rating = 1.0, # 10 MW per-unitized by device base_power\n    prime_mover_type = PrimeMovers.WT,\n    reactive_power_limits = (min = 0.0, max = 0.0), # per-unitized by device base_power\n    power_factor = 1.0,\n    operation_cost = RenewableGenerationCost(nothing),\n    base_power = 10.0, # MVA\n);\nload1 = PowerLoad(;\n    name = \"load1\",\n    available = true,\n    bus = bus1,\n    active_power = 0.0, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    base_power = 10.0, # MVA\n    max_active_power = 1.0, # 10 MW per-unitized by device base_power\n    max_reactive_power = 0.0,\n);\nload2 = PowerLoad(;\n    name = \"load2\",\n    available = true,\n    bus = bus1,\n    active_power = 0.0, # Per-unitized by device base_power\n    reactive_power = 0.0, # Per-unitized by device base_power\n    base_power = 30.0, # MVA\n    max_active_power = 1.0, # 30 MW per-unitized by device base_power\n    max_reactive_power = 0.0,\n);\nadd_components!(system, [bus1, wind1, load1, load2])\n\n# Recall that we can also set the [`System`](@ref)'s unit base to natural units (MW)\n# to make it easier to inspect results:\n\nset_units_base_system!(system, \"NATURAL_UNITS\")\n\n# Before we get started, print `wind1` to see its data:\n\nwind1\n\n# See the `has_time_series` field at the bottom is `false`.\n# Recall that we also can see a summary of the system by printing it:\n\nsystem\n\n# Observe that there is no mention of time series data in the system yet.\n# # Add and Retrieve a Single Time Series\n# Let's start by defining and attaching the wind measurements shown in the data above.\n# This is a single time series profile, so we will use a [`SingleTimeSeries`](@ref).\n# First, define a `TimeSeries.TimeArray` of input data, using the 5-minute\n# [resolution](@ref R) to define the time-stamps in the example data:\n\nwind_values = [6.0, 7, 7, 6, 7, 9, 9, 9, 8, 8, 7, 6, 5, 5, 5, 5, 5, 6, 6, 6, 7, 6, 7, 7];\nresolution = Dates.Minute(5);\ntimestamps = range(DateTime(\"2020-01-01T08:00:00\"); step = resolution, length = 24);\nwind_timearray = TimeArray(timestamps, wind_values);\n\n# Now, use the input data to define a Single Time Series in PowerSystems:\n\nwind_time_series = SingleTimeSeries(;\n    name = \"max_active_power\",\n    data = wind_timearray,\n);\n\n# Note that we've chosen the name `max_active_power`, which is the default time series profile\n# name when using\n# [PowerSimulations.jl](https://sienna-platform.github.io/PowerSimulations.jl/stable/formulation_library/RenewableGen/)\n# for simulations.\n# So far, this time series has been defined, but not attached to our [`System`](@ref) in any way. Now,\n# attach it to `wind1` using [`add_time_series!`](@ref add_time_series!(sys::System, component::Component, time_series::TimeSeriesData; features...)):\n\nadd_time_series!(system, wind1, wind_time_series);\n\n# Let's double-check this worked by calling [`show_time_series`](@ref):\n\nshow_time_series(wind1)\n\n# Now `wind1` has the first time-series data set. Recall that you can also print `wind1` and\n# check the `has_time_series` field like we did above.\n# Finally, let's retrieve and inspect the new timeseries, using `get_time_series_array`:\n\nget_time_series_array(SingleTimeSeries, wind1, \"max_active_power\")\n\n# Verify this matches your expectation based on the input data.\n# # Add and Retrieve a Forecast\n# Next, let's add the wind power forecasts. We will use a [`Deterministic`](@ref) format for\n# the point forecasts.\n# Because we have forecasts with at different [initial times](@ref I), the input data must be\n# a dictionary where the keys are the initial times and the values are vectors or\n# `TimeSeries.TimeArray`s of the forecast data.\n# Set up the example input data:\n\nwind_forecast_data = Dict(\n    DateTime(\"2020-01-01T08:00:00\") => [5.0, 6, 7, 7, 7, 8, 9, 10, 10, 9, 7, 5],\n    DateTime(\"2020-01-01T08:30:00\") => [9.0, 9, 9, 9, 8, 7, 6, 5, 4, 5, 4, 4],\n    DateTime(\"2020-01-01T09:00:00\") => [6.0, 6, 5, 5, 4, 5, 6, 7, 7, 7, 6, 6],\n);\n\n# Define the [`Deterministic`](@ref) forecast and attach it to `wind1`:\n\nwind_forecast = Deterministic(\"max_active_power\", wind_forecast_data, resolution);\nadd_time_series!(system, wind1, wind_forecast);\n\n# Let's call `show_time_series` once again:\n\nshow_time_series(wind1)\n\n# Notice that we now have two types of time series listed -- the single time series and\n# the forecasts.\n# Finally, let's retrieve the forecast data to double check it was added properly, specifying\n# the initial time to get the 2nd forecast window starting at 8:30:\n\nget_time_series_array(\n    Deterministic,\n    wind1,\n    \"max_active_power\";\n    start_time = DateTime(\"2020-01-01T08:30:00\"),\n)\n\n# # Add A Time Series Using Scaling Factors\n# Let's add the load time series. Recall that this data is normalized to the peak system\n# power, so we'll use it to scale both of our loads. We call normalized time series data\n# *scaling factors*.\n# First, let's create our input data `TimeSeries.TimeArray` with the example data and the same\n# time stamps we used in the wind time series:\n\nload_values = [0.3, 0.3, 0.3, 0.3, 0.4, 0.4, 0.4, 0.4, 0.5, 0.5, 0.6, 0.6,\n    0.7, 0.8, 0.8, 0.8, 0.8, 0.8, 0.9, 0.8, 0.8, 0.8, 0.8, 0.8];\nload_timearray = TimeArray(timestamps, load_values);\n\n# Again, define a [`SingleTimeSeries`](@ref), but this time use the\n# `scaling_factor_multiplier` parameter to scale this time series from\n# normalized values to power values:\n\nload_time_series = SingleTimeSeries(;\n    name = \"max_active_power\",\n    data = load_timearray,\n    scaling_factor_multiplier = get_max_active_power,\n);\n\n# Notice that we assigned the\n# [`get_max_active_power`](@ref get_max_active_power(value::PowerLoad)) *function*\n# to scale the time series, rather than a value, making the time series reusable for multiple\n# components or multiple fields in a component. Note that the values are normalized using\n# each device's `max_active_power` parameter, not the system-wide `base_power`.\n# Now, add the scaling factor time series to both loads to save memory and avoid data\n# duplication:\n\nadd_time_series!(system, [load1, load2], load_time_series);\n\n# Let's take a look at `load1`, including printing its parameters...\n\nload1\n\n# ...as well as its time series:\n\nshow_time_series(load1)\n\n# !!! tip \"Important\"\n#     Notice that each load now has two references to `max_active_power`. This is intentional.\n#     There is the parameter, `max_active_power`, which is  the\n#     maximum demand of each load at any time (10 MW or 30 MW). There is also\n#     `max_active_power` the time series, which is the time varying demand over the 2-hour\n#     window, calculated using the scaling factors and the `max_active_power` parameter.\n#     This means that if we change the `max_active_power` parameter, the time series will\n#     also change when we retrieve it! This is also true when we apply the same scaling factors\n#     to multiple components or parameters.\n# Let's check the impact that these two `max_active_power` data sources have on the times\n# series data when we retrieve it. Get the `max_active_power` time series for `load1`:\n\nget_time_series_array(SingleTimeSeries, load1, \"max_active_power\") # in MW\n\n# See that the normalized values have been scaled up by 10 MW.\n# Now let's look at `load2`. First check its `max_active_power` parameter:\n\nget_max_active_power(load2)\n\n# This has a higher peak maximum demand of 30 MW.\n# Next, retrieve its `max_active_power` time series:\n\nget_time_series_array(SingleTimeSeries, load2, \"max_active_power\") # in MW\n\n# Observe the difference compared to `load1`'s time series.\n# Finally, retrieve the underlying time series data with no scaling factor multiplier\n# applied:\n\nget_time_series_array(SingleTimeSeries,\n    load2,\n    \"max_active_power\";\n    ignore_scaling_factors = true,\n)\n\n# Notice that this is the normalized input data, which is still being stored underneath. Each\n# load is using a reference to that data when we call `get_time_series_array` to avoid\n# unnecessary data duplication.\n# # Transform a [`SingleTimeSeries`](@ref) into a Forecast\n# Finally, let's use a workaround to handle the missing load forecast data. We will assume a\n# perfect forecast where the forecast is based on the [`SingleTimeSeries`](@ref) we just added.\n# Rather than unnecessarily duplicating and reformatting data, use PowerSystems.jl's dedicated\n# [`transform_single_time_series!`](@ref) function to generate a [`DeterministicSingleTimeSeries`](@ref),\n# which saves memory while behaving just like a [`Deterministic`](@ref) forecast.\n# Before we call `transform_single_time_series!`, we need to remove the [`SingleTimeSeries`](@ref) from\n# the wind component. This is because the wind component already has a [`Deterministic`](@ref) forecast\n# with the name `\"max_active_power\"`, and having both a [`Deterministic`](@ref) and a\n# [`DeterministicSingleTimeSeries`](@ref) with the same name is not allowed. If we tried to keep both,\n# functions like `get_time_series` wouldn't know which forecast to retrieve when you request\n# `\"max_active_power\"`. Let's remove the [`SingleTimeSeries`](@ref) to avoid this conflict:\n\nremove_time_series!(system, SingleTimeSeries, wind1, \"max_active_power\");\n\n# Now we can transform the remaining [`SingleTimeSeries`](@ref) (the ones attached to the loads):\n\ntransform_single_time_series!(\n    system,\n    Dates.Hour(1), # horizon\n    Dates.Minute(30), # interval\n);\n\n# Let's see the results for `load1`'s time series summary:\n\nshow_time_series(load1)\n\n# Notice we now have a load forecast data set with the resolution, horizon, and, interval\n# matching our wind forecasts.\n# Retrieve the first forecast window:\n\nget_time_series_array(\n    DeterministicSingleTimeSeries,\n    load1,\n    \"max_active_power\";\n    start_time = DateTime(\"2020-01-01T08:00:00\"),\n)\n\n# See that `load1`'s scaling factor multiplier is still being applied as expected.\n# # Transform with Multiple Intervals\n# PowerSystems supports creating multiple forecast transforms from the same\n# [`SingleTimeSeries`](@ref), each with a different [interval](@ref I). This is useful when\n# a component needs forecasts updated at different frequencies.\n# Use `delete_existing = false` to preserve the existing transform and add a second one\n# with a different interval:\n\ntransform_single_time_series!(\n    system,\n    Dates.Hour(1), # horizon\n    Dates.Hour(1); # a longer interval\n    delete_existing = false,\n);\n\n# Now `load1` has two [`DeterministicSingleTimeSeries`](@ref) forecasts with different\n# intervals. Let's verify:\n\nshow_time_series(load1)\n\n# When multiple intervals exist for the same name, you must specify `interval` to\n# disambiguate retrieval:\n\nget_time_series_array(\n    DeterministicSingleTimeSeries,\n    load1,\n    \"max_active_power\";\n    start_time = DateTime(\"2020-01-01T08:00:00\"),\n    interval = Dates.Minute(30),\n)\n\n# You can also query forecast parameters for a specific interval:\n\nget_forecast_horizon(system; interval = Dates.Hour(1))\n\n#\n\nget_forecast_interval(system; interval = Dates.Minute(30))\n\n# To selectively remove one interval's forecasts while keeping the other:\n\nremove_time_series!(\n    system,\n    DeterministicSingleTimeSeries,\n    load1,\n    \"max_active_power\";\n    interval = Dates.Hour(1),\n);\nshow_time_series(load1)\n\n# The 30-minute interval forecast is still present while the 1-hour one has been removed.\n# # Finding, Retrieving, and Inspecting Time Series\n# Now, let's complete this tutorial by doing a few sanity checks on the data that we've added,\n# where are we will also examine components with time series and retrieve\n# the time series data in a few more ways.\n# First, recall that we can print a component to check its `has_time_series` field:\n\nload1\n\n# Also, recall we can print the [`System`](@ref) to summarize the data in our system:\n\nsystem\n\n# Notice that a new table has been added -- the Time Series Summary, showing the count of\n# each Type of component that has a given time series type.\n# Notice that the [`RenewableDispatch`](@ref) generator (`wind1`) only has its [`Deterministic`](@ref) forecast\n# and no [`DeterministicSingleTimeSeries`](@ref). This is because we removed the wind's [`SingleTimeSeries`](@ref)\n# before calling `transform_single_time_series!`, preventing a conflict with its existing\n# [`Deterministic`](@ref) forecast.\n# Let's verify `wind1`'s time series to confirm:\n\nshow_time_series(wind1)\n\n# See that it only has the [`Deterministic`](@ref) forecast, as expected.\n# Finally, let's do a last data sanity check on the forecasts. Since we defined the wind\n# time series in MW instead of scaling factors, let's make sure none of our forecasts exceeds\n# the `max_active_power` parameter.\n# Instead of using `get_time_series_array` where we need to remember some details of\n# the time series we're looking up, let's use [`get_time_series_keys`](@ref) to refresh our\n# memories:\n\nkeys = get_time_series_keys(wind1)\n\n# See the forecast key is first, so let's retrieve it using [`get_time_series`](@ref):\n\nforecast = get_time_series(wind1, keys[1])\n\n# See that unlike when we used `get_time_series_array`, this returns an object we can\n# manipulate.\n# Use [`iterate_windows`](@ref) to cycle through the 3 forecast windows and inspect the peak\n# value:\n\nfor window in iterate_windows(forecast)\n    @show values(maximum(window))\nend\n\n# Finally, use [`get_max_active_power`](@ref get_max_active_power(d::RenewableGen)) to\n# check the expected maximum:\n\nget_max_active_power(wind1)\n\n# See that the forecasts are not exceeding this maximum -- sanity check complete.\n# !!! tip\n#     Unlike [`PowerLoad`](@ref) components, [`RenewableDispatch`](@ref) components do not have a\n#     `max_active_power` field, so check\n#     [`get_max_active_power`](@ref get_max_active_power(d::RenewableGen))\n#     to see how its calculated.\n# # Next Steps\n# In this tutorial, you defined, added, and retrieved four time series data\n# sets, including static time series and deterministic forecasts. Along the way, we\n# reduced data duplication using normalized scaling factors for reuse by multiple components\n# or component fields, as well as by referencing a [`StaticTimeSeries`](@ref) to address missing\n# forecast data.\n# Next you might like to:\n#   - [Parse many timeseries data sets from CSV's](@ref parsing_time_series)\n#   - [See how to improve performance efficiency with your own time series data](@ref \"Improve Performance with Time Series Data\")\n#   - [Review the available time series data formats](@ref ts_data)\n#   - [Learn more about how times series data is stored](@ref \"Data Storage\")\n"
  },
  {
    "path": "scripts/formatter/Project.toml",
    "content": "uuid = \"c6367ca8-164d-4469-afe3-c91cf8860505\"\nauthors = [\"Jose Daniel Lara <jdlara@berkeley.edu>\"]\n\n[deps]\nJuliaFormatter = \"98e50ef6-434e-11e9-1051-2b60c6c9e899\"\nPkg = \"44cfe95a-1eb2-52ea-b672-e2afdf69b78f\"\n\n[compat]\nJuliaFormatter = \"2\"\njulia = \"^1.7\"\n"
  },
  {
    "path": "scripts/formatter/formatter_code.jl",
    "content": "using Pkg\nPkg.activate(@__DIR__)\nPkg.instantiate()\nPkg.update()\n\nusing JuliaFormatter\n\nmain_paths = [\"./src\", \"./test\", \"./docs/src\"]\nfor main_path in main_paths\n    for (root, dir, files) in walkdir(main_path)\n        for f in files\n        @show file_path = abspath(root, f)\n        !((occursin(\".jl\", f) || occursin(\".md\", f))) && continue\n        format(file_path;\n            whitespace_ops_in_indices = true,\n            remove_extra_newlines = true,\n            verbose = true,\n            always_for_in = true,\n            whitespace_typedefs = true,\n            conditional_to_if = true,\n            join_lines_based_on_source = true,\n            separate_kwargs_with_semicolon = true,\n            format_markdown = true,\n            ignore = [\"*LICENSE.md\", \"how_to/install.md\"] # install has complicated formatting\n\n            # always_use_return = true. # Disabled since it throws a lot of false positives\n            )\n        end\n    end\nend\n"
  },
  {
    "path": "scripts/generate_config_file.py",
    "content": "#!/usr/bin/env python\n\n\"\"\"Generates a user descriptor file for parsing power system raw data.\"\"\"\n\n# Note:  This is written in Python instead of Julia because the Julia YAML\n# package does not support writing (only reading).\n\nimport json\nimport os\nimport sys\n\nimport yaml\n\n\nPOWER_SYSTEM_DESCRIPTOR_FILE = os.path.join(\n    \"src\",\n    \"descriptors\",\n    \"power_system_inputs.json\"\n)\n\n\ndef read_json_data(filename):\n    \"\"\"Return the JSON data from a file.\"\"\"\n    with open(filename) as fp_in:\n        return json.load(fp_in)\n\n\ndef generate_config(input_file):\n    \"\"\"Generate user descriptors from the PowerSystems descriptor file.\"\"\"\n    config = {}\n    data = read_json_data(input_file)\n    for key, value in data.items():\n        items = []\n        for item in value:\n            config_item = {\n                \"name\": item[\"name\"],\n                \"custom_name\": item[\"name\"],\n            }\n            items.append(config_item)\n\n        config[key] = items\n\n    return config\n\n\ndef generate_file(output_file, input_file=POWER_SYSTEM_DESCRIPTOR_FILE):\n    \"\"\"Generate user file from the PowerSystems descriptor file.\"\"\"\n    config = generate_config(input_file)\n    with open(output_file, \"w\") as fp_out:\n        yaml.dump(config, fp_out)\n\n    print(\"Generated {} from {}\".format(output_file, input_file))\n\n\ndef main():\n    \"\"\"Controls execution.\"\"\"\n    if len(sys.argv) != 2:\n        print(\"Usage: {} output_file\".format(os.path.basename(__file__)))\n        sys.exit(1)\n\n    generate_file(sys.argv[1])\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "scripts/generate_validation_config_file.py",
    "content": "#!/usr/bin/env python\n\n\"\"\"Generates a validation configuration file from JSON struct data\"\"\"\n\n# Note:  This is written in Python instead of Julia because the Julia YAML\n# package does not support writing (only reading).\n\nimport json\nimport os\nimport sys\nfrom collections import OrderedDict\n\n#import yaml\n\ndef read_json_data(filename):\n    \"\"\"Return the JSON data from a file.\"\"\"\n    with open(filename) as fp_in:\n        return json.load(fp_in)\n\n\ndef generate_config(input_file):\n    \"\"\"Generate validation descriptors from the PowerSystems struct data file.\"\"\"\n    config = {}\n    data = read_json_data(input_file)\n    items = []\n\n    for ps_struct in data[\"auto_generated_structs\"]:\n        new_struct = OrderedDict()\n        new_struct[\"struct_name\"] = ps_struct[\"struct_name\"]\n        new_struct[\"fields\"] = []\n        for field in ps_struct[\"fields\"]:\n            new_field = OrderedDict()\n            new_field[\"name\"] = field[\"name\"]\n            if \"data_type\" in field:\n                new_field[\"data_type\"] = field[\"data_type\"]\n            if \"valid_range\" in field:\n                new_field[\"valid_range\"] = field[\"valid_range\"]\n            if \"validation_action\" in field:\n                new_field[\"validation_action\"] = field[\"validation_action\"]\n            new_struct[\"fields\"].append(new_field)\n        items.append(new_struct)\n    return {\"auto_generated_structs\": items}\n\n\ndef generate_file(input_file, output_file):\n    \"\"\"Generate validation descriptors from the PowerSystems struct data file.\"\"\"\n    config = generate_config(input_file)\n    with open(output_file, \"w\") as fp_out:\n        #yaml.dump(config, fp_out, vspacing=True)\n        json.dump(config, fp_out, indent=4)\n\n    print(\"Generated {} from {}\".format(output_file, input_file))\n\n\ndef main():\n    \"\"\"Controls execution.\"\"\"\n    if len(sys.argv) != 3:\n        example = \"python bin/{} src/descriptors/power_system_structs.json validation.json\".format(\n            os.path.basename(__file__)\n        )\n        print(\"Usage: {} input_file output_file\\nExample:  {}\".format(\n            os.path.basename(__file__), example)\n        )\n        sys.exit(1)\n\n    input_file = sys.argv[1]\n    output_file = sys.argv[2]\n    generate_file(input_file, output_file)\n\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "src/PowerSystems.jl",
    "content": "isdefined(Base, :__precompile__) && __precompile__()\n\n\"\"\"\nModule for constructing self-contained power system objects.\n\"\"\"\nmodule PowerSystems\n\n#################################################################################\n# Exports\n\nexport System\nexport Topology\nexport Bus\nexport ACBus\nexport DCBus\nexport Arc\nexport AggregationTopology\nexport Area\nexport LoadZone\nexport AreaInterchange\nexport get_aggregation_topology_accessor\nexport SupplementalAttribute\nexport GeographicInfo\nexport get_geo_json\nexport PowerPlant\nexport ThermalPowerPlant\nexport CombinedCycleBlock\nexport CombinedCycleFractional\nexport CombinedCycleConfiguration\nexport HydroPowerPlant\nexport RenewablePowerPlant\nexport get_shaft_map\nexport get_reverse_shaft_map\nexport get_components_in_shaft\nexport get_configuration\nexport get_heat_recovery_to_steam_factor\nexport get_penstock_map\nexport get_reverse_penstock_map\nexport get_components_in_penstock\nexport get_hrsg_ct_map\nexport get_hrsg_ca_map\nexport get_ct_hrsg_map\nexport get_ca_hrsg_map\nexport get_pcc_map\nexport get_reverse_pcc_map\nexport get_components_in_pcc\nexport get_operation_exclusion_map\nexport get_inverse_operation_exclusion_map\nexport get_components_in_exclusion_group\n\nexport Component\nexport Device\nexport get_max_active_power\nexport get_max_reactive_power\nexport get_high_voltage\nexport get_low_voltage\nexport Branch\nexport StaticInjection\nexport StaticInjectionSubsystem\nexport DiscreteControlledACBranch\nexport ACBranch\nexport ACTransmission\nexport TwoWindingTransformer\nexport ThreeWindingTransformer\nexport TwoTerminalHVDC\nexport Line\nexport MonitoredLine\nexport GenericArcImpedance\nexport DCBranch\nexport TwoTerminalGenericHVDCLine\nexport TwoTerminalVSCLine\nexport TwoTerminalLCCLine\nexport TModelHVDCLine\nexport Transformer2W\nexport TapTransformer\nexport PhaseShiftingTransformer\nexport FACTSControlDevice\nexport Transformer3W\nexport PhaseShiftingTransformer3W\nexport SynchronousCondenser\n\n# from IS function_data.jl\nexport FunctionData\nexport LinearFunctionData\nexport QuadraticFunctionData\nexport PiecewiseLinearData\nexport PiecewiseStepData\nexport get_proportional_term\nexport get_quadratic_term\nexport get_constant_term\nexport get_slopes\nexport get_average_rates\nexport get_x_lengths\nexport is_convex\nexport is_concave\nexport get_points\nexport get_x_coords\nexport get_y_coords\n\n# from IS value_curve.jl, cost_aliases.jl, and production_variable_cost_curve.jl\nexport ValueCurve\nexport InputOutputCurve, IncrementalCurve, AverageRateCurve\nexport LinearCurve, QuadraticCurve\nexport PiecewisePointCurve, PiecewiseIncrementalCurve, PiecewiseAverageCurve\nexport ProductionVariableCostCurve, CostCurve, FuelCurve\nexport get_function_data, get_initial_input, get_input_at_zero\nexport get_value_curve, get_power_units\n\nexport OperationalCost,\n    OfferCurveCost, MarketBidCost, LoadCost, StorageCost, ImportExportCost\nexport HydroGenerationCost, RenewableGenerationCost, ThermalGenerationCost\nexport HydroReservoirCost\nexport get_fuel_cost, set_fuel_cost!, get_vom_cost\nexport is_market_bid_curve, make_market_bid_curve\nexport make_import_curve, make_export_curve\nexport get_no_load_cost, set_no_load_cost!, get_start_up, set_start_up!\nexport set_shut_down!\nexport get_curtailment_cost\nexport set_curtailment_cost!\nexport get_fixed\nexport set_fixed!\nexport get_charge_variable_cost, set_charge_variable_cost!\nexport get_discharge_variable_cost, set_discharge_variable_cost!\nexport get_energy_shortage_cost, set_energy_shortage_cost!\nexport get_energy_surplus_cost, set_energy_surplus_cost!\nexport get_level_shortage_cost, set_level_shortage_cost!\nexport get_level_surplus_cost, set_level_surplus_cost!\nexport get_spillage_cost, set_spillage_cost!\n\nexport Generator\nexport HydroGen\nexport HydroDispatch\nexport HydroTurbine\nexport HydroReservoir\nexport HydroPumpTurbine\nexport InterconnectingConverter\n\nexport RenewableGen\nexport RenewableNonDispatch\nexport RenewableDispatch\n\nexport ThermalGen\nexport ThermalStandard\nexport ThermalMultiStart\n\nexport ElectricLoad\nexport StaticLoad\nexport PowerLoad\nexport StandardLoad\nexport FixedAdmittance\nexport SwitchedAdmittance\nexport ControllableLoad\nexport InterruptiblePowerLoad\nexport InterruptibleStandardLoad\nexport ShiftablePowerLoad\nexport ExponentialLoad\nexport MotorLoad\nexport LoadConformity\n\nexport Storage\nexport EnergyReservoirStorage\n\nexport DynamicComponent\nexport DynamicInjection\nexport DynamicGenerator\n\nexport DynamicInverter\nexport DynamicBranch\nexport HybridSystem\n\nexport GenericDER\nexport AggregateDistributedGenerationA\nexport SingleCageInductionMachine\nexport SimplifiedSingleCageInductionMachine\nexport ActiveConstantPowerLoad\nexport DynamicExponentialLoad\n\n#AVR Exports\nexport AVR\nexport AVRFixed\nexport AVRSimple\nexport AVRTypeI\nexport AVRTypeII\nexport IEEET1\nexport ESDC1A\nexport ESDC2A\nexport ESAC1A\nexport ESAC6A\nexport ESAC8B\nexport EXAC1\nexport EXAC1A\nexport EXAC2\nexport EXPIC1\nexport ESST1A\nexport ESST4B\nexport ST6B\nexport SCRX\nexport SEXS\nexport ST8C\n\n#Machine Exports\nexport Machine\nexport BaseMachine\nexport RoundRotorMachine\nexport SalientPoleMachine\nexport RoundRotorQuadratic\nexport SalientPoleQuadratic\nexport RoundRotorExponential\nexport SalientPoleExponential\nexport OneDOneQMachine\nexport SauerPaiMachine\nexport MarconatoMachine\nexport SimpleMarconatoMachine\nexport AndersonFouadMachine\nexport SimpleAFMachine\nexport FullMachine\nexport SimpleFullMachine\n\n#PSS Exports\nexport PSS\nexport PSSFixed\nexport PSSSimple\nexport IEEEST\nexport STAB1\nexport PSS2A\nexport PSS2B\nexport PSS2C\nexport CSVGN1\n\n#Shaft Exports\nexport Shaft\nexport SingleMass\nexport FiveMassShaft\n\n#TG Exports\nexport TurbineGov\nexport TGFixed\nexport TGTypeI\nexport TGTypeII\nexport GasTG\nexport GeneralGovModel\nexport HydroTurbineGov\nexport IEEETurbineGov1\nexport SteamTurbineGov1\nexport DEGOV\nexport DEGOV1\nexport PIDGOV\nexport WPIDHY\nexport TGSimple\n\n# Converter Exports\nexport Converter\nexport AverageConverter\nexport RenewableEnergyConverterTypeA\nexport RenewableEnergyVoltageConverterTypeA\n\n# DC Source Exports\nexport DCSource\nexport FixedDCSource\nexport ZeroOrderBESS\n\n# Filter Exports\nexport Filter\nexport LCLFilter\nexport LCFilter\nexport RLFilter\n\n# FrequencyEstimator Exports\nexport FrequencyEstimator\nexport KauraPLL\nexport ReducedOrderPLL\nexport FixedFrequency\n\n# Outer Control Exports\nexport OuterControl\nexport VirtualInertia\nexport ReactivePowerDroop\nexport ActivePowerDroop\nexport ActivePowerPI\nexport ReactivePowerPI\nexport ActiveVirtualOscillator\nexport ReactiveVirtualOscillator\nexport ActiveRenewableControllerAB\nexport ReactiveRenewableControllerAB\n\n# InnerControl Export\nexport InnerControl\nexport VoltageModeControl\nexport CurrentModeControl\nexport RECurrentControlB\n\n# OutputCurrentLimiters Export\nexport OutputCurrentLimiter\nexport MagnitudeOutputCurrentLimiter\nexport InstantaneousOutputCurrentLimiter\nexport PriorityOutputCurrentLimiter\nexport SaturationOutputCurrentLimiter\nexport HybridOutputCurrentLimiter\n\nexport Source\nexport PeriodicVariableSource\n\nexport Contingency\n\n# Outages\nexport Outage\nexport GeometricDistributionForcedOutage\nexport PlannedOutage\nexport FixedForcedOutage\n\nexport get_mean_time_to_recovery\nexport get_outage_transition_probability\nexport get_outage_schedule\n\n# Impedance Correction Data\nexport ImpedanceCorrectionData\nexport WindingCategory\nexport WindingGroupNumber\nexport ImpedanceCorrectionTransformerControlMode\n\nexport get_table_number\nexport get_impedance_correction_curve\nexport get_transformer_winding\nexport get_transformer_control_mode\n\nexport Service\nexport AbstractReserve\nexport Reserve\nexport ReserveNonSpinning\nexport ReserveDirection\nexport ReserveUp\nexport ReserveDown\nexport ReserveSymmetric\nexport ConstantReserve\nexport VariableReserve\nexport AGC\nexport ReserveDemandCurve\nexport ConstantReserveGroup\nexport ConstantReserveNonSpinning\nexport VariableReserveNonSpinning\nexport TransmissionInterface\n\nexport AngleUnits\nexport ACBusTypes\nexport FACTSOperationModes\nexport DiscreteControlledBranchStatus\nexport DiscreteControlledBranchType\nexport PrimeMovers\nexport ThermalFuels\nexport StorageTech\nexport StateTypes\nexport ReservoirDataType\nexport MotorLoadTechnology\nexport HydroTurbineType\nexport ReservoirLocation\n\n# from IS time_series_structs.jl, time_series_cache.jl\nexport TimeSeriesAssociation\nexport TimeSeriesKey\nexport StaticTimeSeriesKey\nexport ForecastKey\nexport TimeSeriesCounts\nexport ForecastCache\nexport StaticTimeSeriesCache\n# from IS time_series_metadata_store.jl and defined for System in base.jl\nexport get_static_time_series_summary_table\nexport get_forecast_summary_table\n# from IS time_series_parser.jl\nexport NormalizationFactor\nexport NormalizationTypes\n# from IS forecasts.jl\nexport Forecast\nexport AbstractDeterministic\nexport TimeSeriesData # abstract_time_series.jl\nexport StaticTimeSeries # static_time_series.jl\nexport Deterministic # deterministic.jl\nexport Probabilistic # Probabilistic.jl\nexport SingleTimeSeries # Single_Time_Series.jl\nexport DeterministicSingleTimeSeries # deterministic_single_time_series.jl\nexport Scenarios # scenarios.jl\n\nexport get_dynamic_components\n\nexport parse_file\nexport open_time_series_store!\nexport add_time_series!\nexport bulk_add_time_series!\nexport begin_time_series_update\nexport remove_time_series!\nexport check_time_series_consistency\nexport clear_time_series!\nexport copy_time_series!\nexport copy_subcomponent_time_series!\nexport add_component!\nexport add_components!\nexport replace_dynamic_injector!\nexport remove_component!\nexport remove_components!\nexport clear_components!\nexport add_service!\nexport remove_service!\nexport clear_services!\nexport get_services\nexport has_service\nexport remove_turbine!\nexport clear_turbines!\nexport has_upstream_turbine\nexport has_downstream_turbine\nexport has_time_series\nexport get_buses\nexport is_component_in_aggregation_topology\nexport get_components_in_aggregation_topology\nexport get_aggregation_topology_mapping\nexport get_contributing_devices\nexport set_upstream_turbine!\nexport set_downstream_turbine!\nexport get_connected_head_reservoirs\nexport get_connected_tail_reservoirs\nexport get_contributing_device_mapping\nexport get_contributing_reserve_mapping\nexport get_turbine_head_reservoirs_mapping\nexport get_turbine_tail_reservoirs_mapping\nexport ServiceContributingDevices\nexport ServiceContributingDevicesKey\nexport ServiceContributingDevicesMapping\nexport TurbineConnectedDevices\nexport TurbineConnectedDevicesKey\nexport TurbineConnectedDevicesMapping\nexport get_component\nexport get_components\nexport get_num_components\nexport get_associated_components\nexport show_components\nexport get_subcomponents\nexport get_components_by_name\nexport get_available\nexport set_available!\nexport get_available_component\nexport get_available_components\nexport get_existing_device_types\nexport get_existing_component_types\nexport get_forecast_horizon\nexport get_forecast_initial_timestamp\nexport get_forecast_interval\nexport get_forecast_window_count\nexport add_supplemental_attribute!\nexport remove_supplemental_attribute!\nexport remove_supplemental_attributes!\nexport get_component_supplemental_attribute_pairs\nexport get_supplemental_attribute\nexport get_supplemental_attributes\nexport get_associated_supplemental_attributes\nexport has_supplemental_attributes\nexport iterate_supplemental_attributes\nexport begin_supplemental_attributes_update\nexport get_time_series\nexport get_time_series_type\nexport get_time_series_array\nexport get_time_series_resolutions\nexport supports_time_series\nexport supports_supplemental_attributes\nexport get_time_series_timestamps\nexport get_time_series_values\nexport get_time_series_counts\nexport get_scenario_count\nexport get_percentiles\nexport get_next_time_series_array!\nexport get_next_time\nexport reset!\nexport get_horizon\nexport get_forecast_initial_times\nexport get_time_series_keys\nexport show_time_series\nexport get_resolution\nexport get_data\nexport iterate_components\nexport get_time_series_multiple\nexport get_variable_cost\nexport get_incremental_variable_cost, get_decremental_variable_cost\nexport get_no_load_cost\nexport get_start_up\nexport get_shut_down\nexport get_incremental_offer_curves, set_incremental_offer_curves!\nexport get_decremental_offer_curves, set_decremental_offer_curves!\nexport get_incremental_initial_input, set_incremental_initial_input!\nexport get_decremental_initial_input, set_decremental_initial_input!\nexport get_ancillary_service_offers, set_ancillary_service_offers!\nexport get_import_offer_curves, set_import_offer_curves!\nexport get_export_offer_curves, set_export_offer_curves!\nexport get_import_variable_cost, get_export_variable_cost\nexport get_energy_import_weekly_limit, set_energy_import_weekly_limit!\nexport get_energy_export_weekly_limit, set_energy_export_weekly_limit!\nexport get_services_bid\nexport set_variable_cost!\nexport set_incremental_variable_cost!, set_decremental_variable_cost!\nexport set_import_variable_cost!, set_export_variable_cost!\nexport set_service_bid!\nexport iterate_windows\nexport get_window\nexport transform_single_time_series!\nexport sanitize_component!\nexport validate_component\nexport validate_component_with_system\nexport get_compression_settings\nexport CompressionSettings\nexport CompressionTypes\n\n# Parsing functions\nexport create_poly_cost\n\n#export make_time_series\nexport get_bus_numbers\nexport set_bus_number!\nexport set_number!  # Remove this in v5.0.\nexport get_name\nexport set_name!\nexport get_component_uuids\nexport get_description\nexport set_description!\nexport get_base_power\nexport get_frequency\nexport get_frequency_droop\nexport set_units_base_system!\nexport with_units_base\nexport to_json\nexport from_json\nexport serialize\nexport deserialize\nexport clear_ext!\nexport convert_component!\nexport set_area!\nexport set_load_zone!\nexport PowerModelsData\nexport PowerSystemTableData\nexport add_dyn_injectors!\nexport get_machine\nexport get_shaft\nexport get_avr\nexport get_prime_mover\nexport get_pss\nexport get_converter\nexport get_outer_control\nexport get_inner_control\nexport get_dc_source\nexport get_freq_estimator\nexport get_filter\nexport get_V_ref\nexport get_P_ref\nexport get_saturation_coeffs\nexport get_units_base\nexport get_runchecks\nexport get_thermal_unit\nexport get_electric_load\nexport get_storage\nexport get_renewable_unit\nexport get_interconnection_rating\nexport get_interconnection_impedance\nexport get_from_to_flow_limit\nexport get_to_from_flow_limit\nexport get_min_active_power_flow_limit\nexport get_max_active_power_flow_limit\n\n# Subsystems\nexport add_subsystem!\nexport get_subsystems\nexport get_num_subsystems\nexport remove_subsystem!\nexport add_component_to_subsystem!\nexport get_subsystem_components\nexport remove_component_from_subsystem!\nexport remove_component_from_subsystems!\nexport has_component\nexport has_components\nexport get_assigned_subsystems\nexport has_subsystems\nexport is_assigned_to_subsystem\nexport from_subsystem\nexport filter_components_by_subsystem!\n\nexport set_runchecks!\nexport check\nexport check_component\nexport check_components\nexport check_ac_transmission_rate_values\n\n# From IS logging.jl, generate_struct_files.jl\nexport configure_logging\nexport open_file_logger\nexport make_logging_config_file\nexport MultiLogger\nexport LogEventTracker\nexport StructField\nexport StructDefinition\nexport generate_struct_file\nexport generate_struct_files\nexport UnitSystem # internal.jl\n\n# ComponentSelector\nexport ComponentSelector\nexport SingularComponentSelector\nexport PluralComponentSelector\nexport DynamicallyGroupedComponentSelector\nexport subtype_to_string\nexport component_to_qualified_string\nexport make_selector\nexport rebuild_selector\nexport get_groups\nexport get_available_groups\n#################################################################################\n# Imports\n\nimport Base: @kwdef\nimport LinearAlgebra\nimport Unicode: normalize\nimport Logging\nimport Dates\nimport TimeSeries\nimport DataFrames\nimport DataStructures: OrderedDict, SortedDict\nimport JSON3\nimport CSV\nimport YAML\nimport UUIDs\nimport Base.to_index\nimport InteractiveUtils\nimport PrettyTables\nimport PowerFlowData\n\n# Import InfrastructureSystems both as full module name (needed for internal macros like @forward)\n# and with alias for convenient usage throughout the codebase\nimport InfrastructureSystems\nimport InfrastructureSystems as IS\nimport InfrastructureSystems:\n    Components,\n    TimeSeriesData,\n    StaticTimeSeries,\n    Forecast,\n    AbstractDeterministic,\n    Deterministic,\n    Probabilistic,\n    SingleTimeSeries,\n    StaticTimeSeriesKey,\n    DeterministicSingleTimeSeries,\n    ForecastKey,\n    Scenarios,\n    ForecastCache,\n    StaticTimeSeriesCache,\n    TimeSeriesKey,\n    TimeSeriesCounts,\n    TimeSeriesAssociation,\n    InfrastructureSystemsComponent,\n    InfrastructureSystemsType,\n    InfrastructureSystemsInternal,\n    SupplementalAttribute,\n    DeviceParameter,\n    FlattenIteratorWrapper,\n    LazyDictFromIterator,\n    DataFormatError,\n    InvalidRange,\n    InvalidValue,\n    GeographicInfo,\n    get_geo_json,\n    copy_time_series!,\n    get_available,\n    set_available!,\n    get_count,\n    get_data,\n    get_horizon,\n    get_resolution,\n    get_window,\n    get_name,\n    get_num_components,\n    get_component_uuids,\n    get_supplemental_attribute,\n    get_supplemental_attributes,\n    set_name!,\n    get_internal,\n    set_internal!,\n    iterate_windows,\n    get_time_series,\n    has_time_series,\n    get_time_series_type,\n    get_time_series_array,\n    get_time_series_timestamps,\n    get_time_series_values,\n    get_time_series_keys,\n    show_time_series,\n    get_scenario_count, # Scenario Forecast Exports\n    get_percentiles, # Probabilistic Forecast Exports\n    get_next_time_series_array!,\n    get_next_time,\n    reset!,\n    has_supplemental_attributes,\n    get_units_info,\n    set_units_info!,\n    to_json,\n    from_json,\n    serialize,\n    deserialize,\n    get_time_series_multiple,\n    compare_values,\n    CompressionSettings,\n    CompressionTypes,\n    NormalizationFactor,\n    NormalizationTypes,\n    UnitSystem,\n    SystemUnitsSettings,\n    open_file_logger,\n    make_logging_config_file,\n    validate_struct,\n    MultiLogger,\n    LogEventTracker,\n    StructField,\n    StructDefinition,\n    FunctionData,\n    LinearFunctionData,\n    QuadraticFunctionData,\n    PiecewiseLinearData,\n    PiecewiseStepData,\n    get_proportional_term,\n    get_quadratic_term,\n    get_constant_term,\n    get_slopes,\n    running_sum,\n    get_x_lengths,\n    is_convex,\n    is_concave,\n    get_points,  # TODO possible rename to disambiguate from geographical information\n    get_x_coords,\n    get_y_coords,\n    get_raw_data_type,\n    supports_time_series,\n    supports_supplemental_attributes,\n    fast_deepcopy_system,\n    ComponentSelector,\n    SingularComponentSelector,\n    PluralComponentSelector,\n    DynamicallyGroupedComponentSelector,\n    NameComponentSelector,\n    ListComponentSelector,\n    TypeComponentSelector,\n    FilterComponentSelector,\n    RegroupedComponentSelector,\n    component_to_qualified_string,\n    subtype_to_string,\n    COMPONENT_NAME_DELIMITER,\n    make_selector,\n    rebuild_selector\n\nimport InfrastructureSystems:\n    ValueCurve,\n    InputOutputCurve,\n    IncrementalCurve,\n    AverageRateCurve,\n    LinearCurve,\n    QuadraticCurve,\n    PiecewisePointCurve,\n    PiecewiseIncrementalCurve,\n    PiecewiseAverageCurve,\n    get_function_data,\n    get_initial_input,\n    get_input_at_zero,\n    get_average_rates,\n    ProductionVariableCostCurve,\n    CostCurve,\n    FuelCurve,\n    get_value_curve,\n    get_vom_cost,\n    get_startup_fuel_offtake,\n    get_power_units,\n    get_fuel_cost\n\n#################################################################################\n\nusing DocStringExtensions\n\n@template (FUNCTIONS, METHODS) = \"\"\"\n                                 $(TYPEDSIGNATURES)\n                                 $(DOCSTRING)\n                                 \"\"\"\n\n#################################################################################\n# Includes\n\n\"\"\"\nSupertype for all PowerSystems components.\nAll subtypes must include a InfrastructureSystemsInternal member.\nSubtypes should call InfrastructureSystemsInternal() by default, but also must\nprovide a constructor that allows existing values to be deserialized.\n\"\"\"\nabstract type Component <: IS.InfrastructureSystemsComponent end\n\n\"\"\" Supertype for \"devices\" (bus, line, etc.) \"\"\"\nabstract type Device <: Component end\n\n\"\"\"\nAll PowerSystems [Device](@ref) types support time series. This can be overridden for \ncustom component types that do not support time series.\n\"\"\"\nsupports_time_series(::Device) = true\n\"\"\"\nAll PowerSystems [Device](@ref) types support supplemental attributes. This can be overridden for \ncustom component types that do not support supplemental attributes.\n\"\"\"\nsupports_supplemental_attributes(::Device) = true\n\n# Include utilities\ninclude(\"utils/logging.jl\")\ninclude(\"utils/IO/base_checks.jl\")\ninclude(\"utils/generate_struct_files.jl\")\n\ninclude(\"definitions.jl\")\ninclude(\"models/static_models.jl\")\ninclude(\"models/dynamic_models.jl\")\ninclude(\"models/injection.jl\")\ninclude(\"models/static_injection_subsystem.jl\")\n\n# PowerSystems models\ninclude(\"models/topological_elements.jl\")\ninclude(\"models/branches.jl\")\n#include(\"models/network.jl\")\n\n# Static types\ninclude(\"models/services.jl\")\ninclude(\"models/reserves.jl\")\ninclude(\"models/generation.jl\")\ninclude(\"models/storage.jl\")\ninclude(\"models/loads.jl\")\ninclude(\"models/dynamic_generator_components.jl\")\ninclude(\"models/dynamic_inverter_components.jl\")\ninclude(\"models/OuterControl.jl\")\n\n# Costs\ninclude(\"models/cost_functions/operational_cost.jl\")\ninclude(\"models/cost_functions/OfferCurveCost.jl\")\ninclude(\"models/cost_functions/MarketBidCost.jl\")\ninclude(\"models/cost_functions/ImportExportCost.jl\")\ninclude(\"models/cost_functions/HydroGenerationCost.jl\")\ninclude(\"models/cost_functions/LoadCost.jl\")\ninclude(\"models/cost_functions/RenewableGenerationCost.jl\")\ninclude(\"models/cost_functions/StorageCost.jl\")\ninclude(\"models/cost_functions/ThermalGenerationCost.jl\")\ninclude(\"models/cost_functions/HydroReservoirCost.jl\")\n\n# Include all auto-generated structs.\ninclude(\"models/generated/includes.jl\")\ninclude(\"models/HybridSystem.jl\")\n\n#Methods for devices\ninclude(\"models/components.jl\")\ninclude(\"models/devices.jl\")\n\n# Dynamic Composed types\ninclude(\"models/dynamic_generator.jl\")\ninclude(\"models/dynamic_inverter.jl\")\ninclude(\"models/dynamic_loads.jl\")\ninclude(\"models/dynamic_machines.jl\")\ninclude(\"models/RoundRotorExponential.jl\")\ninclude(\"models/RoundRotorQuadratic.jl\")\ninclude(\"models/SalientPoleExponential.jl\")\ninclude(\"models/SalientPoleQuadratic.jl\")\ninclude(\"models/dynamic_branch.jl\")\n\ninclude(\"impedance_correction.jl\")\ninclude(\"models/supplemental_constructors.jl\")\ninclude(\"models/supplemental_accessors.jl\")\ninclude(\"models/supplemental_setters.jl\")\n\n# Supplemental attributes\ninclude(\"contingencies.jl\")\ninclude(\"outages.jl\")\n\n# Definitions of PowerSystem\ninclude(\"base.jl\")\ninclude(\"plant_attribute.jl\")\ninclude(\"subsystems.jl\")\ninclude(\"component_selector.jl\")\ninclude(\"data_format_conversions.jl\")\ninclude(\"get_components_interface.jl\")\ninclude(\"component_selector_interface.jl\")\n\n#Data Checks\ninclude(\"utils/IO/system_checks.jl\")\ninclude(\"utils/IO/branchdata_checks.jl\")\n\n# cost function TimeSeries convertion\ninclude(\"models/cost_function_timeseries.jl\")\n\n#Conversions\ninclude(\"utils/conversion.jl\")\n\n# Include Parsing files\ninclude(\"parsers/common.jl\")\ninclude(\"parsers/enums.jl\")\ninclude(\"parsers/pm_io.jl\")\ninclude(\"parsers/im_io.jl\")\ninclude(\"parsers/power_system_table_data.jl\")\ninclude(\"parsers/power_models_data.jl\")\ninclude(\"parsers/powerflowdata_data.jl\")\ninclude(\"parsers/psse_dynamic_data.jl\")\ninclude(\"parsers/psse_metadata_reimport.jl\")\n\n# Better printing\ninclude(\"utils/print.jl\")\n@static if pkgversion(PrettyTables).major == 2\n    # When PrettyTables v2 is more widely adopted in the ecosystem, we can remove this file.\n    # In this case, we should also update the compat bounds in Project.toml to list only\n    # PrettyTables v3.\n    include(\"utils/print_pt_v2.jl\")\nelse\n    include(\"utils/print_pt_v3.jl\")\nend\n\ninclude(\"models/serialization.jl\")\n\n#Deprecated\ninclude(\"deprecated.jl\")\n\nend # module\n"
  },
  {
    "path": "src/base.jl",
    "content": "\nconst SKIP_PM_VALIDATION = false\n\nconst SYSTEM_KWARGS = Set((\n    :area_name_formatter,\n    :branch_name_formatter,\n    :xfrm_3w_name_formatter,\n    :switched_shunt_name_formatter,\n    :transformer_control_objective_formatter,\n    :dcline_name_formatter,\n    :vscline_name_formatter,\n    :bus_name_formatter,\n    :config_path,\n    :frequency,\n    :gen_name_formatter,\n    :generator_mapping,\n    :internal,\n    :load_name_formatter,\n    :loadzone_name_formatter,\n    :runchecks,\n    :shunt_name_formatter,\n    :time_series_directory,\n    :time_series_in_memory,\n    :time_series_read_only,\n    :timeseries_metadata_file,\n    :unit_system,\n    :pm_data_corrections,\n    :import_all,\n    :enable_compression,\n    :compression,\n    :name,\n    :description,\n))\n\n# This will be used in the future to handle serialization changes.\nconst DATA_FORMAT_VERSION = \"5.0.0\"\n\nmutable struct SystemMetadata <: IS.InfrastructureSystemsType\n    name::Union{Nothing, String}\n    description::Union{Nothing, String}\nend\n\n\"\"\"\nA power system\n\n`System` is the main data container in `PowerSystems.jl`, including basic metadata (base\npower, frequency), components (network topology, loads, generators, and services), and\ntime series data.\n\n```julia\nSystem(base_power)\nSystem(base_power, buses, components...)\nSystem(base_power, buses, generators, loads, branches, storage, services; kwargs...)\nSystem(base_power, buses, generators, loads; kwargs...)\nSystem(file; kwargs...)\nSystem(; buses, generators, loads, branches, storage, base_power, services, kwargs...)\nSystem(; kwargs...)\n```\n\n# Arguments\n- `base_power::Float64`: the base power value for the system\n- `buses::Vector{ACBus}`: an array of buses\n- `components...`: Each element (e.g., `buses`, `generators`, ...) must be an iterable\n    containing subtypes of `Component`.\n- `file::AbstractString`: Path to a Matpower, PSSE, or JSON file ending with .m, .raw, or .json\n\n# Keyword arguments\n- `name::String`: System name.\n- `description::String`: System description.\n- `frequency::Float64`: (default = 60.0) Operating frequency (Hz).\n- `runchecks::Bool`: Run available checks on input fields and when add_component! is called.\n  Throws InvalidValue if an error is found.\n- `generator_mapping`: A dictionary mapping generator names to their corresponding topologies. This is used to associate generators with their respective buses when parsing from CSV.\n- `time_series_in_memory::Bool=false`: Store time series data in memory instead of HDF5.\n- `time_series_directory::Union{Nothing, String}`: Directory for the time series HDF5 file.\n    Defaults to the tmp file system.\n- `timeseries_metadata_file`: Path to a file containing time series metadata descriptors. This is used to add time series data to the system from files.\n- `time_series_read_only::Bool=false`: Open the time series store in read-only mode.\n    This is useful for reading time series data without modifying it.\n- `enable_compression::Bool=false`: Enable compression of time series data in HDF5.\n- `compression::CompressionSettings`: Allows customization of HDF5 compression settings.\n- `config_path::String`: specify path to validation config file\n- `unit_system::String`: (Default = `\"SYSTEM_BASE\"`) Set the unit system for\n    [per-unitization](@ref per_unit) while getting and setting data (`\"SYSTEM_BASE\"`,\n        `\"DEVICE_BASE\"`, or `\"NATURAL_UNITS\"`)\n- `bus_name_formatter`: A function that takes a `Dict` of bus data (with keys like `\"name\"` and `\"index\"`) and returns a `String` to use as the bus name when [parsing PSSe or Matpower files](@ref pm_data).\n- `load_name_formatter`: A function that takes a `Dict` of load data (with key `\"source_id\"`) and returns a `String` to use as the load name when [parsing PSSe or Matpower files](@ref pm_data).\n- `loadzone_name_formatter`: A function that takes a load zone identifier (typically an `Int`) and returns a `String` to use as the load zone name when [parsing PSSe or Matpower files](@ref pm_data).\n- `gen_name_formatter`: A function that takes a `Dict` of generator data and returns a `String` to use as the generator name when [parsing PSSe or Matpower files](@ref pm_data).\n- `shunt_name_formatter`: A function that takes a `Dict` of shunt data and returns a `String` to use as the [`FixedAdmittance`](@ref) name when [parsing PSSe or Matpower files](@ref pm_data).\n- `branch_name_formatter`: A function that takes a `Dict` of branch data, a from-bus (`ACBus`), and a to-bus (`ACBus`), and returns a `String` to use as the branch name when [parsing PSSe or Matpower files](@ref pm_data).\n- `pm_data_corrections::Bool`: A function that applies the correction to the data from [`PowerModels.jl`](https://lanl-ansi.github.io/PowerModels.jl/stable/).\n- `import_all::Bool`: A boolean flag to indicate whether to import all available data when [parsing PSSe or Matpower files](@ref pm_data). The additional data will be stored in the `ext` dictionary and can be retrieved using [`get_ext`](@ref)\n- `internal::IS.InfrastructureSystemsInternal`: Internal structure for [`InfrastructureSystems.jl`](https://sienna-platform.github.io/InfrastructureSystems.jl/stable/). This is used only during JSON de-seralization, do not pass it when building a `System` manually.\n\nBy default, time series data is stored in an HDF5 file in the tmp file system to prevent\nlarge datasets from overwhelming system memory (see [Data Storage](@ref)).\n**If the system's time series data will be larger than the amount of tmp space available**, use the\n`time_series_directory` parameter to change its location.\nYou can also override the location by setting the environment\nvariable `SIENNA_TIME_SERIES_DIRECTORY` to another directory.\n\nHDF5 compression is not enabled by default, but you can enable\nit with `enable_compression` to get significant storage savings at the cost of CPU time.\n[`CompressionSettings`](@ref) can be used to customize the HDF5 compression.\n\nIf you know that your dataset will fit in your computer's memory, then you can increase\nperformance by storing it in memory with `time_series_in_memory`.\n\n# Examples\n```julia\nsys = System(100.0; name = \"My Power System\")\nsys = System(100.0; name = \"My Power System\", description = \"System corresponds to scenario A\")\nsys= System(path_to_my_psse_raw_file; # PSSE file bus names are not unique\n    bus_name_formatter = x -> strip(string(x[\"name\"])) * \"-\" * string(x[\"index\"]),\n)\nsys = System(100.0; enable_compression = true)\nsys = System(100.0; compression = CompressionSettings(\n    enabled = true,\n    type = CompressionTypes.DEFLATE,  # BLOSC is also supported\n    level = 3,\n    shuffle = true)\n)\nsys = System(100.0; time_series_in_memory = true)\n```\n\"\"\"\nstruct System <: IS.ComponentContainer\n    data::IS.SystemData\n    frequency::Float64 # [Hz]\n    bus_numbers::Set{Int}\n    runchecks::Base.RefValue{Bool}\n    units_settings::SystemUnitsSettings\n    time_series_directory::Union{Nothing, String}\n    metadata::SystemMetadata\n    internal::IS.InfrastructureSystemsInternal\n\n    function System(\n        data,\n        units_settings::SystemUnitsSettings,\n        internal::IS.InfrastructureSystemsInternal;\n        runchecks = true,\n        frequency = DEFAULT_SYSTEM_FREQUENCY,\n        time_series_directory = nothing,\n        name = nothing,\n        description = nothing,\n        kwargs...,\n    )\n        # Note to devs: if you add parameters to kwargs then consider whether they need\n        # special handling in the deserialization function in this file.\n        # See deserialize for System.\n\n        # Implement a strict check here to make sure that SYSTEM_KWARGS can be used\n        # elsewhere.\n        unsupported = setdiff(keys(kwargs), SYSTEM_KWARGS)\n        !isempty(unsupported) && error(\"Unsupported kwargs = $unsupported\")\n        if !isnothing(get(kwargs, :unit_system, nothing))\n            @warn(\n                \"unit_system kwarg ignored. The value in SystemUnitsSetting takes precedence\"\n            )\n        end\n        bus_numbers = Set(get_number.(IS.get_components(ACBus, data)))\n        return new(\n            data,\n            frequency,\n            bus_numbers,\n            Base.RefValue{Bool}(runchecks),\n            units_settings,\n            time_series_directory,\n            SystemMetadata(name, description),\n            internal,\n        )\n    end\nend\n\nfunction System(data, base_power::Number, internal; kwargs...)\n    unit_system_ = get(kwargs, :unit_system, \"SYSTEM_BASE\")\n    unit_system = UNIT_SYSTEM_MAPPING[unit_system_]\n    units_settings = SystemUnitsSettings(base_power, unit_system)\n    return System(data, units_settings, internal; kwargs...)\nend\n\n\"\"\"Construct an empty `System`. Useful for building a System while parsing raw data.\"\"\"\nfunction System(base_power::Number; kwargs...)\n    return System(_create_system_data_from_kwargs(; kwargs...), base_power; kwargs...)\nend\n\n\"\"\"Construct a `System` from `InfrastructureSystems.SystemData`\"\"\"\nfunction System(\n    data,\n    base_power::Number;\n    internal = IS.InfrastructureSystemsInternal(),\n    kwargs...,\n)\n    return System(data, base_power, internal; kwargs...)\nend\n\n\"\"\"\nSystem constructor when components are constructed externally.\n\"\"\"\nfunction System(base_power::Float64, buses::Vector{ACBus}, components...; kwargs...)\n    data = _create_system_data_from_kwargs(; kwargs...)\n    sys = System(data, base_power; kwargs...)\n\n    for bus in buses\n        add_component!(sys, bus)\n    end\n\n    for component in Iterators.flatten(components)\n        add_component!(sys, component)\n    end\n\n    if get(kwargs, :runchecks, true)\n        check(sys)\n    end\n\n    return sys\nend\n\n\"\"\"Constructs a non-functional System for demo purposes.\"\"\"\nfunction System(\n    ::Nothing;\n    buses = [\n        ACBus(;\n            number = 0,\n            name = \"init\",\n            bustype = ACBusTypes.REF,\n            available = true,\n            angle = 0.0,\n            magnitude = 0.0,\n            voltage_limits = (min = 0.0, max = 0.0),\n            base_voltage = nothing,\n            area = nothing,\n            load_zone = nothing,\n            ext = Dict{String, Any}(),\n        ),\n    ],\n    generators = [ThermalStandard(nothing), RenewableNonDispatch(nothing)],\n    loads = [PowerLoad(nothing)],\n    branches = nothing,\n    storage = nothing,\n    base_power::Float64 = 100.0,\n    services = nothing,\n    kwargs...,\n)\n    for component in Iterators.flatten((generators, loads))\n        if get_name(component) == \"init\"\n            set_bus!(component, first(buses))\n        end\n    end\n    _services = isnothing(services) ? [] : services\n    _branches = isnothing(branches) ? [] : branches\n    _storage = isnothing(storage) ? [] : storage\n    return System(\n        base_power,\n        buses,\n        generators,\n        loads,\n        _branches,\n        _storage,\n        _services;\n        kwargs...,\n    )\nend\n\nfunction system_via_power_models(file_path::AbstractString; kwargs...)\n    pm_kwargs = Dict(k => v for (k, v) in kwargs if !in(k, SYSTEM_KWARGS))\n    sys_kwargs = Dict(k => v for (k, v) in kwargs if in(k, SYSTEM_KWARGS))\n    return System(PowerModelsData(file_path; pm_kwargs...); sys_kwargs...)\nend\n\n\"\"\"Constructs a System from a file path ending with .m, .raw, or .json\n\nIf the file is JSON, then `assign_new_uuids = true` will generate new UUIDs for the system\nand all components. If the file is .raw, then `try_reimport = false` will skip searching for\na `<name>_export_metadata.json` file in the same directory.\n\"\"\"\nfunction System(\n    file_path::AbstractString;\n    assign_new_uuids = false,\n    try_reimport = true,\n    kwargs...,\n)\n    ext = lowercase(splitext(file_path)[2])\n    if ext == \".m\"\n        return system_via_power_models(file_path; kwargs...)\n    elseif ext == \".raw\"\n        try_reimport && return system_from_psse_reimport(file_path; kwargs...)\n        return system_via_power_models(file_path; kwargs...)\n    elseif ext == \".json\"\n        unsupported = setdiff(keys(kwargs), SYSTEM_KWARGS)\n        !isempty(unsupported) && error(\"Unsupported kwargs = $unsupported\")\n        runchecks = get(kwargs, :runchecks, true)\n        time_series_read_only = get(kwargs, :time_series_read_only, false)\n        time_series_directory = get(kwargs, :time_series_directory, nothing)\n        config_path = get(kwargs, :config_path, POWER_SYSTEM_STRUCT_DESCRIPTOR_FILE)\n        sys = deserialize(\n            System,\n            file_path;\n            time_series_read_only = time_series_read_only,\n            runchecks = runchecks,\n            time_series_directory = time_series_directory,\n            config_path = config_path,\n        )\n        _post_deserialize_handling(\n            sys;\n            runchecks = runchecks,\n            assign_new_uuids = assign_new_uuids,\n        )\n        return sys\n    else\n        throw(DataFormatError(\"$file_path is not a supported file type\"))\n    end\nend\n\n\"\"\"\nIf assign_new_uuids = true, generate new UUIDs for the system and all components.\n\nWarning: time series data is not restored by this method. If that is needed, use the normal\nprocess to construct the system from a serialized JSON file instead, such as with\n`System(\"sys.json\")`.\n\"\"\"\nfunction IS.from_json(\n    io::Union{IO, String},\n    ::Type{System};\n    runchecks = true,\n    assign_new_uuids = false,\n    kwargs...,\n)\n    data = JSON3.read(io, Dict)\n    sys = from_dict(System, data; kwargs...)\n    _post_deserialize_handling(\n        sys;\n        runchecks = runchecks,\n        assign_new_uuids = assign_new_uuids,\n    )\n    return sys\nend\n\nfunction _post_deserialize_handling(sys::System; runchecks = true, assign_new_uuids = false)\n    runchecks && check(sys)\n    if assign_new_uuids\n        IS.assign_new_uuid!(sys)\n        for component in get_components(Component, sys)\n            IS.assign_new_uuid!(sys, component)\n        end\n        for component in\n            IS.get_masked_components(InfrastructureSystemsComponent, sys.data)\n            IS.assign_new_uuid!(sys, component)\n        end\n        # Note: this does not change UUIDs for time series data because they are\n        # shared with components.\n    end\nend\n\n\"\"\"\nParse static and dynamic data directly from PSS/e text files. Automatically generates\nall the relationships between the available dynamic injection models and the static counterpart\n\nEach dictionary indexed by id contains a vector with 5 of its components:\n* Machine\n* Shaft\n* AVR\n* TurbineGov\n* PSS\n\nFiles must be parsed from a .raw file (PTI data format) and a .dyr file.\n\n## Examples:\n```julia\nraw_file = \"Example.raw\"\ndyr_file = \"Example.dyr\"\nsys = System(raw_file, dyr_file)\n```\n\n\"\"\"\nfunction System(sys_file::AbstractString, dyr_file::AbstractString; kwargs...)\n    ext = splitext(sys_file)[2]\n    if lowercase(ext) in [\".raw\"]\n        pm_kwargs = Dict(k => v for (k, v) in kwargs if !in(k, SYSTEM_KWARGS))\n        sys = System(PowerModelsData(sys_file; pm_kwargs...); kwargs...)\n    else\n        throw(DataFormatError(\"$sys_file is not a .raw file type\"))\n    end\n    add_dyn_injectors!(sys, dyr_file)\n    return sys\nend\n\n\"\"\"\nConstruct a System from a subsystem of an existing system.\n\n# Arguments\n- `sys::System`: the base system from which the subsystems are derived\n- `subsystem::String`: the name of the subsystem to extract from the original system\n\n# Keyword arguments\n- `runchecks::Bool`: (default = true) whether to run system validation checks.\n\"\"\"\nfunction from_subsystem(sys::System, subsystem::AbstractString; runchecks = true)\n    if !in(subsystem, get_subsystems(sys))\n        error(\"subsystem = $subsystem is not stored\")\n    end\n\n    # It would be faster to create an empty system and then populate it with\n    # deep copies of each component in the subsystem. It would also result in a \"clean\" HDF5\n    # file (the result here will have deleted entries that need to repacked through\n    # serialization/de-serialization). That is not implemented because\n    # 1. The performance loss should not be too large.\n    # 2. We haven't yet implemented deepcopy(Component).\n    # 3. There is extra code complexity in adding copied components in the correct order\n    #    as well as copying time series data.\n    new_sys = deepcopy(sys)\n    filter_components_by_subsystem!(new_sys, subsystem; runchecks = runchecks)\n\n    IS.assign_new_uuid!(new_sys)\n    for component in get_components(Component, new_sys)\n        IS.assign_new_uuid!(new_sys, component)\n    end\n\n    return new_sys\nend\n\n\"\"\"\nFilter out all components that are not part of the subsystem.\n\"\"\"\nfunction filter_components_by_subsystem!(\n    sys::System,\n    subsystem::AbstractString;\n    runchecks = true,\n)\n    component_uuids = get_component_uuids(sys, subsystem)\n    for component in get_components(Component, sys)\n        if !in(IS.get_uuid(component), component_uuids)\n            remove_component!(sys, component)\n        end\n    end\n\n    for component in IS.get_masked_components(Component, sys.data)\n        if !in(IS.get_uuid(component), component_uuids)\n            IS.remove_masked_component!(sys.data, component)\n        end\n    end\n\n    if runchecks\n        check(sys)\n        check_components(sys)\n    end\nend\n\n\"\"\"\nSerializes a system to a JSON file and saves time series to an HDF5 file.\n\n# Arguments\n- `sys::System`: system\n- `filename::AbstractString`: filename to write\n\n# Keyword arguments\n- `user_data::Union{Nothing, Dict} = nothing`: optional metadata to record\n- `pretty::Bool = false`: whether to pretty-print the JSON\n- `force::Bool = false`: whether to overwrite existing files\n- `check::Bool = false`: whether to run system validation checks\n\nRefer to [`check_component`](@ref) for exceptions thrown if `check = true`.\n\"\"\"\nfunction IS.to_json(\n    sys::System,\n    filename::AbstractString;\n    user_data = nothing,\n    pretty = false,\n    force = false,\n    runchecks = false,\n)\n    if runchecks\n        check(sys)\n        check_components(sys)\n    end\n\n    IS.prepare_for_serialization_to_file!(sys.data, filename; force = force)\n    data = to_json(sys; pretty = pretty)\n    open(filename, \"w\") do io\n        write(io, data)\n    end\n\n    mfile = joinpath(dirname(filename), splitext(basename(filename))[1] * \"_metadata.json\")\n    @info \"Serialized System to $filename\"\n    _serialize_system_metadata_to_file(sys, mfile, user_data)\n    return\nend\n\nfunction _serialize_system_metadata_to_file(sys::System, filename, user_data)\n    name = get_name(sys)\n    description = get_description(sys)\n    resolutions = [x.value for x in get_time_series_resolutions(sys)]\n    metadata = OrderedDict(\n        \"name\" => isnothing(name) ? \"\" : name,\n        \"description\" => isnothing(description) ? \"\" : description,\n        \"frequency\" => sys.frequency,\n        \"time_series_resolutions_milliseconds\" => resolutions,\n        \"component_counts\" => IS.get_component_counts_by_type(sys.data),\n        \"time_series_counts\" => IS.get_time_series_counts_by_type(sys.data),\n    )\n    if !isnothing(user_data)\n        metadata[\"user_data\"] = user_data\n    end\n\n    open(filename, \"w\") do io\n        JSON3.pretty(io, metadata)\n    end\n\n    @info \"Serialized System metadata to $filename\"\nend\n\nIS.assign_new_uuid!(sys::System) = IS.assign_new_uuid_internal!(sys)\n\n\"\"\"\nReturn the internal of the system\n\"\"\"\nIS.get_internal(sys::System) = sys.internal\n\n\"\"\"\nReturn a user-modifiable dictionary to store extra information.\n\"\"\"\nget_ext(sys::System) = IS.get_ext(sys.internal)\n\n\"\"\"\nReturn the system's base power.\n\"\"\"\nget_base_power(sys::System) = sys.units_settings.base_value\n\n\"\"\"\nReturn the system's frequency.\n\"\"\"\nget_frequency(sys::System) = sys.frequency\n\n\"\"\"\nClear any value stored in ext.\n\"\"\"\nclear_ext!(sys::System) = IS.clear_ext!(sys.internal)\n\n\"\"\"\nReturn true if checks are enabled on the system.\n\"\"\"\nget_runchecks(sys::System) = sys.runchecks[]\n\n\"\"\"\nEnable or disable system checks.\nApplies to component addition as well as overall system consistency.\n\"\"\"\nfunction set_runchecks!(sys::System, value::Bool)\n    sys.runchecks[] = value\n    @info \"Set runchecks to $value\"\nend\n\nfunction set_units_setting!(\n    component::Component,\n    settings::Union{SystemUnitsSettings, Nothing},\n)\n    set_units_info!(get_internal(component), settings)\n    return\nend\n\nfunction _set_units_base!(system::System, settings::UnitSystem)\n    to_change = (system.units_settings.unit_system != settings)\n    to_change && (system.units_settings.unit_system = settings)\n    return (to_change, settings)\nend\n\n_set_units_base!(system::System, settings::String) =\n    _set_units_base!(system::System, UNIT_SYSTEM_MAPPING[uppercase(settings)])\n\n\"\"\"\nSets the units base for the getter functions on the devices. It modifies the behavior of all getter functions\n\n# Examples\n```julia\nset_units_base_system!(sys, \"NATURAL_UNITS\")\n```\n```julia\nset_units_base_system!(sys, UnitSystem.SYSTEM_BASE)\n```\n\"\"\"\nfunction set_units_base_system!(system::System, units::Union{UnitSystem, String})\n    changed, new_units = _set_units_base!(system::System, units)\n    changed && @info \"Unit System changed to $new_units\"\n    return\nend\n\n_get_units_base(system::System) = system.units_settings.unit_system\n\n\"\"\"\nGet the system's [unit base](@ref per_unit))\n\"\"\"\nfunction get_units_base(system::System)\n    return string(_get_units_base(system))\nend\n\n\"\"\"\nA \"context manager\" that sets the [`System`](@ref)'s [units base](@ref per_unit) to the\ngiven value, executes the function, then sets the units base back.\n\n# Examples\n```julia\nactive_power_mw = with_units_base(sys, UnitSystem.NATURAL_UNITS) do\n    get_active_power(gen)\nend\n# now active_power_mw is in natural units no matter what units base the system is in\n```\n\"\"\"\nfunction with_units_base(f::Function, sys::System, units::Union{UnitSystem, String})\n    old_units = _get_units_base(sys)\n    _set_units_base!(sys, units)\n    try\n        f()\n    finally\n        _set_units_base!(sys, old_units)\n    end\nend\n\n_set_units_base!(c::Component, settings::String) =\n    _set_units_base!(c::Component, UNIT_SYSTEM_MAPPING[uppercase(settings)])\n\nfunction _set_units_base!(c::Component, settings::UnitSystem)\n    units_info = get_internal(c).units_info\n    old_base_value = units_info.base_value\n    set_units_setting!(\n        c,\n        SystemUnitsSettings(old_base_value, settings),\n    )\n    return\nend\n\n\"\"\"\nA \"context manager\" that sets the [`Component`](@ref)'s [units base](@ref per_unit) to the\ngiven value, executes the function, then sets the units base back.\n\n# Examples\n```julia\nactive_power_mw = with_units_base(component, UnitSystem.NATURAL_UNITS) do\n    get_active_power(component)\nend\n# now active_power_mw is in natural units no matter what units base the system is in\n```\n\"\"\"\nfunction with_units_base(f::Function, c::Component, units::Union{UnitSystem, String})\n    internal = get_internal(c)\n    old_units_info = internal.units_info  # Save reference to restore later\n    _set_units_base!(c, units)\n    temp_units_info = internal.units_info  # The temporary object we just created\n    try\n        f()\n    finally\n        # Only restore if units_info is still temp_units_info.\n        # The user may have changed it in the function body, by e.g. removing the component\n        # and then attaching it to a different system.\n        internal.units_info === temp_units_info || error(\n            \"Units info was modified during with_units_base.\")\n        IS.set_units_info!(internal, old_units_info)\n    end\nend\n\nfunction get_units_setting(component::T) where {T <: Component}\n    return get_units_info(get_internal(component))\nend\n\nfunction has_units_setting(component::T) where {T <: Component}\n    return !isnothing(get_units_setting(component))\nend\n\n\"\"\"\nSet the name of the system.\n\"\"\"\nset_name!(sys::System, name::AbstractString) = sys.metadata.name = name\n\n\"\"\"\nGet the name of the system.\n\"\"\"\nget_name(sys::System) = sys.metadata.name\n\n\"\"\"\nSet the description of the system.\n\"\"\"\nset_description!(sys::System, description::AbstractString) =\n    sys.metadata.description = description\n\n\"\"\"\nGet the description of the system.\n\"\"\"\nget_description(sys::System) = sys.metadata.description\n\n\"\"\"\nAdd a component to the system.\n\nA component cannot be added to more than one `System`.\nThrows ArgumentError if the component's name is already stored for its concrete type.\nThrows ArgumentError if any Component-specific rule is violated.\nThrows InvalidValue if any of the component's field values are outside of defined valid\nrange.\n\n# Examples\n```julia\nsys = System(100.0)\n\n# Add a single component.\nadd_component!(sys, bus)\n\n# Add many at once.\nbuses = [bus1, bus2, bus3]\ngenerators = [gen1, gen2, gen3]\nforeach(x -> add_component!(sys, x), Iterators.flatten((buses, generators)))\n```\n\nSee also [`add_components!`](@ref).\n\"\"\"\nfunction add_component!(\n    sys::System,\n    component::T;\n    skip_validation = false,\n    kwargs...,\n) where {T <: Component}\n    set_units_setting!(component, sys.units_settings)\n    @assert has_units_setting(component)\n\n    check_topology(sys, component)\n    check_component_addition(sys, component; kwargs...)\n\n    deserialization_in_progress = _is_deserialization_in_progress(sys)\n    if !deserialization_in_progress\n        # Services are attached to devices at deserialization time.\n        check_for_services_on_addition(sys, component)\n    end\n\n    skip_validation = _validate_or_skip!(sys, component, skip_validation)\n    _kwargs = Dict(k => v for (k, v) in kwargs if k !== :static_injector)\n    IS.add_component!(\n        sys.data,\n        component;\n        allow_existing_time_series = deserialization_in_progress,\n        skip_validation = skip_validation,\n        _kwargs...,\n    )\n\n    if !deserialization_in_progress\n        # Whatever this may change should have been validated above in\n        # check_component_addition, so this should not fail.\n        # Doesn't run at deserialization time because the changes made by this function\n        # occurred when the original addition ran and do not apply to that scenario.\n        handle_component_addition!(sys, component; kwargs...)\n        # Special condition required to populate the bus numbers in the system after\n    elseif component isa Bus\n        handle_component_addition!(sys, component; kwargs...)\n    end\n\n    return\nend\n\n\"\"\"\nAdd many components to the system at once.\n\nA component cannot be added to more than one `System`.\nThrows ArgumentError if the component's name is already stored for its concrete type.\nThrows ArgumentError if any Component-specific rule is violated.\nThrows InvalidValue if any of the component's field values are outside of defined valid\nrange.\n\n# Examples\n```julia\nsys = System(100.0)\n\nbuses = [bus1, bus2, bus3]\ngenerators = [gen1, gen2, gen3]\nadd_components!(sys, Iterators.flatten((buses, generators))\n```\n\"\"\"\nfunction add_components!(sys::System, components)\n    foreach(x -> add_component!(sys, x), components)\n    return\nend\n\n\"\"\"\nAdd a dynamic injector to the system.\n\nA component cannot be added to more than one `System`.\nThrows ArgumentError if the name does not match the `static_injector` name.\nThrows ArgumentError if the `static_injector` is not attached to the system.\n\nAll rules for the generic `add_component!` method also apply.\n\"\"\"\nfunction add_component!(\n    sys::System,\n    dyn_injector::DynamicInjection,\n    static_injector::StaticInjection;\n    kwargs...,\n)\n    add_component!(sys, dyn_injector; static_injector = static_injector, kwargs...)\n    return\nend\n\n\"\"\"\nReplace the dynamic injector in a static component.\n\nSafely removes the old dynamic injector from the system if no other component references it.\nIf another component references the old dynamic injector, it is kept in the system and an\ninfo message is logged.\n\nThrows ArgumentError if the static injector is not attached to the system.\nThrows ArgumentError if the static injector does not have a dynamic injector.\nThrows ArgumentError if the new dynamic injector name does not match the static injector name.\n\"\"\"\nfunction replace_dynamic_injector!(\n    sys::System,\n    static_injector::StaticInjection,\n    new_dynamic_injector::DynamicInjection,\n)\n    throw_if_not_attached(static_injector, sys)\n\n    old_dynamic_injector = get_dynamic_injector(static_injector)\n    if isnothing(old_dynamic_injector)\n        throw(\n            ArgumentError(\n                \"$(get_name(static_injector)) does not have a dynamic injector to replace\",\n            ),\n        )\n    end\n\n    if get_name(new_dynamic_injector) != get_name(static_injector)\n        throw(\n            ArgumentError(\n                \"new_dynamic_injector must have the same name as the static_injector\",\n            ),\n        )\n    end\n\n    # Unlink old dynamic injector from this static component\n    set_dynamic_injector!(static_injector, nothing)\n\n    # Check if any other static injector in the system references the old dynamic injector\n    is_referenced_elsewhere = false\n    for si in get_components(StaticInjection, sys)\n        si === static_injector && continue\n        dyn = get_dynamic_injector(si)\n        if dyn === old_dynamic_injector\n            is_referenced_elsewhere = true\n            break\n        end\n    end\n\n    if is_referenced_elsewhere\n        @info \"The dynamic injector $(get_name(old_dynamic_injector)) is referenced by \" *\n              \"another component and will not be removed from the system.\"\n    else\n        # Safely remove old dynamic injector from the system\n        _handle_component_removal_common!(old_dynamic_injector)\n        IS.remove_component!(sys.data, old_dynamic_injector)\n    end\n\n    # Add the new dynamic injector, linked to the static component\n    add_component!(sys, new_dynamic_injector, static_injector)\n\n    return\nend\n\nfunction _add_service!(\n    sys::System,\n    service::Service,\n    contributing_devices;\n    skip_validation = false,\n    kwargs...,\n)\n    skip_validation = _validate_or_skip!(sys, service, skip_validation)\n    for device in contributing_devices\n        device_type = typeof(device)\n        if !(device_type <: Device)\n            throw(ArgumentError(\"contributing_devices must be of type Device\"))\n        end\n        throw_if_not_attached(device, sys)\n    end\n\n    set_units_setting!(service, sys.units_settings)\n    # Since this isn't atomic, order is important. Add to system before adding to devices.\n    IS.add_component!(sys.data, service; skip_validation = skip_validation, kwargs...)\n\n    for device in contributing_devices\n        add_service_internal!(device, service)\n    end\nend\n\nfunction _validate_types_for_interface(sys::System, contributing_devices)\n    device_types = Set{DataType}()\n    for device in contributing_devices\n        device_type = typeof(device)\n        if !(device_type <: Branch)\n            throw(ArgumentError(\"contributing_devices must be of type Branch\"))\n        end\n        push!(device_types, device_type)\n        throw_if_not_attached(device, sys)\n    end\n    if length(device_types) > 1 && AreaInterchange in device_types\n        throw(\n            ArgumentError(\n                \"contributing_devices can't mix AreaInterchange with other Branch types\",\n            ),\n        )\n    end\n    return\nend\n\nfunction _validate_types_for_agc(contributing_devices)\n    for device in contributing_devices\n        device_type = typeof(device)\n        if !(device_type <: Reserve)\n            throw(ArgumentError(\"contributing_devices of AGC must be of type Reserve\"))\n        end\n    end\n    return\nend\n\nfunction _add_service!(\n    sys::System,\n    service::TransmissionInterface,\n    contributing_devices;\n    skip_validation = false,\n    kwargs...,\n)\n    skip_validation = _validate_or_skip!(sys, service, skip_validation)\n    _validate_types_for_interface(sys, contributing_devices)\n    set_units_setting!(service, sys.units_settings)\n    # Since this isn't atomic, order is important. Add to system before adding to devices.\n    IS.add_component!(sys.data, service; skip_validation = skip_validation, kwargs...)\n\n    for device in contributing_devices\n        add_service_internal!(device, service)\n    end\nend\n\nfunction _add_service!(\n    sys::System,\n    service::AGC,\n    contributing_devices;\n    skip_validation = false,\n    kwargs...,\n)\n    skip_validation = _validate_or_skip!(sys, service, skip_validation)\n    _validate_types_for_agc(contributing_devices)\n    set_units_setting!(service, sys.units_settings)\n    # Since this isn't atomic, order is important. Add to system before adding to devices.\n    IS.add_component!(sys.data, service; skip_validation = skip_validation, kwargs...)\n\n    for device in contributing_devices\n        add_service_internal!(service, device)\n    end\nend\n\n\"\"\"\nSimilar to [`add_component!`](@ref) but for services.\n\n# Arguments\n- `sys::System`: system\n- `service::Service`: service to add\n- `contributing_devices`: Must be an iterable of type Device\n\"\"\"\nfunction add_service!(sys::System, service::Service, contributing_devices; kwargs...)\n    _add_service!(sys, service, contributing_devices; kwargs...)\n    return\nend\n\n\"\"\"\nSimilar to [`add_component!`](@ref) but for services.\n\n# Arguments\n- `sys::System`: system\n- `service::Service`: service to add\n- `contributing_device::Device`: Valid Device\n\"\"\"\nfunction add_service!(sys::System, service::Service, contributing_device::Device; kwargs...)\n    _add_service!(sys, service, [contributing_device]; kwargs...)\n    return\nend\n\n\"\"\"\nSimilar to [`add_service!`](@ref) but for Service and Device already stored in the system.\nPerforms validation checks on the device and the system\n\n# Arguments\n- `device::Device`: Device\n- `service::Service`: Service\n- `sys::System`: system\n\"\"\"\nfunction add_service!(device::Device, service::Service, sys::System)\n    throw_if_not_attached(service, sys)\n    throw_if_not_attached(device, sys)\n    add_service_internal!(device, service)\n    return\nend\n\n\"\"\"\nSimilar to [`add_component!`](@ref) but for ConstantReserveGroup.\n\n# Arguments\n- `sys::System`: system\n- `service::ConstantReserveGroup`: service to add\n\"\"\"\nfunction add_service!(\n    sys::System,\n    service::ConstantReserveGroup;\n    skip_validation = false,\n    kwargs...,\n)\n    skip_validation = _validate_or_skip!(sys, service, skip_validation)\n\n    for _service in get_contributing_services(service)\n        throw_if_not_attached(_service, sys)\n    end\n\n    set_units_setting!(service, sys.units_settings)\n    IS.add_component!(sys.data, service; skip_validation = skip_validation, kwargs...)\n    return\nend\n\n\"\"\"Set ConstantReserveGroup contributing_services with check\"\"\"\nfunction set_contributing_services!(\n    sys::System,\n    service::ConstantReserveGroup,\n    val::Vector{<:Service},\n)\n    for _service in val\n        throw_if_not_attached(_service, sys)\n    end\n    service.contributing_services = val\n    return\nend\n\n\"\"\"\nSimilar to [`add_component!`](@ref) but for ConstantReserveGroup.\n\n# Arguments\n- `sys::System`: system\n- `service::ConstantReserveGroup`: service to add\n- `contributing_services`: contributing services to the group\n\"\"\"\nfunction add_service!(\n    sys::System,\n    service::ConstantReserveGroup,\n    contributing_services::Vector{<:Service};\n    skip_validation = false,\n    kwargs...,\n)\n    skip_validation = _validate_or_skip!(sys, service, skip_validation)\n    set_contributing_services!(sys, service, contributing_services)\n\n    set_units_setting!(service, sys.units_settings)\n    IS.add_component!(sys.data, service; skip_validation = skip_validation, kwargs...)\n    return\nend\n\n\"\"\"\nOpen the time series store for bulk additions or reads\n\nThis is recommended before calling `add_time_series!` many times because of the overhead\nassociated with opening and closing an HDF5 file.\n\nThis is not necessary for an in-memory time series store.\n\n# Examples\n```julia\n# Assume there is a system with an array of Components and SingleTimeSeries\n# stored in the variables components and single_time_series, respectively\nopen_time_series_store!(sys, \"r+\") do\n    for (component, ts) in zip(components, single_time_series)\n        add_time_series!(sys, component, ts)\n    end\nend\n```\nYou can also use this function to make reads faster.\nChange the mode from `\"r+\"` to `\"r\"` to open the file read-only.\n\nSee also: [`begin_time_series_update`](@ref)\n\"\"\"\nfunction open_time_series_store!(\n    func::Function,\n    sys::System,\n    mode = \"r\",\n    args...;\n    kwargs...,\n)\n    IS.open_time_series_store!(func, sys.data, mode, args...; kwargs...)\nend\n\n\"\"\"\nBegin an update of time series. Use this function when adding many time series arrays\nin order to improve performance.\n\nIf an error occurs during the update, changes will be reverted.\n\nUsing this function to remove time series is currently not supported.\n\n# Examples\n```julia\nbegin_time_series_update(sys) do\n    add_time_series!(sys, component1, time_series1)\n    add_time_series!(sys, component2, time_series2)\nend\n```\n\"\"\"\nbegin_time_series_update(func::Function, sys::System) =\n    IS.begin_time_series_update(func, sys.data.time_series_manager)\n\n\"\"\"\nAdd time series data from a metadata file or metadata descriptors.\n\n# Arguments\n- `sys::System`: system\n- `metadata_file::AbstractString`: metadata file for timeseries\n  that includes an array of IS.TimeSeriesFileMetadata instances or a vector.\n- `resolution::DateTime.Period=nothing`: skip time series that don't match this resolution.\n\"\"\"\nfunction add_time_series!(sys::System, metadata_file::AbstractString; resolution = nothing)\n    return IS.add_time_series_from_file_metadata!(\n        sys.data,\n        Component,\n        metadata_file;\n        resolution = resolution,\n    )\nend\n\n\"\"\"\nAdd time series data from a metadata file or metadata descriptors.\n\n# Arguments\n- `sys::System`: system\n- `timeseries_metadata::Vector{IS.TimeSeriesFileMetadata}`: metadata for timeseries\n- `resolution::DateTime.Period=nothing`: skip time series that don't match this resolution.\n\"\"\"\nfunction add_time_series!(\n    sys::System,\n    file_metadata::Vector{IS.TimeSeriesFileMetadata};\n    resolution = nothing,\n)\n    return IS.add_time_series_from_file_metadata!(\n        sys.data,\n        Component,\n        file_metadata;\n        resolution = resolution,\n    )\nend\n\nfunction IS.add_time_series_from_file_metadata_internal!(\n    data::IS.SystemData,\n    ::Type{<:Component},\n    cache::IS.TimeSeriesParsingCache,\n    file_metadata::IS.TimeSeriesFileMetadata,\n)\n    associations = TimeSeriesAssociation[]\n    IS.set_component!(file_metadata, data, PowerSystems)\n    component = file_metadata.component\n    if isnothing(component)\n        return associations\n    end\n\n    ts = IS.make_time_series!(cache, file_metadata)\n    if component isa AggregationTopology && file_metadata.scaling_factor_multiplier in\n       [\"get_max_active_power\", \"get_max_reactive_power\"]\n        uuids = Set{Base.UUID}()\n        for bus in _get_buses(data, component)\n            push!(uuids, IS.get_uuid(bus))\n        end\n        for _component in (\n            load for load in IS.get_components(ElectricLoad, data) if\n            IS.get_uuid(get_bus(load)) in uuids\n        )\n            file_metadata.component = _component\n            if !IS.has_assignment(cache, file_metadata)\n                IS.add_assignment!(cache, file_metadata)\n                push!(associations, TimeSeriesAssociation(_component, ts))\n            end\n        end\n        file_metadata.component = component\n        orig_sf = file_metadata.scaling_factor_multiplier\n        try\n            file_metadata.scaling_factor_multiplier = replace(orig_sf, \"max\" => \"peak\")\n            area_ts = IS.make_time_series!(cache, file_metadata)\n            IS.add_assignment!(cache, file_metadata)\n            push!(associations, TimeSeriesAssociation(component, area_ts))\n        finally\n            file_metadata.scaling_factor_multiplier = orig_sf\n        end\n    else\n        push!(associations, TimeSeriesAssociation(component, ts))\n        IS.add_assignment!(cache, file_metadata)\n    end\n    return associations\nend\n\n\"\"\"\nIterates over all components.\n\n# Examples\n```julia\nfor component in iterate_components(sys)\n    @show component\nend\n```\n\nSee also: [`get_components`](@ref)\n\"\"\"\nfunction iterate_components(sys::System)\n    return IS.iterate_components(sys.data)\nend\n\n\"\"\"\nRemove all components from the system.\n\"\"\"\nfunction clear_components!(sys::System)\n    return IS.clear_components!(sys.data)\nend\n\n\"\"\"\nRemove all components of type T from the system.\n\nThrows ArgumentError if the type is not stored.\n\"\"\"\n# the argument order in this function is un-julian and should be deprecated in 2.0\nfunction remove_components!(::Type{T}, sys::System) where {T <: Component}\n    return remove_components!(sys, T)\nend\n\n\"\"\"\nRemove all components of type `T` from the system.\n\nThrows `ArgumentError` if the type is not stored.\n\"\"\"\nfunction remove_components!(sys::System, ::Type{T}) where {T <: Component}\n    components = IS.remove_components!(T, sys.data)\n    for component in components\n        handle_component_removal!(sys, component)\n    end\n    return components\nend\n\n\"\"\"\nRemove all components of type `T` that match `filter_func` from the system.\n\"\"\"\nfunction remove_components!(\n    filter_func::Function,\n    sys::System,\n    ::Type{T},\n) where {T <: Component}\n    components = collect(get_components(filter_func, T, sys))\n    for component in components\n        remove_component!(sys, component)\n    end\n    return components\nend\n\n\"\"\"\nSet the name for a component that is attached to the system.\n\"\"\"\nset_name!(sys::System, component::Component, name::AbstractString) =\n    set_name!(sys.data, component, name)\n\n\"\"\"\nSet the name of a component.\n\nThrows an exception if the component is attached to a system.\n\"\"\"\nfunction set_name!(component::Component, name::AbstractString)\n    # The units setting is nothing until the component is attached to the system.\n    if get_units_setting(component) !== nothing\n        # This is not allowed because components are stored in the system in a Dict\n        # keyed by name.\n        error(\n            \"The component is attached to a system. \" *\n            \"Call set_name!(system, component, name) instead.\",\n        )\n    end\n\n    component.name = name\nend\n\nfunction clear_units!(component::Component)\n    get_internal(component).units_info = nothing\n    return\nend\n\n\"\"\"\nRemove a component from the system by its value.\n\nThrows ArgumentError if the component is not stored.\n\"\"\"\nfunction remove_component!(sys::System, component::T) where {T <: Component}\n    check_component_removal(sys, component)\n    IS.remove_component!(sys.data, component)\n    handle_component_removal!(sys, component)\n    return\nend\n\n\"\"\"\nThrows ArgumentError if a PowerSystems rule blocks removal from the system.\n\"\"\"\nfunction check_component_removal(sys::System, service::T) where {T <: Service}\n    if T == ConstantReserveGroup\n        return\n    end\n    groupservices = get_components(ConstantReserveGroup, sys)\n    for groupservice in groupservices\n        if service ∈ get_contributing_services(groupservice)\n            throw(\n                ArgumentError(\n                    \"service $(get_name(service)) cannot be removed with an attached ConstantReserveGroup\",\n                ),\n            )\n            return\n        end\n    end\nend\n\n\"\"\"\nRemove a component from the system by its name.\n\nThrows ArgumentError if the component is not stored.\n\"\"\"\nfunction remove_component!(\n    ::Type{T},\n    sys::System,\n    name::AbstractString,\n) where {T <: Component}\n    component = IS.remove_component!(T, sys.data, name)\n    handle_component_removal!(sys, component)\n    return\nend\n\n\"\"\"\nCheck to see if the component of type T exists.\n\"\"\"\nfunction has_components(sys::System, T::Type{<:Component})\n    return IS.has_components(sys.data.components, T)\nend\n\n\"\"\"\nCheck to see if the component of type T with name exists.\n\"\"\"\nfunction has_component(sys::System, T::Type{<:Component}, name::AbstractString)\n    return IS.has_component(sys.data, T, name)\nend\n\nhas_component(T::Type{<:Component}, sys::System, name::AbstractString) =\n    has_component(sys, T, name)\n\n\"\"\"\nGet the component of type T with name. Returns nothing if no component matches. If T is an abstract\ntype then the names of components across all subtypes of T must be unique.\n\nSee [`get_components_by_name`](@ref) for abstract types with non-unique names across subtypes.\n\nThrows ArgumentError if T is not a concrete type and there is more than one component with\n    requested name\n\"\"\"\nfunction IS.get_component(\n    ::Type{T},\n    sys::System,\n    name::AbstractString,\n) where {T <: Component}\n    return IS.get_component(T, sys.data, name)\nend\n\n\"\"\"\nReturn an iterator of components of a given `Type` from a [`System`](@ref).\n\n`T` can be a concrete or abstract [`Component`](@ref) type from the [Type Tree](@ref).\nCall collect on the result if an array is desired.\n\n# Examples\n```julia\niter = get_components(ThermalStandard, sys)\niter = get_components(Generator, sys)\ngenerators = collect(get_components(Generator, sys))\n```\n\nSee also: [`iterate_components`](@ref), [`get_components` with a filter](@ref get_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component}),\n[`get_available_components`](@ref), [`get_buses`](@ref)\n\"\"\"\nfunction IS.get_components(\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component}\n    return IS.get_components(T, sys.data; subsystem_name = subsystem_name)\nend\n\nfunction IS.get_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component}\n    return IS.get_components(filter_func, T, sys.data; subsystem_name = subsystem_name)\nend\n\n\"\"\"\nReturn a vector of components that are attached to the supplemental attribute.\n\"\"\"\nfunction IS.get_components(sys::System, attribute::SupplementalAttribute)\n    return IS.get_components(sys.data, attribute)\nend\n\n\"\"\"\nGet the component by UUID.\n\"\"\"\nIS.get_component(sys::System, uuid::Base.UUID) = IS.get_component(sys.data, uuid)\nIS.get_component(sys::System, uuid::String) = IS.get_component(sys.data, Base.UUID(uuid))\n\n\"\"\"\nChange the UUID of a component.\n\"\"\"\nIS.assign_new_uuid!(sys::System, x::Component) = IS.assign_new_uuid!(sys.data, x)\n\nfunction _get_components_by_name(abstract_types, data::IS.SystemData, name::AbstractString)\n    _components = []\n    for subtype in abstract_types\n        component = IS.get_component(subtype, data, name)\n        if !isnothing(component)\n            push!(_components, component)\n        end\n    end\n\n    return _components\nend\n\n\"\"\"\nGet the components of abstract type T with name. Note that PowerSystems enforces unique\nnames on each concrete type but not across concrete types.\n\nSee [`get_component`](@ref) if the concrete type is known.\n\nThrows ArgumentError if T is not an abstract type.\n\"\"\"\nfunction get_components_by_name(\n    ::Type{T},\n    sys::System,\n    name::AbstractString,\n) where {T <: Component}\n    return IS.get_components_by_name(T, sys.data, name)\nend\n\n\"\"\"\nReturn true if the component is attached to the system.\n\"\"\"\nfunction is_attached(component::T, sys::System) where {T <: Component}\n    existing_component = get_component(T, sys, get_name(component))\n    isnothing(existing_component) && return false\n    return component === existing_component\nend\n\n\"\"\"\nThrows ArgumentError if the component is not attached to the system.\n\"\"\"\nfunction throw_if_not_attached(component::Component, sys::System)\n    if !is_attached(component, sys)\n        throw(ArgumentError(\"$(summary(component)) is not attached to the system\"))\n    end\nend\n\n\"\"\"\nReturn a vector of devices contributing to the service.\n\"\"\"\nfunction get_contributing_devices(sys::System, service::T) where {T <: Service}\n    throw_if_not_attached(service, sys)\n    return [\n        x for x in get_components(supports_services, Device, sys) if has_service(x, service)\n    ]\nend\n\n\"\"\"\nReturn a vector of devices contributing to the service.\n\"\"\"\nfunction get_contributing_devices(sys::System, service::TransmissionInterface)\n    throw_if_not_attached(service, sys)\n    return [x for x in get_components(Branch, sys) if has_service(x, service)]\nend\n\n\"\"\"\nContainer associating a [`Service`](@ref) with the [`Device`](@ref) components that\ncontribute to it.\n\"\"\"\nstruct ServiceContributingDevices\n    service::Service\n    contributing_devices::Vector{Device}\nend\n\nconst ServiceContributingDevicesKey = NamedTuple{(:type, :name), Tuple{DataType, String}}\nconst ServiceContributingDevicesMapping =\n    Dict{ServiceContributingDevicesKey, ServiceContributingDevices}\n\nstruct AGCContributingReserves\n    agc::AGC\n    contributing_reserves::Vector{Reserve}\nend\n\nconst AGCContributingReservesKey = NamedTuple{(:type, :name), Tuple{DataType, String}}\nconst AGCContributingReservesMapping =\n    Dict{AGCContributingReservesKey, AGCContributingReserves}\n\n\"\"\"\nReturns a ServiceContributingDevices object.\n\"\"\"\nfunction _get_contributing_devices(sys::System, service::T) where {T <: Service}\n    uuid = IS.get_uuid(service)\n    devices = ServiceContributingDevices(service, Vector{Device}())\n    for device in get_components(Device, sys)\n        if supports_services(device)\n            for _service in get_services(device)\n                if IS.get_uuid(_service) == uuid\n                    push!(devices.contributing_devices, device)\n                    break\n                end\n            end\n        end\n    end\n    return devices\nend\n\n\"\"\"\nReturns a ServiceContributingDevices object.\n\"\"\"\nfunction _get_contributing_devices(sys::System, service::TransmissionInterface)\n    uuid = IS.get_uuid(service)\n    devices = ServiceContributingDevices(service, Vector{Device}())\n    for device in get_components(Branch, sys)\n        if supports_services(device)\n            for _service in get_services(device)\n                if IS.get_uuid(_service) == uuid\n                    push!(devices.contributing_devices, device)\n                    break\n                end\n            end\n        end\n    end\n    return devices\nend\n\n\"\"\"\nReturn an instance of AGCContributingReservesMapping.\n\"\"\"\nfunction get_contributing_reserve_mapping(sys::System)\n    agcs = AGCContributingReservesMapping()\n    for agc in get_components(AGC, sys)\n        key = AGCContributingReservesKey((typeof(agc), get_name(agc)))\n        agcs[key] = AGCContributingReserves(agc, get_reserves(agc))\n    end\n    return agcs\nend\n\n\"\"\"\nReturn an instance of ServiceContributingDevicesMapping.\n\"\"\"\nfunction get_contributing_device_mapping(sys::System)\n    services = ServiceContributingDevicesMapping()\n    for service in get_components(Service, sys)\n        key = ServiceContributingDevicesKey((typeof(service), get_name(service)))\n        services[key] = _get_contributing_devices(sys, service)\n    end\n\n    return services\nend\n\n\"\"\"\nReturn a vector of connected head reservoirs to the turbine. Reservoirs that have the turbine in their downstream_turbines field are head reservoirs of such turbine.\n\"\"\"\nfunction get_connected_head_reservoirs(sys::System, turbine::T) where {T <: HydroUnit}\n    throw_if_not_attached(turbine, sys)\n    return [\n        x for x in get_components(HydroReservoir, sys) if has_downstream_turbine(x, turbine)\n    ]\nend\n\n\"\"\"\nReturn a vector of connected tail reservoirs to the turbine. Reservoirs that have the turbine in their upstream_turbines field are tail reservoirs of such turbine.\n\"\"\"\nfunction get_connected_tail_reservoirs(sys::System, turbine::T) where {T <: HydroUnit}\n    throw_if_not_attached(turbine, sys)\n    return [\n        x for x in get_components(HydroReservoir, sys) if has_upstream_turbine(x, turbine)\n    ]\nend\n\n\"\"\"\nContainer associating a hydro turbine with its connected [`Device`](@ref) components\n(e.g., [`HydroReservoir`](@ref) units).\n\"\"\"\nstruct TurbineConnectedDevices\n    turbine::HydroUnit\n    connected_devices::Vector{Device}\nend\n\nconst TurbineConnectedDevicesKey = NamedTuple{(:type, :name), Tuple{DataType, String}}\nconst TurbineConnectedDevicesMapping =\n    Dict{TurbineConnectedDevicesKey, TurbineConnectedDevices}\n\n\"\"\"\nReturns a TurbineConnectedDevices object.\n\"\"\"\nfunction _get_connected_head_devices(sys::System, turbine::T) where {T <: HydroUnit}\n    uuid = IS.get_uuid(turbine)\n    devices = TurbineConnectedDevices(turbine, Vector{Device}())\n    for device in get_components(HydroReservoir, sys)\n        # Only add reservoirs that have the turbine in their downstream_turbines field\n        # That is, those reservoirs are a head reservoir to that turbine\n        for _turbine in get_downstream_turbines(device)\n            if IS.get_uuid(_turbine) == uuid\n                push!(devices.connected_devices, device)\n                break\n            end\n        end\n    end\n    return devices\nend\n\n\"\"\"\nReturns a TurbineConnectedDevices object.\n\"\"\"\nfunction _get_connected_tail_devices(sys::System, turbine::T) where {T <: HydroUnit}\n    uuid = IS.get_uuid(turbine)\n    devices = TurbineConnectedDevices(turbine, Vector{Device}())\n    for device in get_components(HydroReservoir, sys)\n        # Only add reservoirs that have the turbine in their upstream_turbines field\n        # That is, those reservoirs are a tail reservoir to that turbine\n        for _turbine in get_upstream_turbines(device)\n            if IS.get_uuid(_turbine) == uuid\n                push!(devices.connected_devices, device)\n                break\n            end\n        end\n    end\n    return devices\nend\n\n\"\"\"\nReturn an instance of TurbineConnectedDevicesMapping.\n\"\"\"\nfunction get_turbine_head_reservoirs_mapping(sys::System)\n    turbine_mapping = TurbineConnectedDevicesMapping()\n    for turbine in get_components(HydroUnit, sys)\n        key = TurbineConnectedDevicesKey((typeof(HydroUnit), get_name(turbine)))\n        turbine_mapping[key] = _get_connected_head_devices(sys, turbine)\n    end\n\n    return turbine_mapping\nend\n\n\"\"\"\nReturn an instance of TurbineConnectedDevicesMapping.\n\"\"\"\nfunction get_turbine_tail_reservoirs_mapping(sys::System)\n    turbine_mapping = TurbineConnectedDevicesMapping()\n    for turbine in get_components(HydroUnit, sys)\n        key = TurbineConnectedDevicesKey((typeof(HydroUnit), get_name(turbine)))\n        turbine_mapping[key] = _get_connected_tail_devices(sys, turbine)\n    end\n\n    return turbine_mapping\nend\n\n\"\"\"\nReturn a vector of components with buses in the [`AggregationTopology`](@ref).\n\"\"\"\nfunction get_components_in_aggregation_topology(\n    ::Type{T},\n    sys::System,\n    aggregator::AggregationTopology,\n) where {T <: StaticInjection}\n    buses = Set{String}((get_name(x) for x in get_buses(sys, aggregator)))\n    components = Vector{T}()\n    for component in get_components(T, sys)\n        bus = get_bus(component)\n        bus_name = get_name(bus)\n        if bus_name in buses\n            push!(components, component)\n        end\n    end\n\n    return components\nend\n\n\"Return whether the given component's bus is in the [`AggregationTopology`](@ref)\"\nfunction is_component_in_aggregation_topology(\n    comp::Component,\n    aggregator::T,\n) where {T <: AggregationTopology}\n    accessor = get_aggregation_topology_accessor(T)\n    return IS.get_uuid(accessor(get_bus(comp))) == IS.get_uuid(aggregator)\nend\n\n\"\"\"\nReturn a mapping of [`AggregationTopology`](@ref) name to vector of [`ACBus`](@ref)es within it.\n\"\"\"\nfunction get_aggregation_topology_mapping(\n    ::Type{T},\n    sys::System,\n) where {T <: AggregationTopology}\n    mapping = Dict{String, Vector{ACBus}}()\n    accessor_func = get_aggregation_topology_accessor(T)\n    for bus in get_components(ACBus, sys)\n        aggregator = accessor_func(bus)\n        name = get_name(aggregator)\n        buses = get(mapping, name, nothing)\n        if isnothing(buses)\n            mapping[name] = Vector{ACBus}([bus])\n        else\n            push!(buses, bus)\n        end\n    end\n\n    return mapping\nend\n\n\"\"\"\nReturn a vector of buses contained within an [`AggregationTopology`](@ref).\n\n# Examples\n```julia\narea = get_component(Area, system, \"my_area\"); # Get an Area named my_area\narea_buses = get_buses(system, area)\n```\n\"\"\"\nfunction get_buses(sys::System, aggregator::AggregationTopology)\n    return _get_buses(sys.data, aggregator)\nend\n\nfunction _get_buses(data::IS.SystemData, aggregator::T) where {T <: AggregationTopology}\n    accessor_func = get_aggregation_topology_accessor(T)\n    buses = Vector{ACBus}()\n    for bus in IS.get_components(ACBus, data)\n        _aggregator = accessor_func(bus)\n        if !isnothing(_aggregator) && IS.get_uuid(_aggregator) == IS.get_uuid(aggregator)\n            push!(buses, bus)\n        end\n    end\n\n    return buses\nend\n\n\"\"\"\nAdd time series data to a component. Assign optional features to differentiate time series\nof the same type with the same name but with different data.\n\nReturns a key that can later be used to retrieve the time series data.\n\nThrows ArgumentError if the component is not stored in the system.\n\n# Examples\n```julia\nts1 = Deterministic(\n    name = \"max_active_power\",\n    data = deterministic_data,\n    resolution = Dates.Hour(1),\n)\nts2 = SingleTimeSeries(\n    name = \"max_active_power\",\n    data = time_array_1,\n)\nts3 = SingleTimeSeries(\n    name = \"max_active_power\",\n    data = time_array_2,\n)\nkey1 = add_time_series!(system, component, ts1)\nkey2 = add_time_series!(system, component, ts2, scenario = \"high\")\nkey3 = add_time_series!(system, component, ts3, scenario = \"low\")\nts1_b = get_time_series(component, key1)\nts2_b = get_time_series(component, key2)\nts3_b = get_time_series(component, key3)\n```\n\"\"\"\nfunction add_time_series!(\n    sys::System,\n    component::Component,\n    time_series::TimeSeriesData;\n    features...,\n)\n    return IS.add_time_series!(sys.data, component, time_series; features...)\nend\n\n\"\"\"\nAdd time series in bulk.\n\nPrefer use of [`begin_time_series_update`](@ref).\n\n# Examples\n```julia\n# Assumes `read_time_series` will return data appropriate for Deterministic forecasts\n# based on the generator name and the filenames match the component and time series names.\nresolution = Dates.Hour(1)\nassociations = (\n    IS.TimeSeriesAssociation(\n        gen,\n        Deterministic(\n            data = read_time_series(get_name(gen) * \".csv\"),\n            name = \"get_max_active_power\",\n            resolution=resolution),\n    )\n    for gen in get_components(ThermalStandard, sys)\n)\nbulk_add_time_series!(sys, associations)\n```\n\"\"\"\nfunction bulk_add_time_series!(\n    sys::System,\n    associations;\n    batch_size::Int = IS.ADD_TIME_SERIES_BATCH_SIZE,\n)\n    return IS.bulk_add_time_series!(sys.data, associations; batch_size = batch_size)\nend\n\n\"\"\"\nAdd the same time series data to multiple components.\n\nThis function stores a single copy of the data. Each component will store a reference to\nthat data. This is significantly more efficent than calling `add_time_series!` for each\ncomponent individually with the same data because in this case, only one time series\narray is stored.\n\nThrows ArgumentError if a component is not stored in the system.\n\"\"\"\nfunction add_time_series!(sys::System, components, time_series::TimeSeriesData; features...)\n    return IS.add_time_series!(sys.data, components, time_series; features...)\nend\n\n#=\n# TODO 1.0: do we need this functionality? not currently present in IS\n\"\"\"\nReturn a vector of time series data from a metadata file.\n\n# Arguments\n- `data::SystemData`: system\n- `metadata_file::AbstractString`: path to metadata file\n- `resolution::{Nothing, Dates.Period}`: skip data that doesn't match this resolution\n\nSee InfrastructureSystems.TimeSeriesFileMetadata for description of what the file\nshould contain.\n\"\"\"\nfunction make_time_series(sys::System, metadata_file::AbstractString; resolution = nothing)\n    return IS.make_time_series(\n        sys.data,\n        metadata_file,\n        PowerSystems;\n        resolution = resolution,\n    )\nend\n\n\"\"\"\nReturn a vector of time series data from a vector of TimeSeriesFileMetadata values.\n\n# Arguments\n- `data::SystemData`: system\n- `timeseries_metadata::Vector{TimeSeriesFileMetadata}`: metadata values\n- `resolution::{Nothing, Dates.Period}`: skip data that doesn't match this resolution\n\"\"\"\nfunction make_time_series(\n    sys::System,\n    metadata::Vector{IS.TimeSeriesFileMetadata};\n    resolution = nothing,\n)\n    return IS.make_time_series!(sys.data, metadata; resolution = resolution)\nend\n=#\n\n\"\"\"\nReturn the compression settings used for system data such as time series arrays.\n\"\"\"\nget_compression_settings(sys::System) = IS.get_compression_settings(sys.data)\n\n\"\"\"\nReturn the initial times for all forecasts. Use `resolution` and/or `interval` keyword\narguments to filter when multiple forecast groups exist.\n\"\"\"\nget_forecast_initial_times(sys::System; kwargs...) =\n    IS.get_forecast_initial_times(sys.data; kwargs...)\n\n\"\"\"\nReturn the window count for all forecasts. Use `resolution` and/or `interval` keyword\narguments to filter when multiple forecast groups exist.\n\"\"\"\nget_forecast_window_count(sys::System; kwargs...) =\n    IS.get_forecast_window_count(sys.data; kwargs...)\n\n\"\"\"\nReturn the horizon for all forecasts. Use `resolution` and/or `interval` keyword\narguments to filter when multiple forecast groups exist.\n\"\"\"\nget_forecast_horizon(sys::System; kwargs...) =\n    IS.get_forecast_horizon(sys.data; kwargs...)\n\n\"\"\"\nReturn the initial timestamp for all forecasts. Use `resolution` and/or `interval` keyword\narguments to filter when multiple forecast groups exist.\n\"\"\"\nget_forecast_initial_timestamp(sys::System; kwargs...) =\n    IS.get_forecast_initial_timestamp(sys.data; kwargs...)\n\n\"\"\"\nReturn the forecast interval. Use `resolution` and/or `interval` keyword arguments to\nselect which forecast group to query when multiple exist.\n\"\"\"\nget_forecast_interval(sys::System; kwargs...) =\n    IS.get_forecast_interval(sys.data; kwargs...)\n\n\"\"\"\nReturn a sorted Vector of distinct resolutions for all time series of the given type\n(or all types).\n\"\"\"\nget_time_series_resolutions(\n    sys::System;\n    time_series_type::Union{Type{<:TimeSeriesData}, Nothing} = nothing,\n) = IS.get_time_series_resolutions(sys.data; time_series_type = time_series_type)\n\n\"\"\"\nReturn an iterator of time series attached to components in the system.\n\nNote that passing a filter function can be much slower than the other filtering parameters\nbecause it reads time series data from media.\n\nCall `collect` on the result to get an array.\n\n# Arguments\n- `sys::System`: system\n- `filter_func = nothing`: Only return time series for which this returns true.\n- `type = nothing`: Only return time series with this type.\n- `name = nothing`: Only return time series matching this value.\n- `resolution = nothing`: Only return time series matching this resolution.\n- `interval = nothing`: Only return time series matching this interval.\n\n# Examples\n```julia\nfor time_series in get_time_series_multiple(sys)\n    @show time_series\nend\n\nts = collect(get_time_series_multiple(sys; type = SingleTimeSeries))\n```\n\"\"\"\nfunction IS.get_time_series_multiple(\n    sys::System,\n    filter_func = nothing;\n    type = nothing,\n    name = nothing,\n    resolution = nothing,\n    interval = nothing,\n)\n    Channel{TimeSeriesData}() do channel\n        for component in\n            IS.iterate_components_with_time_series(sys.data; time_series_type = type)\n            for time_series in get_time_series_multiple(\n                component,\n                filter_func;\n                type = type,\n                name = name,\n                resolution = resolution,\n                interval = interval,\n            )\n                put!(channel, time_series)\n            end\n        end\n    end\nend\n\n\"\"\"\nClear all time series data from the system.\n\nIf you are storing time series data in an HDF5 file, this will\nwill delete the HDF5 file and create a new one.\n\nSee also: [`remove_time_series!`](@ref remove_time_series!(sys::System, ::Type{T}) where {T <: TimeSeriesData})\n\"\"\"\nfunction clear_time_series!(sys::System)\n    return IS.clear_time_series!(sys.data)\nend\n\n\"\"\"\nRemove the time series data for a component or supplemental attribute and time series type.\n\nUse `resolution`, `interval`, and `features` keyword arguments to disambiguate when multiple\ntime series of the same type and name exist with different resolutions, intervals, or\nuser-defined feature tags.\n\"\"\"\nfunction remove_time_series!(\n    sys::System,\n    ::Type{T},\n    owner::Union{Component, SupplementalAttribute},\n    name::String;\n    resolution::Union{Nothing, Dates.Period} = nothing,\n    interval::Union{Nothing, Dates.Period} = nothing,\n    features...,\n) where {T <: TimeSeriesData}\n    return IS.remove_time_series!(\n        sys.data,\n        T,\n        owner,\n        name;\n        resolution = resolution,\n        interval = interval,\n        features...,\n    )\nend\n\n\"\"\"\nRemove all the time series data for a time series type.\n\nSee also: [`clear_time_series!`](@ref)\n\nIf you are storing time series data in an HDF5 file, `remove_time_series!` does\nnot actually free up file space (HDF5 behavior). If you want to remove all or\nmost time series instances then consider using `clear_time_series!`. It\nwill delete the HDF5 file and create a new one. PowerSystems has plans to\nautomate this type of workflow.\n\"\"\"\nfunction remove_time_series!(\n    sys::System,\n    ::Type{T};\n    resolution::Union{Nothing, Dates.Period} = nothing,\n    interval::Union{Nothing, Dates.Period} = nothing,\n) where {T <: TimeSeriesData}\n    return IS.remove_time_series!(sys.data, T; resolution = resolution, interval = interval)\nend\n\n\"\"\"\nTransform all instances of [`SingleTimeSeries`](@ref) in a `System` to\n[`DeterministicSingleTimeSeries`](@ref)\n\nThis can be used to generate a perfect forecast from historical measurements or realizations\nwhen actual forecasts are unavailable, without unnecessarily duplicating data.\n\nIf all `SingleTimeSeries` instances cannot be transformed then none will be.\n\nBy default, any existing `DeterministicSingleTimeSeries` forecasts will be deleted before the\ntransform (`delete_existing = true`). Set `delete_existing = false` to preserve existing\n`DeterministicSingleTimeSeries`; entries with matching name, resolution, features, horizon,\nand interval are skipped, allowing multiple calls with different resolutions to coexist.\n\n# Arguments\n- `sys::System`: System containing the components.\n- `horizon::Dates.Period`: desired [horizon](@ref H) of each forecast [window](@ref W)\n- `interval::Dates.Period`: desired [interval](@ref I) between forecast [windows](@ref W)\n- `resolution::Union{Nothing, Dates.Period} = nothing`: If set, only transform time series\n   with this resolution.\n- `delete_existing::Bool = true`: If `true`, delete all existing\n   `DeterministicSingleTimeSeries` before transforming.\n\"\"\"\nfunction transform_single_time_series!(\n    sys::System,\n    horizon::Dates.Period,\n    interval::Dates.Period;\n    resolution::Union{Nothing, Dates.Period} = nothing,\n    delete_existing::Bool = true,\n)\n    IS.transform_single_time_series!(\n        sys.data,\n        IS.DeterministicSingleTimeSeries,\n        horizon,\n        interval;\n        resolution = resolution,\n        delete_existing = delete_existing,\n    )\n    return\nend\n\n\"\"\"\nAdd a supplemental attribute to the component. The attribute may already be attached to a\ndifferent component.\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::Component,\n    attribute::IS.SupplementalAttribute,\n)\n    return IS.add_supplemental_attribute!(sys.data, component, attribute)\nend\n\n\"\"\"\nBegin an update of supplemental attributes. Use this function when adding\nor removing many supplemental attributes in order to improve performance.\n\nIf an error occurs during the update, changes will be reverted.\n\n# Examples\n```julia\nbegin_supplemental_attributes_update(sys) do\n    add_supplemental_attribute!(sys, component1, attribute1)\n    add_supplemental_attribute!(sys, component2, attribute2)\nend\n```\n\"\"\"\nbegin_supplemental_attributes_update(func::Function, sys::System) =\n    IS.begin_supplemental_attributes_update(func, sys.data.supplemental_attribute_manager)\n\n\"\"\"\nRemove the supplemental attribute from the component. The attribute will be removed from the\nsystem if it is not attached to any other component.\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::Component,\n    attribute::IS.SupplementalAttribute,\n)\n    return IS.remove_supplemental_attribute!(sys.data, component, attribute)\nend\n\n\"\"\"\nRemove all supplemental attributes with the given type from the system.\n\"\"\"\nfunction remove_supplemental_attributes!(\n    ::Type{T},\n    sys::System,\n) where {T <: IS.SupplementalAttribute}\n    return IS.remove_supplemental_attributes!(sys.data, T)\nend\n\n\"\"\"\nReturns an iterator of supplemental attributes. T can be concrete or abstract.\nCall collect on the result if an array is desired.\n\n# Examples\n```julia\niter = get_supplemental_attributes(GeometricDistributionForcedOutage, sys)\niter = get_supplemental_attributes(Outage, sys)\niter = get_supplemental_attributes(x -> get_mean_time_to_recovery(x) ==  >= 0.5, GeometricDistributionForcedOutage, sys)\noutages = get_supplemental_attributes(GeometricDistributionForcedOutage, sys) do outage\n    get_mean_time_to_recovery(x) ==  >= 0.5\nend\noutages = collect(get_supplemental_attributes(GeometricDistributionForcedOutage, sys))\n```\n\nSee also: [`iterate_supplemental_attributes`](@ref)\n\"\"\"\nfunction get_supplemental_attributes(\n    filter_func::Function,\n    ::Type{T},\n    sys::System,\n) where {T <: IS.SupplementalAttribute}\n    return IS.get_supplemental_attributes(filter_func, T, sys.data)\nend\n\nfunction get_supplemental_attributes(\n    ::Type{T},\n    sys::System,\n) where {T <: IS.SupplementalAttribute}\n    return IS.get_supplemental_attributes(T, sys.data)\nend\n\n\"\"\"\n    get_associated_supplemental_attributes(obj)\n\nRetrieves supplemental attributes associated with the given object.\n\nThis function extracts and returns additional metadata or auxiliary information\nthat is linked to the specified object, typically used for extended functionality\nor configuration purposes.\n\n# Arguments\n- `obj`: The object for which to retrieve associated supplemental attributes\n\n# Returns\n- Collection of supplemental attributes associated with the input object\n\n# Examples\n```julia\ngen_attr_pairs = get_component_supplemental_attribute_pairs(\n    GeometricDistributionForcedOutage,\n    ThermalStandard,\n    sys,\n)\nfor (gen, attr) in gen_attr_pairs\n    @show summary(gen) summary(attr)\nend\n\nmy_generators = [gen1, gen2, gen3]\ngen_attr_pairs_limited = get_component_supplemental_attribute_pairs(\n    GeometricDistributionForcedOutage,\n    ThermalStandard,\n    sys,\n    components = my_generators,\n)\nfor (gen, attr) in gen_attr_pairs_limited\n    @show summary(gen) summary(attr)\nend\n```\n\"\"\"\nfunction get_associated_supplemental_attributes(\n    sys::System,\n    ::Type{T};\n    attribute_type::Union{Nothing, Type{<:IS.SupplementalAttribute}} = nothing,\n) where {T <: IS.InfrastructureSystemsComponent}\n    return IS.get_associated_supplemental_attributes(\n        sys.data,\n        T;\n        attribute_type = attribute_type,\n    )\nend\n\n\"\"\"\nReturn the supplemental attribute with the given uuid.\n\nThrows ArgumentError if the attribute is not stored.\n\"\"\"\nfunction get_supplemental_attribute(sys::System, uuid::Base.UUID)\n    return IS.get_supplemental_attribute(sys.data, uuid)\nend\n\n\"\"\"\nIterates over all supplemental_attributes.\n\n# Examples\n```julia\nfor supplemental_attribute in iterate_supplemental_attributes(sys)\n    @show supplemental_attribute\nend\n```\n\nSee also: [`get_supplemental_attributes`](@ref)\n\"\"\"\nfunction iterate_supplemental_attributes(sys::System)\n    return IS.iterate_supplemental_attributes(sys.data)\nend\n\n\"\"\"\nReturn a vector of NamedTuples with pairs of components and supplemental attributes that\nare associated with each other. Limit by `components` and `attributes` if provided.\n\nThe return type is `NamedTuple{(:component, :supplemental_attribute), Tuple{T, U}}[]`\nwhere `T` is the component type and `U` is the supplemental attribute type.\n\n# Arguments\n- `sys::System`: System containing the components and attributes.\n- `::Type{T}`: Type of the components to filter by. Can be concrete or abstract.\n- `::Type{U}`: Type of the supplemental attributes to filter by. Can be concrete or abstract.\n- `components`: Optional iterable. If set, filter pairs where the component is in this\n  iterable.\n- `attributes`: Optional iterable. If set, filter pairs where the supplemental attribute is\n  in this iterable.\n\n# Examples\n```julia\ngen_attr_pairs = get_component_supplemental_attribute_pairs(\n    GeometricDistributionForcedOutage,\n    ThermalStandard,\n    sys,\n)\nfor (gen, attr) in gen_attr_pairs\n    @show summary(gen) summary(attr)\nend\n\nmy_generators = [gen1, gen2, gen3]\ngen_attr_pairs_limited = get_component_supplemental_attribute_pairs(\n    GeometricDistributionForcedOutage,\n    ThermalStandard,\n    sys,\n    components = my_generators,\n)\nfor (gen, attr) in gen_attr_pairs_limited\n    @show summary(gen) summary(attr)\nend\n```\n\"\"\"\nfunction get_component_supplemental_attribute_pairs(\n    ::Type{T},\n    ::Type{U},\n    sys::System;\n    components = nothing,\n    attributes = nothing,\n) where {T <: Component, U <: SupplementalAttribute}\n    return IS.get_component_supplemental_attribute_pairs(\n        T,\n        U,\n        sys.data;\n        components = components,\n        attributes = attributes,\n    )\nend\n\n\"\"\"\nSanitize component values.\n\"\"\"\nsanitize_component!(component::Component, sys::System) = true\n\n\"\"\"\nValidate the component fields using only those fields. Refer to\n[`validate_component_with_system`](@ref) to use other System data for the\nvalidation.\n\nReturn true if the instance is valid.\n\"\"\"\nvalidate_component(component::Component) = true\n\n\"\"\"\nValidate a component against System data. Return true if the instance is valid.\n\nRefer to [`validate_component`](@ref) if the validation logic only requires data contained\nwithin the instance.\n\"\"\"\nvalidate_component_with_system(component::Component, sys::System) = true\n\nBase.@deprecate validate_struct(sys::System, component::Component) validate_component_with_system(\n    component,\n    sys,\n) false\n\n# Keeps the code working with IS.\nIS.validate_struct(component::Component) = validate_component(component)\n\n\"\"\"\nCheck system consistency and validity.\n\"\"\"\nfunction check(sys::System)\n    buses = get_components(ACBus, sys)\n    slack_bus_check(buses)\n    buscheck(sys)\n    critical_components_check(sys)\n    adequacy_check(sys)\n    check_subsystems(sys)\n    return\nend\n\n\"\"\"\nCheck the the consistency of subsystems.\n\"\"\"\nfunction check_subsystems(sys::System)\n    must_be_assigned_to_subsystem = false\n    for (i, component) in enumerate(iterate_components(sys))\n        is_assigned = is_assigned_to_subsystem(sys, component)\n        if i == 1\n            must_be_assigned_to_subsystem = is_assigned\n        elseif is_assigned != must_be_assigned_to_subsystem\n            throw(\n                IS.InvalidValue(\n                    \"If any component is assigned to a subsystem then all \" *\n                    \"components must be assigned to a subsystem.\",\n                ),\n            )\n        end\n        check_subsystems(sys, component)\n    end\nend\n\n\"\"\"\nCheck the values of all components. See [`check_component`](@ref) for exceptions thrown.\n\"\"\"\nfunction check_components(sys::System; check_masked_components = true)\n    must_be_assigned_to_subsystem = false\n    for (i, component) in enumerate(iterate_components(sys))\n        is_assigned = is_assigned_to_subsystem(sys, component)\n        if i == 1\n            must_be_assigned_to_subsystem = is_assigned\n        elseif is_assigned != must_be_assigned_to_subsystem\n            throw(\n                IS.InvalidValue(\n                    \"If any component is assigned to a subsystem then all \" *\n                    \"components must be assigned to a subsystem.\",\n                ),\n            )\n        end\n        check_component(sys, component)\n    end\n\n    if check_masked_components\n        for component in IS.get_masked_components(Component, sys.data)\n            check_component(sys, component)\n        end\n    end\nend\n\n\"\"\"\nCheck the values of components of a given abstract or concrete type.\nSee [`check_component`](@ref) for exceptions thrown.\n\"\"\"\nfunction check_components(\n    sys::System,\n    ::Type{T};\n    check_masked_components = true,\n) where {T <: Component}\n    for component in get_components(T, sys)\n        check_component(sys, component)\n    end\n\n    if check_masked_components\n        for component in IS.get_masked_components(T, sys.data)\n            check_component(sys, component)\n        end\n    end\nend\n\n\"\"\"\nCheck the values of each component in an iterable of components.\nSee [`check_component`](@ref) for exceptions thrown.\n\"\"\"\nfunction check_components(sys::System, components)\n    for component in components\n        check_component(sys, component)\n    end\nend\n\n\"\"\"\nCheck the values of a component.\n\nThrows InvalidValue if any of the component's field values are outside of defined valid\nrange or if the custom validate method for the type fails its check.\n\"\"\"\nfunction check_component(sys::System, component::Component)\n    if !validate_component_with_system(component, sys)\n        throw(IS.InvalidValue(\"Invalid value for $(summary(component))\"))\n    end\n    IS.check_component(sys.data, component)\n    return\nend\n\n\"\"\"\nCheck that all AC transmission [`Line`](@ref) and [`MonitoredLine`](@ref) components\nhave valid rate values relative to the system base power.\n\nReturns `true` if all values are valid, `false` otherwise.\n\"\"\"\nfunction check_ac_transmission_rate_values(sys::System)\n    is_valid = true\n    base_power = get_base_power(sys)\n    for line in\n        Iterators.flatten((get_components(Line, sys), get_components(MonitoredLine, sys)))\n        if !check_rating_values(line, base_power)\n            is_valid = false\n        end\n    end\n    return is_valid\nend\n\n\"\"\"\nSerialize a [System](@ref) instance. Returns a `Dict{String, Any}` \nof the form `Dict(\"data_format_version\" => \"1.0\", \"field1\" => serialize(sys.field1), ...)`,\nwhich can then be written to a JSON3 file.\n\"\"\"\nfunction IS.serialize(sys::T) where {T <: System}\n    data = Dict{String, Any}()\n    data[\"data_format_version\"] = DATA_FORMAT_VERSION\n    for field in fieldnames(T)\n        # Exclude bus_numbers because they will get rebuilt during deserialization.\n        # Exclude time_series_directory because the system may get deserialized on a\n        # different system.\n        if field != :bus_numbers && field != :time_series_directory\n            data[string(field)] = serialize(getfield(sys, field))\n        end\n    end\n\n    return data\nend\n\n\"\"\"\nDeserialize a [System](@ref) instance from a JSON3 file; the reverse of [`IS.serialize`](@ref).\n\"\"\"\nfunction IS.deserialize(\n    ::Type{System},\n    filename::AbstractString;\n    kwargs...,\n)\n    raw = open(filename) do io\n        JSON3.read(io, Dict)\n    end\n\n    if raw[\"data_format_version\"] != DATA_FORMAT_VERSION\n        pre_read_conversion!(raw)\n    end\n\n    # These file paths are relative to the system file.\n    directory = dirname(filename)\n    for file_key in (\"time_series_storage_file\",)\n        if haskey(raw[\"data\"], file_key) && !isabspath(raw[\"data\"][file_key])\n            raw[\"data\"][file_key] = joinpath(directory, raw[\"data\"][file_key])\n        end\n    end\n\n    return from_dict(System, raw; kwargs...)\nend\n\nfunction from_dict(\n    ::Type{System},\n    raw::Dict{String, Any};\n    time_series_read_only = false,\n    time_series_directory = nothing,\n    config_path = POWER_SYSTEM_STRUCT_DESCRIPTOR_FILE,\n    kwargs...,\n)\n    # Read any field that is defined in System but optional for the constructors and not\n    # already handled here.\n    handled = (\n        \"data\",\n        \"units_settings\",\n        \"bus_numbers\",\n        \"internal\",\n        \"data_format_version\",\n        \"metadata\",\n        \"name\",\n        \"description\",\n    )\n    parsed_kwargs = Dict{Symbol, Any}()\n    for field in setdiff(keys(raw), handled)\n        parsed_kwargs[Symbol(field)] = raw[field]\n    end\n\n    # The user can override the serialized runchecks value by passing a kwarg here.\n    if haskey(kwargs, :runchecks)\n        parsed_kwargs[:runchecks] = kwargs[:runchecks]\n    end\n\n    units = IS.deserialize(SystemUnitsSettings, raw[\"units_settings\"])\n    data = IS.deserialize(\n        IS.SystemData,\n        raw[\"data\"];\n        time_series_read_only = time_series_read_only,\n        time_series_directory = time_series_directory,\n        validation_descriptor_file = config_path,\n    )\n    metadata = get(raw, \"metadata\", Dict())\n    name = get(metadata, \"name\", nothing)\n    description = get(metadata, \"description\", nothing)\n    internal = IS.deserialize(InfrastructureSystemsInternal, raw[\"internal\"])\n    sys = System(\n        data,\n        units,\n        internal;\n        name = name,\n        description = description,\n        parsed_kwargs...,\n    )\n\n    if raw[\"data_format_version\"] != DATA_FORMAT_VERSION\n        pre_deserialize_conversion!(raw, sys)\n    end\n\n    ext = get_ext(sys)\n    ext[\"deserialization_in_progress\"] = true\n    try\n        deserialize_components!(sys, raw[\"data\"])\n    finally\n        pop!(ext, \"deserialization_in_progress\")\n        isempty(ext) && clear_ext!(sys)\n    end\n\n    if !get_runchecks(sys)\n        @warn \"The System was deserialized with checks disabled, and so was not validated.\"\n    end\n\n    if raw[\"data_format_version\"] != DATA_FORMAT_VERSION\n        post_deserialize_conversion!(sys, raw)\n    end\n\n    return sys\nend\n\nfunction deserialize_components!(sys::System, raw)\n    # Convert the array of components into type-specific arrays to allow addition by type.\n    data = Dict{Any, Vector{Dict}}()\n    # This field was not present in older versions.\n    masked_components = get(raw, \"masked_components\", [])\n    for component in Iterators.Flatten((raw[\"components\"], masked_components))\n        type = IS.get_type_from_serialization_data(component)\n        components = get(data, type, nothing)\n        if components === nothing\n            components = Vector{Dict}()\n            data[type] = components\n        end\n        push!(components, component)\n    end\n\n    # Maintain a lookup of UUID to component because some component types encode\n    # composed types as UUIDs instead of actual types.\n    component_cache = Dict{Base.UUID, Component}()\n\n    # Add each type to this as we parse.\n    parsed_types = Set()\n\n    function is_matching_type(type, types)\n        return any(x -> type <: x, types)\n    end\n\n    function deserialize_and_add!(;\n        skip_types = nothing,\n        include_types = nothing,\n        post_add_func = nothing,\n    )\n        for (type, components) in data\n            type in parsed_types && continue\n            if !isnothing(skip_types) && is_matching_type(type, skip_types)\n                continue\n            end\n            if !isnothing(include_types) && !is_matching_type(type, include_types)\n                continue\n            end\n            components =\n                _handle_hydro_reservoirs_deserialization_special_cases(components, type)\n            for component in components\n                handle_deserialization_special_cases!(component, type)\n                comp = deserialize(type, component, component_cache)\n                add_component!(sys, comp)\n                component_cache[IS.get_uuid(comp)] = comp\n                if !isnothing(post_add_func)\n                    post_add_func(comp)\n                end\n            end\n            push!(parsed_types, type)\n        end\n    end\n\n    # Run in order based on type composition.\n    # Bus instances can have areas and LoadZones.\n    # AGC instances can have areas and contributing reserves\n    # Most components have buses.\n    # Static injection devices can contain dynamic injection devices.\n    # StaticInjectionSubsystem instances have StaticInjection subcomponents.\n    deserialize_and_add!(; include_types = [Area, LoadZone])\n    deserialize_and_add!(; include_types = [AbstractReserve])\n    deserialize_and_add!(; include_types = [AGC])\n    deserialize_and_add!(; include_types = [Bus])\n    deserialize_and_add!(;\n        include_types = [Arc, Service],\n        skip_types = [ConstantReserveGroup],\n    )\n    deserialize_and_add!(;\n        include_types = [HydroTurbine, HydroPumpTurbine],\n        skip_types = [ConstantReserveGroup, HydroReservoir],\n    )\n    deserialize_and_add!(; include_types = [HydroReservoir])\n    deserialize_and_add!(; include_types = [Branch])\n    deserialize_and_add!(; include_types = [DynamicBranch])\n    deserialize_and_add!(; include_types = [ConstantReserveGroup, DynamicInjection])\n    deserialize_and_add!(; skip_types = [StaticInjectionSubsystem])\n    deserialize_and_add!()\n\n    for subsystem in get_components(StaticInjectionSubsystem, sys)\n        # This normally happens when the subsytem is added to the system.\n        # Workaround for deserialization.\n        for subcomponent in get_subcomponents(subsystem)\n            IS.mask_component!(sys.data, subcomponent)\n        end\n    end\nend\n\n\"\"\"\nAllow types to implement handling of special cases during deserialization.\n\n# Arguments\n- `component::Dict`: The component serialized as a dictionary.\n- `::Type`: The type of the component.\n\"\"\"\nhandle_deserialization_special_cases!(component::Dict, ::Type{<:Component}) = nothing\n\n# TODO DT: Do I need to handle this in the new format upgrade?\n#function handle_deserialization_special_cases!(component::Dict, ::Type{DynamicBranch})\n#    # IS handles deserialization of supplemental attribues in each component.\n#    # In this case the DynamicBranch's composed branch is not part of the system and so\n#    # IS will not handle it. It can never attributes.\n#    if !isempty(component[\"branch\"][\"supplemental_attributes_container\"])\n#        error(\n#            \"Bug: serialized DynamicBranch.branch has supplemental attributes: $component\",\n#        )\n#    end\n#    return\n#end\n\n# This function does an iterative union find to handle the ordering of the reservoir chains\nfunction _handle_hydro_reservoirs_deserialization_special_cases(\n    components::Vector{Dict},\n    ::Type{HydroReservoir},\n)\n\n    # Build a mapping from UUID to component for quick lookup\n    uuid_to_component = Dict{String, Dict}()\n    for component in components\n        uuid_str = string(component[\"internal\"][\"uuid\"])\n        uuid_to_component[uuid_str] = component\n    end\n\n    # Build parent mapping for union-find (each reservoir points to its upstream reservoir)\n    parent = Dict{String, String}()\n    for component in components\n        uuid_str = string(component[\"internal\"][\"uuid\"])\n        upstream_uuids = component[\"upstream_reservoirs\"]\n\n        if isempty(upstream_uuids)\n            parent[uuid_str] = uuid_str  # Root of its own chain\n        else\n            # Assume single upstream reservoir for simplicity\n            parent[uuid_str] = string(upstream_uuids[1])\n        end\n    end\n\n    # Find root of each chain iteratively\n    function find_root(uuid_str)\n        current = uuid_str\n        while parent[current] != current\n            current = parent[current]\n        end\n        return current\n    end\n\n    # Group components by their chain root\n    chains = Dict{String, Vector{Dict}}()\n    for component in components\n        uuid_str = string(component[\"internal\"][\"uuid\"])\n        root = find_root(uuid_str)\n\n        if !haskey(chains, root)\n            chains[root] = Vector{Dict}()\n        end\n        push!(chains[root], component)\n    end\n\n    # Order each chain from upstream (root) to downstream\n    ordered_components = Vector{Dict}()\n    for (root_uuid, chain) in chains\n        # Sort chain by dependency order - upstream reservoirs first\n        chain_ordered = Vector{Dict}()\n        remaining = Set(chain)\n\n        while !isempty(remaining)\n            # Find next component whose upstream is already processed or is a root\n            for component in remaining\n                upstream_uuids = component[\"upstream_reservoirs\"]\n                can_add =\n                    isempty(upstream_uuids) ||\n                    all(\n                        string(uuid) in\n                        [string(c[\"internal\"][\"uuid\"]) for c in chain_ordered] for\n                        uuid in upstream_uuids\n                    )\n\n                if can_add\n                    push!(chain_ordered, component)\n                    delete!(remaining, component)\n                    break\n                end\n            end\n        end\n\n        append!(ordered_components, chain_ordered)\n    end\n    return ordered_components\nend\n\n_handle_hydro_reservoirs_deserialization_special_cases(\n    components::Vector{Dict},\n    ::Type{<:Component}) = components\n\"\"\"\nReturn [`ACBus`](@ref) with `name`.\n\"\"\"\nfunction get_bus(sys::System, name::AbstractString)\n    return get_component(ACBus, sys, name)\nend\n\n\"\"\"\nReturn [`ACBus`](@ref) with `bus_number`.\n\"\"\"\nfunction get_bus(sys::System, bus_number::Int)\n    for bus in get_components(ACBus, sys)\n        if bus.number == bus_number\n            return bus\n        end\n    end\n\n    return nothing\nend\n\n\"\"\"\nReturn [`ACBus`](@ref)es from a set of identification `number`s\n\n# Examples\n```julia\n# View all the bus ID numbers in the System\nget_number.(get_components(ACBus, system))\n# Select a subset\nbuses_by_ID = get_buses(system, Set(101:110))\n```\n\"\"\"\nfunction get_buses(sys::System, bus_numbers::Set{Int})\n    buses = Vector{ACBus}()\n    for bus in get_components(ACBus, sys)\n        if bus.number in bus_numbers\n            push!(buses, bus)\n        end\n    end\n\n    return buses\nend\n\n\"\"\"\nReturn all the device types in the system. It does not return component types or masked components.\n\"\"\"\nfunction get_existing_device_types(sys::System)\n    device_types = Vector{DataType}()\n    for component_type in keys(sys.data.components.data)\n        if component_type <: Device\n            push!(device_types, component_type)\n        end\n    end\n    return device_types\nend\n\n\"\"\"\nReturn all the component types in the system. It does not return masked components.\n\"\"\"\nfunction get_existing_component_types(sys::System)\n    return collect(keys(sys.data.components.data))\nend\n\nfunction _is_deserialization_in_progress(sys::System)\n    ext = get_ext(sys)\n    return get(ext, \"deserialization_in_progress\", false)\nend\n\ncheck_for_services_on_addition(sys::System, component::Component) = nothing\n\nfunction check_for_services_on_addition(sys::System, component::T) where {T <: Device}\n    if supports_services(component) && length(get_services(component)) > 0\n        throw(\n            ArgumentError(\n                \"type $(IS.strip_module_name(string(T))) cannot be added with services\",\n            ),\n        )\n    end\n    return\nend\n\nfunction check_topology(sys::System, component::AreaInterchange)\n    throw_if_not_attached(get_from_area(component), sys)\n    throw_if_not_attached(get_to_area(component), sys)\n    return\nend\n\nfunction check_topology(sys::System, component::Component)\n    check_attached_buses(sys, component)\n    return\nend\n\n\"\"\"\nThrows ArgumentError if any bus attached to the component is invalid.\n\"\"\"\ncheck_attached_buses(sys::System, component::Component) = nothing\n\nfunction check_attached_buses(sys::System, component::StaticInjection)\n    throw_if_not_attached(get_bus(component), sys)\n    return\nend\n\nfunction check_attached_buses(sys::System, component::Branch)\n    throw_if_not_attached(get_from_bus(component), sys)\n    throw_if_not_attached(get_to_bus(component), sys)\n    return\nend\n\nfunction check_attached_buses(\n    sys::System,\n    component::ThreeWindingTransformer,\n)\n    bus_primary = get_from(get_primary_star_arc(component))\n    bus_secondary = get_from(get_secondary_star_arc(component))\n    bus_tertiary = get_from(get_tertiary_star_arc(component))\n    star_bus = get_star_bus(component)\n    throw_if_not_attached(bus_primary, sys)\n    throw_if_not_attached(bus_secondary, sys)\n    throw_if_not_attached(bus_tertiary, sys)\n    throw_if_not_attached(star_bus, sys)\n    return\nend\n\nfunction check_attached_buses(sys::System, component::DynamicBranch)\n    check_attached_buses(sys, get_branch(component))\n    return\nend\n\nfunction check_attached_buses(sys::System, component::Arc)\n    throw_if_not_attached(get_from(component), sys)\n    throw_if_not_attached(get_to(component), sys)\n    return\nend\n\n\"\"\"\nThrows ArgumentError if a PowerSystems rule blocks addition to the system.\n\nThis method is tied with handle_component_addition!. If the methods are re-implemented for\na subtype then whatever is added in handle_component_addition! must be checked here.\n\"\"\"\ncheck_component_addition(sys::System, component::Component; kwargs...) = nothing\n\n\"\"\"\nThrows ArgumentError if a PowerSystems rule blocks removal from the system.\n\"\"\"\ncheck_component_removal(sys::System, component::Component) = nothing\n\nfunction check_component_removal(sys::System, static_injector::StaticInjection)\n    if get_dynamic_injector(static_injector) !== nothing\n        name = get_name(static_injector)\n        throw(ArgumentError(\"$name cannot be removed with an attached dynamic injector\"))\n    end\nend\n\nfunction check_component_removal(sys::System, area::Area)\n    for interchange in get_components(AreaInterchange, sys)\n        if area in [get_from_area(interchange), get_to_area(interchange)]\n            throw(\n                ArgumentError(\n                    \"Area $(summary(area)) cannot be removed with attached AreaInterchange: $(summary(interchange))\",\n                ),\n            )\n        end\n    end\n    return\nend\n\n\"\"\"\nRefer to docstring for check_component_addition!\n\"\"\"\nhandle_component_addition!(sys::System, component::Component; kwargs...) = nothing\n\nhandle_component_removal!(sys::System, component::Component) = nothing\n\nfunction check_component_addition(sys::System, branch::AreaInterchange; kwargs...)\n    throw_if_not_attached(get_from_area(branch), sys)\n    throw_if_not_attached(get_to_area(branch), sys)\n    return\nend\n\nfunction check_component_addition(sys::System, branch::Branch; kwargs...)\n    arc = get_arc(branch)\n    throw_if_not_attached(get_from(arc), sys)\n    throw_if_not_attached(get_to(arc), sys)\n    return\nend\n\nfunction check_component_addition(\n    sys::System,\n    component::ThreeWindingTransformer;\n    kwargs...,\n)\n    bus_primary = get_from(get_primary_star_arc(component))\n    bus_secondary = get_from(get_secondary_star_arc(component))\n    bus_tertiary = get_from(get_tertiary_star_arc(component))\n    star_bus = get_star_bus(component)\n    throw_if_not_attached(bus_primary, sys)\n    throw_if_not_attached(bus_secondary, sys)\n    throw_if_not_attached(bus_tertiary, sys)\n    throw_if_not_attached(star_bus, sys)\n    return\nend\n\nfunction check_component_addition(sys::System, dyn_branch::DynamicBranch; kwargs...)\n    if !_is_deserialization_in_progress(sys)\n        throw_if_not_attached(dyn_branch.branch, sys)\n    end\n    arc = get_arc(dyn_branch)\n    throw_if_not_attached(get_from(arc), sys)\n    throw_if_not_attached(get_to(arc), sys)\n    return\nend\n\nfunction check_component_addition(sys::System, dyn_injector::DynamicInjection; kwargs...)\n    if _is_deserialization_in_progress(sys)\n        # Ordering of component addition makes these checks impossible.\n        return\n    end\n\n    static_injector = get(kwargs, :static_injector, nothing)\n    if static_injector === nothing\n        throw(\n            ArgumentError(\"static_injector must be passed when adding a DynamicInjection\"),\n        )\n    end\n\n    if get_name(dyn_injector) != get_name(static_injector)\n        throw(\n            ArgumentError(\n                \"static_injector must have the same name as the DynamicInjection\",\n            ),\n        )\n    end\n\n    throw_if_not_attached(static_injector, sys)\n    return\nend\n\nfunction check_component_addition(sys::System, bus::Bus; kwargs...)\n    number = get_number(bus)\n    if number in sys.bus_numbers\n        throw(ArgumentError(\"bus number $number is already stored in the system\"))\n    end\n\n    area = get_area(bus)\n    if !isnothing(area)\n        throw_if_not_attached(area, sys)\n    end\n\n    load_zone = get_load_zone(bus)\n    if !isnothing(load_zone)\n        throw_if_not_attached(load_zone, sys)\n    end\nend\n\nfunction handle_component_addition!(sys::System, bus::Bus; kwargs...)\n    number = get_number(bus)\n    if number in sys.bus_numbers\n        throw(ArgumentError(\"bus number $number is already stored\"))\n    end\n    push!(sys.bus_numbers, number)\n    return\nend\n\nfunction handle_component_addition!(sys::System, component::Branch; kwargs...)\n    _handle_branch_addition_common!(sys, component)\n    return\nend\n\nfunction handle_component_addition!(sys::System, component::DynamicBranch; kwargs...)\n    _handle_branch_addition_common!(sys, component)\n    remove_component!(sys, component.branch)\n    return\nend\n\nfunction handle_component_addition!(sys::System, dyn_injector::DynamicInjection; kwargs...)\n    static_injector = kwargs[:static_injector]\n    static_base_power = get_base_power(static_injector)\n    set_base_power!(dyn_injector, static_base_power)\n    set_dynamic_injector!(static_injector, dyn_injector)\n    return\nend\n\nfunction handle_component_addition!(\n    sys::System,\n    subsystem::StaticInjectionSubsystem;\n    kwargs...,\n)\n    for subcomponent in get_subcomponents(subsystem)\n        if is_attached(subcomponent, sys)\n            IS.mask_component!(sys.data, subcomponent)\n            copy_subcomponent_time_series!(subsystem, subcomponent)\n        else\n            IS.add_masked_component!(sys.data, subcomponent)\n        end\n    end\nend\n\nfunction _handle_branch_addition_common!(sys::System, component::Branch)\n    # If this arc is already attached to the system, assign it to the branch.\n    # Else, add it to the system.\n    arc = get_arc(component)\n    _arc = get_component(Arc, sys, get_name(arc))\n    if isnothing(_arc)\n        add_component!(sys, arc)\n    else\n        set_arc!(component, _arc)\n    end\n    return\nend\n\nfunction _handle_branch_addition_common!(\n    sys::System,\n    component::ThreeWindingTransformer,\n)\n    # If this arc is already attached to the system, assign it to the 3W XFRM.\n    # Else, add it to the system.\n    arcs = [\n        get_primary_star_arc(component),\n        get_secondary_star_arc(component),\n        get_tertiary_star_arc(component),\n    ]\n    set_arc_methods = [\n        set_primary_star_arc!,\n        set_secondary_star_arc!,\n        set_tertiary_star_arc!,\n    ]\n    for (ix, arc) in enumerate(arcs)\n        _arc = get_component(Arc, sys, get_name(arc))\n        if isnothing(_arc)\n            add_component!(sys, arc)\n        else\n            set_arc_methods[ix](component, _arc)\n        end\n    end\n    return\nend\n\n_handle_branch_addition_common!(sys::System, component::AreaInterchange) = nothing\n\n\"\"\"\nThrows ArgumentError if the bus number is not stored in the system.\n\"\"\"\nfunction handle_component_removal!(sys::System, bus::Bus)\n    _handle_component_removal_common!(bus)\n    number = get_number(bus)\n    if !(number in sys.bus_numbers)\n        throw(ArgumentError(\"bus number $number is not stored\"))\n    end\n    pop!(sys.bus_numbers, number)\n    return\nend\n\nfunction handle_component_removal!(sys::System, device::Device)\n    _handle_component_removal_common!(device)\n    # This may have to be refactored if handle_component_removal! needs to be implemented\n    # for a subtype.\n    clear_services!(device)\n    return\nend\n\nfunction handle_component_removal!(sys::System, service::Service)\n    _handle_component_removal_common!(service)\n    for device in get_components(Device, sys)\n        if !supports_services(device)\n            continue\n        end\n        _remove_service!(device, service)\n    end\nend\n\nfunction handle_component_removal!(sys::System, component::StaticInjectionSubsystem)\n    _handle_component_removal_common!(component)\n    subcomponents = collect(get_subcomponents(component))\n    for subcomponent in subcomponents\n        IS.remove_masked_component!(sys.data, subcomponent)\n    end\nend\n\nfunction handle_component_removal!(sys::System, value::T) where {T <: AggregationTopology}\n    _handle_component_removal_common!(value)\n    for device in get_components(ACBus, sys)\n        if get_aggregation_topology_accessor(T)(device) == value\n            _remove_aggregration_topology!(device, value)\n        end\n    end\nend\n\nfunction handle_component_removal!(sys::System, dyn_injector::DynamicInjection)\n    _handle_component_removal_common!(dyn_injector)\n    injectors = get_components_by_name(StaticInjection, sys, get_name(dyn_injector))\n    found = false\n    for static_injector in injectors\n        _dyn_injector = get_dynamic_injector(static_injector)\n        _dyn_injector === nothing && continue\n        if _dyn_injector === dyn_injector\n            @assert !found\n            set_dynamic_injector!(static_injector, nothing)\n            found = true\n        end\n    end\n\n    @assert found\nend\n\nfunction _handle_component_removal_common!(component)\n    clear_units!(component)\nend\n\n\"\"\"\nReturn a sorted vector of bus numbers in the system.\n\"\"\"\nfunction get_bus_numbers(sys::System)\n    return sort(collect(sys.bus_numbers))\nend\n\n_fetch_match_fn(match_fn::Function) = match_fn\n_fetch_match_fn(::Nothing) = IS.isequivalent\n\nfunction IS.compare_values(\n    match_fn::Union{Function, Nothing},\n    x::T,\n    y::T;\n    compare_uuids = false,\n    exclude = Set{Symbol}(),\n) where {T <: Union{StaticInjection, DynamicInjection}}\n    # Must implement this method because a device of one of these subtypes might have a\n    # reference to its counterpart, and vice versa, and so infinite recursion will occur\n    # in the default function.\n    match = true\n    for name in fieldnames(T)\n        name in exclude && continue\n        val1 = getfield(x, name)\n        val2 = getfield(y, name)\n        if val1 isa StaticInjection || val2 isa DynamicInjection\n            if !compare_uuids\n                name1 = get_name(val1)\n                name2 = get_name(val2)\n                if !_fetch_match_fn(match_fn)(name1, name2)\n                    @error \"values do not match\" T name name1 name2\n                    match = false\n                end\n            else\n                uuid1 = IS.get_uuid(val1)\n                uuid2 = IS.get_uuid(val2)\n                if uuid1 != uuid2\n                    @error \"values do not match\" T name uuid1 uuid2\n                    match = false\n                end\n            end\n        elseif !isempty(fieldnames(typeof(val1)))\n            if !IS.compare_values(\n                match_fn,\n                val1,\n                val2;\n                compare_uuids = compare_uuids,\n                exclude = exclude,\n            )\n                @error \"values do not match\" T name val1 val2\n                match = false\n            end\n        elseif val1 isa AbstractArray\n            if !IS.compare_values(\n                match_fn,\n                val1,\n                val2;\n                compare_uuids = compare_uuids,\n                exclude = exclude,\n            )\n                match = false\n            end\n        else\n            if !_fetch_match_fn(match_fn)(val1, val2)\n                @error \"values do not match\" T name val1 val2\n                match = false\n            end\n        end\n    end\n\n    return match\nend\n\nfunction _create_system_data_from_kwargs(;\n    time_series_in_memory = false,\n    time_series_directory = nothing,\n    compression = nothing,\n    enable_compression = false,\n    config_path = POWER_SYSTEM_STRUCT_DESCRIPTOR_FILE,\n    kwargs...,\n)\n    if isnothing(compression)\n        compression = IS.CompressionSettings(; enabled = enable_compression)\n    end\n\n    return IS.SystemData(;\n        validation_descriptor_file = config_path,\n        time_series_in_memory = time_series_in_memory,\n        time_series_directory = time_series_directory,\n        compression = compression,\n    )\nend\n\n\"\"\"\nConverts a Line component to a MonitoredLine component and replaces the original in the\nsystem\n\"\"\"\nfunction convert_component!(\n    sys::System,\n    line::Line,\n    linetype::Type{MonitoredLine};\n    kwargs...,\n)\n    new_line = linetype(\n        line.name,\n        line.available,\n        line.active_power_flow,\n        line.reactive_power_flow,\n        line.arc,\n        line.r,\n        line.x,\n        line.b,\n        (from_to = line.rating, to_from = line.rating),\n        line.rating,\n        line.angle_limits,\n        line.rating_b,\n        line.rating_c,\n        line.g,\n        line.services,\n        line.ext,\n        _copy_internal_for_conversion(line),\n    )\n    IS.assign_new_uuid!(sys, line)\n    add_component!(sys, new_line)\n    copy_time_series!(new_line, line)\n    # TODO: PSY4\n    # copy_supplemental_attibutes!(new_line, line)\n    remove_component!(sys, line)\n    return\nend\n\n\"\"\"\nConverts a MonitoredLine component to a Line component and replaces the original in the\nsystem.\n\"\"\"\nfunction convert_component!(\n    sys::System,\n    line::MonitoredLine,\n    linetype::Type{Line};\n    kwargs...,\n)\n    force = get(kwargs, :force, false)\n    if force\n        @warn(\"Possible data loss converting from $(typeof(line)) to $linetype\")\n    else\n        error(\n            \"Possible data loss converting from $(typeof(line)) to $linetype, add `force = true` to convert anyway.\",\n        )\n    end\n\n    new_line = linetype(\n        line.name,\n        line.available,\n        line.active_power_flow,\n        line.reactive_power_flow,\n        line.arc,\n        line.r,\n        line.x,\n        line.b,\n        line.rating,\n        line.angle_limits,\n        line.rating_b,\n        line.rating_c,\n        line.g,\n        line.services,\n        line.ext,\n        _copy_internal_for_conversion(line),\n    )\n    IS.assign_new_uuid!(sys, line)\n    add_component!(sys, new_line)\n    copy_time_series!(new_line, line)\n    # TODO: PSY4\n    # copy_supplemental_attibutes!(new_line, line)\n    remove_component!(sys, line)\n    return\nend\n\n\"\"\"\nConverts a PowerLoad component to a StandardLoad component and replaces the original in the\nsystem. Does not set any fields in StandardLoad that lack a PowerLoad equivalent.\n\"\"\"\nfunction convert_component!(\n    sys::System,\n    old_load::PowerLoad,\n    new_type::Type{StandardLoad};\n    kwargs...,\n)\n    new_load = new_type(;\n        name = get_name(old_load),\n        available = get_available(old_load),\n        bus = get_bus(old_load),\n        base_power = get_base_power(old_load),\n        constant_active_power = get_active_power(old_load),\n        constant_reactive_power = get_reactive_power(old_load),\n        max_constant_active_power = get_max_active_power(old_load),\n        max_constant_reactive_power = get_max_active_power(old_load),\n        conformity = get_conformity(old_load),\n        dynamic_injector = get_dynamic_injector(old_load),\n        internal = _copy_internal_for_conversion(old_load),\n        services = Device[],\n    )\n    IS.assign_new_uuid!(sys, old_load)\n    add_component!(sys, new_load)\n    copy_time_series!(new_load, old_load)\n    # TODO: PSY4\n    # copy_supplemental_attibutes!(new_line, line)\n    for service in get_services(old_load)\n        add_service!(new_load, service, sys)\n    end\n    remove_component!(sys, old_load)\nend\n\n\"\"\"\nSet the number of a bus.\n\"\"\"\nfunction set_bus_number!(sys::System, bus::Bus, number::Int)\n    throw_if_not_attached(bus, sys)\n\n    orig = get_number(bus)\n    if number == orig\n        return\n    end\n\n    if number in sys.bus_numbers\n        throw(ArgumentError(\"bus number $number is already stored in the system\"))\n    end\n\n    set_number!(bus, number)\n    replace!(sys.bus_numbers, orig => number)\n    return\nend\n\nfunction set_number!(bus::ACBus, number::Int)\n    Base.depwarn(\n        \"This method will be removed in v5.0 because its use breaks system consistency\" *\n        \"checks. Please call `set_bus_number!(::System, bus, number)` instead.\",\n        :set_number!,\n    )\n    bus.number = number\n    return\nend\n\n# Use this function to avoid deepcopy of shared_system_references.\nfunction _copy_internal_for_conversion(component::Component)\n    internal = get_internal(component)\n    return InfrastructureSystemsInternal(;\n        uuid = deepcopy(internal.uuid),\n        units_info = deepcopy(internal.units_info),\n        shared_system_references = nothing,\n        ext = deepcopy(internal.ext),\n    )\nend\n\nfunction _validate_or_skip!(sys, component, skip_validation)\n    if skip_validation && get_runchecks(sys)\n        @warn(\n            \"skip_validation is deprecated; construct System with runchecks = true or call set_runchecks!. Disabling System.runchecks\"\n        )\n        set_runchecks!(sys, false)\n    end\n\n    # Always skip if system checks are disabled.\n    if !skip_validation && !get_runchecks(sys)\n        skip_validation = true\n    end\n\n    if !skip_validation\n        sanitize_component!(component, sys)\n        if !validate_component_with_system(component, sys)\n            throw(IS.InvalidValue(\"Invalid value for $(summary(component))\"))\n        end\n    end\n\n    return skip_validation\nend\n\n\"\"\"\nReturns counts of time series including attachments to components and supplemental\nattributes.\n\"\"\"\nget_time_series_counts(sys::System) = IS.get_time_series_counts(sys.data)\n\n\"\"\"\nChecks time series in the system for inconsistencies.\n\nFor SingleTimeSeries, returns a Tuple of initial_timestamp and length.\n\nThis is a no-op for subtypes of Forecast because those are already guaranteed to be\nconsistent.\n\nThrows InfrastructureSystems.InvalidValue if any time series is inconsistent.\n\"\"\"\nfunction check_time_series_consistency(sys::System, ::Type{T}) where {T <: TimeSeriesData}\n    return IS.check_time_series_consistency(sys.data, T)\nend\n\nstores_time_series_in_memory(sys::System) = IS.stores_time_series_in_memory(sys.data)\n\n\"\"\"\nMake a `deepcopy` of a [`System`](@ref) more quickly by skipping the copying of time\nseries and/or supplemental attributes.\n\n# Arguments\n\n  - `data::System`: the `System` to copy\n  - `skip_time_series::Bool = true`: whether to skip copying time series\n  - `skip_supplemental_attributes::Bool = true`: whether to skip copying supplemental\n    attributes\n\nNote that setting both `skip_time_series` and `skip_supplemental_attributes` to `false`\nresults in the same behavior as `deepcopy` with no performance improvement.\n\"\"\"\nfunction fast_deepcopy_system(\n    sys::System;\n    skip_time_series::Bool = true,\n    skip_supplemental_attributes::Bool = true,\n)\n    new_data = IS.fast_deepcopy_system(\n        sys.data;\n        skip_time_series = skip_time_series,\n        skip_supplemental_attributes = skip_supplemental_attributes,\n    )\n    new_sys = System(\n        new_data,\n        deepcopy(sys.units_settings),\n        deepcopy(sys.internal);\n        runchecks = deepcopy(sys.runchecks[]),\n        frequency = deepcopy(sys.frequency),\n        time_series_directory = deepcopy(sys.time_series_directory),\n        name = deepcopy(sys.metadata.name),\n        description = deepcopy(sys.metadata.description))\n    # deepcopying sys.data separately from sys.units_settings broke the shared units references, so we have to fix them here\n    for comp in iterate_components(new_sys)\n        comp.internal.units_info = new_sys.units_settings\n    end\n    return new_sys\nend\n\n\"\"\"\nReturn a DataFrame with the number of static time series for components and supplemental\nattributes.\n\"\"\"\nfunction get_static_time_series_summary_table(sys::System)\n    return IS.get_static_time_series_summary_table(sys.data)\nend\n\n\"\"\"\nReturn a DataFrame with the number of forecasts for components and supplemental\nattributes.\n\"\"\"\nfunction get_forecast_summary_table(sys::System)\n    return IS.get_forecast_summary_table(sys.data)\nend\n\nIS.get_base_component_type(sys::System) = Component\n"
  },
  {
    "path": "src/component_selector.jl",
    "content": "# Most of the `ComponentSelector` functionality in PowerSystems.jl is implemented by\n# wrapping the InfrastructureSystems.jl versions (that wrapping occurs in\n# `component_selector_interface.jl`). An exception is `TopologyComponentSelector`, which is\n# wholly implemented in PSY rather than in IS because it depends on\n# `PSY.AggregationTopology`.\n\n\"\"\"\n`PluralComponentSelector` represented by an `AggregationTopology` and a type of `Component`.\n\"\"\"\n@kwdef struct TopologyComponentSelector <: DynamicallyGroupedComponentSelector\n    component_type::Type{<:Component}\n    topology_type::Type{<:AggregationTopology}\n    topology_name::AbstractString\n    groupby::Union{Symbol, Function}\n    name::String\n\n    TopologyComponentSelector(\n        component_type::Type{<:InfrastructureSystemsComponent},\n        topology_type::Type{<:AggregationTopology},\n        topology_name::AbstractString,\n        groupby::Union{Symbol, Function},\n        name::String,\n    ) =\n        new(\n            component_type,\n            topology_type,\n            topology_name,\n            IS.validate_groupby(groupby),\n            name,\n        )\nend\n\n# Construction\nTopologyComponentSelector(\n    component_type::Type{<:InfrastructureSystemsComponent},\n    topology_type::Type{<:AggregationTopology},\n    topology_name::AbstractString,\n    groupby::Union{Symbol, Function},\n    name::Nothing = nothing,\n) =\n    TopologyComponentSelector(\n        component_type,\n        topology_type,\n        topology_name,\n        groupby,\n        component_to_qualified_string(topology_type, topology_name) *\n        COMPONENT_NAME_DELIMITER * subtype_to_string(component_type),\n    )\n\n\"\"\"\nMake a `ComponentSelector` from an `AggregationTopology` and a type of component. Optionally\nprovide a name and/or grouping behavior for the `ComponentSelector`.\n\"\"\"\nmake_selector(\n    component_type::Type{<:Component},\n    topology_type::Type{<:AggregationTopology},\n    topology_name::AbstractString;\n    groupby::Union{Symbol, Function} = IS.DEFAULT_GROUPBY,\n    name::Union{String, Nothing} = nothing,\n) = TopologyComponentSelector(\n    component_type,\n    topology_type,\n    topology_name,\n    groupby,\n    name,\n)\n\n# Contents\nfunction IS.get_components(\n    scope_limiter::Union{Function, Nothing},\n    selector::TopologyComponentSelector,\n    sys::System,\n)\n    agg_topology = get_component(selector.topology_type, sys, selector.topology_name)\n    isnothing(agg_topology) && return IS._make_empty_iterator(selector.component_type)\n\n    combo_filter = IS.optional_and_fns(\n        scope_limiter,\n        Base.Fix2(is_component_in_aggregation_topology, agg_topology),\n    )\n    return IS.get_components(combo_filter, selector.component_type, sys)\nend\n"
  },
  {
    "path": "src/component_selector_interface.jl",
    "content": "# A continuation of `get_components_interface.jl` to facilitate neater documentation of\n# `ComponentSelector`. See the long comment at the top of that file.\n\n# get_components\n\"\"\"\nGet the components of the [`System`](@ref) that make up the [`ComponentSelector`](@ref).\nOptionally specify a filter function `scope_limiter` as the first argument to limit the\ncomponents that should be considered.\n\n# Arguments\n\n  - `scope_limiter::Union{Function, Nothing}`: see [`ComponentSelector`](@ref)\n  - `selector::ComponentSelector`: the `ComponentSelector` whose components to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_components(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n) =\n    IS.get_components(scope_limiter, selector, sys)\n\n\"\"\"\nGet the components of the [`System`](@ref) that make up the [`ComponentSelector`](@ref).\n\n# Arguments\n\n  - `selector::ComponentSelector`: the `ComponentSelector` whose components to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_components(selector::ComponentSelector, sys::System) =\n    IS.get_components(selector, sys)\n\n# get_component\n\"\"\"\nGet the component of the [`System`](@ref) that makes up the\n[`SingularComponentSelector`](@ref); `nothing` if there is none. Optionally specify a filter\nfunction `scope_limiter` as the first argument to limit the components that should be\nconsidered.\n\n# Arguments\n\n  - `scope_limiter::Union{Function, Nothing}`: see [`ComponentSelector`](@ref)\n  - `selector::SingularComponentSelector`: the `SingularComponentSelector` whose component\n    to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_component(\n    scope_limiter::Union{Function, Nothing},\n    selector::SingularComponentSelector,\n    sys::System,\n) =\n    IS.get_component(scope_limiter, selector, sys)\n\n\"\"\"\nGet the component of the [`System`](@ref) that makes up the\n[`SingularComponentSelector`](@ref); `nothing` if there is none.\n\n# Arguments\n\n  - `selector::SingularComponentSelector`: the `SingularComponentSelector` whose component to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_component(selector::SingularComponentSelector, sys::System) =\n    IS.get_component(selector, sys)\n\n# get_available_components\n\"\"\"\nLike [`get_components`](@ref get_components(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n)) but only operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_components(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n) =\n    IS.get_available_components(scope_limiter, selector::ComponentSelector, sys::System)\n\n\"\"\"\nLike [`get_components`](@ref get_components(selector::ComponentSelector, sys::System)) but\nonly operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_components(selector::ComponentSelector, sys::System) =\n    IS.get_available_components(selector::ComponentSelector, sys::System)\n\n# get_available_component\n\"\"\"\nLike [`get_component`](@ref get_component(\n    scope_limiter::Union{Function, Nothing},\n    selector::IS.SingularComponentSelector,\n    sys::System,\n)) but only operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_component(\n    scope_limiter::Union{Function, Nothing},\n    selector::IS.SingularComponentSelector,\n    sys::System,\n) =\n    IS.get_available_component(scope_limiter, selector, sys)\n\n\"\"\"\nLike [`get_component`](@ref get_component(\n    selector::IS.SingularComponentSelector,\n    sys::System,\n)) but only operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_component(\n    selector::IS.SingularComponentSelector,\n    sys::System,\n) =\n    IS.get_available_component(selector, sys)\n\n# get_groups\n\"\"\"\nGet the groups that make up the [`ComponentSelector`](@ref). Optionally specify a filter\nfunction `scope_limiter` as the first argument to limit the components that should be\nconsidered.\n\n# Arguments\n\n  - `scope_limiter::Union{Function, Nothing}`: see [`ComponentSelector`](@ref)\n  - `selector::ComponentSelector`: the `ComponentSelector` whose groups to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_groups(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n) =\n    IS.get_groups(scope_limiter, selector, sys)\n\n\"\"\"\nGet the groups that make up the [`ComponentSelector`](@ref).\n\n# Arguments\n\n  - `selector::ComponentSelector`: the `ComponentSelector` whose groups to retrieve\n  - `sys::System`: the system from which to draw components\n\"\"\"\nget_groups(selector::ComponentSelector, sys::System) =\n    IS.get_groups(selector, sys)\n\n# get_available_groups\n\"\"\"\nLike [`get_groups`](@ref get_groups(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n)) but only operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_groups(\n    scope_limiter::Union{Function, Nothing},\n    selector::ComponentSelector,\n    sys::System,\n) =\n    IS.get_available_groups(scope_limiter, selector, sys)\n\n\"\"\"\nLike [`get_groups`](@ref get_groups(selector::ComponentSelector, sys::System)) but\nonly operates on components for which [`get_available`](@ref) is `true`.\n\"\"\"\nget_available_groups(selector::ComponentSelector, sys::System) =\n    IS.get_available_groups(selector, sys)\n"
  },
  {
    "path": "src/contingencies.jl",
    "content": "\"\"\"\nSupertype for contingency events that can be attached to components as supplemental\nattributes.\n\nConcrete subtypes include [`Outage`](@ref) and its descendants.\n\"\"\"\nabstract type Contingency <: SupplementalAttribute end\n"
  },
  {
    "path": "src/data_format_conversions.jl",
    "content": "# This file contains code to convert serialized data from old formats to work with newer\n# code.\n\n#\n# In version 1.0.1 the DeterministicMetadata struct added field time_series type.\n# Deserialization needs to add this field and value.\n#\n\n# List of structs that have a \"variable\" field that requires 3.0.0 VariableCost -> 4.0.0 FunctionData conversion\nconst COST_CONTAINERS =\n    [\"MultiStartCost\", \"StorageManagementCost\", \"ThreePartCost\", \"TwoPartCost\"]\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    ::Val{Symbol(\"2.0.0\")},\n    ::Val{Symbol(\"3.0.0\")},\n)\n    for component in raw[\"data\"][\"components\"]\n        if component[\"__metadata__\"][\"type\"] == \"Bus\"\n            component[\"__metadata__\"][\"type\"] = \"ACBus\"\n            continue\n        end\n        if component[\"__metadata__\"][\"type\"] == \"HVDCLine\"\n            component[\"__metadata__\"][\"type\"] = \"TwoTerminalGenericHVDCLine\"\n            continue\n        end\n        if component[\"__metadata__\"][\"type\"] == \"VSCDCLine\"\n            component[\"__metadata__\"][\"type\"] = \"TwoTerminalLCCLine\"\n            continue\n        end\n        if haskey(component, \"prime_mover\") && haskey(component, \"dynamic_injector\")\n            component[\"prime_mover_type\"] = pop!(component, \"prime_mover\")\n        end\n    end\n    return\nend\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    ::Val{Symbol(\"1.0.0\")},\n    ::Val{Symbol(\"3.0.0\")},\n)\n    _convert_data!(raw, Val{Symbol(\"1.0.0\")}(), Val{Symbol(\"2.0.0\")}())\n    _convert_data!(raw, Val{Symbol(\"2.0.0\")}(), Val{Symbol(\"3.0.0\")}())\n    return\nend\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    ::Val{Symbol(\"1.0.1\")},\n    ::Val{Symbol(\"3.0.0\")},\n)\n    _convert_data!(raw, Val{Symbol(\"2.0.0\")}(), Val{Symbol(\"3.0.0\")}())\n    return\nend\n\n_convert_cost(old_cost::Real) = LinearFunctionData(old_cost)\n\n_convert_cost((squared_term, proportional_term)::Tuple{<:Real, <:Real}) =\n    QuadraticFunctionData(squared_term, proportional_term, 0)\n\nfunction _convert_cost(points::Vector)\n    # We can't rely on the typing to be nice after deserialization, so \"dispatch\" on the structure\n    ((length(points) == 2) && all(typeof.(points) .<: Real)) &&\n        return _convert_cost(Tuple(points))\n\n    @assert all(length.(points) .== 2)\n    @assert all([all(typeof.(point) .<: Real) for point in points])\n    # NOTE: old representation stored points as (y, x); new representation is (x, y)\n    return PiecewiseLinearData([(x, y) for (y, x) in points])\nend\n\n# _convert_op_cost: take a component type, an old operational cost type, and old operational\n# cost data; and create the proper new operational cost struct. Some of these cost structs\n# no longer exist, so we dispatch instead on symbols.\n_convert_op_cost(::Val{:ThermalStandard}, ::Val{:ThreePartCost}, op_cost::Dict) =\n    ThermalGenerationCost(\n        CostCurve(InputOutputCurve(op_cost[\"variable\"])),\n        op_cost[\"fixed\"],\n        op_cost[\"start_up\"],\n        op_cost[\"shut_down\"],\n    )\n\nfunction _convert_op_cost(::Val{:RenewableDispatch}, ::Val{:TwoPartCost}, op_cost::Dict)\n    (op_cost[\"fixed\"] != 0) && throw(\n        ArgumentError(\"Not implemented for nonzero fixed cost, got $(op_cost[\"fixed\"])\"),\n    )\n    return RenewableGenerationCost(CostCurve(InputOutputCurve(op_cost[\"variable\"])))\nend\n\n_convert_op_cost(::Val{:GenericBattery}, ::Val{:StorageManagementCost}, op_cost::Dict) =\n    StorageCost(;\n        charge_variable_cost = CostCurve(InputOutputCurve(op_cost[\"variable\"])),\n        discharge_variable_cost = CostCurve(InputOutputCurve(op_cost[\"variable\"])),\n        fixed = op_cost[\"fixed\"],\n        start_up = float(op_cost[\"start_up\"]),\n        shut_down = float(op_cost[\"shut_down\"]),\n        energy_shortage_cost = op_cost[\"energy_shortage_cost\"],\n        energy_surplus_cost = op_cost[\"energy_surplus_cost\"],\n    )\n\n_convert_op_cost(::Val{:HydroDispatch}, ::Val{:TwoPartCost}, op_cost::Dict) =\n    HydroGenerationCost(CostCurve(InputOutputCurve(op_cost[\"variable\"])), op_cost[\"fixed\"])\n\n# TODO implement remaining _convert_op_cost methods\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    ::Val{Symbol(\"3.0.0\")},\n    ::Val{Symbol(\"4.0.0\")},\n)\n    for component in vcat(raw[\"data\"][\"components\"], raw[\"data\"][\"masked_components\"])\n        # Convert costs: all old cost structs are in fields named `operation_cost`\n        if haskey(component, \"operation_cost\")\n            op_cost = component[\"operation_cost\"]\n            # Step 1: insert a FunctionData\n            if op_cost[\"__metadata__\"][\"type\"] in COST_CONTAINERS &&\n               haskey(op_cost[\"variable\"], \"cost\")\n                old_cost = op_cost[\"variable\"][\"cost\"]\n                new_cost = _convert_cost(old_cost)\n                op_cost[\"variable\"] = new_cost\n            end\n            # Step 2: convert TwoPartCost/ThreePartCost to new domain-specific cost structs\n            comp_type = Val{Symbol(component[\"__metadata__\"][\"type\"])}()\n            op_cost_type = Val{Symbol(op_cost[\"__metadata__\"][\"type\"])}()\n            new_op_cost = IS.serialize(_convert_op_cost(comp_type, op_cost_type, op_cost))\n            component[\"operation_cost\"] = new_op_cost\n        end\n\n        (component[\"__metadata__\"][\"type\"] == \"RenewableFix\") &&\n            (component[\"__metadata__\"][\"type\"] = \"RenewableNonDispatch\")\n\n        if component[\"__metadata__\"][\"type\"] ∈ [\"BatteryEMS\", \"GenericBattery\"]\n            old_type = component[\"__metadata__\"][\"type\"]\n            component[\"__metadata__\"][\"type\"] = \"EnergyReservoirStorage\"\n            component[\"storage_technology_type\"] = IS.serialize(StorageTech.OTHER_CHEM)\n            soc_min = component[\"state_of_charge_limits\"][\"min\"]\n            soc_max = component[\"state_of_charge_limits\"][\"max\"]\n            if soc_max == 0.0\n                component[\"storage_capacity\"] = 0.0\n                component[\"storage_level_limits\"] = Dict(\"min\" => 0.0, \"max\" => 1.0)\n                (component[\"initial_energy\"] != 0.0) && throw(\n                    ArgumentError(\n                        \"Maximum state of charge is zero but initial energy is not; cannot parse\",\n                    ),\n                )\n                component[\"initial_storage_capacity_level\"] = 0.0\n            else\n                # Derive storage_capacity from old state of charge limits and normalize new\n                # state of charge limits, initial capacity accordingly\n                @warn \"Parsing $PowerSystems 3.0.0 $old_type as $PowerSystems 4.0.0 $(component[\"__metadata__\"][\"type\"]), accuracy of conversion not guaranteed\"\n                component[\"storage_capacity\"] = soc_max\n                component[\"storage_level_limits\"] =\n                    Dict(\"min\" => soc_min / soc_max, \"max\" => 1.0)\n                component[\"initial_storage_capacity_level\"] =\n                    component[\"initial_energy\"] / soc_max\n            end\n        end\n        if haskey(component, \"rate\")  # Line, TapTransformer, etc.\n            component[\"rating\"] = component[\"rate\"]\n        end\n    end\n    return\nend\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    from::Val,\n    ::Val{Symbol(\"4.0.0\")},\n)\n    _convert_data!(raw, from, Val{Symbol(\"3.0.0\")}())\n    _convert_data!(raw, Val{Symbol(\"3.0.0\")}(), Val{Symbol(\"4.0.0\")}())\n    return\nend\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    ::Val{Symbol(\"4.0.0\")},\n    ::Val{Symbol(\"5.0.0\")},\n)\n    error(\"Conversion from 4.0.0 to 5.0.0 JSON format is not supported yet.\")\n    #=\n    for component in raw[\"data\"][\"components\"]\n        if component[\"__metadata__\"][\"type\"] == \"TwoTerminalHVDCLine\"\n            component[\"__metadata__\"][\"type\"] = \"TwoTerminalGenericHVDCLine\"\n            continue\n        end\n        if component[\"__metadata__\"][\"type\"] ∈ (\"Transformer2W\", \"TapTransformer\") &&\n           \"winding_group_number\" ∉ keys(component)\n            component[\"winding_group_number\"] = WindingGroupNumber.GROUP_0\n            continue\n        end\n    end\n    =#\n    return\nend\n\nfunction _convert_data!(\n    raw::Dict{String, Any},\n    from::Val,\n    ::Val{Symbol(\"5.0.0\")},\n)\n    _convert_data!(raw, from, Val{Symbol(\"4.0.0\")}())\n    _convert_data!(raw, Val{Symbol(\"4.0.0\")}(), Val{Symbol(\"5.0.0\")}())\n    return\nend\n\n# Conversions to occur immediately after the data is loaded from disk\nfunction pre_read_conversion!(raw)\n    if VersionNumber(raw[\"data_format_version\"]) < v\"4.0.0\"\n        haskey(raw[\"data\"], \"subsystems\") ||\n            (raw[\"data\"][\"subsystems\"] = Dict{String, Any}())\n        haskey(raw[\"data\"], \"attributes\") || (raw[\"data\"][\"attributes\"] = Any[])\n    end\nend\n\n# Conversions to occur before deserialize_components!\nfunction pre_deserialize_conversion!(raw, sys::System)\n    old = raw[\"data_format_version\"]\n    if old == DATA_FORMAT_VERSION\n        return\n    else\n        _convert_data!(raw, Val{Symbol(old)}(), Val{Symbol(DATA_FORMAT_VERSION)}())\n        @warn(\n            \"System loaded in the data format version $old will be automatically upgraded to $DATA_FORMAT_VERSION upon saving\"\n        )\n    end\nend\n\n# Conversions to occur at the end of deserialization\nfunction post_deserialize_conversion!(sys::System, raw)\n    old = raw[\"data_format_version\"]\n    if old == \"1.0.1\" || old == \"2.0.0\" || old == \"3.0.0\"\n        # Version 1.0.1 can be converted\n        raw[\"data_format_version\"] = DATA_FORMAT_VERSION\n        @warn(\n            \"System loaded in the data format version $old will be automatically upgraded to $DATA_FORMAT_VERSION upon saving\"\n        )\n        return\n    else\n        error(\"Conversion of data from $old to $DATA_FORMAT_VERSION is not supported\")\n    end\nend\n"
  },
  {
    "path": "src/definitions.jl",
    "content": "const MinMax = NamedTuple{(:min, :max), Tuple{Float64, Float64}}\nconst UpDown = NamedTuple{(:up, :down), Tuple{Float64, Float64}}\nconst StartUpShutDown = NamedTuple{(:startup, :shutdown), Tuple{Float64, Float64}}\nconst FromTo = NamedTuple{(:from, :to), Tuple{Float64, Float64}}\nconst TurbinePump = NamedTuple{(:turbine, :pump), Tuple{Float64, Float64}}\n# Exception to CamelCase convention for aliases due to confusssing reading of FromToToFrom\nconst FromTo_ToFrom = NamedTuple{(:from_to, :to_from), Tuple{Float64, Float64}}\nconst StartUpStages = NamedTuple{(:hot, :warm, :cold), NTuple{3, Float64}}\n\n# Intended for use with generators that are not multi-start (e.g. ThermalStandard).\n# Operators use `hot` when they don’t have multiple stages.\n\"Convert a single start-up cost value to a `StartUpStages`\"\nsingle_start_up_to_stages(start_up::Real) =\n    (hot = Float64(start_up), warm = 0.0, cold = 0.0)\n\nIS.@scoped_enum(GeneratorCostModels, PIECEWISE_LINEAR = 1, POLYNOMIAL = 2,)\n@doc\"\n    GeneratorCostModel\n\nEnumeration representing different cost models for generators in power system analysis.\n\" GeneratorCostModels\n\nIS.@scoped_enum(AngleUnits, DEGREES = 1, RADIANS = 2,)\n@doc\"\nAngleUnits\n\nAn enumeration of angular measurement units used throughout the PowerSystems package.\n\nValues\n- `DEGREES`: Angles expressed in degrees.\n- `RADIANS`: Angles expressed in radians.\n\nUsage\nUse `AngleUnits` to make unit semantics explicit for functions, fields, and APIs that accept or return angular values. When performing trigonometric calculations with Base functions (`sin`, `cos`, etc.), convert degrees to radians (e.g., `θ * π/180`) if the unit is `DEGREES`.\n\nExamples\njulia> unit = AngleUnits.DEGREES\nAngleUnits.DEGREES\n\njulia> θ = 30.0\njulia> θ_rad = unit == AngleUnits.DEGREES ? θ * (π/180) : θ\n\" AngleUnits\n\nIS.@scoped_enum(ACBusTypes, PQ = 1, PV = 2, REF = 3, ISOLATED = 4, SLACK = 5,)\n@doc\"\nACBusTypes\n\nEnumeration of AC power system bus types (MATPOWER Table B‑1).\nEach variant corresponds to a standard bus classification used in power flow\nand steady‑state network models:\n\n- PQ (1): Load bus — active (P) and reactive (Q) power injections are specified;\n    the bus voltage magnitude and angle are solved by the power‑flow algorithm.\n- PV (2): Generator (PV) bus — active power (P) and voltage magnitude (V) are\n    specified; reactive power (Q) and voltage angle are solved.\n- REF (3): Reference bus — a named reference for the system voltage angle; often\n    equivalent to a slack bus in semantics but provided separately for clarity.\n- ISOLATED (4): Isolated bus — not connected to the main network (islanded or\n    disconnected); typically excluded from the global power‑flow solution.\n- SLACK (5): Slack bus — balances the system active and reactive power mismatch\n    and sets the reference voltage angle (commonly one per connected network).\n\nNotes\n- Numeric values follow the MATPOWER convention for bus type codes.\n- Use the enum members (e.g., `ACBusTypes.PQ`, `ACBusTypes.SLACK`) when\n    constructing or interpreting network data structures to ensure clarity and\n    compatibility with MATPOWER-based data conventions.\n\nReference: MATPOWER manual, Table B‑1 (http://www.pserc.cornell.edu/matpower/MATPOWER-manual.pdf).\n\" ACBusTypes\n\nIS.@scoped_enum(\n    LoadConformity,\n    NON_CONFORMING = 0,\n    CONFORMING = 1,\n    UNDEFINED = 2,\n)\n@doc\"\"\"\n    LoadConformity\n\nWECC-defined enumeration for load conformity classification used in dynamic modeling.\n\nLoad conformity indicates whether a load follows system voltage and frequency variations\naccording to WECC modeling standards:\n\n- `NON_CONFORMING = 0`: Load that does not respond predictably to voltage and frequency changes,\n  typically representing constant power loads or loads with complex control systems\n- `CONFORMING = 1`: Load that responds predictably to voltage and frequency variations,\n  following standard load modeling practices for dynamic studies\n- `UNDEFINED = 2`: Load conformity status is not specified or unknown\n\nThis classification is essential for WECC dynamic studies as it determines how loads are\nmodeled during system disturbances and stability analysis.\n\"\"\" LoadConformity\n\n# \"From PSSE POM v33 Manual\"\nIS.@scoped_enum(\n    FACTSOperationModes,\n    OOS = 0, # out-of-service (i.e., Series and Shunt links open)\n    NML = 1, # Normal mode of operation, where Series and Shunt links are operating.\n    BYP = 2, # Series link is bypassed (i.e., like a zero impedance line) and Shunt link operates as a STATCOM.\n)\n@doc\"\n    FACTSOperationModes\n\nEnumeration defining the operational modes for FACTS (Flexible AC Transmission System) devices.\nBased on PSSE POM v33 Manual specifications.\n\n# Values\n- `OOS = 0`: Out-of-service mode where both Series and Shunt links are open\n- `NML = 1`: Normal mode of operation where both Series and Shunt links are operating\n- `BYP = 2`: Bypass mode where Series link is bypassed (acts like zero impedance line)\n  and Shunt link operates as a STATCOM\n\" FACTSOperationModes\n\nIS.@scoped_enum(\n    DiscreteControlledBranchType,\n    SWITCH = 0,\n    BREAKER = 1,\n    OTHER = 2,\n)\n@doc\"\n    DiscreteControlledBranchType\n\nAn enumeration representing different types of discrete controlled branches in power systems.\n\n# Values\n- `SWITCH = 0`: Represents a switch device that can be opened or closed\n- `BREAKER = 1`: Represents a circuit breaker that can interrupt current flow\n- `OTHER = 2`: Represents other types of discrete controlled branch devices\n\" DiscreteControlledBranchType\n\nIS.@scoped_enum(\n    DiscreteControlledBranchStatus,\n    OPEN = 0,\n    CLOSED = 1,\n)\n@doc\"\nDiscreteControlledBranchStatus\n\nEnumeration describing the controlled (commanded) status of a branch device\n(such as a breaker or a switch) in a power system model.\n\nValues\n- OPEN = 0: The device is open (interrupting state) — the branch is non-conducting.\n- CLOSED = 1: The device is closed (conducting state) — the branch provides a normal conduction path.\n\nNotes\n- This enum represents the intended or commanded state used by control and protection\n    logic; it may differ from actual measured/telemetry state during faults or failures.\n- The integer encoding (0/1) is chosen for compact storage and interop with serialization\n    or external data formats.\n\" DiscreteControlledBranchStatus\n\nIS.@scoped_enum(\n    WindingCategory,\n    TR2W_WINDING = 0,       # Transformer2W only winding associated with a TICT\n    PRIMARY_WINDING = 1,    # Primary winding of Trasnformer3W associated with a TICT\n    SECONDARY_WINDING = 2,  # Secondary winding of Trasnformer3W associated with a TICT\n    TERTIARY_WINDING = 3,   # Tertiary winding of Trasnformer3W associated with a TICT\n)\n@doc\"\n    WindingCategory\n\nAn enumeration representing different types of transformer windings used in power system analysis.\nReflects how to interpret the Transformer Impedance Correction Table (TICT) winding association as described in [`ImpedanceCorrectionData`](@ref).\n\n# Values\n- `TR2W_WINDING = 0`: Winding associated with a two-winding transformer (Transformer2W) connected to a tap-changing transformer's [`ImpedanceCorrectionData`](@ref)\n- `PRIMARY_WINDING = 1`: Primary winding of a three-winding transformer (Transformer3W) associated with a [`ImpedanceCorrectionData`](@ref)\n- `SECONDARY_WINDING = 2`: Secondary winding of a three-winding transformer (Transformer3W) associated with a [`ImpedanceCorrectionData`](@ref)\n- `TERTIARY_WINDING = 3`: Tertiary winding of a three-winding transformer (Transformer3W) associated with a [`ImpedanceCorrectionData`](@ref)\n\nThis enumeration is used to categorize transformer windings based on their role and configuration\nin the power system model, particularly in relation to tap-changing transformers.\n\" WindingCategory\n\nIS.@scoped_enum(\n    WindingGroupNumber,\n    UNDEFINED = -99,\n    GROUP_0 = 0, # 0 Degrees\n    GROUP_1 = 1, # -30 Degrees\n    GROUP_5 = 5, # -150 Degrees\n    GROUP_6 = 6, # 180 Degrees\n    GROUP_7 = 7, # 150 Degrees\n    GROUP_11 = 11, # 30 Degrees\n)\n@doc\"\n    WindingGroupNumber\n\nEnumeration defining transformer winding group numbers based on IEC 60076-1 standard.\nThese numbers represent the phase displacement between primary and secondary windings\nof three-phase transformers.\n\n# Valid Values\n- `UNDEFINED = -99`: Undefined or unspecified winding group\n- `GROUP_0 = 0`: 0° phase displacement (Yy0, Dd0, Dz0)\n- `GROUP_1 = 1`: -30° phase displacement (Yy1, Dd1, Dz1)\n- `GROUP_5 = 5`: -150° phase displacement (Yy5, Dd5, Dz5)\n- `GROUP_6 = 6`: 180° phase displacement (Yy6, Dd6, Dz6)\n- `GROUP_7 = 7`: 150° phase displacement (Yy7, Dd7, Dz7)\n- `GROUP_11 = 11`: 30° phase displacement (Yy11, Dd11, Dz11)\n\n# Notes\nThe phase displacement is measured from the primary to secondary winding, with\npositive angles representing a lead and negative angles representing a lag.\nClock notation follows the convention where each hour represents 30°.\n\" WindingGroupNumber\n\nIS.@scoped_enum(\n    ImpedanceCorrectionTransformerControlMode,\n    PHASE_SHIFT_ANGLE = 1,\n    TAP_RATIO = 2,\n)\n@doc\"\"\"\n    ImpedanceCorrectionTransformerControlMode\n\nEnumeration defining the control modes for impedance correction in transformers,\nbased on PSS/E transformer control definitions.\n\n# Values\n- `PHASE_SHIFT_ANGLE = 1`: Control mode for phase-shifting transformers where the\n  impedance correction is applied based on the phase shift angle. Used when the\n  transformer primarily controls power flow through phase angle adjustment.\n- `TAP_RATIO = 2`: Control mode for tap-changing transformers where the impedance\n  correction is applied based on the tap ratio. Used when the transformer primarily\n  controls voltage magnitude through tap position changes.\n\n# Notes\nThis enumeration corresponds to PSS/E transformer control field definitions for\ndetermining how impedance corrections are calculated and applied in power flow\nand dynamic simulation studies.\n\"\"\" ImpedanceCorrectionTransformerControlMode\n\nIS.@scoped_enum(\n    TransformerControlObjective, # COD1 or COD2 in PSS\\e\n    UNDEFINED = -99,\n    VOLTAGE_DISABLED = -1,\n    REACTIVE_POWER_FLOW_DISABLED = -2,\n    ACTIVE_POWER_FLOW_DISABLED = -3,\n    CONTROL_OF_DC_LINE_DISABLED = -4,\n    ASYMMETRIC_ACTIVE_POWER_FLOW_DISABLED = -5,\n    FIXED = 0,\n    VOLTAGE = 1,\n    REACTIVE_POWER_FLOW = 2,\n    ACTIVE_POWER_FLOW = 3,\n    CONTROL_OF_DC_LINE = 4,\n    ASYMMETRIC_ACTIVE_POWER_FLOW = 5,\n)\n@doc\"\n    TransformerControlObjective\n\nEnumeration of transformer control objectives based on PSS/E COD1 and COD2 fields.\n\nThis enumeration defines the control modes for transformer tap changers and phase shifters\nas specified in the PSS/E-35 manual.\n\n# Values\n- `UNDEFINED = -99`: Undefined control objective\n- `VOLTAGE_DISABLED = -1`: Voltage control disabled\n- `REACTIVE_POWER_FLOW_DISABLED = -2`: Reactive power flow control disabled\n- `ACTIVE_POWER_FLOW_DISABLED = -3`: Active power flow control disabled\n- `CONTROL_OF_DC_LINE_DISABLED = -4`: DC line control disabled\n- `ASYMMETRIC_ACTIVE_POWER_FLOW_DISABLED = -5`: Asymmetric active power flow control disabled\n- `FIXED = 0`: Fixed tap position (no automatic control)\n- `VOLTAGE = 1`: Voltage magnitude control at controlled bus\n- `REACTIVE_POWER_FLOW = 2`: Reactive power flow control through the transformer\n- `ACTIVE_POWER_FLOW = 3`: Active power flow control through the transformer\n- `CONTROL_OF_DC_LINE = 4`: Control of DC transmission line\n- `ASYMMETRIC_ACTIVE_POWER_FLOW = 5`: Asymmetric active power flow control\n\n# Notes\nNegative values indicate disabled control modes, while positive values represent active\ncontrol objectives. The `FIXED` mode (0) indicates manual tap position control without\nautomatic adjustment.\n\" TransformerControlObjective\n\nIS.@scoped_enum(\n    MotorLoadTechnology,\n    INDUCTION = 1,\n    SYNCHRONOUS = 2,\n    UNDETERMINED = 3,\n)\n@doc\"\n    MotorLoadTechnology\n\nAn enumeration representing different motor load technologies used in industrial applications.\n\n# Values\n- `INDUCTION`: Induction motor technology, commonly used for general-purpose applications\n- `SYNCHRONOUS`: Synchronous motor technology, used for applications requiring constant speed\n- `UNDETERMINED`: Motor technology type is not specified or unknown\n\" MotorLoadTechnology\n\nIS.@scoped_enum(\n    PrimeMovers,\n    BA = 1,  # Energy Storage, Battery\n    BT = 2,  # Turbines Used in a Binary Cycle (including those used for geothermal applications)\n    CA = 3,  # Combined-Cycle – Steam Part\n    CC = 4,  # Combined-Cycle - Aggregated Plant *augmentation of EIA\n    CE = 5,  # Energy Storage, Compressed Air\n    CP = 6,  # Energy Storage, Concentrated Solar Power\n    CS = 7,  # Combined-Cycle Single-Shaft Combustion turbine and steam turbine share a single generator\n    CT = 8,  # Combined-Cycle Combustion Turbine Part\n    ES = 9,  # Energy Storage, Other (Specify on Schedule 9, Comments)\n    FC = 10,  # Fuel Cell\n    FW = 11,  # Energy Storage, Flywheel\n    GT = 12,  # Combustion (Gas) Turbine (including jet engine design)\n    HA = 13,  # Hydrokinetic, Axial Flow Turbine\n    HB = 14,  # Hydrokinetic, Wave Buoy\n    HK = 15,  # Hydrokinetic, Other\n    HY = 16,  # Hydraulic Turbine (including turbines associated with delivery of water by pipeline)\n    IC = 17,  # Internal Combustion (diesel, piston, reciprocating) Engine\n    PS = 18,  # Energy Storage, Reversible Hydraulic Turbine (Pumped Storage)\n    OT = 19,  # Other – Specify on SCHEDULE 9.\n    ST = 20,  # Steam Turbine (including nuclear, geothermal and solar steam; does not include combined-cycle turbine)\n    PVe = 21,  # Photovoltaic *renaming from EIA PV to PVe to avoid conflict with BusType.PV\n    WT = 22,  # Wind Turbine, Onshore\n    WS = 23,  # Wind Turbine, Offshore\n)\n@doc\"\n    PrimeMovers\n\nEnumeration of prime mover types used in electric power generation, as defined by the\nU.S. Energy Information Administration (EIA) Form 923 instructions.\n\nPrime movers are the engines, turbines, water wheels, or similar machines that drive\nelectric generators or provide mechanical energy for other purposes. This enumeration\nprovides standardized codes for different types of prime movers used in power plants.\n\nPVe is used for photovoltaic systems renaming from EIA PV to avoid conflict with BusType.PV\n\n# References\n- [EIA Form 923 Instructions](https://www.eia.gov/survey/form/eia_923/instructions.pdf)\n\n# See Also\n- [`ThermalStandard`](@ref): Uses prime mover information for generator specifications\n- [`ThermalMultiStart`](@ref): Uses prime mover information for generator specifications\n\" PrimeMovers\n\nIS.@scoped_enum(\n    ThermalFuels,\n    COAL = 1,  # General Coal Category.\n    ANTHRACITE_COAL = 2,# ANT\n    BITUMINOUS_COAL = 3, # BIT\n    LIGNITE_COAL = 4, # LIG\n    SUBBITUMINOUS_COAL = 5, # SUB\n    WASTE_COAL = 6, # WC # includes anthracite culm, bituminous gob, fine coal, lignite waste, waste coal\n    REFINED_COAL = 7,  # RC # ncludes any coal which meets the IRS definition of refined coal [Notice 2010-54 or any superseding IRS notices]. Does not include coal processed by coal preparation plants.)\n    SYNTHESIS_GAS_COAL = 8, # SGC\n    DISTILLATE_FUEL_OIL = 9,  # DFO # includes Diesel, No. 1, No. 2, and No. 4\n    JET_FUEL = 10, # JF\n    KEROSENE = 11, # KER\n    PETROLEUM_COKE = 12,  # PC\n    RESIDUAL_FUEL_OIL = 13,  # RFO # includes No. 5, No. 6 Fuel Oils, and Bunker Oil\n    PROPANE = 14, # PG # Propane, gaseous\n    SYNTHESIS_GAS_PETROLEUM_COKE = 15,  # SGP\n    WASTE_OIL = 16,  # WO # including crude oil, liquid butane, liquid propane, naphtha, oil waste, re-refined motor oil, sludge oil, tar oil, or other petroleum-based liquid wastes\n    BLASTE_FURNACE_GAS = 17,  # BFG\n    NATURAL_GAS = 18,  # NG    # Natural Gas\n    OTHER_GAS = 19,  # OOG    # Other Gas and blast furnace gas\n    NUCLEAR = 20,  # NUC # Nuclear Fission (Uranium, Plutonium, Thorium)\n    AG_BYPRODUCT = 21,  # AB    # Agricultural Crop Byproducts/Straw/Energy Crops\n    MUNICIPAL_WASTE = 22,  # MSW    # Municipal Solid Waste – Biogenic component\n    OTHER_BIOMASS_SOLIDS = 23,  # OBS\n    WOOD_WASTE_SOLIDS = 24,  # WDS # including paper 18 pellets, railroad ties, utility poles, wood chips, bark, and wood waste solid\n    OTHER_BIOMASS_LIQUIDS = 26,  # OBL\n    SLUDGE_WASTE = 27, # SLW\n    BLACK_LIQUOR = 28, # BLQ\n    WOOD_WASTE_LIQUIDS = 29, # WDL # includes red liquor, sludge wood, spent sulfite liquor, and other wood-based liquid. Excluding black liquour\n    LANDFILL_GAS = 30, # LFG\n    OTHEHR_BIOMASS_GAS = 31, # OBG # includes digester gas, methane, and other biomass gasses\n    GEOTHERMAL = 32,  # GEO\n    WASTE_HEAT = 33, # WH # WH should only be reported where the fuel source for the waste heat is undetermined, and for combined-cycle steam turbines that do not have supplemental firing.\n    TIREDERIVED_FUEL = 34, # TDF\n    OTHER = 35,  # OTH\n)\n\n@doc\"\n    ThermalFuels\n\nEnumeration of thermal fuel types based on AER (Aggregated Energy Reporting) fuel codes\nas defined by the U.S. Energy Information Administration (EIA) Form 923.\n\nThe fuel codes represent standardized categories for reporting fuel consumption in\nelectric power generation, covering major thermal fuel types including:\n\n- Coal and coal-derived fuels\n- Natural gas and petroleum products\n- Nuclear fuel\n- Biomass and waste fuels\n- Other thermal energy sources\n\nReference: EIA Form 923 Instructions (https://www.eia.gov/survey/form/eia_923/instructions.pdf)\nGeneral Coal and Geothermal codes not directly from the current EIA 923 form but kept for compatibility with older versions of the form.\nSee also: [`ThermalStandard`](@ref)\n\" ThermalFuels\n\nIS.@scoped_enum(\n    StorageTech,\n    PTES = 1, # Pumped thermal energy storage\n    LIB = 2, # LiON Battery\n    LAB = 3, # Lead Acid Battery\n    FLWB = 4, # Redox Flow Battery\n    SIB = 5, # Sodium Ion Battery\n    ZIB = 6, # Zinc Ion Battery,\n    HGS = 7, # Hydrogen Gas Storage,\n    LAES = 8, # Liquid Air Storage\n    OTHER_CHEM = 9, # Chemmical Storage\n    OTHER_MECH = 10, # Mechanical Storage\n    OTHER_THERM = 11, # Thermal Storage\n)\n@doc\"\n    StorageTech\n\nEnumeration of energy storage technologies used in power systems.\n\n# Values\n- `PTES`: Pumped thermal energy storage\n- `LIB`: Lithium-ion Battery\n- `LAB`: Lead Acid Battery\n- `FLWB`: Redox Flow Battery\n- `SIB`: Sodium Ion Battery\n- `ZIB`: Zinc Ion Battery\n- `HGS`: Hydrogen Gas Storage\n- `LAES`: Liquid Air Energy Storage\n- `OTHER_CHEM`: Chemical Storage (other than specified)\n- `OTHER_MECH`: Mechanical Storage (other than specified)\n- `OTHER_THERM`: Thermal Storage (other than specified)\n\nThis enumeration is used to classify different types of energy storage systems\nbased on their underlying technology and storage mechanism.\n\" StorageTech\n\nIS.@scoped_enum(\n    PumpHydroStatus,\n    OFF = 0,\n    GEN = 1,\n    PUMP = -1,\n)\n@doc\"\nPumpHydroStatus\n\nOperating status of a pumped‑storage hydro unit.\n\nValues\n- OFF = 0: Unit is idle — neither generating nor pumping.\n- GEN = 1: Generating mode (turbine operation), producing active power.\n- PUMP = -1: Pumping mode, consuming active power to store energy.\n\nNotes\n- The sign of the value reflects the net direction of active power (positive = generation, negative = pumping).\n- Intended for use in scheduling, dispatch, and state-tracking of pumped‑storage units.\n\" PumpHydroStatus\n\nIS.@scoped_enum(StateTypes, Differential = 1, Algebraic = 2, Hybrid = 3,)\n\n@doc \"\"\"\nCategorization of dynamic state variables.\n\n# Values\n- `Differential`: State governed by a differential equation\n- `Algebraic`: State governed by an algebraic constraint\n- `Hybrid`: State with both differential and algebraic aspects\n\"\"\" StateTypes\n\nIS.@scoped_enum(\n    ReservoirDataType,\n    USABLE_VOLUME = 1,\n    TOTAL_VOLUME = 2,\n    HEAD = 3,\n    ENERGY = 4,\n)\n@doc\"\nReservoirDataType\n\nEnumeration of reservoir accounting unit classes.\n\nThis enum identifies the type of data recorded or tracked for a reservoir. Use these values when specifying\nthe kind of measurement or accounting quantity associated with a reservoir (for example in time series,\nstorage models, reporting, or data exchange).\n\nValues\n- USABLE_VOLUME: Volume available for operations and dispatch (active storage). Typically reported in cubic meters (m³) or other volumetric units.\n- TOTAL_VOLUME: Total reservoir volume including dead and active storage. Reported in the same volumetric units as USABLE_VOLUME.\n- HEAD: Hydraulic head or water surface elevation relative to a datum, typically reported in meters (m).\n- ENERGY: Stored or deliverable energy associated with the reservoir (e.g., potential energy or expected generation), often expressed in MWh, GWh, or joules.\n\" ReservoirDataType\n\nIS.@scoped_enum(\n    HydroTurbineType,\n    UNKNOWN = 0,          # Default / unspecified\n    PELTON = 1,           # Impulse turbine for high head\n    FRANCIS = 2,          # Reaction turbine for medium head\n    KAPLAN = 3,           # Propeller-type turbine for low head\n    TURGO = 4,            # Impulse turbine similar to Pelton\n    CROSSFLOW = 5,        # Banki-Michell (crossflow) turbine\n    BULB = 6,             # Kaplan variation for very low head\n    DERIAZ = 7,           # Diagonal flow turbine\n    PROPELLER = 8,        # Simple propeller turbine\n    OTHER = 9             # Catch-all for less common designs\n)\n@doc\"\n    HydroTurbineType\n\nEnumeration of hydro turbine types supported in `PowerSystems.jl`.\n\nThis type is used to categorize hydroelectric generators by their\nturbine design and operating head. It provides a standardized set\nof turbine types to ensure consistent modeling and data handling\nacross different systems.\n\n# Values\n- `UNKNOWN`   : Default value when the turbine type is not specified.\n- `PELTON`    : Impulse turbine, typically used for high-head, low-flow sites.\n- `FRANCIS`   : Reaction turbine, widely used for medium-head applications.\n- `KAPLAN`    : Adjustable-blade propeller turbine for low-head, high-flow sites.\n- `TURGO`     : Impulse turbine similar to Pelton but suitable for higher flow rates.\n- `CROSSFLOW` : Banki-Michell (crossflow) impulse turbine, robust for small hydro.\n- `BULB`      : Compact Kaplan variant, typically installed in low-head run-of-river plants.\n- `DERIAZ`    : Diagonal flow reaction turbine with variable pitch blades.\n- `PROPELLER` : Fixed-blade propeller turbine, simpler than Kaplan but less efficient at part load.\n- `OTHER`     : Placeholder for less common or custom turbine designs.\n\" HydroTurbineType\n\nIS.@scoped_enum(\n    ReservoirLocation,\n    HEAD = 1,\n    TAIL = 2,\n)\n@doc\"\nReservoirLocation\n\nEnumeration representing the location of a hydro reservoir relative to its associated turbine.\n\n# Values\n- `HEAD`: The reservoir is located upstream of the turbine, typically at a higher elevation.\n- `TAIL`: The reservoir is located downstream of the turbine at a lower or same elevation.\n\n\" ReservoirLocation\n\nIS.@scoped_enum(\n    CombinedCycleConfiguration,\n    SingleShaftCombustionSteam = 1,\n    SeparateShaftCombustionSteam = 2,\n    DoubleCombustionOneSteam = 3,\n    TripleCombustionOneSteam = 4,\n    Other = 5,\n)\n\n@doc \"\"\"\nConfiguration types for combined cycle power plants.\n\n# Values\n- `SingleShaftCombustionSteam`: Single-shaft arrangement with one combustion and one steam turbine\n- `SeparateShaftCombustionSteam`: Separate shafts for combustion and steam turbines\n- `DoubleCombustionOneSteam`: Two combustion turbines feeding one steam turbine\n- `TripleCombustionOneSteam`: Three combustion turbines feeding one steam turbine\n- `Other`: Other combined cycle configuration\n\"\"\" CombinedCycleConfiguration\n\nconst PS_MAX_LOG = parse(Int, get(ENV, \"PS_MAX_LOG\", \"50\"))\nconst DEFAULT_BASE_MVA = 100.0\n\nconst POWER_SYSTEM_STRUCT_DESCRIPTOR_FILE =\n    joinpath(dirname(pathof(PowerSystems)), \"descriptors\", \"power_system_structs.json\")\n\nconst DEFAULT_SYSTEM_FREQUENCY = 60.0\n\nconst INFINITE_TIME = 1e4\nconst START_COST = 1e8\nconst INFINITE_COST = 1e8\nconst INFINITE_BOUND = 1e6\nconst BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL = 0.01\n\nconst PSSE_PARSER_TAP_RATIO_UBOUND = 1.5\nconst PSSE_PARSER_TAP_RATIO_LBOUND = 0.5\nconst PARSER_TAP_RATIO_CORRECTION_TOL = 1e-5\n\nconst ZERO_IMPEDANCE_REACTANCE_THRESHOLD = 1e-4\n\nconst WINDING_NAMES = Dict(\n    WindingCategory.PRIMARY_WINDING => \"primary\",\n    WindingCategory.SECONDARY_WINDING => \"secondary\",\n    WindingCategory.TERTIARY_WINDING => \"tertiary\",\n)\n\nconst TRANSFORMER3W_PARAMETER_NAMES = [\n    \"COD\", \"CONT\", \"NOMV\", \"WINDV\", \"RMA\", \"RMI\",\n    \"NTP\", \"VMA\", \"VMI\", \"RATA\", \"RATB\", \"RATC\",\n]\n"
  },
  {
    "path": "src/deprecated.jl",
    "content": "# BEGIN 4.0.0  deprecations\nexport TwoTerminalHVDCLine\n\n\"\"\"\nDeprecated method for the old TwoTerminalHVDCLine that returns the new TwoTerminalGenericHVDCLine.\nThis constructor is used for some backward compatibility and will be removed in a future version.\n\"\"\"\nfunction TwoTerminalHVDCLine(\n    name,\n    available,\n    active_power_flow,\n    arc,\n    active_power_limits_from,\n    active_power_limits_to,\n    reactive_power_limits_from,\n    reactive_power_limits_to,\n    loss::NamedTuple{(:l0, :l1), Tuple{Float64, Float64}},\n    services,\n    ext,\n    internal,\n)\n    new_loss = LinearCurve(loss.l0, loss.l1)\n    @warn(\n        \"The TwoTerminalHVDCLine constructor is deprecated. Use TwoTerminalGenericHVDCLine instead. \\\n         This constructor will be removed in a future version.\",)\n    TwoTerminalGenericHVDCLine(\n        name,\n        available,\n        active_power_flow,\n        arc,\n        active_power_limits_from,\n        active_power_limits_to,\n        reactive_power_limits_from,\n        reactive_power_limits_to,\n        new_loss,\n        services,\n        ext,\n        internal,\n    )\nend\n\n\"\"\"\nDeprecated method for the old TwoTerminalHVDCLine that returns the new [`TwoTerminalGenericHVDCLine`](@ref).\nThis constructor is used for some backward compatibility and will be removed in a future version.\n\"\"\"\nfunction TwoTerminalHVDCLine(\n    name,\n    available,\n    active_power_flow,\n    arc,\n    active_power_limits_from,\n    active_power_limits_to,\n    reactive_power_limits_from,\n    reactive_power_limits_to,\n    loss::NamedTuple{(:l0, :l1), Tuple{Float64, Float64}},\n    services = Device[],\n    ext = Dict{String, Any}(),\n)\n    @warn(\n        \"The TwoTerminalHVDCLine constructor is deprecated. Use TwoTerminalGenericHVDCLine instead. \\\n         This constructor will be removed in a future version.\",)\n    new_loss = LinearCurve(loss.l0, loss.l1)\n    TwoTerminalGenericHVDCLine(\n        name,\n        available,\n        active_power_flow,\n        arc,\n        active_power_limits_from,\n        active_power_limits_to,\n        reactive_power_limits_from,\n        reactive_power_limits_to,\n        new_loss,\n        services,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\n\"\"\"\nDeprecated method for the old TwoTerminalHVDCLine that returns the new [`TwoTerminalGenericHVDCLine`](@ref).\nThis constructor is used for some backward compatibility and will be removed in a future version.\n\"\"\"\nfunction TwoTerminalHVDCLine(\n    name,\n    available,\n    active_power_flow,\n    arc,\n    active_power_limits_from,\n    active_power_limits_to,\n    reactive_power_limits_from,\n    reactive_power_limits_to,\n    loss::Union{LinearCurve, PiecewiseIncrementalCurve},\n    services = Device[],\n    ext = Dict{String, Any}(),\n)\n    @warn(\n        \"The TwoTerminalHVDCLine constructor is deprecated. Use TwoTerminalGenericHVDCLine instead. \\\n         This constructor will be removed in a future version.\",)\n    return TwoTerminalGenericHVDCLine(\n        name,\n        available,\n        active_power_flow,\n        arc,\n        active_power_limits_from,\n        active_power_limits_to,\n        reactive_power_limits_from,\n        reactive_power_limits_to,\n        loss,\n        services,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\n\"\"\"\nDeprecated method for the old TwoTerminalHVDCLine that returns the new [`TwoTerminalGenericHVDCLine`](@ref).\nThis constructor is used for some backward compatibility and will be removed in a future version.\n\"\"\"\nfunction TwoTerminalHVDCLine(\n    name,\n    available,\n    active_power_flow,\n    arc,\n    active_power_limits_from,\n    active_power_limits_to,\n    reactive_power_limits_from,\n    reactive_power_limits_to,\n    loss = LinearCurve(0.0),\n    services = Device[],\n    ext = Dict{String, Any}(),\n)\n    @warn(\n        \"The TwoTerminalHVDCLine constructor is deprecated. Use TwoTerminalGenericHVDCLine instead. \\\n         This constructor will be removed in a future version.\",)\n    TwoTerminalGenericHVDCLine(\n        name,\n        available,\n        active_power_flow,\n        arc,\n        active_power_limits_from,\n        active_power_limits_to,\n        reactive_power_limits_from,\n        reactive_power_limits_to,\n        loss,\n        services,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\n\"\"\"\nDeprecated method for the old TwoTerminalHVDCLine that returns the new [`TwoTerminalGenericHVDCLine`](@ref).\nThis constructor is used for some backward compatibility and will be removed in a future version.\n\"\"\"\nfunction TwoTerminalHVDCLine(;\n    name,\n    available,\n    active_power_flow,\n    arc,\n    active_power_limits_from,\n    active_power_limits_to,\n    reactive_power_limits_from,\n    reactive_power_limits_to,\n    loss = LinearCurve(0.0),\n    services = Device[],\n    ext = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    @warn(\n        \"The TwoTerminalHVDCLine constructor is deprecated. Use TwoTerminalGenericHVDCLine instead. \\\n         This constructor will be removed in a future version.\",)\n    TwoTerminalGenericHVDCLine(\n        name,\n        available,\n        active_power_flow,\n        arc,\n        active_power_limits_from,\n        active_power_limits_to,\n        reactive_power_limits_from,\n        reactive_power_limits_to,\n        loss,\n        services,\n        ext,\n        internal,\n    )\nend\n"
  },
  {
    "path": "src/descriptors/power_system_inputs.json",
    "content": "{\n    \"dc_branch\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Unique ID\"\n        },\n        {\n            \"name\": \"connection_points_from\",\n            \"description\": \"From Bus ID\"\n        },\n        {\n            \"name\": \"connection_points_to\",\n            \"description\": \"To Bus ID\"\n        },\n        {\n            \"name\": \"active_power_flow\",\n            \"description\": \"Active power flow\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"mw_load\",\n            \"description\": \"Power demand (MW)\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"rate\",\n            \"unit\": \"MVA\",\n            \"description\": \"Apparent power limit rating\",\n            \"unit_system\": \"SYSTEM_BASE\",\n            \"default_value\": \"system_base_power\"\n        },\n        {\n            \"name\": \"rectifier_firing_angle_max\",\n            \"unit\": \"degree\",\n            \"value_range\": [],\n            \"description\": \"Nominal maximum firing angle\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"rectifier_firing_angle_min\",\n            \"unit\": \"degree\",\n            \"value_range\": [],\n            \"description\": \"Minimum steady state firing angle\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"rectifier_xrc\",\n            \"description\": \"Commutating transformer reactance/bridge\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"rectifier_tap_limits_max\",\n            \"value_range\": [],\n            \"description\": \"Max tap setting\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"rectifier_tap_limits_min\",\n            \"value_range\": [],\n            \"description\": \"Min tap setting\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"inverter_firing_angle_max\",\n            \"unit\": \"degree\",\n            \"value_range\": [],\n            \"description\": \"Nominal maximum firing angle\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"inverter_firing_angle_min\",\n            \"unit\": \"degree\",\n            \"value_range\": [],\n            \"description\": \"Minimum steady state firing angle\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"inverter_xrc\",\n            \"description\": \"Commutating transformer reactance/bridge\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"inverter_tap_limits_max\",\n            \"value_range\": [],\n            \"description\": \"Max tap setting\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"inverter_tap_limits_min\",\n            \"value_range\": [],\n            \"description\": \"Min tap setting\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"loss\",\n            \"unit\": \"%\",\n            \"description\": \"Power Losses on the Line\",\n            \"default_value\": 0.0\n        },\n        {\n            \"name\": \"min_active_power_limit_from\",\n            \"value_range\": [],\n            \"description\": \"Minimum Active Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"max_active_power_limit_from\",\n            \"value_range\": [],\n            \"description\": \"Maximum Active Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"min_active_power_limit_to\",\n            \"value_range\": [],\n            \"description\": \"Minimum Active Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"max_active_power_limit_to\",\n            \"value_range\": [],\n            \"description\": \"Maximum Active Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"min_reactive_power_limit_from\",\n            \"value_range\": [],\n            \"description\": \"Minimum reActive Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"max_reactive_power_limit_from\",\n            \"value_range\": [],\n            \"description\": \"Maximum reActive Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"min_reactive_power_limit_to\",\n            \"value_range\": [],\n            \"description\": \"Minimum reActive Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"max_reactive_power_limit_to\",\n            \"value_range\": [],\n            \"description\": \"Maximum reActive Power Limit\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0,\n            \"base_reference\": \"rate\"\n        },\n        {\n            \"name\": \"control_mode\",\n            \"description\": \"Control Mode\",\n            \"default_value\": \"Power\"\n        },\n        {\n            \"name\": \"dc_line_category\",\n            \"value_options\": [\n                \"TwoTerminalLCCLine\",\n                \"TwoTerminalGenericHVDCLine\"\n            ],\n            \"description\": \"Type of Struct\",\n            \"default_value\": \"TwoTerminalGenericHVDCLine\"\n        }\n    ],\n    \"branch\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Unique branch ID\"\n        },\n        {\n            \"name\": \"connection_points_from\",\n            \"description\": \"From Bus ID\"\n        },\n        {\n            \"name\": \"connection_points_to\",\n            \"description\": \"To Bus ID\"\n        },\n        {\n            \"name\": \"r\",\n            \"description\": \"Branch resistance p.u.\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"name\": \"x\",\n            \"description\": \"Branch reactance p.u.\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"name\": \"primary_shunt\",\n            \"description\": \"Branch line charging susceptance p.u.\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"rate\",\n            \"description\": \"Continuous MW flow limit\",\n            \"unit_system\": \"SYSTEM_BASE\"\n        },\n        {\n            \"unit\": \"radian\",\n            \"name\": \"min_angle_limits\",\n            \"description\": \"Minimum Angle Limits\",\n            \"default_value\": -3.1416\n        },\n        {\n            \"unit\": \"radian\",\n            \"name\": \"max_angle_limits\",\n            \"description\": \"Maximum endpoint angle limits\",\n            \"default_value\": 3.1416\n        },\n        {\n            \"name\": \"active_power_flow\",\n            \"unit\": \"MW\",\n            \"description\": \"Active power flow\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"rate\",\n            \"default_value\": 0.0\n        },\n        {\n            \"name\": \"reactive_power_flow\",\n            \"unit\": \"MVAr\",\n            \"description\": \"Reactive power flow\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"rate\",\n            \"default_value\": 0.0\n        },\n        {\n            \"name\": \"tap\",\n            \"unit\": \"%\",\n            \"description\": \"Transformer winding ratio\",\n            \"default_value\": 1.0\n        }\n        ,\n        {\n            \"name\": \"is_transformer\",\n            \"unit\": \"bool\",\n            \"description\": \"Transformer flag\",\n            \"default_value\": null\n        }\n    ],\n    \"generator\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Unique generator ID: Concatenated from Bus ID_Unit Type_Gen ID\"\n        },\n        {\n            \"name\": \"available\",\n            \"description\": \"Availability\",\n            \"default_value\": true\n        },\n        {\n            \"name\": \"bus_id\",\n            \"description\": \"Connection Bus ID\"\n        },\n        {\n            \"name\": \"fuel\",\n            \"description\": \"Unit Fuel\"\n        },\n        {\n            \"name\": \"fuel_price\",\n            \"unit\": \"$/MMBTU\",\n            \"description\": \"Fuel Price\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"active_power\",\n            \"description\": \"Real power injection setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"reactive_power\",\n            \"description\": \"Reactive power StaticInjection setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"active_power_limits_max\",\n            \"description\": \"Maximum real power StaticInjection (Unit Capacity)\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"active_power_limits_min\",\n            \"description\": \"Minimum real power StaticInjection (Unit minimum stable level)\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\"\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"reactive_power_limits_max\",\n            \"description\": \"Maximum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"reactive_power_limits_min\",\n            \"description\": \"Minimum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"hours\",\n            \"name\": \"min_down_time\",\n            \"description\": \"Minimum off time required before unit restart\"\n        },\n        {\n            \"unit\": \"hours\",\n            \"name\": \"min_up_time\",\n            \"description\": \"Minimum on time required before unit shutdown\"\n        },\n        {\n            \"unit\": \"MW(p.u.)/Min\",\n            \"name\": \"ramp_limits\",\n            \"description\": \"Maximum ramp up and ramp down rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW/Min\",\n            \"name\": \"ramp_up\",\n            \"description\": \"Maximum ramp up rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW/Min\",\n            \"name\": \"ramp_down\",\n            \"description\": \"Maximum ramp down rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MMBTU\",\n            \"name\": \"startup_heat_cold_cost\",\n            \"description\": \"Heat required to startup from cold\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_a0\",\n            \"description\": \"Heat rate constant term\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_a1\",\n            \"description\": \"Heat rate proportional term\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_a2\",\n            \"description\": \"Heat rate quadratic term\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_avg_0\",\n            \"description\": \"Heat rate Average 0 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_1\",\n            \"description\": \"Heat rate Incremental 1 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_2\",\n            \"description\": \"Heat rate Incremental 2 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_3\",\n            \"description\": \"Heat rate Incremental 3 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_4\",\n            \"description\": \"Heat rate Incremental 4 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_5\",\n            \"description\": \"Heat rate Incremental 5 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_6\",\n            \"description\": \"Heat rate Incremental 6 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_7\",\n            \"description\": \"Heat rate Incremental 7 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_8\",\n            \"description\": \"Heat rate Incremental 8 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_9\",\n            \"description\": \"Heat rate Incremental 9 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_10\",\n            \"description\": \"Heat rate Incremental 10 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_11\",\n            \"description\": \"Heat rate Incremental 11 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"heat_rate_incr_12\",\n            \"description\": \"Heat rate Incremental 12 TODO\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_0\",\n            \"description\": \"Operating cost at output_point_0\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_1\",\n            \"description\": \"Operating cost at output_point_1\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_2\",\n            \"description\": \"Operating cost at output_point_2\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_3\",\n            \"description\": \"Operating cost at output_point_3\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_4\",\n            \"description\": \"Operating cost at output_point_4\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_5\",\n            \"description\": \"Operating cost at output_point_5\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_6\",\n            \"description\": \"Operating cost at output_point_6\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_7\",\n            \"description\": \"Operating cost at output_point_7\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_8\",\n            \"description\": \"Operating cost at output_point_8\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_9\",\n            \"description\": \"Operating cost at output_point_9\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_10\",\n            \"description\": \"Operating cost at output_point_10\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_11\",\n            \"description\": \"Operating cost at output_point_11\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/hr\",\n            \"name\": \"cost_point_12\",\n            \"description\": \"Operating cost at output_point_12\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_0\",\n            \"description\": \"Output point 0 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_1\",\n            \"description\": \"Output point 1 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_2\",\n            \"description\": \"Output point 2 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_3\",\n            \"description\": \"Output point 3 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_4\",\n            \"description\": \"Output point 4 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_5\",\n            \"description\": \"Output point 5 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_6\",\n            \"description\": \"Output point 6 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_7\",\n            \"description\": \"Output point 7 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_8\",\n            \"description\": \"Output point 8 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_9\",\n            \"description\": \"Output point 9 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_10\",\n            \"description\": \"Output point 10 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_11\",\n            \"description\": \"Output point 11 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_point_12\",\n            \"description\": \"Output point 12 on heat rate curve as a percentage of PMax\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MVA\",\n            \"name\": \"base_mva\",\n            \"description\": \"Unit equivalent circuit base_mva\",\n            \"unit_system\": \"natural_units\"\n        },\n        {\n            \"unit\": \"$/MW\",\n            \"name\": \"variable_cost\",\n            \"description\": \"Variable Cost of Generation\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/MW\",\n            \"name\": \"fixed_cost\",\n            \"description\": \"Fixed Cost of Generation\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"$/start\",\n            \"name\": \"startup_cost\",\n            \"description\": \"Cost associated with Start-up\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/start\",\n            \"name\": \"shutdown_cost\",\n            \"description\": \"Cost associated with Shutdown\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"$/MW\",\n            \"name\": \"curtailment_cost\",\n            \"description\": \"Cost of curtailing production\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"power_factor\",\n            \"description\": \"Power Factor\",\n            \"default_value\": 1.0\n        },\n        {\n            \"name\": \"unit_type\",\n            \"description\": \"Unit Prime Mover Type\"\n        },\n        {\n            \"name\": \"category\",\n            \"description\": \"Category\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"cold_start_time\",\n            \"description\": \"Time before which a Cold start is eligible\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"warm_start_time\",\n            \"description\": \"Time before which a Warm start is eligible\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"hot_start_time\",\n            \"description\": \"Time before which a Hot Start is eligible\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"startup_ramp\",\n            \"description\": \"Startup ramp capability\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"shutdown_ramp\",\n            \"description\": \"Shutdown ramp capability\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"status_at_start\",\n            \"description\": \"State of the generator at the start of the simulation\",\n            \"default_value\": true\n        },\n        {\n            \"name\": \"time_at_status\",\n            \"description\": \"Number of hours spent in current state \",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"cold_start_cost\",\n            \"description\": \"Cost for Cold start of ThermalGen\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"warm_start_cost\",\n            \"description\": \"Cost for Warm of ThermalGen\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"hot_start_cost\",\n            \"description\": \"Cost for Hot of ThermalGen\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"must_run\",\n            \"description\": \"Boolean that indicates if ThermalGen must be online always\",\n            \"default_value\": false\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"pump_load\",\n            \"description\": \"PHES Pump Load\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"pump_rating\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"pump_active_power_limits_max\",\n            \"description\": \"Maximum real power StaticInjection (Unit Capacity)\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"pump_rating\",\n            \"default_value\": 1.0\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"pump_active_power_limits_min\",\n            \"description\": \"Minimum real power StaticInjection (Unit minimum stable level)\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"pump_rating\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"pump_reactive_power_limits_max\",\n            \"description\": \"Maximum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"pump_reactive_power_limits_min\",\n            \"description\": \"Minimum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"hours\",\n            \"name\": \"pump_min_down_time\",\n            \"description\": \"Minimum off time required before unit restart\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"hours\",\n            \"name\": \"pump_min_up_time\",\n            \"description\": \"Minimum on time required before unit shutdown\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW(p.u.)/Min\",\n            \"name\": \"pump_ramp_limits\",\n            \"description\": \"Maximum ramp up and ramp down rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW/Min\",\n            \"name\": \"pump_ramp_up\",\n            \"description\": \"Maximum ramp up rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW/Min\",\n            \"name\": \"pump_ramp_down\",\n            \"description\": \"Maximum ramp down rate\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_mva\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"generator_category\",\n            \"value_options\": [\n                \"HydroDispatch\",\n                \"RenewableNonDispatch\",\n                \"RenewableDispatch\",\n                \"ThermalStandard\",\n                \"ThermalMultiStart\"\n            ],\n            \"description\": \"Type of Struct\",\n            \"default_value\": \"ThermalStandard\"\n        }\n    ],\n    \"simulation_objects\": [],\n    \"reserves\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Reserve product name\"\n        },\n        {\n            \"name\": \"contributing_devices\",\n            \"description\": \"Contributing Devices for reserve requirement\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"requirement\",\n            \"description\": \"reserve requirement\",\n            \"unit_system\": \"SYSTEM_BASE\"\n        },\n        {\n            \"unit\": \"seconds\",\n            \"name\": \"timeframe\",\n            \"description\": \"Response time to satisfy reserve requirement\"\n        },\n        {\n            \"name\": \"eligible_device_categories\",\n            \"description\": \"Eligible Device Categories\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"eligible_device_subcategories\",\n            \"description\": \"Eligible Device SubCategories\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"eligible_regions\",\n            \"description\": \"Eligible Regions\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"reserve_category\",\n            \"value_options\": [\n                \"ConstantReserve\",\n                \"VariableReserve\",\n                \"Transfer\"\n            ],\n            \"description\": \"Type of Struct\",\n            \"default_value\": \"ConstantReserve\"\n        },\n        {\n            \"name\": \"direction\",\n            \"description\": \"Direction\",\n            \"value_options\": [\n                \"Up\",\n                \"Down\"\n            ]\n        }\n    ],\n    \"facts\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"FACTS object name\"\n        },\n        {\n            \"name\": \"available\",\n            \"description\": \"availability\",\n            \"default_value\": true\n        },\n        {\n            \"name\": \"bus\",\n            \"description\": \"Sending end bus number\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"control_mode\",\n            \"value_options\": [\n                \"OOS\",\n                \"NML\",\n                \"BYP\"\n            ],\n            \"description\": \"Control mode of operation\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"voltage_setpoint\",\n            \"description\": \"Voltage setpoint at sending bus in p.u,\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.9\n        },\n        {\n            \"name\": \"max_shunt_current\",\n            \"description\": \"Maximum shunt current at the sending end bus in MVA.\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 9999.0\n        },\n        {\n            \"name\": \"reactive_power_required\",\n            \"description\": \"Total MVAr required to hold voltage at sending bus, in %.\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 100.0\n        }\n    ],\n    \"storage\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Storage object name\"\n        },\n        {\n            \"name\": \"position\",\n            \"description\": \"head or tail\",\n            \"default_value\": \"head\"\n        },\n        {\n            \"name\": \"available\",\n            \"description\": \"availability\",\n            \"default_value\": true\n        },\n        {\n            \"name\": \"generator_name\",\n            \"description\": \"Generator name associated with storage\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"bus_id\",\n            \"description\": \"Connection Bus ID\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"energy_level\",\n            \"unit\": \"MWh\",\n            \"description\": \"Energy Level setpoint\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"active_power\",\n            \"description\": \"Real power injection setpoint\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MVar\",\n            \"name\": \"reactive_power\",\n            \"description\": \"Reactive power StaticInjection setpoint\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"input_active_power_limit_max\",\n            \"description\": \"Maximum real power limit on charging\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"input_active_power_limit_min\",\n            \"description\": \"Minimum real power limit on charging\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"output_active_power_limit_max\",\n            \"description\": \"Maximum real power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"output_active_power_limit_min\",\n            \"description\": \"Minimum real power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"output_reactive_power_limits_max\",\n            \"description\": \"Maximum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MVAR\",\n            \"name\": \"output_reactive_power_limits_min\",\n            \"description\": \"Minimum reactive power StaticInjection\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"MVA\",\n            \"name\": \"rating\",\n            \"description\": \"Apparent power injection limit rating\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"unit\": \"MW\",\n            \"name\": \"base_power\",\n            \"description\": \"Continuous MW flow limit\",\n            \"unit_system\": \"natural_units\"\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"input_efficiency\",\n            \"description\": \"Storage Input Efficiency\",\n            \"default_value\": 1.0\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"output_efficiency\",\n            \"description\": \"Storage Output Efficiency\",\n            \"default_value\": 1.0\n        },\n        {\n            \"unit\": \"%\",\n            \"name\": \"efficiency\",\n            \"description\": \"Battery Efficiency\",\n            \"default_value\": 1.0\n        },\n        {\n            \"unit\": \"MWh\",\n            \"name\": \"storage_capacity\",\n            \"description\": \"Storage Capacity\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"unit\": \"MWh\",\n            \"name\": \"min_storage_capacity\",\n            \"description\": \"Storage Capacity minimum\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        },\n        {\n            \"unit\": \"MWh\",\n            \"name\": \"storage_target\",\n            \"description\": \"End period storage target level\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        }\n    ],\n    \"bus\": [\n        {\n            \"name\": \"bus_id\",\n            \"description\": \"Numeric Bus ID\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"name\",\n            \"description\": \"Bus name from RTS-96\"\n        },\n        {\n            \"name\": \"area\",\n            \"description\": \"area membership\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"zone\",\n            \"description\": \"zone membership\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"kV\",\n            \"name\": \"base_voltage\",\n            \"description\": \"Bus voltage rating\",\n            \"unit_system\": \"natural_units\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"bus_type\",\n            \"value_options\": [\n                \"PQ\",\n                \"PV\",\n                \"REF\"\n            ],\n            \"description\": \"Bus control type\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"kV\",\n            \"name\": \"voltage\",\n            \"description\": \"voltage magnitude setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_voltage\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"radian\",\n            \"name\": \"angle\",\n            \"description\": \"voltage angle setpoint\",\n            \"default_value\": null\n        },\n        {\n            \"unit\": \"kV\",\n            \"name\": \"voltage_limits_min\",\n            \"description\": \"Minimum voltage setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_voltage\",\n            \"default_value\": 0.95\n        },\n        {\n            \"unit\": \"kV\",\n            \"name\": \"voltage_limits_max\",\n            \"description\": \"Maximum voltage setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_voltage\",\n            \"default_value\": 1.05\n        },\n        {\n            \"name\": \"max_active_power\",\n            \"description\": \"Maximum Active Power\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        },\n        {\n            \"name\": \"max_reactive_power\",\n            \"description\": \"Maximum Rective Power\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        },\n        {\n            \"name\": \"active_power\",\n            \"description\": \"Active Power Setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        },\n        {\n            \"name\": \"reactive_power\",\n            \"description\": \"Rective Power Setpoint\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        },\n        {\n            \"name\": \"base_power\",\n            \"description\": \"base power for demand\",\n            \"unit_system\": \"natural_units\",\n            \"default_value\": \"system_base_power\"\n        },\n        {\n            \"name\": \"shunt_g\",\n            \"description\": \"shunt conductance\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        },\n        {\n            \"name\": \"shunt_b\",\n            \"description\": \"shunt reactance\",\n            \"unit_system\": \"device_base\",\n            \"base_reference\": \"base_power\",\n            \"default_value\": 0\n        }\n    ],\n    \"load\": [\n        {\n            \"name\": \"name\",\n            \"description\": \"Load Name\"\n        },\n        {\n            \"name\": \"available\",\n            \"description\": \"Availability\",\n            \"default_value\": true\n        },\n        {\n            \"name\": \"bus_id\",\n            \"description\": \"Connection Bus ID\",\n            \"default_value\": null\n        },\n        {\n            \"name\": \"active_power\",\n            \"description\": \"Active power setpoint\",\n            \"default_value\": 0.0,\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"name\": \"reactive_power\",\n            \"description\": \"Reactive power setpoint\",\n            \"default_value\": 0.0,\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"name\": \"base_power\",\n            \"description\": \"base\",\n            \"unit_system\": \"natural_units\",\n            \"default_value\": \"system_base_power\"\n        },\n        {\n            \"name\": \"max_active_power\",\n            \"description\": \"max active power\",\n            \"unit_system\": \"device_base\"\n        },\n        {\n            \"name\": \"max_reactive_power\",\n            \"description\": \"max reactive power\",\n            \"unit_system\": \"device_base\",\n            \"default_value\": 0.0\n        }\n    ]\n}\n"
  },
  {
    "path": "src/descriptors/power_system_structs.json",
    "content": "{\n    \"auto_generated_structs\": [\n        {\n            \"struct_name\": \"Area\",\n            \"docstring\": \"A collection of buses for control purposes.\\n\\nThe `Area` can be specified when defining each [`ACBus`](@ref) or [`DCBus`](@ref) in the area\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"peak_active_power\",\n                    \"comment\": \"Peak active power in the area\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n\n                },\n                {\n                    \"name\": \"peak_reactive_power\",\n                    \"comment\": \"Peak reactive power in the area\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"load_response\",\n                    \"comment\": \"Load-frequency damping parameter modeling how much the load in the area changes due to changes in frequency (MW/Hz). [Example here.](https://doi.org/10.1109/NAPS50074.2021.9449687)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AggregationTopology\"\n        },\n        {\n            \"struct_name\": \"AreaInterchange\",\n            \"docstring\": \"Flow exchanged between Areas. This Interchange is agnostic to the lines connecting the areas. It does not substitute Interface which is the total flow across a group of lines\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Area(nothing)\",\n                    \"name\": \"from_area\",\n                    \"comment\": \"Area from which the power is extracted\",\n                    \"data_type\": \"Area\"\n                },\n                {\n                    \"null_value\": \"Area(nothing)\",\n                    \"name\": \"to_area\",\n                    \"comment\": \"Area to which the power is injected\",\n                    \"data_type\": \"Area\"\n                },\n                {\n                    \"name\": \"flow_limits\",\n                    \"null_value\": \"(from_to=0.0, to_from=0.0)\",\n                    \"comment\": \"Max flow between the areas. It ignores lines and other branches totals\",\n                    \"data_type\": \"FromTo_ToFrom\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Service interfaces that this device contributes to\",\n                    \"null_value\": \"Service[]\",\n                    \"default\": \"Service[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Branch\"\n        },\n        {\n            \"struct_name\": \"LoadZone\",\n            \"docstring\": \"A load zone for electricity price analysis.\\n\\nThe load zone can be specified when defining each [`ACBus`](@ref) or [`DCBus`](@ref) in the zone\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"peak_active_power\",\n                    \"comment\": \"Peak active power in the zone (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"peak_reactive_power\",\n                    \"comment\": \"Peak reactive power in the zone (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AggregationTopology\"\n        },\n        {\n            \"struct_name\": \"TransmissionInterface\",\n            \"docstring\": \"A collection of branches that make up an interface or corridor for the transfer of power, such as between different [`Areas`](@ref Area) or [`LoadZones`](@ref LoadZone).\\n\\nThe interface can be used to constrain the power flow across it\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow_limits\",\n                    \"comment\": \"Minimum and maximum active power flow limits on the interface (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"violation_penalty\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Penalty cost for violating the flow limits in the interface\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"INFINITE_COST\"\n                },\n                {\n                    \"name\": \"direction_mapping\",\n                    \"comment\": \"Dictionary of the line `name`s in the interface and their direction of flow (1 or -1) relative to the flow of the interface\",\n                    \"null_value\": \"Dict{String, Int}()\",\n                    \"data_type\": \"Dict{String, Int}\",\n                    \"default\": \"Dict{String, Int}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Service\"\n        },\n        {\n            \"struct_name\": \"ACBus\",\n            \"docstring\": \"An AC bus\",\n            \"inner_constructor_check\": \"check_bus_params\",\n            \"fields\": [\n                {\n                    \"name\": \"number\",\n                    \"comment\": \"A unique bus identification number (positive integer)\",\n                    \"null_value\": \"0\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations. This field should not be confused with the ISOLATED enum value (@ref acbustypes_list)\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bustype\",\n                    \"comment\": \"Used to describe the connectivity and behavior of this bus. [Options are listed here.](@ref acbustypes_list)\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, ACBusTypes}\"\n                },\n                {\n                    \"name\": \"angle\",\n                    \"comment\": \"angle of the bus in radians\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Union{Nothing, Float64}\"\n                },\n                {\n                    \"name\": \"magnitude\",\n                    \"comment\": \"voltage as a multiple of `base_voltage`\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": \"voltage_limits\",\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"voltage_limits\",\n                    \"comment\": \"limits on the voltage variation as multiples of `base_voltage`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"Union{Nothing, MinMax}\"\n                },\n                {\n                    \"name\": \"base_voltage\",\n                    \"comment\": \"the base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"area\",\n                    \"comment\": \"the area containing the bus\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Area}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"load_zone\",\n                    \"comment\": \"the load zone containing the bus\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, LoadZone}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Bus\"\n        },\n        {\n            \"struct_name\": \"DCBus\",\n            \"docstring\": \"A DC bus\",\n            \"fields\": [\n                {\n                    \"name\": \"number\",\n                    \"comment\": \"A unique bus identification number (positive integer)\",\n                    \"null_value\": \"0\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations.\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"magnitude\",\n                    \"comment\": \"voltage as a multiple of `base_voltage`\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": \"voltage_limits\",\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"voltage_limits\",\n                    \"comment\": \"limits on the voltage variation as multiples of `base_voltage`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"Union{Nothing, MinMax}\"\n                },\n                {\n                    \"name\": \"base_voltage\",\n                    \"comment\": \"the base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"area\",\n                    \"comment\": \"the area containing the DC bus\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Area}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"load_zone\",\n                    \"comment\": \"the load zone containing the DC bus\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, LoadZone}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Bus\"\n        },\n        {\n            \"struct_name\": \"Arc\",\n            \"docstring\": \"A topological directed edge connecting two buses.\\n\\nArcs are used to define the `from` and `to` buses when defining a line or transformer\",\n            \"fields\": [\n                {\n                    \"name\": \"from\",\n                    \"comment\": \"The initial bus\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"Bus\"\n                },\n                {\n                    \"name\": \"to\",\n                    \"comment\": \"The terminal bus\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"Bus\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"custom_code\": \"get_name(arc::Arc) = (get_name ∘ get_from)(arc) * \\\" -> \\\" * (get_name ∘ get_to)(arc)\",\n            \"supertype\": \"Topology\"\n        },\n        {\n            \"struct_name\": \"Line\",\n            \"docstring\": \"An AC transmission line\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow on the line (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"b\",\n                    \"null_value\": \"(from=0.0, to=0.0)\",\n                    \"data_type\": \"FromTo\",\n                    \"comment\": \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow on the line must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"angle_limits\",\n                    \"comment\": \"Minimum and maximum angle limits (radians)\",\n                    \"null_value\": \"(min=-3.1416, max=3.1416)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_b\",\n                    \"comment\": \"Second current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_c\",\n                    \"comment\": \"Third current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"g\",\n                    \"null_value\": \"(from=0.0, to=0.0)\",\n                    \"data_type\": \"FromTo\",\n                    \"comment\": \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\",\n                    \"default\": \"(from=0.0, to=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ACTransmission\"\n        },\n        {\n            \"struct_name\": \"GenericArcImpedance\",\n            \"docstring\": \"A virtual impedance between two buses that does not correspond to a physical component. This can be used to model the effects of network reductions (e.g. Ward reduction).\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow on the line (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"max_flow\",\n                    \"comment\": \"Maximum allowable flow on the generic impedance. When defining a GenericArcImpedance before it is attached to a `System`, `max_flow` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n               {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ACTransmission\"\n        },\n        {\n            \"struct_name\": \"DiscreteControlledACBranch\",\n            \"docstring\": \"Used to represent switches and breakers connecting AC Buses\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow on the line (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow on the branch must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"discrete_branch_type\",\n                    \"comment\": \"Type of discrete control\",\n                    \"null_value\": \"DiscreteControlledBranchType.BREAKER\",\n                    \"data_type\": \"DiscreteControlledBranchType\",\n                    \"default\": \"DiscreteControlledBranchType.OTHER\"\n                },\n                {\n                    \"name\": \"branch_status\",\n                    \"comment\": \"Open or Close status\",\n                    \"null_value\": \"DiscreteControlledBranchStatus.CLOSED\",\n                    \"data_type\": \"DiscreteControlledBranchStatus\",\n                    \"default\": \"DiscreteControlledBranchStatus.CLOSED\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ACTransmission\"\n        },\n        {\n            \"struct_name\": \"MonitoredLine\",\n            \"docstring\": \"An AC transmission line with additional power flow constraints specified by the system operator, more restrictive than the line's thermal limits.\\n\\nFor example, monitored lines can be used to restrict line flow following a contingency elsewhere in the network. See the `flow_limits` parameter. If monitoring is not needed, see [`Line`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow on the line (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"b\",\n                    \"null_value\": \"(from=0.0, to=0.0)\",\n                    \"data_type\": \"FromTo\",\n                    \"comment\": \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"flow_limits\",\n                    \"null_value\": \"(from_to=0.0, to_from=0.0)\",\n                    \"comment\": \"Minimum and maximum permissable flow on the line (MVA), if different from the thermal rating defined in `rating`\",\n                    \"data_type\": \"FromTo_ToFrom\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"angle_limits\",\n                    \"comment\": \"Minimum and maximum angle limits (radians)\",\n                    \"null_value\": \"(min=-3.1416, max=3.1416)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_b\",\n                    \"comment\": \"Second current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_c\",\n                    \"comment\": \"Third current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"g\",\n                    \"null_value\": \"(from=0.0, to=0.0)\",\n                    \"data_type\": \"FromTo\",\n                    \"comment\": \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\",\n                    \"default\": \"(from=0.0, to=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ACTransmission\"\n        },\n        {\n            \"struct_name\": \"PhaseShiftingTransformer\",\n            \"docstring\": \"A phase-shifting transformer regulating the phase angle between two buses to control active power flow in the system.\\n\\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow through the transformer (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"primary_shunt\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Complex{Float64}\",\n                    \"comment\": \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"tap\",\n                    \"comment\": \"Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"α\",\n                    \"comment\": \"Initial condition of phase shift (radians) between the `from` and `to` buses \",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1.571,\n                        \"max\": 1.571\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_voltage_primary\",\n                    \"comment\": \"Primary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_secondary\",\n                    \"comment\": \"Secondary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_to(arc))\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_b\",\n                    \"comment\": \"Second current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_c\",\n                    \"comment\": \"Third current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"phase_angle_limits\",\n                    \"comment\": \"Minimum and maximum phase angle limits (radians)\",\n                    \"null_value\": \"(min=-3.1416, max=3.1416)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=-3.1416, max=3.1416)\"\n                },\n                {\n                    \"name\": \"control_objective\",\n                    \"comment\": \"Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoWindingTransformer\"\n        },\n        {\n            \"struct_name\": \"TapTransformer\",\n            \"docstring\": \"A 2-winding transformer, with a tap changer for variable turns ratio.\\n\\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow through the transformer (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"primary_shunt\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Complex{Float64}\",\n                    \"comment\": \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"tap\",\n                    \"comment\": \"Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_voltage_primary\",\n                    \"comment\": \"Primary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_secondary\",\n                    \"comment\": \"Secondary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_to(arc))\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_b\",\n                    \"comment\": \"Second current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_c\",\n                    \"comment\": \"Third current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                   \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"winding_group_number\",\n                    \"null_value\": \"WindingGroupNumber.UNDEFINED\",\n                    \"data_type\": \"WindingGroupNumber\",\n                    \"comment\": \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\",\n                    \"default\": \"WindingGroupNumber.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective\",\n                    \"comment\": \"Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoWindingTransformer\"\n        },\n        {\n            \"struct_name\": \"Transformer2W\",\n            \"docstring\": \"A basic 2-winding transformer.\\n\\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow through the transformer (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"primary_shunt\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Complex{Float64}\",\n                    \"comment\": \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                   \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_voltage_primary\",\n                    \"comment\": \"Primary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_secondary\",\n                    \"comment\": \"Secondary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_to(arc))\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_b\",\n                    \"comment\": \"Second current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_c\",\n                    \"comment\": \"Third current rating; entered in MVA.\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"winding_group_number\",\n                    \"null_value\": \"WindingGroupNumber.UNDEFINED\",\n                    \"data_type\": \"WindingGroupNumber\",\n                    \"comment\": \"Vector group number ('clock number') indicating phase shift (radians) between the `from` and `to` buses\",\n                    \"default\": \"WindingGroupNumber.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoWindingTransformer\"\n        },\n        {\n            \"struct_name\": \"Transformer3W\",\n            \"docstring\": \"A 3-winding transformer.\\n\\nThe model uses an equivalent star model with a star (hidden) bus. The user must transform the data to use `CW = CZ = CM = 1` and `COD1 = COD2 = COD3 = 0` (no voltage control) if taken from a PSS/E 3W transformer model. Three equivalent impedances (connecting each side to the star bus) are required to define the model. Shunt conductance (iron losses) and magnetizing susceptance can be considered from the star bus to ground. The model is described in Chapter 3.6 in J.D. Glover, M.S. Sarma and T. Overbye: Power Systems Analysis and Design.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"primary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"secondary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"tertiary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"name\": \"star_bus\",\n                    \"comment\": \"Star (hidden) Bus that this component (equivalent model) is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power_flow_primary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_primary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_flow_secondary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_secondary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_flow_tertiary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_tertiary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_12\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_12\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_23\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_23\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_13\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_13\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"base_power_12\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power_23\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power_13\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_voltage_primary\",\n                    \"comment\": \"Primary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(primary_star_arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_secondary\",\n                    \"comment\": \"Secondary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(secondary_star_arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_tertiary\",\n                    \"comment\": \"Tertiary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(tertiary_star_arc))\"\n                },\n                {\n                    \"name\": \"g\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"b\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"primary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"secondary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"tertiary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_primary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_secondary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_tertiary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for primary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for secondary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for tertiary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"primary_group_number\",\n                    \"null_value\": \"WindingGroupNumber.UNDEFINED\",\n                    \"data_type\": \"WindingGroupNumber\",\n                    \"comment\": \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\",\n                    \"default\": \"WindingGroupNumber.UNDEFINED\"\n                },\n                {\n                    \"name\": \"secondary_group_number\",\n                    \"null_value\": \"WindingGroupNumber.UNDEFINED\",\n                    \"data_type\": \"WindingGroupNumber\",\n                    \"comment\": \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\",\n                    \"default\": \"WindingGroupNumber.UNDEFINED\"\n                },\n                {\n                    \"name\": \"tertiary_group_number\",\n                    \"null_value\": \"WindingGroupNumber.UNDEFINED\",\n                    \"data_type\": \"WindingGroupNumber\",\n                    \"comment\": \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\",\n                    \"default\": \"WindingGroupNumber.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective_primary\",\n                    \"comment\": \"Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective_secondary\",\n                    \"comment\": \"Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective_tertiary\",\n                    \"comment\": \"Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ThreeWindingTransformer\"\n        },\n        {\n            \"struct_name\": \"PhaseShiftingTransformer3W\",\n            \"docstring\": \"A 3-winding phase-shifting transformer.\\n\\n. Phase shifts are specified in radians for primary, secondary, and tertiary windings.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"primary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"secondary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"tertiary_star_arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"name\": \"star_bus\",\n                    \"comment\": \"Star (hidden) Bus that this component (equivalent model) is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power_flow_primary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_primary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_flow_secondary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_secondary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_flow_tertiary\",\n                    \"comment\": \"Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_flow_tertiary\",\n                    \"comment\": \"Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_12\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_12\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_23\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_23\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r_13\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"x_13\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E).\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 4\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":ohm\"\n                },\n                {\n                    \"name\": \"α_primary\",\n                    \"comment\": \"Initial condition of primary phase shift (radians) between the `from` and `to` buses \",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1.571,\n                        \"max\": 1.571\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"α_secondary\",\n                    \"comment\": \"Initial condition of secondary phase shift (radians) between the `from` and `to` buses \",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1.571,\n                        \"max\": 1.571\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"α_tertiary\",\n                    \"comment\": \"Initial condition of tertiary phase shift (radians) between the `from` and `to` buses \",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1.571,\n                        \"max\": 1.571\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power_12\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power_23\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power_13\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_voltage_primary\",\n                    \"comment\": \"Primary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(primary_star_arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_secondary\",\n                    \"comment\": \"Secondary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(secondary_star_arc))\"\n                },\n                {\n                    \"name\": \"base_voltage_tertiary\",\n                    \"comment\": \"Tertiary base voltage in kV\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"get_base_voltage(get_from(tertiary_star_arc))\"\n                },\n                {\n                    \"name\": \"g\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"name\": \"b\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":siemens\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"primary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"secondary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"tertiary_turns_ratio\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_primary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_secondary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available_tertiary\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Status if primary winding is available or not.\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_primary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for primary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_secondary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for secondary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"rating_tertiary\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Rating (in MVA) for tertiary winding.\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"phase_angle_limits\",\n                    \"comment\": \"Minimum and maximum phase angle limits (radians)\",\n                    \"null_value\": \"(min=-3.1416, max=3.1416)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=-3.1416, max=3.1416)\"\n                },\n                {\n                    \"name\": \"control_objective_primary\",\n                    \"comment\": \"Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective_secondary\",\n                    \"comment\": \"Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"control_objective_tertiary\",\n                    \"comment\": \"Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\",\n                    \"data_type\": \"TransformerControlObjective\",\n                    \"null_value\": \"TransformerControlObjective.UNDEFINED\",\n                    \"default\": \"TransformerControlObjective.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ThreeWindingTransformer\"\n        },\n        {\n            \"struct_name\": \"TwoTerminalGenericHVDCLine\",\n            \"docstring\": \"A High Voltage DC line, which must be connected to an [`ACBus`](@ref) on each end.\\n\\nThis model is appropriate for operational simulations with a linearized DC power flow approximation with losses proportional to the power flow. For modeling a DC network, see [`TModelHVDCLine`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"name\": \"active_power_limits_from\",\n                    \"comment\": \"Minimum and maximum active power flows to the FROM node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits_to\",\n                    \"comment\": \"Minimum and maximum active power flows to the TO node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_from\",\n                    \"comment\": \"Minimum and maximum reactive power limits to the FROM node (MVAR)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_to\",\n                    \"comment\": \"Minimum and maximum reactive power limits to the TO node (MVAR)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"loss\",\n                    \"comment\": \"Loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"Union{LinearCurve, PiecewiseIncrementalCurve}\",\n                    \"default\": \"LinearCurve(0.0)\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoTerminalHVDC\"\n        },\n        {\n            \"struct_name\": \"TwoTerminalVSCLine\",\n            \"docstring\": \"A High Voltage Voltage-Source Converter DC line, which must be connected to an [`ACBus`](@ref) on each end.\\n\\nThis model is appropriate for operational simulations with a linearized DC power flow approximation with losses using a voltage-current model. For modeling a DC network, see [`TModelHVDCLine`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flowing from the from-bus to the to-bus in DC.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum output power rating of the converter (MVA)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits_from\",\n                    \"comment\": \"Minimum and maximum active power flows to the FROM node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits_to\",\n                    \"comment\": \"Minimum and maximum active power flows to the TO node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"g\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Series conductance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"dc_current\",\n                    \"comment\": \"DC current (A) on the converter flowing in the DC line, from `from` bus to `to` bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"reactive_power_from\",\n                    \"comment\": \"Initial condition of reactive power flowing into the from-bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"dc_voltage_control_from\",\n                    \"comment\": \"Converter control type in the `from` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"name\": \"ac_voltage_control_from\",\n                    \"comment\": \"Converter control type in the `from` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"name\": \"dc_setpoint_from\",\n                    \"comment\": \"Converter DC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_from = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `from` bus; if negative, the converter is withdrawing power from the AC network at the `from` bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"ac_setpoint_from\",\n                    \"comment\": \"Converter AC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_from = false`, this value is the power factor setpoint.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"converter_loss_from\",\n                    \"comment\": \"Loss model coefficients in the `from` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"Union{LinearCurve, QuadraticCurve}\",\n                    \"default\": \"LinearCurve(0.0)\"\n                },\n                {\n                    \"name\": \"max_dc_current_from\",\n                    \"comment\": \"Maximum stable dc current limits (A).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1e8\"\n                },\n                {\n                    \"name\": \"rating_from\",\n                    \"comment\": \"Converter rating in MVA in the `from` bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1e8\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_from\",\n                    \"comment\": \"Limits on the Reactive Power at the `from` side.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.0, max=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"power_factor_weighting_fraction_from\",\n                    \"comment\": \"Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"voltage_limits_from\",\n                    \"comment\": \"Limits on the Voltage at the DC `from` Bus in [per unit](@ref per_unit.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.0, max=999.9)\"\n                },\n                {\n                    \"name\": \"reactive_power_to\",\n                    \"comment\": \"Initial condition of reactive power flowing into the to-bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"dc_voltage_control_to\",\n                    \"comment\": \"Converter control type in the `to` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"name\": \"ac_voltage_control_to\",\n                    \"comment\": \"Converter control type in the `to` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"name\": \"dc_setpoint_to\",\n                    \"comment\": \"Converter DC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_to = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `to` bus; if negative, the converter is withdrawing power from the AC network at the `to` bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"ac_setpoint_to\",\n                    \"comment\": \"Converter AC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_to = false`, this value is the power factor setpoint.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"converter_loss_to\",\n                    \"comment\": \"Loss model coefficients in the `to` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"Union{LinearCurve, QuadraticCurve}\",\n                    \"default\": \"LinearCurve(0.0)\"\n                },\n                {\n                    \"name\": \"max_dc_current_to\",\n                    \"comment\": \"Maximum stable dc current limits (A).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1e8\"\n                },\n                {\n                    \"name\": \"rating_to\",\n                    \"comment\": \"Converter rating in MVA in the `to` bus.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1e8\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_to\",\n                    \"comment\": \"Limits on the Reactive Power at the `to` side.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.0, max=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"power_factor_weighting_fraction_to\",\n                    \"comment\": \"Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"voltage_limits_to\",\n                    \"comment\": \"Limits on the Voltage at the DC `to` Bus.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.0, max=999.9)\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoTerminalHVDC\"\n        },\n        {\n            \"struct_name\": \"TwoTerminalLCCLine\",\n            \"docstring\": \"A Non-Capacitor Line Commutated Converter (LCC)-HVDC transmission line.\\n\\nAs implemented in PSS/E.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"Arc(ACBus(nothing), ACBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a rectifier bus `to` an inverter bus. The rectifier bus must be specified in the `from` bus and inverter bus in the `to` bus.\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Series resistance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n                },\n                {\n                    \"name\": \"transfer_setpoint\",\n                    \"comment\": \"Desired set-point of power. If `power_mode = true` this value is in MW units, and if `power_mode = false` is in Amperes units. This parameter must not be specified in per-unit. A positive value represents the desired consumed power at the rectifier bus, while a negative value represents the desired power at the inverter bus (i.e. the absolute value of `transfer_setpoint` is the generated power at the inverter bus).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"scheduled_dc_voltage\",\n                    \"comment\": \"Scheduled compounded DC voltage in kV. By default this parameter is the scheduled DC voltage in the inverter bus This parameter must not be specified in per-unit.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"rectifier_bridges\",\n                    \"comment\": \"Number of bridges in series in the rectifier side.\",\n                    \"null_value\": \"0\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"rectifier_delay_angle_limits\",\n                    \"comment\": \"Minimum and maximum rectifier firing delay angle (α) (radians)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"rectifier_rc\",\n                    \"comment\": \"Rectifier commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"rectifier_xc\",\n                    \"comment\": \"Rectifier commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"rectifier_base_voltage\",\n                    \"comment\": \"Rectifier primary base AC voltage in kV, entered in kV.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"inverter_bridges\",\n                    \"comment\": \"Number of bridges in series in the inverter side.\",\n                    \"null_value\": \"0\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"inverter_extinction_angle_limits\",\n                    \"comment\": \"Minimum and maximum inverter extinction angle (γ) (radians)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"inverter_rc\",\n                    \"comment\": \"Inverter commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"inverter_xc\",\n                    \"comment\": \"Inverter commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"inverter_base_voltage\",\n                    \"comment\": \"Inverter primary base AC voltage in kV, entered in kV.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"power_mode\",\n                    \"data_type\": \"Bool\",\n                    \"comment\": \"Boolean flag to identify if the LCC line is in power mode or current mode. If `power_mode = true`, setpoint values must be specified in MW, and if `power_mode = false` setpoint values must be specified in Amperes.\",\n                    \"null_value\": \"false\",\n                    \"default\": \"true\"\n                },\n                {\n                    \"name\": \"switch_mode_voltage\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Mode switch DC voltage, in kV. This parameter must not be added in per-unit. If LCC line is in power mode control, and DC voltage falls below this value, the line switch to current mode control.\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"compounding_resistance\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Compounding Resistance, in ohms. This parameter is for control of the DC voltage in the rectifier or inverter end. For inverter DC voltage control, the paremeter is set to zero; for rectifier DC voltage control, the paremeter is set to the DC line resistance; otherwise, set to a fraction of the DC line resistance.\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"min_compounding_voltage\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Minimum compounded voltage, in kV. This parameter must not be added in per-unit. Only used in constant gamma operation (γ_min = γ_max), and the AC transformer is used to control the DC voltage.\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"rectifier_transformer_ratio\",\n                    \"comment\": \"Rectifier transformer ratio between the primary and secondary side AC voltages.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"rectifier_tap_setting\",\n                    \"comment\": \"Rectifier transformer tap setting.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"rectifier_tap_limits\",\n                    \"comment\": \"Minimum and maximum rectifier tap limits as a ratio between the primary and secondary side AC voltages.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.51, max=1.5)\"\n                },\n                {\n                    \"name\": \"rectifier_tap_step\",\n                    \"comment\": \"Rectifier transformer tap step value\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.00625\"\n                },\n                {\n                    \"name\": \"rectifier_delay_angle\",\n                    \"comment\": \"Rectifier firing delay angle (α).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"rectifier_capacitor_reactance\",\n                    \"comment\": \"Commutating rectifier capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"inverter_transformer_ratio\",\n                    \"comment\": \"Inverter transformer ratio between the primary and secondary side AC voltages.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"inverter_tap_setting\",\n                    \"comment\": \"Inverter transformer tap setting.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"inverter_tap_limits\",\n                    \"comment\": \"Minimum and maximum inverter tap limits as a ratio between the primary and secondary side AC voltages.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.51, max=1.5)\"\n                },\n                {\n                    \"name\": \"inverter_tap_step\",\n                    \"comment\": \"Inverter transformer tap step value.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.00625\"\n                },\n                {\n                    \"name\": \"inverter_extinction_angle\",\n                    \"comment\": \"Inverter extinction angle (γ).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"inverter_capacitor_reactance\",\n                    \"comment\": \"Commutating inverter capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"active_power_limits_from\",\n                    \"comment\": \"Minimum and maximum active power flows to the FROM node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"(min=0.0, max=0.0)\"\n                },\n                {\n                    \"name\": \"active_power_limits_to\",\n                    \"comment\": \"Minimum and maximum active power flows to the TO node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"(min=0.0, max=0.0)\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_from\",\n                    \"comment\": \"Minimum and maximum reactive power limits to the FROM node (MVAR)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"(min=0.0, max=0.0)\"\n                },\n                {\n                    \"name\": \"reactive_power_limits_to\",\n                    \"comment\": \"Minimum and maximum reactive power limits to the TO node (MVAR)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"(min=0.0, max=0.0)\"\n                },\n                {\n                    \"name\": \"loss\",\n                    \"comment\": \"A generic loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"Union{LinearCurve, PiecewiseIncrementalCurve}\",\n                    \"default\": \"LinearCurve(0.0)\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TwoTerminalHVDC\"\n        },\n        {\n            \"struct_name\": \"TModelHVDCLine\",\n            \"docstring\": \"A High Voltage DC transmission line for modeling DC transmission networks.\\n\\nThis line must be connected to a [`DCBus`](@ref) on each end. It uses a T-Model of the line impedance. This is suitable for operational simulations with a multi-terminal DC network\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"active_power_flow\",\n                    \"comment\": \"Initial condition of active power flow on the line (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"null_value\": \"Arc(DCBus(nothing), DCBus(nothing))\",\n                    \"name\": \"arc\",\n                    \"comment\": \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\",\n                    \"data_type\": \"Arc\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"r\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Total series Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"l\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Total series Inductance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\"\n                },\n                {\n                    \"null_value\": \"0.0\",\n                    \"name\": \"c\",\n                    \"data_type\": \"Float64\",\n                    \"comment\": \"Shunt capacitance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n                },\n                {\n                    \"name\": \"active_power_limits_from\",\n                    \"comment\": \"Minimum and maximum active power flows to the FROM node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits_to\",\n                    \"comment\": \"Minimum and maximum active power flows to the TO node (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DCBranch\"\n        },\n        {\n            \"struct_name\": \"InterruptiblePowerLoad\",\n            \"docstring\": \"A [static](@ref S) power load that can be compensated for temporary or continuous interruptions to its requested demand.\\n\\n These loads are most commonly used for operational optimizations and can be used to model, for example, large commercial and industrial customers enrolled in demand response programs. This load has a target demand profile (set by a [`max_active_power` time series](@ref ts_data) for an operational simulation) that can be reduced to satisfy other system needs. For simpler loads without an operating cost for demand response, see [`PowerLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial steady state active power demand (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial steady state reactive power demand (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_active_power\",\n                    \"comment\": \"Maximum active power (MW) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"LoadCost(nothing)\",\n                    \"data_type\": \"Union{LoadCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of interrupting load\"\n                },\n                {\n                    \"name\": \"conformity\",\n                    \"comment\": \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\",\n                    \"data_type\": \"LoadConformity\",\n                    \"default\": \"LoadConformity.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ControllableLoad\"\n        },\n        {\n            \"struct_name\": \"InterruptibleStandardLoad\",\n                \"docstring\": \"A voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\\n\\nA `StandardLoad` breaks the ZIP into three pieces: Z (constant impedance), I (constant current), and P (constant power), according to `P = P_P * V^0 + P_I * V^1 + P_Z * V^2` for active power and `Q = Q_P * V^0 + Q_I * V^1 + Q_Z * V^2` for reactive power. (Voltage V is in per unit.)\\n\\nFor an alternative exponential formulation of the ZIP model, see [`ExponentialLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the load (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"LoadCost(nothing)\",\n                    \"data_type\": \"Union{LoadCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of interrupting load\"\n                },\n                {\n                    \"name\": \"conformity\",\n                    \"comment\": \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\",\n                    \"data_type\": \"LoadConformity\",\n                    \"default\": \"LoadConformity.UNDEFINED\"\n                },\n                {\n                    \"name\": \"constant_active_power\",\n                    \"comment\": \"Constant active power demand in MW (P_P)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"constant_reactive_power\",\n                    \"comment\": \"Constant reactive power demand in MVAR (Q_P)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"impedance_active_power\",\n                    \"comment\": \"Active power coefficient in MW for constant impedance load (P_Z)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"impedance_reactive_power\",\n                    \"comment\": \"Reactive power coefficient in MVAR for constant impedance load (Q_Z)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"current_active_power\",\n                    \"comment\": \"Active power coefficient in MW for constant current load (P_I)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"current_reactive_power\",\n                    \"comment\": \"Reactive power coefficient in MVAR for constant current load (Q_I)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_constant_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant power load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_constant_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant power load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_impedance_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant impedance load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_impedance_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant impedance load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_current_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant current load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_current_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant current load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ControllableLoad\"\n        },\n        {\n            \"struct_name\": \"ShiftablePowerLoad\",\n            \"docstring\": \"A [static](@ref S) power load that can be partially or completed shifted to later time periods.\\n\\n These loads are used to model demand response. This load has a target demand profile (set by a [`max_active_power` time series](@ref ts_data) for an operational simulation). Load in the profile can be shifted to later time periods to aid in satisfying other system needs; however, any shifted load must be served within a designated time horizon (e.g., 24 hours), which is set by `load_balance_time_horizon`.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial steady state active power demand (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial steady state reactive power demand (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_active_power\",\n                    \"comment\": \"Maximum active power (MW) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"load_balance_time_horizon\",\n                    \"comment\": \"Number of time periods over which load must be balanced\",\n                    \"null_value\": \"1\",\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"LoadCost(nothing)\",\n                    \"data_type\": \"Union{LoadCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of interrupting load\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ControllableLoad\"\n        },\n        {\n            \"struct_name\": \"FACTSControlDevice\",\n            \"docstring\": \"Facts control devices.\\n\\nMost often used in AC power flow studies as a control of voltage and, active and reactive power.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Sending end bus number\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"control_mode\",\n                    \"comment\": \"Control mode. Used to describe the behavior of the control device. [Options are listed here.](@ref factsmodes_list)\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, FACTSOperationModes}\"\n                },\n                {\n                    \"name\": \"voltage_setpoint\",\n                    \"comment\": \"Voltage setpoint at the sending end bus, it has to be a [`PV`](@ref acbustypes_list) bus, in p.u. ([`SYSTEM_BASE`](@ref per_unit)).\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"max_shunt_current\",\n                    \"comment\": \"Maximum shunt current at the sending end bus; entered in MVA at unity voltage.\",\n                    \"internal_default\": \"9999.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"reactive_power_required\",\n                    \"comment\": \"Total MVAr required to hold voltage at sending bus, in %.\",\n                    \"internal_default\": \"100.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"Corresponding dynamic injection model for FACTS control device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticInjection\"\n        },\n        {\n            \"struct_name\": \"FixedAdmittance\",\n            \"docstring\": \"A fixed admittance.\\n\\nMost often used in dynamics or AC power flow studies as a source of reactive power\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"Y\",\n                    \"comment\": \"Fixed admittance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Complex{Float64}\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection model for admittance\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ElectricLoad\"\n        },\n        {\n            \"struct_name\": \"SwitchedAdmittance\",\n            \"docstring\": \"A switched admittance, with discrete steps to adjust the admittance.\\n\\nMost often used in power flow studies, iterating over the steps to see impacts of admittance on the results. Total admittance is calculated as: `Y` + `number_of_steps` * `Y_increase`\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"Y\",\n                    \"comment\": \"Initial admittance at N = 0\",\n                    \"null_value\": \"0.0 + 0.0im\",\n                    \"data_type\": \"Complex{Float64}\"\n                },\n                {\n                    \"name\": \"initial_status\",\n                    \"comment\": \"Vector of initial switched shunt status, one for in-service and zero for out-of-service for block i (1 through 8)\",\n                    \"null_value\": \"Int[]\",\n                    \"data_type\": \"Vector{Int}\",\n                    \"default\": \"Int[]\"\n                },\n                {\n                    \"name\": \"number_of_steps\",\n                    \"comment\": \"Vector with number of steps for each adjustable shunt block. For example, `number_of_steps[2]` are the number of available steps for admittance increment at block 2.\",\n                    \"null_value\": \"Int[]\",\n                    \"data_type\": \"Vector{Int}\",\n                    \"default\": \"Int[]\"\n                },\n                {\n                    \"name\": \"Y_increase\",\n                    \"comment\": \"Vector with admittance increment step for each adjustable shunt block. For example, `Y_increase[2]` is the complex admittance increment for each step at block 2.\",\n                    \"null_value\": \"Complex{Float64}[]\",\n                    \"data_type\": \"Vector{Complex{Float64}}\",\n                    \"default\": \"Complex{Float64}[]\"\n                },\n                {   \"name\": \"admittance_limits\",\n                    \"comment\": \"Shunt admittance limits for switched shunt model\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=1.0, max=1.0)\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection model for admittance\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ElectricLoad\"\n        },\n        {\n            \"struct_name\": \"PowerLoad\",\n            \"docstring\": \"A [static](@ref S) power load, most commonly used for operational models such as power flow and operational optimizations.\\n\\nThis load consumes a set amount of power (set by `active_power` for a power flow simulation or a `max_active_power` time series for an operational simulation). For loads that can be compensated for load interruptions through demand response programs, see [`InterruptiblePowerLoad`](@ref). For voltage-dependent loads used in [dynamics](@ref D) modeling, see [`StandardLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial steady-state active power demand (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial steady-state reactive power demand (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"max_active_power\",\n                    \"comment\": \"Maximum active power (MW) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"conformity\",\n                    \"comment\": \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\",\n                    \"data_type\": \"LoadConformity\",\n                    \"default\": \"LoadConformity.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticLoad\"\n        },\n        {\n            \"struct_name\": \"MotorLoad\",\n            \"docstring\": \"A [static](@ref S) power load, most commonly used for operational models such as power flow and operational optimizations.\\n\\nThis load consumes a set amount of power (set by `active_power` for a power flow simulation or a `max_active_power` time series for an operational simulation). For loads that can be compensated for load interruptions through demand response programs, see [`InterruptiblePowerLoad`](@ref). For voltage-dependent loads used in [dynamics](@ref D) modeling, see [`StandardLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `MotorLoad`) must have unique names, but components of different types (e.g., `MotorLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial steady-state active power demand (MW). A positive value indicates power consumption.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial steady-state reactive power demand (MVAR). A positive value indicates reactive power consumption.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_active_power\",\n                    \"comment\": \"Maximum active power (MW) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"default\": \"nothing\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n            {\n                    \"name\": \"motor_technology\",\n                    \"comment\": \"AC Motor type. Options are listed [here](@ref motor_list)\",\n                    \"null_value\": \"MotorLoadTechnology.UNDETERMINED\",\n                    \"data_type\": \"MotorLoadTechnology\",\n                    \"default\": \"MotorLoadTechnology.UNDETERMINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticLoad\"\n        },\n        {\n            \"struct_name\": \"StandardLoad\",\n                \"docstring\": \"A voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\\n\\nA `StandardLoad` breaks the ZIP into three pieces: Z (constant impedance), I (constant current), and P (constant power), according to `P = P_P * V^0 + P_I * V^1 + P_Z * V^2` for active power and `Q = Q_P * V^0 + Q_I * V^1 + Q_Z * V^2` for reactive power. (Voltage V is in per unit.)\\n\\nFor an alternative exponential formulation of the ZIP model, see [`ExponentialLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the load (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"constant_active_power\",\n                    \"comment\": \"Constant active power demand in MW (P_P)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"constant_reactive_power\",\n                    \"comment\": \"Constant reactive power demand in MVAR (Q_P)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"impedance_active_power\",\n                    \"comment\": \"Active power coefficient in MW for constant impedance load (P_Z)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"impedance_reactive_power\",\n                    \"comment\": \"Reactive power coefficient in MVAR for constant impedance load (Q_Z)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"current_active_power\",\n                    \"comment\": \"Active power coefficient in MW for constant current load (P_I)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"current_reactive_power\",\n                    \"comment\": \"Reactive power coefficient in MVAR for constant current load (Q_I)\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_constant_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant power load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_constant_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant power load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_impedance_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant impedance load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_impedance_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant impedance load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_current_active_power\",\n                    \"comment\": \"Maximum active power (MW) drawn by constant current load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_current_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) drawn by constant current load\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"conformity\",\n                    \"comment\": \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\",\n                    \"data_type\": \"LoadConformity\",\n                    \"default\": \"LoadConformity.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticLoad\"\n        },\n        {\n            \"struct_name\": \"ExponentialLoad\",\n            \"docstring\": \"A voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\\n\\nAn `ExponentialLoad` models active power as P = P0 * V^α and reactive power as Q = Q0 * V^β, where the exponents α and β select govern the voltage dependency. For an alternative three-part formulation of the ZIP model, see [`StandardLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Active power coefficient, P0 (MW)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Reactive power coefficient, Q0 (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"α\",\n                    \"comment\": \"Exponent relating voltage dependency for active power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"β\",\n                    \"comment\": \"Exponent relating voltage dependency for reactive power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"max_active_power\",\n                    \"comment\": \"Maximum active power (MW) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"max_reactive_power\",\n                    \"comment\": \"Maximum reactive power (MVAR) that this load can demand\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"conformity\",\n                    \"comment\": \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\",\n                    \"data_type\": \"LoadConformity\",\n                    \"default\": \"LoadConformity.UNDEFINED\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticLoad\"\n        },\n        {\n            \"struct_name\": \"SingleCageInductionMachine\",\n            \"docstring\": \"Parameters of 5-states three-phase single cage induction machine with quadratic torque-speed relationship\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"R_s\",\n                    \"comment\": \"Armature stator resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_r\",\n                    \"comment\": \"Rotor resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_ls\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Stator Leakage Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_lr\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Rotor Leakage Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_m\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Stator-Rotor Mutual Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Motor Inertia Constant [s]\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"A\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Torque-Speed Quadratic Term\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"B\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Torque-Speed Linear Term\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 100.0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"C\",\n                    \"comment\": \"(**Do not modify.**) Torque-Speed Constant Term\",\n                    \"internal_default\": \"PowerSystems.calculate_IM_torque_params(A, B)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"τ_ref\",\n                    \"comment\": \"Reference torque parameter\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"B_shunt\",\n                    \"comment\": \"Susceptance Initialization Corrector Term\",\n                    \"internal_default\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_ad\",\n                    \"comment\": \"(**Do not modify.**) Equivalent d-axis reactance\",\n                    \"internal_default\": \"(1.0 / X_m + 1.0 / X_ls + 1.0 / X_lr)^(-1)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_aq\",\n                    \"comment\": \"(**Do not modify.**) Equivalent q-axis reactance\",\n                    \"internal_default\": \"X_ad\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψ_qs: stator flux in the q-axis,\\n\\tψ_ds: stator flux in the d-axis,\\n\\tψ_qr: rotor flux in the q-axis,\\n\\tψ_dr: rotor flux in the d-axis, \\n\\tωr: Rotor speed [pu],\",\n                    \"internal_default\": \"[:ψ_qs, :ψ_ds, :ψ_qr, :ψ_dr, :ωr]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SingleCageInductionMachine has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"SimplifiedSingleCageInductionMachine\",\n            \"docstring\": \"Parameters of 3-states three-phase single cage induction machine with quadratic torque-speed relationship\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"R_s\",\n                    \"comment\": \"Armature stator resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_r\",\n                    \"comment\": \"Rotor resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_ls\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Stator Leakage Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_lr\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Rotor Leakage Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_m\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Stator-Rotor Mutual Reactance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Motor Inertia Constant [s]\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"A\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Torque-Speed Quadratic Term\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"B\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Torque-Speed Linear Term\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 100.0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"C\",\n                    \"comment\": \"(**Do not modify.**) Torque-Speed Constant Term\",\n                    \"internal_default\": \"PowerSystems.calculate_IM_torque_params(A, B)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"τ_ref\",\n                    \"comment\": \"Reference torque parameter\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"B_shunt\",\n                    \"comment\": \"Susceptance Initialization Corrector Term\",\n                    \"internal_default\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_ss\",\n                    \"comment\": \"(**Do not modify.**) Stator self reactance\",\n                    \"internal_default\": \"X_ls + X_m\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_rr\",\n                    \"comment\": \"(**Do not modify.**) Rotor self reactance\",\n                    \"internal_default\": \"X_lr + X_m\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_p\",\n                    \"comment\": \"(**Do not modify.**) Transient reactance\",\n                    \"internal_default\": \"X_ss - X_m^2 / X_rr\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψ_qr: rotor flux in the q-axis,\\n\\tψ_dr: rotor flux in the d-axis, \\n\\tωr: Rotor speed [pu],\",\n                    \"internal_default\": \"[:ψ_qr, :ψ_dr, :ωr]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SimplifiedSingleCageInductionMachine has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"DynamicExponentialLoad\",\n            \"docstring\": \"Parameters of 2-states of a generic dynamic load model based on [\\\"Voltage stability analysis using generic dynamic load models.\\\"](https://doi.org/10.1109/59.317575)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"a\",\n                    \"comment\": \"Active power static exponential coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"b\",\n                    \"comment\": \"Reactive power static exponential coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"α\",\n                    \"comment\": \"Active power transient exponential coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"β\",\n                    \"comment\": \"Reactive power transient exponential coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_p\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Active Power Time Constant\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_q\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactive Power Time Constant\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the load (MVA) for [per unitization](@ref per_unit)\",\n                    \"internal_default\": \"100.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p: Integrator state of the active power,\\n\\tx_q: Integrator state of the reactive power,\",\n                    \"internal_default\": \"[:x_p, :x_q]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) DynamicExponentialLoad has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"ActiveConstantPowerLoad\",\n            \"docstring\": \"Parameters of 12-[states](@ref S) active power load based on the paper, [\\\"Dynamic Stability of a Microgrid With an Active Load.\\\"](https://doi.org/10.1109/TPEL.2013.2241455)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"r_load\",\n                    \"comment\": \"DC-side resistor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"c_dc\",\n                    \"comment\": \"DC-side capacitor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rf\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Converter side filter resistance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lf\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Converter side filter inductance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"cf\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"AC Converter filter capacitance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rg\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Network side filter resistance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lg\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Network side filter inductance\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kp_pll\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Proportional constant for PI-PLL block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ki_pll\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Integral constant for PI-PLL block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kpv\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Proportional constant for Voltage Control block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kiv\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Integral constant for Voltage Control block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kpc\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Proportional constant for Current Control block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kic\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Integral constant for Current Control block\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 100.0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference active power (pu)\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reference reactive power (pu)\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference voltage (pu)\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"ω_ref\",\n                    \"comment\": \"Reference frequency (pu)\",\n                    \"internal_default\": \"1.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"is_filter_differential\",\n                    \"comment\": \"Boolean to decide if filter [states](@ref S) are differential or algebraic\",\n                    \"internal_default\": \"1\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tθ_pll: PLL deviation angle, \\n\\tϵ_pll: PLL integrator state, \\n\\tη: DC-voltage controller integrator state, \\n\\tv_dc: DC voltage at the capacitor, \\n\\tγd: d-axis Current controller integrator state, \\n\\tγq: q-axis Current controller integrator state, \\n\\tir_cnv: Real current out of the converter,\\n\\tii_cnv: Imaginary current out of the converter,\\n\\tvr_filter: Real voltage at the filter's capacitor,\\n\\tvi_filter: Imaginary voltage at the filter's capacitor,\\n\\tir_filter: Real current out of the filter,\\n\\tii_filter: Imaginary current out of the filter\",\n                    \"internal_default\": \"[:θ_pll, :ϵ_pll, :η, :v_dc, :γd, :γq, :ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ActiveConstantPowerLoad has 12 states\",\n                    \"internal_default\": 12,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"InterconnectingConverter\",\n            \"docstring\": \"Interconnecting Power Converter (IPC) for transforming power from an ACBus to a DCBus\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus on the AC side of this converter\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"dc_bus\",\n                    \"comment\": \"Bus on the DC side of this converter\",\n                    \"null_value\": \"DCBus(nothing)\",\n                    \"data_type\": \"DCBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Active power (MW) on the DC side\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"active_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum output power rating of the converter (MVA)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the converter in MVA\",\n                    \"null_value\": 100.0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"dc_current\",\n                    \"comment\": \"DC current (A) on the converter\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"max_dc_current\",\n                    \"comment\": \"Maximum stable dc current limits (A)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1e8\"\n                },\n                {\n                    \"name\": \"loss_function\",\n                    \"comment\": \"Linear or quadratic loss function with respect to the converter current\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"Union{LinearCurve, QuadraticCurve}\",\n                    \"default\": \"LinearCurve(0.0)\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticInjection\"\n        },\n        {\n            \"struct_name\": \"CSVGN1\",\n            \"docstring\": \"Parameters of static shunt compensator: CSVGN1 in PSSE\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Gain in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Rmin\",\n                    \"comment\": \"Reactor minimum Mvar\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vmax\",\n                    \"comment\": \"Maximum voltage in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vmin\",\n                    \"comment\": \"Minimum voltage in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"CBase\",\n                    \"comment\": \"Capacitor (MVAR)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 100.0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"R_th\",\n                    \"comment\": \"Source Thevenin resistance\",\n                    \"internal_default\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"X_th\",\n                    \"comment\": \"Source Thevenin reactance\",\n                    \"internal_default\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tthy: thyristor,\\n\\tvr1: regulator output 1,\\n\\tvr2: regulator output 2\",\n                    \"internal_default\": \"[:thy, :vr1, :vr2]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) CSVGN1 has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"HydroDispatch\",\n            \"docstring\": \"A hydropower generator without a reservoir, suitable for modeling run-of-river hydropower.\\n\\nFor hydro generators with an upper reservoir, see [`HydroReservoir`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.HY\",\n                    \"data_type\": \"PrimeMovers\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"ramp_limits\",\n                    \"comment\": \"ramp up and ramp down limits in MW/min\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"time_limits\",\n                    \"comment\": \"Minimum up and Minimum down time limits in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"default\": \"false\",\n                    \"name\": \"status\",\n                    \"comment\": \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"INFINITE_TIME\",\n                    \"default\": \"INFINITE_TIME\",\n                    \"name\": \"time_at_status\",\n                    \"comment\": \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"HydroGenerationCost(nothing)\",\n                    \"data_type\": \"Union{HydroGenerationCost, MarketBidCost}\",\n                    \"default\": \"HydroGenerationCost(nothing)\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"HydroGen\"\n        },\n        {\n            \"struct_name\": \"HydroTurbine\",\n            \"docstring\": \"A hydropower generator that must have a [`HydroReservoir`](@ref) attached, suitable for modeling independent turbines and reservoirs.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"HydroGenerationCost(nothing)\",\n                    \"data_type\": \"Union{HydroGenerationCost, MarketBidCost}\",\n                    \"default\": \"HydroGenerationCost(nothing)\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"powerhouse_elevation\",\n                    \"comment\": \"Height level in meters above the sea level of the powerhouse on which the turbine is installed.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ramp_limits\",\n                    \"comment\": \"ramp up and ramp down limits in MW/min\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"default\": \"nothing\",\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"time_limits\",\n                    \"comment\": \"Minimum up and Minimum down time limits in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"outflow_limits\",\n                    \"comment\": \"Turbine outflow limits in m3/s. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"efficiency\",\n                    \"comment\": \"Turbine efficiency [0, 1.0]\",\n                    \"null_value\": \"1.0\",\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"turbine_type\",\n                    \"comment\": \"Type of the turbine\",\n                    \"null_value\": \"HydroTurbineType.UNKNOWN\",\n                    \"data_type\": \"HydroTurbineType\",\n                    \"default\": \"HydroTurbineType.UNKNOWN\"\n                },\n                {\n                    \"name\": \"conversion_factor\",\n                    \"comment\": \"Conversion factor from flow/volume to energy: m^3 -> p.u-hr\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\",\n                    \"default\": \"PrimeMovers.HY\"\n                },\n                {\n                    \"name\": \"travel_time\",\n                    \"comment\": \"Downstream (from reservoir into turbine) travel time in hours.\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"HydroUnit\"\n        },\n        {\n            \"struct_name\": \"HydroPumpTurbine\",\n            \"docstring\": \"A hydropower pumped turbine that needs to have two [`HydroReservoir`](@ref)s attached, suitable for modeling independent pumped hydro with reservoirs.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the turbine unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW) for the turbine\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits_pump\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW) for the pump\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"outflow_limits\",\n                    \"comment\": \"Turbine/Pump outflow limits in m3/s. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\"\n                },\n                {\n                    \"name\": \"powerhouse_elevation\",\n                    \"comment\": \"Height level in meters above the sea level of the powerhouse on which the turbine is installed.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ramp_limits\",\n                    \"comment\": \"ramp up and ramp down limits in MW/min\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"time_limits\",\n                    \"comment\": \"Minimum up and Minimum down time limits in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n\n                    \"null_value\": \"PumpHydroStatus.OFF\",\n                    \"default\": \"PumpHydroStatus.OFF\",\n                    \"name\": \"status\",\n                    \"comment\": \"Initial Operating status of a pumped‑storage hydro unit. See [PumpHydroStatus](@ref) for reference\",\n                    \"data_type\": \"PumpHydroStatus\"\n                },\n                {\n                    \"null_value\": \"INFINITE_TIME\",\n                    \"default\": \"INFINITE_TIME\",\n                    \"name\": \"time_at_status\",\n                    \"comment\": \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"HydroGenerationCost(nothing)\",\n                    \"data_type\": \"Union{HydroGenerationCost, MarketBidCost}\",\n                    \"default\": \"HydroGenerationCost(nothing)\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"active_power_pump\",\n                    \"comment\": \"Initial active power set point of the pump unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"efficiency\",\n                    \"comment\": \"Turbine/Pump efficiency [0, 1.0]\",\n                    \"null_value\": \"(turbine = 1.0, pump = 1.0)\",\n                    \"default\": \"(turbine = 1.0, pump = 1.0)\",\n                    \"data_type\": \"TurbinePump\"\n                },\n                {\n                    \"name\": \"transition_time\",\n                    \"comment\": \"Transition time in hours to switch into the specific mode.\",\n                    \"null_value\": \"(turbine = 0.0, pump = 0.0)\",\n                    \"data_type\": \"TurbinePump\",\n                    \"default\": \"(turbine = 0.0, pump = 0.0)\"\n                },\n                {\n                    \"name\": \"minimum_time\",\n                    \"comment\": \"Minimum operating time in hours for the specific mode.\",\n                    \"null_value\": \"(turbine = 0.0, pump = 0.0)\",\n                    \"data_type\": \"TurbinePump\",\n                    \"default\": \"(turbine = 0.0, pump = 0.0)\"\n                },\n                {\n                    \"name\": \"travel_time\",\n                    \"comment\": \"Downstream (from reservoir into turbine) travel time in hours.\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"conversion_factor\",\n                    \"comment\": \"Conversion factor from flow/volume to energy: m^3 -> p.u-hr\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"must_run\",\n                    \"comment\": \"Whether the unit must run (i.e., cannot be curtailed)\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"false\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\",\n                    \"default\": \"PrimeMovers.PS\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"HydroUnit\"\n        },\n        {\n            \"struct_name\": \"HydroReservoir\",\n            \"docstring\": \"A hydropower reservoir that have attached [`HydroTurbine`](@ref)(s) or [`HydroPumpTurbine`](@ref)(s) used to generate power.\\nSee [How to Define Hydro Generators with Reservoirs](@ref hydro_resv) for supported configurations.\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"storage_level_limits\",\n                    \"comment\": \"Storage level limits for the reservoir in m^3, m, or MWh, based on the [`ReservoirDataType`](@ref  hydroreservoir_list) selected for `level_data_type`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"initial_level\",\n                    \"comment\": \"Initial level of the reservoir relative to the `storage_level_limits.max`.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"spillage_limits\",\n                    \"comment\": \"Amount of water allowed to be spilled from the reservoir. If nothing, infinite spillage is allowed.\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\"\n                },\n                {\n                    \"name\": \"inflow\",\n                    \"comment\": \"Amount of water refilling the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"outflow\",\n                    \"comment\": \"Amount of water naturally going out of the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"level_targets\",\n                    \"comment\": \"Reservoir level targets at the end of a simulation as a fraction of the `storage_level_limits.max`.\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, Float64}\"\n                },\n                {\n                    \"name\": \"intake_elevation\",\n                    \"comment\": \"Height of the intake of the reservoir, towards the downstream turbines, in meters above the sea level.\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"head_to_volume_factor\",\n                    \"comment\": \"Head to volume relationship for the reservoir.\",\n                    \"null_value\": \"LinearCurve(0.0)\",\n                    \"data_type\": \"ValueCurve\"\n                },\n                {\n                    \"name\": \"upstream_turbines\",\n                    \"null_value\": \"Device[]\",\n                    \"data_type\": \"Vector{HydroUnit}\",\n                    \"default\": \"Device[]\",\n                    \"comment\": \"Vector of [HydroUnit](@ref)(s) that are immediately upstream of this reservoir. This reservoir is the tail reservoir for these units, and their flow goes into this reservoir.\"\n                },\n                {\n                    \"name\": \"downstream_turbines\",\n                    \"null_value\": \"Device[]\",\n                    \"data_type\": \"Vector{HydroUnit}\",\n                    \"default\": \"Device[]\",\n                    \"comment\": \"Vector of [HydroUnit](@ref)(s) that are immediately downstream of this reservoir. This reservoir is the head reservoir for these units, and its feed flow into these units.\"\n                },\n                {\n                    \"name\": \"upstream_reservoirs\",\n                    \"null_value\": \"Device[]\",\n                    \"data_type\": \"Vector{Device}\",\n                    \"default\": \"Device[]\",\n                    \"comment\": \"Vector of [Device](@ref)(s) reservoirs that are immediately upstream of this reservoir. This reservoir receives the spillage flow from upstream_reservoirs.\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"HydroReservoirCost(nothing)\",\n                    \"data_type\": \"HydroReservoirCost\",\n                    \"default\": \"HydroReservoirCost(nothing)\",\n                    \"comment\": \"[`OperationalCost`](@ref) of reservoir.\"\n                },\n                {\n                    \"name\": \"level_data_type\",\n                    \"null_value\": \"ReservoirDataType.USABLE_VOLUME\",\n                    \"data_type\": \"ReservoirDataType\",\n                    \"default\": \"ReservoirDataType.USABLE_VOLUME\",\n                    \"comment\": \"Reservoir level data type. See [ReservoirDataType](@ref) for reference.\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Device\"\n        },\n        {\n            \"struct_name\": \"RenewableDispatch\",\n            \"docstring\": \"A renewable (e.g., wind or solar) generator whose output can be curtailed to satisfy power system constraints.\\n\\nThese generators can also participate in reserves markets, including upwards reserves by proactively curtailing some available power (based on its [`max_active_power` time series](@ref ts_data)). Example uses include: a utility-scale wind or solar generator whose PPA allows curtailment. For non-curtailable or must-take renewables, see [`RenewableNonDispatch`](@ref).\\n\\nRenewable generators do not have a `max_active_power` parameter, which is instead calculated when calling [`get_max_active_power()`](@ref get_max_active_power(d::T) where {T <: RenewableGen})\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits, used in some production cost model simulations and in power flow if the unit is connected to a [`PV`](@ref acbustypes_list) bus. Set to `nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"power_factor\",\n                    \"comment\": \"Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"RenewableGenerationCost(nothing)\",\n                    \"data_type\": \"Union{RenewableGenerationCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"RenewableGen\"\n        },\n        {\n            \"struct_name\": \"RenewableNonDispatch\",\n            \"docstring\": \"A non-dispatchable (i.e., non-curtailable or must-take) renewable generator.\\n\\nIts output is equal to its [`max_active_power` time series](@ref ts_data) by default. Example use: an aggregation of behind-the-meter distributed energy resources like rooftop solar. For curtailable or downward dispatachable generation, see [`RenewableDispatch`](@ref).\\n\\nRenewable generators do not have a `max_active_power` parameter, which is instead calculated when calling [`get_max_active_power()`](@ref get_max_active_power(d::T) where {T <: RenewableGen})\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\"\n                },\n                {\n                    \"name\": \"power_factor\",\n                    \"comment\": \"Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"RenewableGen\"\n        },\n        {\n            \"struct_name\": \"ThermalStandard\",\n            \"docstring\": \"A thermal generator, such as a fossil fuel and nuclear generator.\\n\\nThis is a standard representation with options to include a minimum up time, minimum down time, and ramp limits. For a more detailed representation the start-up and shut-down processes, including hot starts, see [`ThermalMultiStart`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"status\",\n                    \"comment\": \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"active_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"ramp_limits\",\n                    \"comment\": \"ramp up and ramp down limits in MW/min\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"ThermalGenerationCost(nothing)\",\n                    \"data_type\": \"Union{ThermalGenerationCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"time_limits\",\n                    \"comment\": \"Minimum up and Minimum down time limits in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"must_run\",\n                    \"comment\": \"Set to `true` if the unit is must run\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"false\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\",\n                    \"default\": \"PrimeMovers.OT\"\n                },\n                {\n                    \"name\": \"fuel\",\n                    \"comment\": \"Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\",\n                    \"null_value\": \"ThermalFuels.OTHER\",\n                    \"data_type\": \"ThermalFuels\",\n                    \"default\": \"ThermalFuels.OTHER\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"null_value\": \"INFINITE_TIME\",\n                    \"name\": \"time_at_status\",\n                    \"comment\": \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"INFINITE_TIME\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ThermalGen\"\n        },\n        {\n            \"struct_name\": \"SynchronousCondenser\",\n            \"docstring\": \"A Synchronous Machine connected to the system to provide inertia or reactive power support\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"active_power_losses\",\n                    \"comment\": \"Active Power Loss incurred by having the unit online.\",\n                    \"null_value\": \"0.0\",\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticInjection\"\n        },\n        {\n            \"struct_name\": \"ThermalMultiStart\",\n            \"docstring\": \"A thermal generator, such as a fossil fuel or nuclear generator, that can start-up again from a *hot*, *warm*, or *cold* state.\\n\\n`ThermalMultiStart` has a detailed representation of the start-up process based on the time elapsed since the last shut down, as well as a detailed shut-down process. The model is based on [\\\"Tight and Compact MILP Formulation for the Thermal Unit Commitment Problem.\\\"](https://doi.org/10.1109/TPWRS.2013.2251373). For a simplified representation of the start-up and shut-down processes, see [`ThermalStandard`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"status\",\n                    \"comment\": \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"active_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.OT\",\n                    \"data_type\": \"PrimeMovers\"\n                },\n                {\n                    \"name\": \"fuel\",\n                    \"comment\": \"Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\",\n                    \"null_value\": \"ThermalFuels.OTHER\",\n                    \"data_type\": \"ThermalFuels\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"ramp_limits\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"power_trajectory\",\n                    \"comment\": \"Power trajectory the unit will take during the start-up and shut-down ramp process\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, StartUpShutDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"time_limits\",\n                    \"comment\": \"Minimum up and Minimum down time limits in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, UpDown}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"start_time_limits\",\n                    \"comment\": \"Time limits for start-up based on turbine temperature in hours\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, StartUpStages}\"\n                },\n                {\n                    \"name\": \"start_types\",\n                    \"comment\": \"Number of start-up based on turbine temperature, where `1` = *hot*, `2` = *warm*, and `3` = *cold*\",\n                    \"null_value\": \"1\",\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 3\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"ThermalGenerationCost(nothing)\",\n                    \"data_type\": \"Union{ThermalGenerationCost, MarketBidCost}\",\n                    \"comment\": \"[`OperationalCost`](@ref) of generation\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"time_at_status\",\n                    \"comment\": \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\",\n                    \"null_value\": \"INFINITE_TIME\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"INFINITE_TIME\"\n                },\n                {\n                    \"name\": \"must_run\",\n                    \"comment\": \"Set to `true` if the unit is must run\",\n                    \"null_value\": \"false\",\n                    \"data_type\": \"Bool\",\n                    \"default\": \"false\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ThermalGen\"\n        },\n        {\n            \"struct_name\": \"EnergyReservoirStorage\",\n            \"docstring\": \"An energy storage device, modeled as a generic energy reservoir.\\n\\nThis is suitable for modeling storage charging and discharging with average efficiency losses, ignoring the physical dynamics of the storage unit. A variety of energy storage types and chemistries can be modeled with this approach. For pumped hydro storage, alternatively see [`HydroPumpTurbine`](@ref) and [`HydroReservoir`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"prime_mover_type\",\n                    \"comment\": \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\",\n                    \"null_value\": \"PrimeMovers.BA\",\n                    \"data_type\": \"PrimeMovers\"\n                },\n                {\n                    \"name\": \"storage_technology_type\",\n                    \"comment\": \"Storage Technology Complementary to EIA 923. Options are listed [here](@ref storagetech_list)\",\n                    \"null_value\": \"StorageTech.OTHER_CHEM\",\n                    \"data_type\": \"StorageTech\"\n                },\n                {\n                    \"name\": \"storage_capacity\",\n                    \"comment\": \"Maximum storage capacity (can be in units of, e.g., MWh for batteries or liters for hydrogen). When in MWh, this value divided by base_power (MVA) gives an approximate duration in hours, assuming unity power factor. For understanding this relationship, see [per unitization](@ref per_unit)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"storage_level_limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"comment\": \"Minimum and maximum allowable storage levels [0, 1], which can be used to model derates or other restrictions, such as state-of-charge restrictions on battery cycling\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"initial_storage_capacity_level\",\n                    \"null_value\": \"0.0\",\n                    \"comment\": \"Initial storage capacity level as a ratio [0, 1.0] of `storage_capacity`\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"rating\",\n                    \"comment\": \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"input_active_power_limits\",\n                    \"comment\": \"Minimum and maximum limits on the input active power (i.e., charging)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"output_active_power_limits\",\n                    \"comment\": \"Minimum and maximum limits on the output active power (i.e., discharging)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"efficiency\",\n                    \"comment\": \"Average efficiency [0, 1] `in` (charging/filling) and `out` (discharging/consuming) of the storage system\",\n                    \"null_value\": \"(in=0.0, out=0.0)\",\n                    \"data_type\": \"NamedTuple{(:in, :out), Tuple{Float64, Float64}}\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": \"reactive_power_limits\",\n                    \"validation_action\": \"warn\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": \"100.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1e-4,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"comment\": \"[`OperationalCost`](@ref) of storage\",\n                    \"null_value\": \"StorageCost(nothing)\",\n                    \"data_type\": \"Union{StorageCost, MarketBidCost}\",\n                    \"default\": \"StorageCost(nothing)\"\n                },\n                {\n                    \"name\": \"conversion_factor\",\n                    \"comment\": \"Conversion factor of `storage_capacity` to MWh, if different than 1.0. For example, X MWh/liter hydrogen\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"storage_target\",\n                    \"comment\": \"Storage target at the end of simulation as ratio of storage capacity\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"cycle_limits\",\n                    \"comment\": \"Storage Maximum number of cycles per year\",\n                    \"null_value\": \"0\",\n                    \"data_type\": \"Int\",\n                    \"default\": \"1e4\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Storage\"\n        },\n        {\n            \"struct_name\": \"ConstantReserve\",\n            \"docstring\": \"A reserve product with a constant procurement requirement, such as 3% of the system base power at all times.\\n\\nThis reserve product includes online generators that can respond right away after an unexpected contingency, such as a transmission line or generator outage. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\",\n            \"parametric\": \"ReserveDirection\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"time_frame\",\n                    \"comment\": \"the saturation time_frame in minutes to provide reserve contribution\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"requirement\",\n                    \"comment\": \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"sustained_time\",\n                    \"comment\": \"the time in seconds reserve contribution must sustained at a specified level\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"3600.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_output_fraction\",\n                    \"comment\": \"the maximum fraction of each device's output that can be assigned to the service\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_participation_factor\",\n                    \"comment\": \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"deployed_fraction\",\n                    \"comment\": \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Reserve{T}\"\n        },\n        {\n            \"struct_name\": \"ConstantReserveNonSpinning\",\n            \"docstring\": \"A non-spinning reserve product with a constant procurement requirement, such as 3% of the system base power at all times.\\n\\nThis reserve product includes back-up generators that might not be currently synchronized with the power system, but can come online quickly after an unexpected contingency, such as a transmission line or generator outage. This is only an upwards reserve. For faster-responding upwards or downwards reserves from components already synchronized with the system, see [`ConstantReserve`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"time_frame\",\n                    \"comment\": \"the saturation time frame in minutes that a participating device must provide its reserve contribution\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"requirement\",\n                    \"comment\": \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"sustained_time\",\n                    \"comment\": \"the time in seconds reserve contribution must sustained at a specified level\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"3600.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_output_fraction\",\n                    \"comment\": \"the maximum fraction of each device's output that can be assigned to the service\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_participation_factor\",\n                    \"comment\": \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"deployed_fraction\",\n                    \"comment\": \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ReserveNonSpinning\"\n        },\n        {\n            \"struct_name\": \"ConstantReserveGroup\",\n            \"docstring\": \"A reserve product met by a group of individual reserves.\\n\\nThe group reserve requirement is added in addition to any individual reserve requirements, and devices that contribute to individual reserves within the group can also contribute to the overarching group reserve requirement. Example: A group of spinning and non-spinning reserves, where online generators providing spinning reserves can also contribute to the non-spinning reserve requirement.\\n\\nThis model has a constant procurement requirement, such as 3% of the system base power at all times. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\",\n            \"parametric\": \"ReserveDirection\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"requirement\",\n                    \"comment\": \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"contributing_services\",\n                    \"comment\": \"Services that contribute to this group requirement. Services must be added for this constraint to have an effect when conducting simulations in [`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/latest/)\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"null_value\": \"Vector{Service}()\",\n                    \"default\": \"Vector{Service}()\",\n                    \"exclude_setter\": true\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Service\"\n        },\n        {\n            \"struct_name\": \"ReserveDemandCurve\",\n            \"docstring\": \"A reserve product with an [Operating Reserve Demand Curve (ORDC)](https://hepg.hks.harvard.edu/files/hepg/files/ordcupdate-final.pdf) for operational simulations.\\n\\nThe ORDC is modeled as a discretized set of `(Reserve capacity (MW), Price (\\\\$/MWh))` steps, which can vary with time. Use [`set_variable_cost!`](@ref) to define the ORDCs.\\n\\nWhen defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\",\n            \"parametric\": \"ReserveDirection\",\n            \"fields\": [\n                {\n                    \"name\": \"variable\",\n                    \"comment\": \"Create this object with `variable` = `nothing`, then add assign a cost curve or time-series of `variable_cost` using the [`set_variable_cost!`](@ref) function, which will automatically update this parameter\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, TimeSeriesKey, CostCurve{PiecewiseIncrementalCurve}}\"\n                },\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"time_frame\",\n                    \"comment\": \"the saturation time_frame in minutes to provide reserve contribution\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"sustained_time\",\n                    \"comment\": \"the time in seconds that the reserve contribution must sustained at a specified level\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"3600.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_participation_factor\",\n                    \"comment\": \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"deployed_fraction\",\n                    \"comment\": \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Reserve{T}\"\n        },\n        {\n            \"struct_name\": \"VariableReserve\",\n            \"docstring\": \"A reserve product with a time-varying procurement requirement, such as a higher requirement during hours with an expected high load or high ramp.\\n\\nThis reserve product includes online generators that can respond right away after an unexpected contingency, such as a transmission line or generator outage. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref). To model the time varying requirement, a [\\\"`requirement`\\\" time series should be added](@ref ts_data) to this reserve\",\n            \"parametric\": \"ReserveDirection\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"time_frame\",\n                    \"comment\": \"the saturation time_frame in minutes to provide reserve contribution\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"requirement\",\n                    \"comment\": \"the required quantity of the product should be scaled by a TimeSeriesData\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"sustained_time\",\n                    \"comment\": \"the time in seconds reserve contribution must sustained at a specified level\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"3600.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_output_fraction\",\n                    \"comment\": \"the maximum fraction of each device's output that can be assigned to the service\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_participation_factor\",\n                    \"comment\": \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"deployed_fraction\",\n                    \"comment\": \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Reserve{T}\"\n        },\n        {\n            \"struct_name\": \"VariableReserveNonSpinning\",\n            \"docstring\": \"A non-spinning reserve product with a time-varying procurement requirement, such as a higher requirement during hours with an expected high load or high ramp.\\n\\nThis reserve product includes back-up generators that might not be currently synchronized with the power system, but can come online quickly after an unexpected contingency, such as a transmission line or generator outage. To model the time varying requirement, a [\\\"`requirement`\\\" time series should be added](@ref ts_data) to this reserve.\\n\\nThis is only an upwards reserve. For faster-responding upwards or downwards reserves from components already synchronized with the system, see [`VariableReserve`](@ref)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"time_frame\",\n                    \"comment\": \"the saturation time_frame in minutes to provide reserve contribution\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"requirement\",\n                    \"comment\": \"the required quantity of the product should be scaled by a TimeSeriesData\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"sustained_time\",\n                    \"comment\": \"the time in seconds reserve contribution must sustained at a specified level\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"14400.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_output_fraction\",\n                    \"comment\": \"the maximum fraction of each device's output that can be assigned to the service\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"max_participation_factor\",\n                    \"comment\": \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\",\n                    \"null_value\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"1.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"deployed_fraction\",\n                    \"comment\": \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"default\": \"0.0\",\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"ReserveNonSpinning\"\n        },\n        {\n            \"struct_name\": \"AGC\",\n            \"docstring\": \"Automatic generation control (AGC) for the system or a certain `Area` within the system.\\n\\nThis model uses a proportional–integral–derivative (PID) control to simulate a \\\"smooth\\\" response of the AGC to the area control error (ACE). Refer to [\\\"AGC Simulation Model for Large Renewable Energy Penetration Studies.\\\"](https://doi.org/10.1109/NAPS50074.2021.9449687)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bias\",\n                    \"comment\": \"Area frequency bias in MW/Hz\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"K_p\",\n                    \"comment\": \"PID Proportional Constant\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"K_i\",\n                    \"comment\": \"PID Integral Constant\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"K_d\",\n                    \"comment\": \"PID Derivative Constant\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"delta_t\",\n                    \"comment\": \"PID Discretization period [Seconds]\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"area\",\n                    \"comment\": \"the area controlled by the AGC\",\n                    \"null_value\": \"Area(nothing)\",\n                    \"data_type\": \"Union{Nothing, Area}\",\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"initial_ace\",\n                    \"comment\": \"Initial condition for ACE\",\n                    \"default\": \"0.0\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"reserves\",\n                    \"data_type\": \"Vector{Reserve}\",\n                    \"comment\": \"Reserves that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Service\"\n        },\n        {\n            \"struct_name\": \"AVRFixed\",\n            \"docstring\": \"Parameters of a AVR that returns a fixed voltage to the rotor winding\",\n            \"fields\": [\n                {\n                    \"name\": \"Vf\",\n                    \"comment\": \"Fixed voltage field applied to the rotor winding in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\",\n                    \"null_value\": 0,\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{StateTypes}()\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"AVRSimple\",\n            \"docstring\": \"Parameters of a simple proportional AVR in the derivative of EMF\\ni.e. an integrator controller on EMF\",\n            \"fields\": [\n                {\n                    \"name\": \"Kv\",\n                    \"comment\": \"Proportional Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVf: field voltage\",\n                    \"internal_default\": \"[:Vf]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) Fixed AVR has 1 [state](@ref S)\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) Simple AVR has 1 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"SEXS\",\n            \"docstring\": \"Parameters of Simplified Excitation System Model - SEXS in PSSE\",\n            \"fields\": [\n                {\n                    \"name\": \"Ta_Tb\",\n                    \"comment\": \"Ratio of lead and lag time constants\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Lag time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Field circuit time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_lim\",\n                    \"comment\": \"Field voltage limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\tVf: Voltage field,\\tVr: Lead-lag state\",\n                    \"internal_default\": \"[:Vf, :Vr]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SEXS has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) SEXS has 2 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESDC1A\",\n            \"docstring\": \"Self-excited shunt fields with the voltage regulator operating in a mode commonly termed buck-boost. \\nParameters of IEEE Std 421.5 Type DC1A Excitacion System. This model corresponds to ESDC1A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Amplifier Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 10,\n                        \"max\": 500\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Amplifier Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator input Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator input Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter constant related to self-excited field\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter time constant, integration rate associated with exciter control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Excitation control system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Excitation control system stabilizer time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"switch\",\n                    \"comment\": \"Switch\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVt: Terminal Voltage,\\n\\tVr1: input lead lag,\\n\\tVr2: Regulator Output,\\n\\tVf: Exciter Output, \\n\\tVr3: Rate feedback integrator\",\n                    \"internal_default\": \"[:Vt, :Vr1, :Vr2, :Vf, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The ESDC1A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ESDC1A has 5 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESDC2A\",\n            \"docstring\": \"Is used to represent field-controlled dc commutator exciters with continuously acting voltage regulators having power supplies derived from the generator or auxiliaries bus.\\nParameters of IEEE Std 421.5 Type DC2A Excitacion System. This model corresponds to ESDC2A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Amplifier Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 10,\n                        \"max\": 500\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Amplifier Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator input Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator input Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter constant related to self-excited field\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter time constant, integration rate associated with exciter control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Excitation control system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Excitation control system stabilizer time constant. Appropiate Data: 5.0 <= Tf/Kf <= 15.0\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"switch\",\n                    \"comment\": \"Switch\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVt: Terminal Voltage,\\n\\tVr1: input lead lag,\\n\\tVr2: Regulator Output,\\n\\tVf: Exciter Output, \\n\\tVr3: Rate feedback integrator\",\n                    \"internal_default\": \"[:Vt, :Vr1, :Vr2, :Vf, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The ESDC2A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ESDC2A has 5 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"IEEET1\",\n            \"docstring\": \"1968 IEEE type 1 excitation system model\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Amplifier Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 10,\n                        \"max\": 500\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Amplifier Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter constant related to self-excited field\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter time constant, integration rate associated with exciter control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Excitation control system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Excitation control system stabilizer time constant. Appropiate Data: 5 <= Tf/Kf <= 15\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"switch\",\n                    \"comment\": \"Switch\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVt: Terminal Voltage,\\n\\tVr: Regulator Output,\\n\\tVf: Exciter Output, \\n\\tVr3: Rate feedback integrator\",\n                    \"internal_default\": \"[:Vt, :Vr1, :Vf, :Vr2]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The IEEET1 has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEET1 I has 4 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"AVRTypeI\",\n            \"docstring\": \"Parameters of an Automatic Voltage Regulator Type I - Resembles IEEE Type DC1\",\n            \"fields\": [\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Amplifier Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Field circuit integral deviation\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Stabilizer Gain in s * pu/pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Amplifier Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Field Circuit Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Stabilizer Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for pi controler `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ae\",\n                    \"comment\": \"1st ceiling coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Be\",\n                    \"comment\": \"2nd ceiling coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVf: Voltage field,\\n\\tVr1: Amplifier State,\\n\\tVr2: Stabilizing Feedback State,\\n\\tVm: Measured voltage\",\n                    \"internal_default\": \"[:Vf, :Vr1, :Vr2, :Vm]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The AVR Type I has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) AVR Type I has 4 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"AVRTypeII\",\n            \"docstring\": \"Parameters of an Automatic Voltage Regulator Type II -  Typical static exciter model\",\n            \"fields\": [\n                {\n                    \"name\": \"K0\",\n                    \"comment\": \"Regulator Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"First Pole in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"First zero in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"First Pole in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"First zero in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Field Circuit Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for pi controler `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ae\",\n                    \"comment\": \"1st ceiling coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Be\",\n                    \"comment\": \"2nd ceiling coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVf: Voltage field,\\n\\tVr1: First Lead-Lag state,\\n\\tVr2: Second lead-lag state,\\n\\tVm: Measured voltage\",\n                    \"internal_default\": \"[:Vf, :Vr1, :Vr2, :Vm]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) AVR Type II has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) AVR Type II has 4 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"SCRX\",\n            \"docstring\": \"This exciter is based on an IEEE type SCRX solid state exciter.  The output field voltage is varied by a control system to maintain the system voltage at Vref.  Please note that this exciter model has no initialization capabilities - this means that it will respond to whatever inputs it receives regardless of the state of the machine model\",\n            \"fields\": [\n                {\n                    \"name\": \"Ta_Tb\",\n                    \"comment\": \"Lead input constant ratio\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.05,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Lag input constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 5,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Regulator Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 20,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Regulator Time Constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Efd_lim\",\n                    \"comment\": \"Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"switch\",\n                    \"comment\": \"Switch\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"rc_rfd\",\n                    \"comment\": \"Field current capability. Set = 0 for negative current capability. Typical value 10\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVr1: First integrator,\\n\\tVr2: Second integrator\",\n                    \"internal_default\": \"[:Vr1, :Vr2]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SCRX has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) SCRX has 2 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESAC1A\",\n            \"docstring\": \"This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\\nParameters of IEEE Std 421.5 Type AC1A Excitacion System. This model corresponds to ESAC1A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator numerator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    }\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for regulator output `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback excitation system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Rate feedback time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Demagnetizing factor, function of exciter alternator reactances\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter field voltage: `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: Lead-lag state,\\n\\tVr2: Regulator output state,\\n\\tVe: Integrator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Ve, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ESAC1A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ESAC1A has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EXAC1A\",\n            \"docstring\": \"Modified ESAC1A. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\\nParameters of IEEE Std 421.5 Type AC1A Excitacion System. EXAC1A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator numerator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    }\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for regulator output `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback excitation system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Rate feedback time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Demagnetizing factor, function of exciter alternator reactances\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter field voltage: `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: Lead-lag state,\\n\\tVr2: Regulator output state,\\n\\tVe: Integrator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Ve, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) EXAC1A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) EXAC1A has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EXAC1\",\n            \"docstring\": \"Modified ESAC1A. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\\nParameters of IEEE Std 421.5 Type AC1A.  EXAC1 in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator numerator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    }\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for regulator output `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback excitation system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Rate feedback time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Demagnetizing factor, function of exciter alternator reactances\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: Lead-lag state,\\n\\tVr2: Regulator output state,\\n\\tVe: Integrator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Ve, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) EXAC1 has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) EXAC1 has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EXAC2\",\n            \"docstring\": \"Modified AC2. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\\nParameters of IEEE Std 421.5 Type AC2A Excitacion System. The alternator main exciter is used, feeding its output via non-controlled rectifiers. The Type AC2C model is similar to that of Type AC1C except for the inclusion of exciter time constant compensation and exciter field current limiting elements. EXAC2 in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator numerator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    }\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for regulator output `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kb\",\n                    \"comment\": \"Second Stage regulator gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 500\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter field voltage `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kl\",\n                    \"comment\": \"Exciter field current limiter gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kh\",\n                    \"comment\": \"Exciter field current regulator feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback excitation system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Rate feedback time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Demagnetizing factor, function of exciter alternator reactances\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_lr\",\n                    \"comment\": \"Maximum exciter field current\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: Lead-lag state,\\n\\tVr2: Regulator output state,\\n\\tVe: Integrator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Ve, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) EXAC2 has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) EXAC2 has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESAC6A\",\n            \"docstring\": \"Modified AC6A. Used to represent field-controlled alternator-rectifier excitation systems with system-supplied electronic voltage regulators. \\nParameters of IEEE Std 421.5 Type AC6A Excitacion System. ESAC6A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output lag time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tk\",\n                    \"comment\": \"Voltage Regulator lead time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Regulator numerator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for regulator output `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter field voltage `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"VFE_lim\",\n                    \"comment\": \"Exciter field current limiter reference\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -5,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kh\",\n                    \"comment\": \"Exciter field current regulator feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"VH_max\",\n                    \"comment\": \"Exciter field current limiter maximum output\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Th\",\n                    \"comment\": \"Exciter field current limiter denominator (lag) time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Tj\",\n                    \"comment\": \"Exciter field current limiter numerator (lead) time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Demagnetizing factor, function of exciter alternator reactances\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: Lead-lag state,\\n\\tVr2: Regulator output state,\\n\\tVe: Integrator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Ve, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ESAC6A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ESAC6A has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESAC8B\",\n            \"docstring\": \"Excitation System AC8B. Used to represent the Basler Digital Excitation Control System (DECS) with PID controller in PSSE.\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kp\",\n                    \"comment\": \"Regulator proportional PID gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki\",\n                    \"comment\": \"Regulator integral PID gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Regulator derivative PID gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Td\",\n                    \"comment\": \"Regulator derivative PID time constant.\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Regulator output gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1000\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Regulator output lag time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter field voltage `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter field time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter field proportional constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tx_i: Internal PI-block state,\\n\\tx_d: Internal Derivative-block state,\\n\\tVr: Voltage regulator state,\\n\\tEfd: Exciter output state\",\n                    \"internal_default\": \"[:Vm, :x_i, :x_d, :Vr, :Efd]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ESAC8B has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ESAC8B has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential, StateTypes.Hybrid, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESST1A\",\n            \"docstring\": \"This excitation system supplies power through a transformer from the generator terminals and its regulated by a controlled rectifier (via thyristors).\\nParameters of IEEE Std 421.5 Type ST1A Excitacion System. ESST1A in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"UEL_flags\",\n                    \"comment\": \"Code input for Underexcitization limiter (UEL) entry. Not supported\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"PSS_flags\",\n                    \"comment\": \"Code input for Power System Stabilizer (PSS) or (VOS) entry\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vi_lim\",\n                    \"comment\": \"Voltage error limits (regulator input) (Vi_min, Vi_max)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"First regulator denominator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"First regulator denominator (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    }\n                },\n                {\n                    \"name\": \"Tc1\",\n                    \"comment\": \"Second regulator denominator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb1\",\n                    \"comment\": \"Second regulator denominator (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Voltage regulator gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 50,\n                        \"max\": 1000\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for regulator output `(Va_min, Va_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Limits for exciter output `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Rate feedback time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"K_lr\",\n                    \"comment\": \"Exciter output current limiter gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"I_lr\",\n                    \"comment\": \"Exciter output current limit reference\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: First Lead-lag state,\\n\\tVr2: Second lead-lag state,\\n\\tVa: Regulator output state,\\n\\tVr3: Feedback output state\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Va, :Vr3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ST1A has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ST1A has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EXPIC1\",\n            \"docstring\": \"Generic Proportional/Integral Excitation System\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Voltage regulator gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 500\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Limits for pi controler `(Vr_min, Vr_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ta_2\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ta_3\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta_4\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Rate feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf_1\",\n                    \"comment\": \"Rate Feedback time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 15\n                    },\n                    \"validation_actions\": \"error\"\n                },\n                {\n                    \"name\": \"Tf_2\",\n                    \"comment\": \"Rate Feedback time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Efd_lim\",\n                    \"comment\": \"Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ke\",\n                    \"comment\": \"Exciter constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_sat\",\n                    \"comment\": \"Exciter output voltage for saturation factor: (E1, E2)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Kp\",\n                    \"comment\": \"Potential source gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki\",\n                    \"comment\": \"current source gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.1\n                    }\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Exciter regulation factor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"saturation_coeffs\",\n                    \"comment\": \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\",\n                    \"data_type\": \"Tuple{Float64, Float64}\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"default\": \"PowerSystems.get_avr_saturation(E_sat, Se)\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVr1: First Lead-lag state,\\n\\tVr2: Second regulator lead-lag state,\\n\\tVr2: Third regulator lead-lag state \\n\\tVf: Exciter output \\n\\tVr3: First feedback integrator,\\n\\tVr4: second feedback integrator\",\n                    \"internal_default\": \"[:Vm, :Vr1, :Vr2, :Vf, :Vr3, :Vr4]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) EXPIC1 has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) EXPIC has 6 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ESST4B\",\n            \"docstring\": \"In these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\\nParameters of IEEE Std 421.5 Type ST4B Excitacion System. ESST4B in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_pr\",\n                    \"comment\": \"Regulator propotional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 75\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_ir\",\n                    \"comment\": \"Regulator integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 75\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Voltage regulator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_pm\",\n                    \"comment\": \"Voltage regulator proportional gain output\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_im\",\n                    \"comment\": \"Voltage regulator integral gain output\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 18\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vm_lim\",\n                    \"comment\": \"Limits for inner loop output `(Vm_min, Vm_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kg\",\n                    \"comment\": \"Feedback gain constant of the inner loop field regulator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kp\",\n                    \"comment\": \"Potential circuit (voltage) gain coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki\",\n                    \"comment\": \"Compound circuit (current) gain coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"VB_max\",\n                    \"comment\": \"Maximum available exciter voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 20\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Xl\",\n                    \"comment\": \"Reactance associated with potential source\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"θp\",\n                    \"comment\": \"Potential circuit phase angle (degrees)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -90,\n                        \"max\": 90\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"θp_rad\",\n                    \"comment\": \"(**Do not modify.**) Potential circuit phase angle (radians)\",\n                    \"null_value\": 0,\n                    \"default\": \"θp*π*inv(180)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tVt: Sensed Terminal Voltage,\\n\\tVr1: Regulator Integrator,\\n\\tVr2: Regulator Output,\\n\\tVm: Output integrator\",\n                    \"internal_default\": \"[:Vt, :Vr1, :Vr2, :Vm]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ST4B has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ST4B has 4 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ST6B\",\n            \"docstring\": \"In these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\\nParameters of IEEE Std 421.5 Type ST6B Excitacion System. ST6B in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"OEL_Flag\",\n                    \"comment\": \"OEL Flag for ST6B: 1: before HV gate, 2: after HV gate\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_pa\",\n                    \"comment\": \"Regulator proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_ia\",\n                    \"comment\": \"Regulator integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_da\",\n                    \"comment\": \"Regulator derivative gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_da\",\n                    \"comment\": \"Voltage regulator derivative channel time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Regulator output limits (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"K_ff\",\n                    \"comment\": \"Pre-control gain of the inner loop field regulator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_m\",\n                    \"comment\": \"Forward gain of the inner loop field regulator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_ci\",\n                    \"comment\": \"Exciter output current limit adjustment gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_lr\",\n                    \"comment\": \"Exciter output current limiter gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"I_lr\",\n                    \"comment\": \"Exciter current limiter reference\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kg\",\n                    \"comment\": \"Feedback gain constant of the inner loop field regulator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tg\",\n                    \"comment\": \"Feedback time constant of the inner loop field voltage regulator in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tx_i: Regulator Integrator,\\n\\tx_d: Regulator Derivative,\\n\\tVg: Regulator Feedback\",\n                    \"internal_default\": \"[:Vm, :x_i, :x_d, :Vg]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ST6B has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ST6B has 4 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"ST8C\",\n            \"docstring\": \"In these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\\nParameters of IEEE Std 421.5 Type ST8C Excitacion System. ST8C in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"OEL_Flag\",\n                    \"comment\": \"OEL Flag for ST8C: <2: Summation at Voltage Error, 2: OEL takeover at gate\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"UEL_Flag\",\n                    \"comment\": \"UEL Flag for ST8C: <2: Summation at Voltage Error, 2: UEL takeover at gate\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"SCL_Flag\",\n                    \"comment\": \"SCL Flag for ST8C: <2: Summation at Voltage Error, 2: SCL Takeover at UEL and OEL gates\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"SW1_Flag\",\n                    \"comment\": \"SW1 Flag for Power Source Selector for ST8C: <2: Source from generator terminal voltage, 2: Independent power source\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    }\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Regulator input filter time constant in seconds\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_pr\",\n                    \"comment\": \"Regulator proportional gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_ir\",\n                    \"comment\": \"Regulator integral gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vpi_lim\",\n                    \"comment\": \"Regulator input limits (Vpi_min, Vpi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"K_pa\",\n                    \"comment\": \"Field current regulator proportional gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_ia\",\n                    \"comment\": \"Field current regulator integral gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Va_lim\",\n                    \"comment\": \"Field current regulator output limits (Va_min, Va_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"K_a\",\n                    \"comment\": \"Field current regulator proportional gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_a\",\n                    \"comment\": \"Controlled rectifier bridge equivalent time constant in seconds\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (Vr_min, Vr_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"K_f\",\n                    \"comment\": \"Exciter field current feedback gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_f\",\n                    \"comment\": \"Field current feedback time constant in seconds\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_c1\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_p\",\n                    \"comment\": \"Potential circuit (voltage) gain coefficient (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_i1\",\n                    \"comment\": \"Potential circuit (current) gain coefficient (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"X_l\",\n                    \"comment\": \"Reactance associated with potential source (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"θ_p\",\n                    \"comment\": \"Potential circuit phase angle (degrees)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"VB1_max\",\n                    \"comment\": \"Maximum available exciter voltage (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_c2\",\n                    \"comment\": \"Rectifier loading factor proportional to commutating reactance (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_i2\",\n                    \"comment\": \"Potential circuit (current) gain coefficient (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"VB2_max\",\n                    \"comment\": \"Maximum available exciter voltage (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ifd_ref\",\n                    \"comment\": \"Reference Field Current Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed terminal voltage,\\n\\tx_a1: Regulator Integrator state,\\n\\tx_a2: Field Current regulator state,\\n\\tx_a3: Controller rectifier bridge state,\\n\\tx_a4: Regulator Feedback state\",\n                    \"internal_default\": \"[:Vm, :x_a1, :x_a2, :x_a3, :x_a4]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ST8C has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) ST8C has 5 states\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EXST1\",\n            \"docstring\": \"IEEE Type ST1 Excitation System (PTI version)\",\n            \"fields\": [\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Voltage Measurement Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vi_lim\",\n                    \"comment\": \"Voltage input limits (Vi_min, Vi_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Numerator lead-lag (lead) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Denominator lead-lag (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Amplifier Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Amplifier Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vr_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (Vr_min, Vr_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kc\",\n                    \"comment\": \"Current field constant limiter multiplier\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kf\",\n                    \"comment\": \"Excitation control system stabilizer gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Excitation control system stabilizer time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVm: Sensed Terminal Voltage,\\n\\tVrll: Lead-Lag state,\\n\\tVr: Regulator Output, \\n\\tVfb: Feedback state\",\n                    \"internal_default\": \"[:Vm, :Vrll, :Vr, :Vfb]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The EXST1 has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"EX4VSA\",\n            \"docstring\": \"IEEE Excitation System for Voltage Security Assesment\",\n            \"fields\": [\n                {\n                    \"name\": \"Iflim\",\n                    \"comment\": \"OEL Field current limit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"d\",\n                    \"comment\": \"OEL parameter d\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"f\",\n                    \"comment\": \"OEL parameter f\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Spar\",\n                    \"comment\": \"OEL parameter Spar\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K1\",\n                    \"comment\": \"OEL delay time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K2\",\n                    \"comment\": \"OEL parameter K2\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Oel_lim\",\n                    \"comment\": \"Oel integrator limits (Oel_min, Oel_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"G\",\n                    \"comment\": \"AVR Exciter Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Numerator lead-lag (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Denominator lead-lag (lag) time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Exciter Time Constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"E_lim\",\n                    \"comment\": \"Voltage regulator limits (regulator output) (E_min, E_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tVll: Lead-lag internal state,\\n\\tVex: Exciter Output, \\n\\toel: OEL integrator state\",\n                    \"internal_default\": \"[:Vll, :Vex, :oel]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The EX4VSA has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"AVR\"\n        },\n        {\n            \"struct_name\": \"BaseMachine\",\n            \"docstring\": \"Parameters of a Classic Machine: GENCLS in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Reactance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"eq_p\",\n                    \"comment\": \"Fixed EMF behind the impedance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) BaseMachine has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) BaseMachine has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"RoundRotorMachine\",\n            \"docstring\": \"Parameters of 4-[states](@ref S) round-rotor synchronous machine with quadratic/exponential saturation:\\nIEEE Std 1110 §5.3.2 (Model 2.2). GENROU or GENROE model in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Armature resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xl\",\n                    \"comment\": \"Stator leakage reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Saturation factor at 1 and 1.2 pu flux: S(1.0) = B(|ψ_pp|-A)^2\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"γ_d1\",\n                    \"comment\": \"(**Do not modify.**) γ_d1 parameter\",\n                    \"internal_default\": \"(Xd_pp - Xl) / (Xd_p - Xl)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_q1\",\n                    \"comment\": \"(**Do not modify.**) γ_q1 parameter\",\n                    \"internal_default\": \"(Xd_pp - Xl) / (Xq_p - Xl)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_d2\",\n                    \"comment\": \"(**Do not modify.**) γ_d2 parameter\",\n                    \"internal_default\": \"(Xd_p - Xd_pp) / (Xd_p - Xl)^2\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_q2\",\n                    \"comment\": \"(**Do not modify.**) γ_q2 parameter\",\n                    \"internal_default\": \"(Xq_p - Xd_pp) / (Xq_p - Xl)^2\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_qd\",\n                    \"comment\": \"(**Do not modify.**) γ_qd parameter\",\n                    \"internal_default\": \"(Xq - Xl) / (Xd - Xl)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\teq_p: q-axis generator voltage behind the transient reactance,\\n\\ted_p: d-axis generator voltage behind the transient reactance,\\n\\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\\n\\tψ_kq: flux linkage in the first equivalent damping circuit in the d-axis\",\n                    \"internal_default\": \"[:eq_p, :ed_p, :ψ_kd, :ψ_kq]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) RoundRotorMachine has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"SalientPoleMachine\",\n            \"docstring\": \"Parameters of 3-[states](@ref S) salient-pole synchronous machine with quadratic/exponential saturation:\\nIEEE Std 1110 §5.3.1 (Model 2.1). GENSAL or GENSAE model in PSSE and PSLF\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Armature resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xl\",\n                    \"comment\": \"Stator leakage reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Se\",\n                    \"comment\": \"Saturation factor at 1 and 1.2 pu flux: Se(eq_p) = B(eq_p-A)^2\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"γ_d1\",\n                    \"comment\": \"(**Do not modify.**) γ_d1 parameter\",\n                    \"internal_default\": \"(Xd_pp - Xl) / (Xd_p - Xl)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_q1\",\n                    \"comment\": \"(**Do not modify.**) γ_q1 parameter\",\n                    \"internal_default\": \"(Xd_p - Xd_pp) / (Xd_p - Xl)\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"γ_d2\",\n                    \"comment\": \"(**Do not modify.**) γ_d2 parameter\",\n                    \"internal_default\": \"(Xd_p - Xd_pp) / (Xd_p - Xl)^2\",\n                    \"data_type\": \"Float64\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\teq_p: q-axis generator voltage behind the transient reactance,\\n\\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\\n\\tψq_pp: phasonf of the subtransient flux linkage in the q-axis\",\n                    \"internal_default\": \"[:eq_p, :ψ_kd, :ψq_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SalientPoleMachine has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"AndersonFouadMachine\",\n            \"docstring\": \"Parameters of 6-[states](@ref S) synchronous machine: Anderson-Fouad model\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψq: q-axis stator flux,\\n\\tψd: d-axis stator flux,\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage,\\n\\teq_pp: q-axis subtransient voltage,\\n\\ted_pp: d-axis subtransient voltage\",\n                    \"internal_default\": \"[:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The states AndersonFouadMachine has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"FullMachine\",\n            \"docstring\": \"Parameter of a full order flux stator-rotor model without zero sequence flux in the stator.\\n The derivative of stator fluxes (ψd and ψq) is NOT neglected. Only one q-axis damping circuit is considered. All parameters are in machine per unit.\\n Refer to Chapter 3 of [Power System Stability and Control by P. Kundur](https://www.accessengineeringlibrary.com/content/book/9781260473544) or Chapter 11 of [Power System Dynamics: Stability and Control, by J. Machowski, J. Bialek and J. Bumby](https://www.wiley.com/en-us/Power+System+Dynamics%3A+Stability+and+Control%2C+3rd+Edition-p-9781119526360), for more details.\\n Note that the models are somewhat different (but equivalent) due to the different Park Transformation used in both books\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_f\",\n                    \"comment\": \"Field rotor winding resistance in per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_1d\",\n                    \"comment\": \" Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_1q\",\n                    \"comment\": \"Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_d\",\n                    \"comment\": \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski)\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_q\",\n                    \"comment\": \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_ad\",\n                    \"comment\": \"Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_aq\",\n                    \"comment\": \"Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_f1d\",\n                    \"comment\": \"Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_ff\",\n                    \"comment\": \"Field rotor winding inductance, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_1d\",\n                    \"comment\": \"Inductance of the d-axis rotor damping circuit, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_1q\",\n                    \"comment\": \"Inductance of the q-axis rotor damping circuit, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"inv_d_fluxlink\",\n                    \"data_type\": \"Array{Float64,2}\",\n                    \"internal_default\": \"inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]])\",\n                    \"comment\": \"(**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\"\n                },\n                {\n                    \"name\": \"inv_q_fluxlink\",\n                    \"data_type\": \"Array{Float64,2}\",\n                    \"internal_default\": \"inv([[-L_q L_aq]; [-L_aq L_1q]])\",\n                    \"comment\": \"(**Do not modify.**) Equations 3.128, 3.132 From Kundur\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψd: d-axis stator flux,\\n\\tψq: q-axis stator flux,\\n\\tψf: field rotor flux,\\n\\tψ1d: d-axis rotor damping flux,\\n\\tψ1q: q-axis rotor damping flux\",\n                    \"internal_default\": \"[:ψd, :ψq, :ψf, :ψ1d, :ψ1q]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FullMachine has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"SauerPaiMachine\",\n            \"docstring\": \"Parameters of synchronous machine: Sauer Pai model\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xl\",\n                    \"comment\": \"Stator Leakage Reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"γ_d1\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"(Xd_pp-Xl)/(Xd_p-Xl)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"γ_q1\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"(Xq_pp-Xl)/(Xq_p-Xl)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"γ_d2\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"(Xd_p - Xd_pp) / (Xd_p - Xl)^2\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"γ_q2\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"(Xq_p - Xq_pp) / (Xq_p - Xl)^2\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψq: q-axis stator flux,\\n\\tψd: d-axis stator flux,\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage\\n\\tψd_pp: subtransient flux linkage in the d-axis\\n\\tψq_pp: subtransient flux linkage in the q-axis\",\n                    \"internal_default\": \"[:ψq, :ψd, :eq_p, :ed_p, :ψd_pp, :ψq_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SauerPaiMachine has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"MarconatoMachine\",\n            \"docstring\": \"Parameters of 6-[states](@ref S) synchronous machine: Marconato model\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_AA\",\n                    \"comment\": \"Time constant of d-axis additional leakage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"γd\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"γq\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψq: q-axis stator flux,\\n\\tψd: d-axis stator flux,\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage,\\n\\teq_pp: q-axis subtransient voltage,\\n\\ted_pp: d-axis subtransient voltage\",\n                    \"internal_default\": \"[:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) MarconatoMachine has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"OneDOneQMachine\",\n            \"docstring\": \"Parameters of 4-[states](@ref S) synchronous machine: Simplified Marconato model\\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when\\n transmission network dynamics is neglected\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage\",\n                    \"internal_default\": \"[:eq_p, :ed_p]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) OneDOneQMachine has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"SimpleAFMachine\",\n            \"docstring\": \"Parameters of 4-[states](@ref S) simplified Anderson-Fouad (SimpleAFMachine) model.\\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when transmission network\\n dynamics is neglected.\\n If transmission dynamics is considered use the full order Anderson Fouad model\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage,\\n\\teq_pp: q-axis subtransient voltage,\\n\\ted_pp: d-axis subtransient voltage\",\n                    \"internal_default\": \"[:eq_p, :ed_p, :eq_pp, :ed_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SimpleAFMachine has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"SimpleFullMachine\",\n            \"docstring\": \"Parameter of a full order flux stator-rotor model without zero sequence flux in the stator.\\n The derivative of stator fluxes (ψd and ψq) is neglected. This is standard when\\n transmission network dynamics is neglected. Only one q-axis damping circuit\\n is considered. All per unit are in machine per unit.\\n Refer to Chapter 3 of Power System Stability and Control by P. Kundur or Chapter 11 of Power System Dynamics: Stability and Control, by J. Machowski, J. Bialek and J. Bumby, for more details.\\n Note that the models are somewhat different (but equivalent) due to the different Park Transformation used in both books\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_f\",\n                    \"comment\": \"Field rotor winding resistance in per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_1d\",\n                    \"comment\": \" Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_1q\",\n                    \"comment\": \"Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_d\",\n                    \"comment\": \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski)\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_q\",\n                    \"comment\": \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_ad\",\n                    \"comment\": \"Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_aq\",\n                    \"comment\": \"Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_f1d\",\n                    \"comment\": \"Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_ff\",\n                    \"comment\": \"Field rotor winding inductance, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_1d\",\n                    \"comment\": \"Inductance of the d-axis rotor damping circuit, in per unit\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"L_1q\",\n                    \"comment\": \"Inductance of the q-axis rotor damping circuit, in per unit\",\n                    \"null_value\": 2,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"inv_d_fluxlink\",\n                    \"data_type\": \"Array{Float64,2}\",\n                    \"internal_default\": \"inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]])\",\n                    \"comment\": \"(**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\"\n                },\n                {\n                    \"name\": \"inv_q_fluxlink\",\n                    \"data_type\": \"Array{Float64,2}\",\n                    \"internal_default\": \"inv([[-L_q L_aq]; [-L_aq L_1q]])\",\n                    \"comment\": \"(**Do not modify.**) Equations 3.128, 3.132 From Kundur\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tψf: field rotor flux,\\n\\tψ1d: d-axis rotor damping flux,\\n\\tψ1q: q-axis rotor damping flux\",\n                    \"internal_default\": \"[:ψf, :ψ1d, :ψ1q]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SimpleFullMachine has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"SimpleMarconatoMachine\",\n            \"docstring\": \"Parameters of 4-[states](@ref S) synchronous machine: Simplified Marconato model\\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when transmission network\\n dynamics is neglected\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Resistance after EMF in machine per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in d-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq\",\n                    \"data_type\": \"Float64\",\n                    \"null_value\": 0,\n                    \"comment\": \"Reactance after EMF in q-axis per unit\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_p\",\n                    \"comment\": \"Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_p\",\n                    \"comment\": \"Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xd_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in d-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Xq_pp\",\n                    \"comment\": \"Sub-Transient reactance after EMF in q-axis per unit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_p\",\n                    \"comment\": \"Time constant of transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_p\",\n                    \"comment\": \"Time constant of transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Td0_pp\",\n                    \"comment\": \"Time constant of sub-transient d-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tq0_pp\",\n                    \"comment\": \"Time constant of sub-transient q-axis voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_AA\",\n                    \"comment\": \"Time constant of d-axis additional leakage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"γd\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"γq\",\n                    \"data_type\": \"Float64\",\n                    \"internal_default\": \"((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p)\",\n                    \"comment\": \"(**Do not modify.**) Internal equation\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\teq_p: q-axis transient voltage,\\n\\ted_p: d-axis transient voltage,\\n\\teq_pp: q-axis subtransient voltage,\\n\\ted_pp: d-axis subtransient voltage\",\n                    \"internal_default\": \"[:eq_p, :ed_p, :eq_pp, :ed_pp]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SimpleMarconatoMachine has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Machine\"\n        },\n        {\n            \"struct_name\": \"PSSFixed\",\n            \"docstring\": \"Parameters of a PSS that returns a fixed voltage to add to the reference for the AVR\",\n            \"fields\": [\n                {\n                    \"name\": \"V_pss\",\n                    \"comment\": \"Fixed voltage stabilization signal in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PSSFixed has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PSSFixed has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"PSSSimple\",\n            \"docstring\": \"Parameters of a PSS that returns a proportional droop voltage to add to the reference for the AVR\",\n            \"fields\": [\n                {\n                    \"name\": \"K_ω\",\n                    \"comment\": \"Proportional gain for frequency\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_p\",\n                    \"comment\": \"Proportional gain for active power\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PSSSimple has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PSSSimple has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"IEEEST\",\n            \"docstring\": \"IEEE Stabilizing Model PSS. \",\n            \"fields\": [\n                {\n                    \"name\": \"input_code\",\n                    \"comment\": \"Code input for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control\",\n                    \"comment\": \"ACBus identification [`number`](@ref ACBus) for control. `0` identifies the bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"A1\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"A2\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"A3\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"A4\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"A5\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"A6\",\n                    \"comment\": \"Filter coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": \"2.0\"\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Ks\",\n                    \"comment\": \"Proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ls_lim\",\n                    \"comment\": \"PSS output limits for regulator output `(Ls_min, Ls_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vcu\",\n                    \"comment\": \"Cutoff limiter upper bound\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": \"1.25\"\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vcl\",\n                    \"comment\": \"Cutoff limiter lower bound\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": \"1.0\"\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p1: 1st filter integration,\\n\\tx_p2: 2nd filter integration, \\n\\tx_p3: 3rd filter integration, \\n\\tx_p4: 4rd filter integration, \\n\\tx_p5: T1/T2 lead-lag integrator, \\n\\tx_p6: T3/T4 lead-lag integrator, \\n\\t:x_p7 last integer,\",\n                    \"internal_default\": \"[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) IEEEST has 7 states\",\n                    \"internal_default\": 7,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEEST has 7 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"STAB1\",\n            \"docstring\": \"Speed-Sensitive Stabilizing Model\",\n            \"fields\": [\n                {\n                    \"name\": \"KT\",\n                    \"comment\": \"K/T for washout filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T\",\n                    \"comment\": \"Time constant for washout filter\",\n                    \"null_value\": 0.01,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.01,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1T3\",\n                    \"comment\": \"Time constant division T1/T3\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0.01,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.01,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2T4\",\n                    \"comment\": \"Time constant division T2/T4\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant\",\n                    \"null_value\": 0.01,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.01,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"H_lim\",\n                    \"comment\": \"PSS output limit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p1: washout filter,\\n\\tx_p2: T1/T3 lead-lag block, \\n\\tx_p3: T2/T4 lead-lag block,\",\n                    \"internal_default\": \"[:x_p1, :x_p2, :x_p3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) STAB1 has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) STAB1 has 3 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"PSS2A\",\n            \"docstring\": \"IEEE Dual-Input Stabilizer Model\",\n            \"fields\": [\n                {\n                    \"name\": \"input_code_1\",\n                    \"comment\": \"First Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_1\",\n                    \"comment\": \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"input_code_2\",\n                    \"comment\": \"Second Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_2\",\n                    \"comment\": \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"M_rtf\",\n                    \"comment\": \"M parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"N_rtf\",\n                    \"comment\": \"N parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tw1\",\n                    \"comment\": \"Time constant for first washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw2\",\n                    \"comment\": \"Time constant for second washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Time constant for low-pass filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw3\",\n                    \"comment\": \"Time constant for first washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw4\",\n                    \"comment\": \"Time constant for second washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T7\",\n                    \"comment\": \"Time constant for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks2\",\n                    \"comment\": \"Gain for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks3\",\n                    \"comment\": \"Gain for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T8\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T9\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks1\",\n                    \"comment\": \"Gain before lead-lag blocks\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vst_lim\",\n                    \"comment\": \"PSS output limits `(Vst_min, Vst_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p1: 1st washout 1st input, \\n\\tx_p2: 2nd washout 1st input, \\n\\tx_p3: transducer 1st input, \\n\\tx_p4: 1st washout 2nd input, \\n\\tx_p5: 2nd washout 2nd input, \\n\\tx_p6: transducer 2nd input, \\n\\tx_p7: ramp tracking filter state 1, \\n\\tx_p8: ramp tracking filter state 2, \\n\\tx_p9: ramp tracking filter state 3, \\n\\tx_p10: ramp tracking filter state 4, \\n\\tx_p11: ramp tracking filter state 5, \\n\\tx_p12: ramp tracking filter state 6, \\n\\tx_p13: ramp tracking filter state 7, \\n\\tx_p14: ramp tracking filter state 8, \\n\\tx_p15: 1st lead-lag, \\n\\tx_p16: 2nd lead-lag,\",\n                    \"internal_default\": \"[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) IEEEST has 16 states\",\n                    \"internal_default\": 16,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEEST has 16 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"PSS2B\",\n            \"docstring\": \"IEEE 421.5 2005 PSS2B IEEE Dual-Input Stabilizer Model\",\n            \"fields\": [\n                {\n                    \"name\": \"input_code_1\",\n                    \"comment\": \"First Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_1\",\n                    \"comment\": \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"input_code_2\",\n                    \"comment\": \"Second Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_2\",\n                    \"comment\": \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"M_rtf\",\n                    \"comment\": \"M parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"N_rtf\",\n                    \"comment\": \"N parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tw1\",\n                    \"comment\": \"Time constant for first washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw2\",\n                    \"comment\": \"Time constant for second washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Time constant for low-pass filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw3\",\n                    \"comment\": \"Time constant for first washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw4\",\n                    \"comment\": \"Time constant for second washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T7\",\n                    \"comment\": \"Time constant for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks2\",\n                    \"comment\": \"Gain for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks3\",\n                    \"comment\": \"Gain for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T8\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T9\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks1\",\n                    \"comment\": \"Gain before lead-lag blocks\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T10\",\n                    \"comment\": \"Time constant for third lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T11\",\n                    \"comment\": \"Time constant for third lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vs1_lim\",\n                    \"comment\": \"First input limits `(Vs1_min, Vs1_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vs2_lim\",\n                    \"comment\": \"Second input limits `(Vs2_min, Vs2_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vst_lim\",\n                    \"comment\": \"PSS output limits `(Vst_min, Vst_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p1: 1st washout 1st input, \\n\\tx_p2: 2nd washout 1st input, \\n\\tx_p3: transducer 1st input, \\n\\tx_p4: 1st washout 2nd input, \\n\\tx_p5: 2nd washout 2nd input, \\n\\tx_p6: transducer 2nd input, \\n\\tx_p7: ramp tracking filter state 1, \\n\\tx_p8: ramp tracking filter state 2, \\n\\tx_p9: ramp tracking filter state 3, \\n\\tx_p10: ramp tracking filter state 4, \\n\\tx_p11: ramp tracking filter state 5, \\n\\tx_p12: ramp tracking filter state 6, \\n\\tx_p13: ramp tracking filter state 7, \\n\\tx_p14: ramp tracking filter state 8, \\n\\tx_p15: 1st lead-lag, \\n\\tx_p16: 2nd lead-lag, \\n\\tx_p17: 3rd lead-lag,\",\n                    \"internal_default\": \"[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) IEEEST has 17 states\",\n                    \"internal_default\": 17,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEEST has 17 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"PSS2C\",\n            \"docstring\": \"IEEE 421.5 2016 PSS2C IEEE Dual-Input Stabilizer Model\",\n            \"fields\": [\n                {\n                    \"name\": \"input_code_1\",\n                    \"comment\": \"First Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 7\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_1\",\n                    \"comment\": \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"input_code_2\",\n                    \"comment\": \"Second Input Code for stabilizer\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 6\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"remote_bus_control_2\",\n                    \"comment\": \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"M_rtf\",\n                    \"comment\": \"M parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"N_rtf\",\n                    \"comment\": \"N parameter for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 8\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tw1\",\n                    \"comment\": \"Time constant for first washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw2\",\n                    \"comment\": \"Time constant for second washout filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Time constant for low-pass filter for first input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw3\",\n                    \"comment\": \"Time constant for first washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw4\",\n                    \"comment\": \"Time constant for second washout filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T7\",\n                    \"comment\": \"Time constant for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks2\",\n                    \"comment\": \"Gain for low-pass filter for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks3\",\n                    \"comment\": \"Gain for second input\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T8\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T9\",\n                    \"comment\": \"Time constant for ramp tracking filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ks1\",\n                    \"comment\": \"Gain before lead-lag blocks\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Time constant for first lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time constant for second lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T10\",\n                    \"comment\": \"Time constant for third lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T11\",\n                    \"comment\": \"Time constant for third lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Vs1_lim\",\n                    \"comment\": \"First input limits `(Vs1_min, Vs1_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vs2_lim\",\n                    \"comment\": \"Second input limits `(Vs2_min, Vs2_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Vst_lim\",\n                    \"comment\": \"PSS output limits `(Vst_min, Vst_max)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"T12\",\n                    \"comment\": \"Time constant for fourth lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T13\",\n                    \"comment\": \"Time constant for fourth lead-lag block\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"PSS_Hysteresis_param\",\n                    \"comment\": \"PSS output hysteresis parameters `(PSSOFF, PSSON)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Xcomp\",\n                    \"comment\": \"Stator Leakage Reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tcomp\",\n                    \"comment\": \"Time measured with compensated frequency\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"hysteresis_binary_logic\",\n                    \"comment\": \"Hysteresis memory variable\",\n                    \"null_value\": 0,\n                    \"default\": \"1\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tx_p1: 1st washout 1st input, \\n\\tx_p2: 2nd washout 1st input, \\n\\tx_p3: transducer 1st input, \\n\\tx_p4: 1st washout 2nd input, \\n\\tx_p5: 2nd washout 2nd input, \\n\\tx_p6: transducer 2nd input, \\n\\tx_p7: ramp tracking filter state 1, \\n\\tx_p8: ramp tracking filter state 2, \\n\\tx_p9: ramp tracking filter state 3, \\n\\tx_p10: ramp tracking filter state 4, \\n\\tx_p11: ramp tracking filter state 5, \\n\\tx_p12: ramp tracking filter state 6, \\n\\tx_p13: ramp tracking filter state 7, \\n\\tx_p14: ramp tracking filter state 8, \\n\\tx_p15: 1st lead-lag, \\n\\tx_p16: 2nd lead-lag, \\n\\tx_p17: 3rd lead-lag, \\n\\tx_p18: 4th lead-lag, \\n\\tx_p19: washout block for compensated frequency,\",\n                    \"internal_default\": \"[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17, :x_p18, :x_p19]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) IEEEST has 19 states\",\n                    \"internal_default\": 19,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEEST has 19 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"PSS\"\n        },\n        {\n            \"struct_name\": \"SingleMass\",\n            \"docstring\": \"Parameters of single mass shaft model. Typically represents the rotor mass\",\n            \"fields\": [\n                {\n                    \"name\": \"H\",\n                    \"comment\": \"Rotor inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D\",\n                    \"comment\": \"Rotor natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tδ: rotor angle,\\n\\tω: rotor speed\",\n                    \"internal_default\": \"[:δ, :ω]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) SingleMass has 1 state\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Shaft\"\n        },\n        {\n            \"struct_name\": \"FiveMassShaft\",\n            \"docstring\": \"Parameters of 5 mass-spring shaft model.\\n It contains a High-Pressure (HP) steam turbine, Intermediate-Pressure (IP)\\n steam turbine, Low-Pressure (LP) steam turbine, the Rotor and an Exciter (EX) mover\",\n            \"fields\": [\n                {\n                    \"name\": \"H\",\n                    \"comment\": \"Rotor inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H_hp\",\n                    \"comment\": \"High pressure turbine inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H_ip\",\n                    \"comment\": \"Intermediate pressure turbine inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H_lp\",\n                    \"comment\": \"Low pressure turbine inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"H_ex\",\n                    \"comment\": \" Exciter inertia constant in MWs/MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D\",\n                    \"comment\": \"Rotor natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_hp\",\n                    \"comment\": \"High pressure turbine natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_ip\",\n                    \"comment\": \"Intermediate pressure turbine natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_lp\",\n                    \"comment\": \"Low pressure turbine natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_ex\",\n                    \"comment\": \"Exciter natural damping in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_12\",\n                    \"comment\": \"High-Intermediate pressure turbine damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_23\",\n                    \"comment\": \"Intermediate-Low pressure turbine damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_34\",\n                    \"comment\": \"Low pressure turbine-Rotor damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_45\",\n                    \"comment\": \"Rotor-Exciter damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_hp\",\n                    \"comment\": \"High pressure turbine angle coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_ip\",\n                    \"comment\": \"Intermediate pressure turbine angle coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_lp\",\n                    \"comment\": \"Low pressure turbine angle coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_ex\",\n                    \"comment\": \"Exciter angle coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\n\\tδ: rotor angle,\\n\\tω: rotor speed,\\n\\tδ_hp: rotor angle of high pressure turbine,\\n\\tω_hp: rotor speed of high pressure turbine,\\n\\tδ_ip: rotor angle of intermediate pressure turbine,\\n\\tω_ip: rotor speed of intermediate pressure turbine,\\n\\tδ_lp: rotor angle of low pressure turbine,\\n\\tω_lp: rotor speed of low pressure turbine,\\n\\tδ_ex: rotor angle of exciter,\\n\\tω_lp: rotor speed of exciter\",\n                    \"internal_default\": \"[:δ, :ω, :δ_hp, :ω_hp, :δ_ip, :ω_ip, :δ_lp, :ω_lp, :δ_ex, :ω_ex]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FiveMassShaft has 10 states\",\n                    \"internal_default\": 10,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"Shaft\"\n        },\n        {\n            \"struct_name\": \"TGFixed\",\n            \"docstring\": \"Parameters of a fixed Turbine Governor that returns a fixed mechanical torque\\n given by the product of P_ref*efficiency\",\n            \"fields\": [\n                {\n                    \"name\": \"efficiency\",\n                    \"comment\": \"Efficiency factor that multiplies `P_ref`\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGFixed has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGFixed has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"GasTG\",\n            \"docstring\": \"Parameters of Gas Turbine-Governor. GAST in PSSE and GAST_PTI in PowerWorld\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Speed droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.1\n                    }\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Governor time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.5\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Combustion chamber time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.5\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Load limit time constant (exhaust gas measurement time)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 5\n                    }\n                },\n                {\n                    \"name\": \"AT\",\n                    \"comment\": \"Ambient temperature load limit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Kt\",\n                    \"comment\": \"Load limit feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    }\n                },\n                {\n                    \"name\": \"V_lim\",\n                    \"comment\": \"Operational control limits on fuel valve opening (V_min, V_max)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"D_turb\",\n                    \"comment\": \"Speed damping coefficient of gas turbine rotor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Load Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the GAST model are:\\n\\tx_g1: Fuel valve opening,\\n\\tx_g2: Fuel flow,\\n\\tx_g3: Exhaust temperature load\",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) GasTG has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) GAST has 3 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"DEGOV\",\n            \"docstring\": \"Parameters Woodward Diesel Governor Model. DEGOV in PowerWorld\",\n            \"fields\": [\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Governor mechanism time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Turbine power time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Turbine exhaust temperature time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Governor gain (reciprocal of droop)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Governor lead time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Governor lag time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Actuator time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"Td\",\n                    \"comment\": \"Engine time delay\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Load Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the DEGOV model are:\\n\\tx_ecb1: Electric control box 1,\\n\\tx_ecb2: Electric control box 2,\\n\\tx_a1: Actuator 1,\\n\\tx_a2: Actuator 2,\\n\\tx_a3: Actuator 3,\",\n                    \"internal_default\": \"[:x_ecb1, :x_ecb2, :x_a1, :x_a2, :x_a3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) DEGOV has 5 states\",\n                    \"internal_default\": 5,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) DEGOV has 5 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"DEGOV1\",\n            \"docstring\": \"Parameters Woodward Diesel Governor Model. DEGOV1 in PSSE\",\n            \"fields\": [\n                {\n                    \"name\": \"droop_flag\",\n                    \"comment\": \"Droop control Flag. 0 for throttle feedback and 1 for electric power feedback\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Governor mechanism time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Turbine power time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Turbine exhaust temperature time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Governor gain for actuator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Governor lead time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Governor lag time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Actuator time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"Td\",\n                    \"comment\": \"Engine time delay in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"T_lim\",\n                    \"comment\": \"Operational control limits on actuator (T_min, T_max)\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Steady state droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"Te\",\n                    \"comment\": \"Power transducer time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 100.0\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Load Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the DEGOV1 model depends on the droop flag\",\n                    \"internal_default\": \"PowerSystems.get_degov1_states(droop_flag)[1]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The number of [states](@ref S) of the DEGOV1 model depends on the droop flag\",\n                    \"internal_default\": \"PowerSystems.get_degov1_states(droop_flag)[2]\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"GeneralGovModel\",\n            \"docstring\": \"GE General Governor/Turbine Model. The GeneralGovModel (GGOV1) model is a general purpose governor model used for a variety of prime movers controlled by proportional-integral-derivative (PID) governors including gas turbines\",\n            \"fields\": [\n                {\n                    \"name\": \"Rselect\",\n                    \"comment\": \"Feedback signal for governor droop\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"fuel_flag\",\n                    \"comment\": \"Flag Switch for fuel source characteristic\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Speed droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tpelec\",\n                    \"comment\": \"Electrical power transducer time constant, seconds\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"speed_error_signal\",\n                    \"comment\": \"Speed error signal limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kp_gov\",\n                    \"comment\": \"Governor proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki_gov\",\n                    \"comment\": \"Governor integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd_gov\",\n                    \"comment\": \"Governor derivative gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Td_gov\",\n                    \"comment\": \"Governor derivative time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"valve_position_limits\",\n                    \"comment\": \"Valve position limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_act\",\n                    \"comment\": \"Actuator time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K_turb\",\n                    \"comment\": \"Turbine gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Wf_nl\",\n                    \"comment\": \"No load fuel flow, pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Turbine lag time constant, sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Turbine lead time constant, sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_eng\",\n                    \"comment\": \"Transport lag time constant for diesel engine, sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tf_load\",\n                    \"comment\": \"Load limiter time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kp_load\",\n                    \"comment\": \"Load limiter proportional gain for PI controller\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki_load\",\n                    \"comment\": \"Load integral gain for PI controller\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ld_ref\",\n                    \"comment\": \"Load limiter integral gain for PI controller\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Dm\",\n                    \"comment\": \"Mechanical damping coefficient, pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"R_open\",\n                    \"comment\": \"Maximum valve opening rate, pu/sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"R_close\",\n                    \"comment\": \"Maximum valve closing rate, pu/sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki_mw\",\n                    \"comment\": \"Power controller (reset) gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"A_set\",\n                    \"comment\": \"Acceleration limiter setpoint, pu/sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ka\",\n                    \"comment\": \"Acceleration limiter gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Acceleration limiter time constant \",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"T_rate\",\n                    \"comment\": \"Turbine rating\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"db\",\n                    \"comment\": \"Speed governor deadband\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tsa\",\n                    \"comment\": \"Temperature detection lead time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tsb\",\n                    \"comment\": \"Temperature detection lag time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"R_lim\",\n                    \"comment\": \"Maximum rate of load increase\",\n                    \"null_value\": \"(up = 0.0, down = 0.0)\",\n                    \"data_type\": \"UpDown\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the GGOV1 model are:\\n\\tPe: Machine Electrical Power Measurement,\\n\\tx_g1: Governor differential control,\\n\\tx_g2: Governor integral control, \\n\\tx_g3: Turbine actuator, \\n\\tx_g4: Turbine Lead-Lag, \\n\\tx_g5: Turbine load limiter measurement, \\n\\tx_g6: Turbine Load Limiter Integral Control, \\n\\tx_g7: Supervisory Load Control, \\n\\tx_g8: Acceleration Control, \\n\\tx_g9 Temperature Detection Lead - Lag:\",\n                    \"internal_default\": \"[:Pe, :x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7, :x_g8, :x_g9]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) GeneralGovModel has 10 states\",\n                    \"internal_default\": 10,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) GGOV1 has 10 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"PIDGOV\",\n            \"docstring\": \"Hydro Turbine-Governor with PID controller.\",\n            \"fields\": [\n                {\n                    \"name\": \"feedback_flag\",\n                    \"comment\": \"Feedback signal for governor droop: 0 for electrical power, and 1 for gate position.\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Rperm\",\n                    \"comment\": \"Speed permanent droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_reg\",\n                    \"comment\": \"Speed detector time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kp\",\n                    \"comment\": \"Governor proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki\",\n                    \"comment\": \"Governor integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Governor derivative gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Governor derivative time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Gate-servo time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"D_turb\",\n                    \"comment\": \"Turbine damping factor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"gate_openings\",\n                    \"comment\": \"Gate-opening speed at different loads\",\n                    \"null_value\": \"(0.0, 0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64, Float64}\"\n                },\n                {\n                    \"name\": \"power_gate_openings\",\n                    \"comment\": \"Power at gate_openings\",\n                    \"null_value\": \"(0.0, 0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64, Float64}\"\n                },\n                {\n                    \"name\": \"G_lim\",\n                    \"comment\": \"Minimum/Maximum Gate openings `(G_min, G_max)`.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"A_tw\",\n                    \"comment\": \"Factor multiplying Tw\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tw\",\n                    \"comment\": \"Water inertia time constant, sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_lim\",\n                    \"comment\": \"Gate opening velocity limits `(G_min, G_max)`.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\\n\\tx_g1: Filtered input measurement,\\n\\tx_g2: PI block internal state,\\n\\tx_g3: First regulator state, \\n\\tx_g4: Derivative block internal state, \\n\\tx_g5: Second regulator state, \\n\\tx_g6: Gate position state, \\n\\tx_g7: Water inertia state\",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PIDGOV has 7 states\",\n                    \"internal_default\": 7,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"WPIDHY\",\n            \"docstring\": \"Woodward PID Hydro Governor\",\n            \"fields\": [\n                {\n                    \"name\": \"T_reg\",\n                    \"comment\": \"Input time constant of the governor in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"reg\",\n                    \"comment\": \"Input governor gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kp\",\n                    \"comment\": \"Governor proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ki\",\n                    \"comment\": \"Governor integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Kd\",\n                    \"comment\": \"Governor derivative gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"Governor derivative/high-frequency time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tb\",\n                    \"comment\": \"Gate-servo time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"V_lim\",\n                    \"comment\": \"Gate opening velocity limits `(G_min, G_max)`.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"G_lim\",\n                    \"comment\": \"Minimum/Maximum Gate velocity `(G_min, G_max)`.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Tw\",\n                    \"comment\": \"Water inertia time constant, sec\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"P_lim\",\n                    \"comment\": \"Minimum/Maximum Gate openings `(P_min, P_max)`.\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"D\",\n                    \"comment\": \"Turbine damping coefficient\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"gate_openings\",\n                    \"comment\": \"Gate-opening speed at different loads\",\n                    \"null_value\": \"(0.0, 0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64, Float64}\"\n                },\n                {\n                    \"name\": \"power_gate_openings\",\n                    \"comment\": \"Power at gate_openings\",\n                    \"null_value\": \"(0.0, 0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64, Float64}\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\\n\\tx_g1: Filtered input measurement,\\n\\tx_g2: PI block internal state,\\n\\tx_g3: First regulator state, \\n\\tx_g4: Derivative block internal state, \\n\\tx_g5: Second regulator state, \\n\\tx_g6: Gate position state, \\n\\tx_g7: Water inertia state\",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PIDGOV has 7 states\",\n                    \"internal_default\": 7,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"SteamTurbineGov1\",\n            \"docstring\": \"Steam Turbine-Governor. This model considers both TGOV1 or TGOV1DU in PSS/E\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Governor time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"valve_position_limits\",\n                    \"comment\": \"Valve position limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Lead Lag Lead Time constant \",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Lead Lag Lag Time constant \",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"D_T\",\n                    \"comment\": \"Turbine Damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"DB_h\",\n                    \"comment\": \"Deadband for overspeed\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"DB_l\",\n                    \"comment\": \"Deadband for underspeed\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": null,\n                        \"max\": 0\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T_rate\",\n                    \"comment\": \"Turbine Rate (MW). If zero, generator base is used\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the SteamTurbineGov1 model are:\\n\\tx_g1: Valve Opening,\\n\\tx_g2: Lead-lag state\",\n                    \"internal_default\": \"[:x_g1, :x_g2]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGOV1 has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) TGOV1 has 2 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"HydroTurbineGov\",\n            \"docstring\": \"Hydro Turbine-Governor\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Permanent droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"r\",\n                    \"comment\": \"Temporary Droop\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 2\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"Tr\",\n                    \"comment\": \"Governor time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 30\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tf\",\n                    \"comment\": \"Filter Time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.1\n                    },\n                    \"valiation_action\": \"error\"\n                },\n                {\n                    \"name\": \"Tg\",\n                    \"comment\": \"Servo time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"VELM\",\n                    \"comment\": \"gate velocity limit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"gate_position_limits\",\n                    \"comment\": \"Gate position limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Tw\",\n                    \"comment\": \"water time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 3\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"At\",\n                    \"comment\": \"Turbine gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.8,\n                        \"max\": 1.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"D_T\",\n                    \"comment\": \"Turbine Damping\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"q_nl\",\n                    \"comment\": \"No-power flow\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the HydroTurbineGov model are:\\n\\tx_g1: filter_output,\\n\\tx_g2: desired gate, \\n\\tx_g3: gate opening, \\n\\tx_g4: turbine flow\",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3, :x_g4]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) HYGOV has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) HYGOV has 4 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"IEEETurbineGov1\",\n            \"docstring\": \"IEEE Type 1 Speed-Governing Model\",\n            \"fields\": [\n                {\n                    \"name\": \"K\",\n                    \"comment\": \"Governor Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 5,\n                        \"max\": 30\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Input Filter Lag\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Input Filter Lead\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Valve position Time Constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": \"eps()\",\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"error\"\n                },\n                {\n                    \"name\": \"U0\",\n                    \"comment\": \"Maximum Valve Opening Rate\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0.01,\n                        \"max\": 0.03\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"U_c\",\n                    \"comment\": \"Maximum Valve closing rate\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -0.3,\n                        \"max\": 0\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"valve_position_limits\",\n                    \"comment\": \"Valve position limits in MW\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Time Constant inlet steam\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K1\",\n                    \"comment\": \"Fraction of high presure shaft power\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -2,\n                        \"max\": 1\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K2\",\n                    \"comment\": \"Fraction of low presure shaft power\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Time constant for second boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K3\",\n                    \"comment\": \"Fraction of high presure shaft power second boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K4\",\n                    \"comment\": \"Fraction of low presure shaft power second boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.5\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T6\",\n                    \"comment\": \"Time constant for third boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K5\",\n                    \"comment\": \"Fraction of high presure shaft power third boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.35\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K6\",\n                    \"comment\": \"Fraction of low presure shaft power third boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.55\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"T7\",\n                    \"comment\": \"Time constant for fourth boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 10\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K7\",\n                    \"comment\": \"Fraction of high presure shaft power fourth boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"K8\",\n                    \"comment\": \"Fraction of low presure shaft power fourth boiler pass\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 0.3\n                    },\n                    \"validation_action\": \"warn\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the IEEETurbineGov model are:\\n\\tx_g1: First Governor integrator,\\n\\tx_g2: Governor output,\\n\\tx_g3: First Turbine integrator, \\n\\tx_g4: Second Turbine Integrator, \\n\\tx_g5: Third Turbine Integrator, \\n\\tx_g6: Fourth Turbine Integrator, \",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) IEEEG1 has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"states_types\",\n                    \"comment\": \"(**Do not modify.**) IEEEG1 has 6 [differential](@ref states_list) [states](@ref S)\",\n                    \"internal_default\": \"[StateTypes.Differential, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid]\",\n                    \"data_type\": \"Vector{StateTypes}\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"TGTypeI\",\n            \"docstring\": \"Parameters of a Turbine Governor Type I\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ts\",\n                    \"comment\": \"Governor time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tc\",\n                    \"comment\": \"Servo time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T3\",\n                    \"comment\": \"Transient gain time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T4\",\n                    \"comment\": \"Power fraction time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T5\",\n                    \"comment\": \"Reheat time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"valve_position_limits\",\n                    \"comment\": \"Valve position limits in MW\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\\n\\tx_g1: Governor state,\\n\\tx_g2: Servo state,\\n\\tx_g3: Reheat state\",\n                    \"internal_default\": \"[:x_g1, :x_g2, :x_g3]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGTypeI has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"TGTypeII\",\n            \"docstring\": \"Parameters of a Turbine Governor Type II\",\n            \"fields\": [\n                {\n                    \"name\": \"R\",\n                    \"comment\": \"Droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T1\",\n                    \"comment\": \"Transient gain time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T2\",\n                    \"comment\": \"Power fraction time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"τ_limits\",\n                    \"comment\": \"Power into the governor limits\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\\n\\tx_g1: lead-lag state\",\n                    \"internal_default\": \"[:xg]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGTypeII has 1 state\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"TGSimple\",\n            \"docstring\": \"Parameters of a Simple one-state Turbine Governor\",\n            \"fields\": [\n                {\n                    \"name\": \"d_t\",\n                    \"comment\": \"Inverse Droop parameter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tm\",\n                    \"comment\": \"Turbine Governor Low-Pass Time Constant [s]\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the TGSimple model are:\\n\\tτm: mechanical torque\",\n                    \"internal_default\": \"[:τm]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) TGSimple has 1 state\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"TurbineGov\"\n        },\n        {\n            \"struct_name\": \"AverageConverter\",\n            \"docstring\": \"Parameters of an average converter model\",\n            \"fields\": [\n                {\n                    \"name\": \"rated_voltage\",\n                    \"comment\": \"Rated voltage (V)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rated_current\",\n                    \"comment\": \"Rated current (A)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) AverageConverter has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) AverageConverter has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Converter\"\n        },\n        {\n            \"struct_name\": \"RenewableEnergyConverterTypeA\",\n            \"docstring\": \"Parameters of a renewable energy generator/converter model, this model corresponds to REGCA1 in PSSE\",\n            \"fields\": [\n                {\n                    \"name\": \"T_g\",\n                    \"comment\": \"Converter time constant (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Rrpwr\",\n                    \"comment\": \"Low Voltage Power Logic (LVPL) ramp rate limit (pu/s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Brkpt\",\n                    \"comment\": \"LVPL characteristic voltage 2 (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Zerox\",\n                    \"comment\": \"LVPL characteristic voltage 1 (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Lvpl1\",\n                    \"comment\": \"LVPL gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vo_lim\",\n                    \"comment\": \"Voltage limit for high voltage reactive current management (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Lv_pnts\",\n                    \"comment\": \"Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Io_lim\",\n                    \"comment\": \"Current limit (pu) for high voltage reactive current management (specified as a negative value)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": null,\n                        \"max\": 0\n                    }\n                },\n                {\n                    \"name\": \"T_fltr\",\n                    \"comment\": \"Voltage filter time constant for low voltage active current management (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_hv\",\n                    \"comment\": \"Overvoltage compensation gain used in the high voltage reactive current management\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iqr_lims\",\n                    \"comment\": \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Accel\",\n                    \"comment\": \"Acceleration factor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Lvpl_sw\",\n                    \"comment\": \"Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Initial condition of reactive power from power flow\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_source\",\n                    \"comment\": \"Output resistor used for the Thevenin Equivalent\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_source\",\n                    \"comment\": \"Output reactance used for the Thevenin Equivalent\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0e5\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\tIp: Converter lag for Ipcmd,\\tIq: Converter lag for Iqcmd,\\tVmeas: Voltage filter for low voltage active current management\",\n                    \"internal_default\": \"[:Ip, :Iq, :Vmeas]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) RenewableEnergyConverterTypeA has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Converter\"\n        },\n        {\n            \"struct_name\": \"RenewableEnergyVoltageConverterTypeA\",\n            \"docstring\": \"Parameters of a renewable energy generator/converter model, this model corresponds to REGCA1 in PSSE, but to be interfaced using a Voltage Source instead of a Current Source\",\n            \"fields\": [\n                {\n                    \"name\": \"T_g\",\n                    \"comment\": \"Converter time constant (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Rrpwr\",\n                    \"comment\": \"Low Voltage Power Logic (LVPL) ramp rate limit (pu/s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Brkpt\",\n                    \"comment\": \"LVPL characteristic voltage 2 (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Zerox\",\n                    \"comment\": \"LVPL characteristic voltage 1 (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Lvpl1\",\n                    \"comment\": \"LVPL gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vo_lim\",\n                    \"comment\": \"Voltage limit for high voltage reactive current management (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Lv_pnts\",\n                    \"comment\": \"Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Io_lim\",\n                    \"comment\": \"Current limit (pu) for high voltage reactive current management (specified as a negative value)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": null,\n                        \"max\": 0\n                    }\n                },\n                {\n                    \"name\": \"T_fltr\",\n                    \"comment\": \"Voltage filter time constant for low voltage active current management (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_hv\",\n                    \"comment\": \"Overvoltage compensation gain used in the high voltage reactive current management\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iqr_lims\",\n                    \"comment\": \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Accel\",\n                    \"comment\": \"Acceleration factor\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Lvpl_sw\",\n                    \"comment\": \"Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Initial condition of reactive power from power flow\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) are:\\tIp: Converter lag for Ipcmd,\\tIq: Converter lag for Iqcmd,\\tVmeas: Voltage filter for low voltage active current management\",\n                    \"internal_default\": \"[:Ip, :Iq, :Vmeas]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) RenewableEnergyVoltageConverterTypeA has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Converter\"\n        },\n        {\n            \"struct_name\": \"FixedDCSource\",\n            \"docstring\": \"Parameters of a Fixed DC Source that returns a fixed DC voltage\",\n            \"fields\": [\n                {\n                    \"name\": \"voltage\",\n                    \"comment\": \"Voltage (V)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FixedDCSource has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FixedDCSource has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DCSource\"\n        },\n        {\n            \"struct_name\": \"ZeroOrderBESS\",\n            \"docstring\": \"Parameters for the DC-side with a Battery Energy Storage System from [\\\"Grid-Coupled Dynamic Response of Battery-Driven Voltage Source Converters.\\\"](https://arxiv.org/abs/2007.11776)\",\n            \"fields\": [\n                {\n                    \"name\": \"rated_voltage\",\n                    \"comment\": \"Rated voltage (V)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rated_current\",\n                    \"comment\": \"Rated current (A)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"battery_voltage\",\n                    \"comment\": \"battery voltage in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"battery_resistance\",\n                    \"comment\": \"Battery resistance in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"dc_dc_inductor\",\n                    \"comment\": \"DC/DC inductance in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"dc_link_capacitance\",\n                    \"comment\": \"DC-link capacitance in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fs\",\n                    \"comment\": \"DC/DC converter switching frequency (kHz)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kpv\",\n                    \"comment\": \"voltage controller proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kiv\",\n                    \"comment\": \"voltage controller integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kpi\",\n                    \"comment\": \"current controller proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kii\",\n                    \"comment\": \"current controller integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vdc_ref\",\n                    \"comment\": \"Reference DC-Voltage Set-point in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"default\": \"1.1\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ZeroOrderBESS model are:\\n\\tv_dc: DC-link voltage,\\n\\ti_b: Battery current,\\n\\t ν: integrator state of the voltage controller,\\n\\t ζ: integrator state of the PI current controller\",\n                    \"internal_default\": \"[:v_dc, :i_b, :ν, :ζ]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ZeroOrderBESS has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"DCSource\"\n        },\n        {\n            \"struct_name\": \"LCLFilter\",\n            \"docstring\": \"Parameters of a LCL filter outside the converter, the [states](@ref S) are in the grid's reference frame\",\n            \"fields\": [\n                {\n                    \"name\": \"lf\",\n                    \"comment\": \"Series inductance in p.u. of converter filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rf\",\n                    \"comment\": \"Series resistance in p.u. of converter filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"cf\",\n                    \"comment\": \"Shunt capacitance in p.u. of converter filter\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lg\",\n                    \"comment\": \"Series inductance in p.u. of converter filter to the grid\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rg\",\n                    \"comment\": \"Series resistance in p.u. of converter filter to the grid\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the LCLFilter model are:\\n\\tir_cnv: Real current out of the converter,\\n\\tii_cnv: Imaginary current out of the converter,\\n\\tvr_filter: Real voltage at the filter's capacitor,\\n\\tvi_filter: Imaginary voltage at the filter's capacitor,\\n\\tir_filter: Real current out of the filter,\\n\\tii_filter: Imaginary current out of the filter\",\n                    \"internal_default\": \"[:ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) LCLFilter has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Filter\"\n        },\n        {\n            \"struct_name\": \"LCFilter\",\n            \"docstring\": \"Parameters of a LCL filter outside the converter\",\n            \"fields\": [\n                {\n                    \"name\": \"lf\",\n                    \"comment\": \"filter inductance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rf\",\n                    \"comment\": \"filter resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"cf\",\n                    \"comment\": \"filter capacitance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the LCFilter model are:\\n\\tir_filter: Real current out of the filter,\\n\\tii_filter: Imaginary current out of the filter\",\n                    \"internal_default\": \"[:ir_filter, :ii_filter]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) LCFilter has two states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Filter\"\n        },\n        {\n            \"struct_name\": \"RLFilter\",\n            \"docstring\": \"Parameters of RL series filter in algebraic representation\",\n            \"fields\": [\n                {\n                    \"name\": \"rf\",\n                    \"comment\": \"Series resistance in p.u. of converter filter to the grid\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lf\",\n                    \"comment\": \"Series inductance in p.u. of converter filter to the grid\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) RLFilter has zero [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) RLFilter has zero states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"Filter\"\n        },\n        {\n            \"struct_name\": \"KauraPLL\",\n            \"docstring\": \"Parameters of a Phase-Locked Loop (PLL) based on [\\\"Operation of a phase locked loop system under distorted utility conditions\\\"](https://doi.org/10.1109/28.567077) by Vikram Kaura, and Vladimir Blasko\",\n            \"fields\": [\n                {\n                    \"name\": \"ω_lp\",\n                    \"comment\": \"PLL low-pass filter frequency (rad/sec)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kp_pll\",\n                    \"comment\": \"PLL proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ki_pll\",\n                    \"comment\": \"PLL integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the KauraPLL model are:\\n\\tvd_pll: d-axis of the measured voltage in the PLL synchronous reference frame (SRF),\\n\\tvq_pll: q-axis of the measured voltage in the PLL SRF,\\n\\tε_pll: Integrator state of the PI controller,\\n\\tθ_pll: Phase angle displacement in the PLL SRF\",\n                    \"internal_default\": \"[:vd_pll, :vq_pll, :ε_pll, :θ_pll]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) KauraPLL has 4 states\",\n                    \"internal_default\": 4,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"FrequencyEstimator\"\n        },\n        {\n            \"struct_name\": \"ReducedOrderPLL\",\n            \"docstring\": \"Parameters of a Phase-Locked Loop (PLL) based on [\\\"Reduced-order Structure-preserving Model for Parallel-connected Three-phase Grid-tied Inverters.\\\"](https://doi.org/10.1109/COMPEL.2017.8013389)\",\n            \"fields\": [\n                {\n                    \"name\": \"ω_lp\",\n                    \"comment\": \"PLL low-pass filter frequency (rad/sec)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kp_pll\",\n                    \"comment\": \"PLL proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ki_pll\",\n                    \"comment\": \"PLL integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ReducedOrderPLL model are:\\n\\tvq_pll: q-axis of the measured voltage in the PLL synchronous reference frame (SRF),\\n\\tε_pll: Integrator state of the PI controller,\\n\\tθ_pll: Phase angle displacement in the PLL SRF\",\n                    \"internal_default\": \"[:vq_pll, :ε_pll, :θ_pll]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ReducedOrderPLL has 3 states\",\n                    \"internal_default\": 3,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"FrequencyEstimator\"\n        },\n        {\n            \"struct_name\": \"FixedFrequency\",\n            \"docstring\": \"Parameters of a Fixed Frequency Estimator (i.e. no PLL)\",\n            \"fields\": [\n                {\n                    \"name\": \"frequency\",\n                    \"comment\": \"Reference Frequency (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FixedFrequency has no [states](@ref S)\",\n                    \"internal_default\": \"Vector{Symbol}()\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) FixedFrequency has no states\",\n                    \"internal_default\": 0,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"FrequencyEstimator\"\n        },\n        {\n            \"struct_name\": \"VirtualInertia\",\n            \"docstring\": \"Parameters of a Virtual Inertia with SRF using VSM for active power controller\",\n            \"fields\": [\n                {\n                    \"name\": \"Ta\",\n                    \"comment\": \"VSM inertia constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kd\",\n                    \"comment\": \"VSM damping constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kω\",\n                    \"comment\": \"frequency droop gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the VirtualInertia model are:\\n\\tθ_oc: Phase angle displacement of the virtual synchronous generator model\\n\\tω_oc: Speed of the rotating reference frame of the virtual synchronous generator model\",\n                    \"internal_default\": \"[:θ_oc, :ω_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) VirtualInertia has two states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ActivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ActivePowerDroop\",\n            \"docstring\": \"Parameters of an Active Power droop controller\",\n            \"fields\": [\n                {\n                    \"name\": \"Rp\",\n                    \"comment\": \"Droop Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ωz\",\n                    \"comment\": \"filter frequency cutoff\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ActivePowerDroop model are:\\n\\tθ_oc: Phase angle displacement of the inverter model,\\n\\tp_oc: Measured active power of the inverter model\",\n                    \"internal_default\": \"[:θ_oc, :p_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ActivePowerDroop has two states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ActivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ActivePowerPI\",\n            \"docstring\": \"Parameters of a Proportional-Integral Active Power controller for a specified power reference\",\n            \"fields\": [\n                {\n                    \"name\": \"Kp_p\",\n                    \"comment\": \"Proportional Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ki_p\",\n                    \"comment\": \"Integral Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ωz\",\n                    \"comment\": \"filter frequency cutoff\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ActivePowerPI model are:\\n\\tσp_oc: Integrator state of the PI Controller,\\n\\tp_oc: Measured active power of the inverter model\",\n                    \"internal_default\": \"[:σp_oc, :p_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ActivePowerPI has two states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ActivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ActiveVirtualOscillator\",\n            \"docstring\": \"Parameters of an Active Virtual Oscillator controller. Model is based on [\\\"Model Reduction for Inverters with Current Limiting and Dispatchable Virtual Oscillator Control.\\\"](https://doi.org/10.1109/TEC.2021.3083488)\",\n            \"fields\": [\n                {\n                    \"name\": \"k1\",\n                    \"comment\": \"VOC Synchronization Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ψ\",\n                    \"comment\": \"Rotation angle of the controller\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ActiveVirtualOscillator model are:\\n\\tθ_oc: Phase angle displacement of the inverter model\",\n                    \"internal_default\": \"[:θ_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ActiveVirtualOscillator has one state\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ActivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ActiveRenewableControllerAB\",\n            \"docstring\": \"Parameters of Active Power Controller including REPCA1 and REECB1\",\n            \"fields\": [\n                {\n                    \"name\": \"bus_control\",\n                    \"comment\": \"ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"from_branch_control\",\n                    \"comment\": \"Monitored branch FROM bus number for line drop compensation (if 0 generator power will be used)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"to_branch_control\",\n                    \"comment\": \"Monitored branch TO bus number for line drop compensation (if 0 generator power will be used)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"branch_id_control\",\n                    \"comment\": \"Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\",\n                    \"null_value\": 0,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"Freq_Flag\",\n                    \"comment\": \"Frequency Flag for REPCA1: 0: disable, 1:enable\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"K_pg\",\n                    \"comment\": \"Active power PI control proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_ig\",\n                    \"comment\": \"Active power PI control integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_p\",\n                    \"comment\": \"Real power measurement filter time constant (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fdbd_pnts\",\n                    \"comment\": \"Frequency error dead band thresholds `(fdbd1, fdbd2)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"fe_lim\",\n                    \"comment\": \"Upper/Lower limit on frequency error `(fe_min, fe_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_lim\",\n                    \"comment\": \"Upper/Lower limit on power reference `(P_min, P_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_g\",\n                    \"comment\": \"Power Controller lag time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_dn\",\n                    \"comment\": \"Droop for over-frequency conditions\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": null,\n                        \"max\": 0\n                    }\n                },\n                {\n                    \"name\": \"D_up\",\n                    \"comment\": \"Droop for under-frequency conditions\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"dP_lim\",\n                    \"comment\": \"Upper/Lower limit on power reference ramp rates`(dP_min, dP_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_lim_inner\",\n                    \"comment\": \"Upper/Lower limit on power reference for REECB`(P_min_inner, P_max_inner)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_pord\",\n                    \"comment\": \"Power filter time constant REECB time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ActiveRenewableControllerAB model depends on the Flag\",\n                    \"internal_default\": \"PowerSystems.get_activeRETypeAB_states(Freq_Flag)[1]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The states of the ActiveRenewableControllerAB model depends on the Flag\",\n                    \"internal_default\": \"PowerSystems.get_activeRETypeAB_states(Freq_Flag)[2]\",\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ActivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ReactiveRenewableControllerAB\",\n            \"docstring\": \"Parameters of Reactive Power Controller including REPCA1 and REECB1\",\n            \"fields\": [\n                {\n                    \"name\": \"bus_control\",\n                    \"comment\": \"ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"from_branch_control\",\n                    \"comment\": \"Monitored branch FROM bus identification number for line drop compensation (if 0 generator power will be used)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"to_branch_control\",\n                    \"comment\": \"Monitored branch TO bus identification number for line drop compensation (if 0 generator power will be used)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"branch_id_control\",\n                    \"comment\": \"Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\",\n                    \"null_value\": 0,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"VC_Flag\",\n                    \"comment\": \"Voltage Compensator Flag for REPCA1\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Ref_Flag\",\n                    \"comment\": \"Flag for Reactive Power Control for REPCA1. 0: Q-control, 1: V-control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"PF_Flag\",\n                    \"comment\": \"Flag for Power Factor Control for Outer Control of REECB1. 0: Q-control, 1: Power Factor Control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"V_Flag\",\n                    \"comment\": \"Flag for Voltage Control for Outer Control of REECB1. 0: Voltage Control, 1: Q-Control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"T_fltr\",\n                    \"comment\": \"Voltage or Q-power of REPCA Filter Time Constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_p\",\n                    \"comment\": \"Reactive power PI control proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_i\",\n                    \"comment\": \"Reactive power PI control integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_ft\",\n                    \"comment\": \"Reactive power lead time constant (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_fv\",\n                    \"comment\": \"Reactive power lag time constant (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_frz\",\n                    \"comment\": \"Voltage below which state ξq_oc (integrator state) is freeze\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"R_c\",\n                    \"comment\": \"Line drop compensation resistance (used when VC_Flag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_c\",\n                    \"comment\": \"Line drop compensation reactance (used when VC_Flag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_c\",\n                    \"comment\": \"Reactive current compensation gain (pu) (used when VC_Flag = 0)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"e_lim\",\n                    \"comment\": \"Upper/Lower limit on Voltage or Q-power deadband output `(e_min, e_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"dbd_pnts\",\n                    \"comment\": \"Voltage or Q-power error dead band thresholds `(dbd1, dbd2)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"Q_lim\",\n                    \"comment\": \"Upper/Lower limit on reactive power V/Q control in REPCA `(Q_min, Q_max)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_p\",\n                    \"comment\": \"Active power lag time constant in REECB (s). Used only when PF_Flag = 1\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_lim_inner\",\n                    \"comment\": \"Upper/Lower limit on reactive power input in REECB `(Q_min_inner, Q_max_inner)`. Only used when V_Flag = 1\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_lim\",\n                    \"comment\": \"Upper/Lower limit on reactive power PI controller in REECB `(V_min, V_max)`. Only used when V_Flag = 1\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"K_qp\",\n                    \"comment\": \"Reactive power regulator proportional gain (used when V_Flag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_qi\",\n                    \"comment\": \"Reactive power regulator integral gain (used when V_Flag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reference Reactive Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ReactiveRenewableControllerAB model depends on the Flag\",\n                    \"internal_default\": \"PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[1]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The states of the ReactiveRenewableControllerAB model depends on the Flag\",\n                    \"internal_default\": \"PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[2]\",\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ReactivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ReactivePowerDroop\",\n            \"docstring\": \"Parameters of a Reactive Power droop controller\",\n            \"fields\": [\n                {\n                    \"name\": \"kq\",\n                    \"comment\": \"frequency droop gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ωf\",\n                    \"comment\": \"filter frequency cutoff\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ReactivePowerDroop model are:\\n\\tq_oc: Filtered reactive output power\",\n                    \"internal_default\": \"[:q_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ReactivePowerDroop has 1 state\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ReactivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ReactivePowerPI\",\n            \"docstring\": \"Parameters of a Proportional-Integral Reactive Power controller for a specified power reference\",\n            \"fields\": [\n                {\n                    \"name\": \"Kp_q\",\n                    \"comment\": \"Proportional Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Ki_q\",\n                    \"comment\": \"Integral Gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ωf\",\n                    \"comment\": \"filter frequency cutoff\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reactive Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ReactivePowerPI model are:\\n\\tσq_oc: Integrator state of the PI Controller,\\n\\tq_oc: Measured reactive power of the inverter model\",\n                    \"internal_default\": \"[:σq_oc, :q_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ReactivePowerPI has two states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ReactivePowerControl\"\n        },\n        {\n            \"struct_name\": \"ReactiveVirtualOscillator\",\n            \"docstring\": \"Parameters of a Reactive Virtual Oscillator controller. Model is based on [\\\"Model Reduction for Inverters with Current Limiting and Dispatchable Virtual Oscillator Control.\\\"](https://doi.org/10.1109/TEC.2021.3083488)\",\n            \"fields\": [\n                {\n                    \"name\": \"k2\",\n                    \"comment\": \"VOC voltage-amplitude control gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"Reference Voltage Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reference Reactive Power Set-point (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the ReactiveVirtualOscilator model are:\\n\\tE_oc: voltage reference state for inner control in the d-axis\",\n                    \"internal_default\": \"[:E_oc]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) ReactiveVirtualOscillator has 1 state\",\n                    \"internal_default\": 1,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"ReactivePowerControl\"\n        },\n        {\n            \"struct_name\": \"VoltageModeControl\",\n            \"docstring\": \"Parameters of an inner loop current control PID using virtual impedance based on [\\\"A Virtual Synchronous Machine implementation for distributed control of power converters in SmartGrids.\\\"](https://doi.org/10.1016/j.epsr.2015.01.001)\",\n            \"fields\": [\n                {\n                    \"name\": \"kpv\",\n                    \"comment\": \"voltage controller proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kiv\",\n                    \"comment\": \"voltage controller integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kffv\",\n                    \"comment\": \"Binary variable to enable feed-forward gain of voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rv\",\n                    \"comment\": \"virtual resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lv\",\n                    \"comment\": \"virtual inductance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kpc\",\n                    \"comment\": \"current controller proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kic\",\n                    \"comment\": \"current controller integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kffi\",\n                    \"comment\": \"Binary variable to enable feed-forward gain of current\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ωad\",\n                    \"comment\": \"active damping filter cutoff frequency (rad/sec)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kad\",\n                    \"comment\": \"active damping gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the VoltageModeControl model are:\\n\\tξd_ic: d-axis integrator state of the PI voltage controller,\\n\\tξq_ic: q-axis integrator state of the PI voltage controller,\\n\\tγd_ic: d-axis integrator state of the PI current controller,\\n\\tγq_ic: q-axis integrator state of the PI current controller,\\n\\tϕd_ic: d-axis low-pass filter of active damping,\\n\\tϕq_ic: q-axis low-pass filter of active damping\",\n                    \"internal_default\": \"[:ξd_ic, :ξq_ic, :γd_ic, :γq_ic, :ϕd_ic, :ϕq_ic]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) VoltageModeControl has 6 states\",\n                    \"internal_default\": 6,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"InnerControl\"\n        },\n        {\n            \"struct_name\": \"CurrentModeControl\",\n            \"docstring\": \"Parameters of an inner loop proportional integral (PI) current control based on [\\\"Reduced-order Structure-preserving Model for Parallel-connected Three-phase Grid-tied Inverters.\\\"](https://doi.org/10.1109/COMPEL.2017.8013389)\",\n            \"fields\": [\n                {\n                    \"name\": \"kpc\",\n                    \"comment\": \"Current controller proportional gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kic\",\n                    \"comment\": \"Current controller integral gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kffv\",\n                    \"comment\": \"Gain to enable feed-forward gain of voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the CurrentModeControl model are:\\n\\tγd_ic: d-axis integrator state of the PI current controller,\\n\\tγq_ic: q-axis integrator state of the PI current controller\",\n                    \"internal_default\": \"[:γd_ic, :γq_ic]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) CurrentControl has 2 states\",\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"InnerControl\"\n        },\n        {\n            \"struct_name\": \"RECurrentControlB\",\n            \"docstring\": \"Parameters of the Inner Control part of the REECB model in PSS/E\",\n            \"fields\": [\n                {\n                    \"name\": \"Q_Flag\",\n                    \"comment\": \"Q Flag used for I_qinj\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"PQ_Flag\",\n                    \"comment\": \"PQ Flag used for the Current Limit Logic\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Vdip_lim\",\n                    \"comment\": \"Limits for Voltage Dip Logic `(Vdip, Vup)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_rv\",\n                    \"comment\": \"Voltage Filter Time Constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"dbd_pnts\",\n                    \"comment\": \"Voltage error deadband thresholds `(dbd1, dbd2)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"K_qv\",\n                    \"comment\": \"Reactive current injection gain during over and undervoltage conditions\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iqinj_lim\",\n                    \"comment\": \"Limits for Iqinj `(I_qh1, I_ql1)`\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref0\",\n                    \"comment\": \"User defined reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_vp\",\n                    \"comment\": \"Voltage regulator proportional gain (used when QFlag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"K_vi\",\n                    \"comment\": \"Voltage regulator integral gain (used when QFlag = 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_iq\",\n                    \"comment\": \"Time constant for low-pass filter for state q_V when QFlag = 0\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on total converter current\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of the RECurrentControlB depends on the Flags\",\n                    \"internal_default\": \"PowerSystems.get_REControlB_states(Q_Flag)\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The states of the RECurrentControlB depends on the Flags\",\n                    \"internal_default\": \"2\",\n                    \"data_type\": \"Int\"\n                }\n            ],\n            \"supertype\": \"InnerControl\"\n        },\n        {\n            \"struct_name\": \"MagnitudeOutputCurrentLimiter\",\n            \"docstring\": \"Parameters of Magnitude (Circular) Current Controller Limiter. Regulates only the magnitude of the inverter output current\",\n            \"fields\": [\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                }\n            ],\n            \"supertype\": \"OutputCurrentLimiter\"\n        },\n        {\n            \"struct_name\": \"InstantaneousOutputCurrentLimiter\",\n            \"docstring\": \"Parameters of Instantaneous (Square) Current Controller Limiter. Regulates inverter output current on the d and q axis separately\",\n            \"fields\": [\n                {\n                    \"name\": \"Id_max\",\n                    \"comment\": \"Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iq_max\",\n                    \"comment\": \"Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                }\n            ],\n            \"supertype\": \"OutputCurrentLimiter\"\n        },\n        {\n            \"struct_name\": \"PriorityOutputCurrentLimiter\",\n            \"docstring\": \"Parameters of Priority-Based Current Controller Limiter. Regulates the magnitude of the inverter output current and prioritizes a specific angle for the resultant current signal\",\n            \"fields\": [\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ϕ_I\",\n                    \"comment\": \"Pre-defined angle (measured against the d-axis) for I_ref once limit I_max is hit\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": -1.571,\n                        \"max\": 1.571\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                }\n            ],\n            \"supertype\": \"OutputCurrentLimiter\"\n        },\n        {\n            \"struct_name\": \"SaturationOutputCurrentLimiter\",\n            \"docstring\": \"Parameters of Saturation Current Controller Limiter. Regulates the magnitude of the inverter output current, and applies a closed loop feedback regulated by a static gain which provides ant-windup\",\n            \"fields\": [\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on current controller input current (device base)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kw\",\n                    \"comment\": \"Defined feedback gain\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                }\n            ],\n            \"supertype\": \"OutputCurrentLimiter\"\n        },\n        {\n            \"struct_name\": \"HybridOutputCurrentLimiter\",\n            \"docstring\": \"Parameters of Hybrid Current Controller Limiter. Regulates the magnitude of the inverter output current, but with a closed loop feedback regulated by a virtual impedance which provides ant-windup. Described in: Novel Hybrid Current Limiter for Grid-Forming Inverter Control During Unbalanced Faults by Baeckland and Seo, 2023 \",\n            \"fields\": [\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on current controller input current (device base)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rv\",\n                    \"comment\": \"Real part of the virtual impedance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"lv\",\n                    \"comment\": \"Imaginary part of the virtual impedance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ext\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                }\n            ],\n            \"supertype\": \"OutputCurrentLimiter\"\n        },\n        {\n            \"struct_name\": \"AggregateDistributedGenerationA\",\n            \"docstring\": \"Parameters of the DERA1 model in PSS/E\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"Pf_Flag\",\n                    \"comment\": \"Flag for Power Factor Control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Freq_Flag\",\n                    \"comment\": \"Flag to enable/disable frequency control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"PQ_Flag\",\n                    \"comment\": \"Flag used to enforce maximum current\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Gen_Flag\",\n                    \"comment\": \"Flag to specify generator or storage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Vtrip_Flag\",\n                    \"comment\": \"Flag to enable/disable voltage trip logic\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Ftrip_Flag\",\n                    \"comment\": \"Flag to enable/disable frequency trip logic\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"T_rv\",\n                    \"comment\": \"Voltage measurement transducer time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Trf\",\n                    \"comment\": \"Frequency measurement transducer time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"dbd_pnts\",\n                    \"comment\": \"Voltage deadband thresholds `(dbd1, dbd2)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"K_qv\",\n                    \"comment\": \"Proportional voltage control gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tp\",\n                    \"comment\": \"Power measurement transducer time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"T_iq\",\n                    \"comment\": \"Time constant for low-pass filter for state q_V when QFlag = 0\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_dn\",\n                    \"comment\": \"Reciprocal of droop for over-frequency conditions (>0) (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_up\",\n                    \"comment\": \"Reciprocal of droop for under-frequency conditions <=0) (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fdbd_pnts\",\n                    \"comment\": \"Frequency control deadband thresholds `(fdbd1, fdbd2)`\",\n                    \"null_value\": \"(0.0, 0.0)\",\n                    \"data_type\": \"Tuple{Float64, Float64}\"\n                },\n                {\n                    \"name\": \"fe_lim\",\n                    \"comment\": \"Frequency error limits (femin, femax)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"P_lim\",\n                    \"comment\": \"Power limits (Pmin, Pmax)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"dP_lim\",\n                    \"comment\": \"Power reference ramp rate limits (dPmin, dPmax)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Tpord\",\n                    \"comment\": \"Power filter time constant\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kpg\",\n                    \"comment\": \"PI controller proportional gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kig\",\n                    \"comment\": \"PI controller integral gain (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Maximum limit on total converter current (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"vl_pnts\",\n                    \"comment\": \"Low voltage cutout points `[(tv10, vl0), (tv11, vl1)]`\",\n                    \"null_value\": \"[(0.0, 0.0), (0.0, 0.0)]\",\n                    \"data_type\": \"Vector{Tuple{Float64,Float64}}\"\n                },\n                {\n                    \"name\": \"vh_pnts\",\n                    \"comment\": \"High voltage cutout points `[(tvh0, vh0), (tvh1, vh1)]`\",\n                    \"null_value\": \"[(0.0, 0.0), (0.0, 0.0)]\",\n                    \"data_type\": \"Vector{Tuple{Float64,Float64}}\"\n                },\n                {\n                    \"name\": \"Vrfrac\",\n                    \"comment\": \"Fraction of device that recovers after voltage comes back to within vl1 < V < vh1 (0 <= Vrfrac <= 1)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"fl\",\n                    \"comment\": \"Inverter frequency break-point for low frequency cut-out (Hz)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fh\",\n                    \"comment\": \"Inverter frequency break-point for high frequency cut-out (Hz)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"tfl\",\n                    \"comment\": \"Low frequency cut-out timer corresponding to frequency fl (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"tfh\",\n                    \"comment\": \"High frequency cut-out timer corresponding to frequency fh (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tg\",\n                    \"comment\": \"Current control time constant (to represent behavior of inner control loops) (> 0) (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rrpwr\",\n                    \"comment\": \"Ramp rate for real power increase following a fault (pu/s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tv\",\n                    \"comment\": \"Time constant on the output of the multiplier (s)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Vpr\",\n                    \"comment\": \"Voltage below which frequency tripping is disabled (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iq_lim\",\n                    \"comment\": \"Reactive current injection limits (Iqll, Iqhl)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"V_ref\",\n                    \"comment\": \"User defined voltage reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Pfa_ref\",\n                    \"comment\": \"Reference power factor\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"ω_ref\",\n                    \"comment\": \"Reference Frequency (pu)\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reference reactive power, in pu\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference active power, in pu\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"100.0\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of AggregateDistributedGenerationA depends on the Flags\",\n                    \"internal_default\": \"PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[1]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The states of AggregateDistributedGenerationA depends on the Flags\",\n                    \"internal_default\": \"PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[2]\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"Source\",\n            \"docstring\": \"An infinite bus with a constant voltage output.\\n\\nCommonly used in dynamics simulations to represent a very large machine on a single bus or for the representation of import/exports in operational simulations\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"null_value\": \"false\",\n                    \"name\": \"available\",\n                    \"comment\": \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\",\n                    \"data_type\": \"Bool\"\n                },\n                {\n                    \"name\": \"bus\",\n                    \"comment\": \"Bus that this component is connected to\",\n                    \"null_value\": \"ACBus(nothing)\",\n                    \"data_type\": \"ACBus\"\n                },\n                {\n                    \"name\": \"active_power\",\n                    \"comment\": \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power\",\n                    \"comment\": \"Initial reactive power set point of the unit (MVAR)\",\n                    \"null_value\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"active_power_limits\",\n                    \"comment\": \"Minimum and maximum stable active power levels (MW)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\",\n                    \"default\": \"(min=0.0, max=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"reactive_power_limits\",\n                    \"comment\": \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\",\n                    \"validation_action\": \"warn\",\n                    \"null_value\": \"nothing\",\n                    \"data_type\": \"Union{Nothing, MinMax}\",\n                    \"default\": \"(min=0.0, max=0.0)\",\n                    \"needs_conversion\": true,\n                    \"conversion_unit\": \":mva\"\n                },\n                {\n                    \"name\": \"R_th\",\n                    \"comment\": \"Source Thevenin resistance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_th\",\n                    \"comment\": \"Source Thevenin reactance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem)\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"internal_voltage\",\n                    \"comment\": \"Internal Voltage (pu)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    },\n                    \"default\": \"1.0\"\n                },\n                {\n                    \"name\": \"internal_angle\",\n                    \"comment\": \"Internal Angle\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base Power in MVA\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"100.0\"\n                },\n                {\n                    \"name\": \"operation_cost\",\n                    \"null_value\": \"ImportExportCost(nothing)\",\n                    \"data_type\": \"ImportExportCost\",\n                    \"default\": \"ImportExportCost(nothing)\",\n                    \"comment\": \"[`ImportExportCost`](@ref) of the source.\"\n                },\n                {\n                    \"name\": \"dynamic_injector\",\n                    \"data_type\": \"Union{Nothing, DynamicInjection}\",\n                    \"comment\": \"corresponding dynamic injection device\",\n                    \"null_value\": \"nothing\",\n                    \"exclude_setter\": true,\n                    \"default\": \"nothing\"\n                },\n                {\n                    \"name\": \"services\",\n                    \"data_type\": \"Vector{Service}\",\n                    \"comment\": \"Services that this device contributes to\",\n                    \"null_value\": \"Device[]\",\n                    \"default\": \"Device[]\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"StaticInjection\"\n        },\n        {\n            \"struct_name\": \"PeriodicVariableSource\",\n            \"docstring\": \"This struct acts as an infinity bus with time varying phasor values magnitude and angle V(t) \\theta(t). Time varying functions are represented using fourier series\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"R_th\",\n                    \"comment\": \"Source Thevenin resistance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"X_th\",\n                    \"comment\": \"Source Thevenin reactance\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"internal_voltage_bias\",\n                    \"comment\": \"a0 term of the Fourier Series for the voltage\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"internal_voltage_frequencies\",\n                    \"comment\": \"Frequencies in radians/s\",\n                    \"null_value\": [\n                        0\n                    ],\n                    \"data_type\": \"Vector{Float64}\",\n                    \"default\": \"[0.0]\"\n                },\n                {\n                    \"name\": \"internal_voltage_coefficients\",\n                    \"comment\": \"Coefficients for terms n > 1. First component corresponds to sin and second component to cos\",\n                    \"null_value\": \"[(0.0, 0.0)]\",\n                    \"data_type\": \"Vector{Tuple{Float64,Float64}}\",\n                    \"default\": \"[(0.0, 0.0)]\"\n                },\n                {\n                    \"name\": \"internal_angle_bias\",\n                    \"comment\": \"a0 term of the Fourier Series for the angle\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"0.0\"\n                },\n                {\n                    \"name\": \"internal_angle_frequencies\",\n                    \"comment\": \"Frequencies in radians/s\",\n                    \"null_value\": [\n                        0\n                    ],\n                    \"data_type\": \"Vector{Float64}\",\n                    \"default\": \"[0.0]\"\n                },\n                {\n                    \"name\": \"internal_angle_coefficients\",\n                    \"comment\": \"Coefficients for terms n > 1. First component corresponds to sin and second component to cos\",\n                    \"null_value\": \"[(0.0, 0.0)]\",\n                    \"data_type\": \"Vector{Tuple{Float64,Float64}}\",\n                    \"default\": \"[(0.0, 0.0)]\"\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the source (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"100.0\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) for time, voltage and angle\",\n                    \"internal_default\": \"[:Vt, :θt]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) PeriodicVariableSource has 2 states\",\n                    \"null_value\": 2,\n                    \"internal_default\": 2,\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        },\n        {\n            \"struct_name\": \"GenericDER\",\n            \"docstring\": \"Parameters of a Generic Distributed Energy Resource Model. Based on [\\\"Modeling Framework and Coordination of DER and Flexible Loads for Ancillary Service Provision.\\\"](http://hdl.handle.net/10125/70994)\",\n            \"fields\": [\n                {\n                    \"null_value\": \"init\",\n                    \"name\": \"name\",\n                    \"comment\": \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\",\n                    \"exclude_setter\": true,\n                    \"data_type\": \"String\"\n                },\n                {\n                    \"name\": \"Qref_Flag\",\n                    \"comment\": \"Reactive Power Control Mode. 1 VoltVar Control, 2 Constant Q Control, 3 Constant PF Control\",\n                    \"null_value\": 1,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 1,\n                        \"max\": 3\n                    }\n                },\n                {\n                    \"name\": \"PQ_Flag\",\n                    \"comment\": \"Active and reactive power priority mode. 0 for Q priority, 1 for P priority\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Gen_Flag\",\n                    \"comment\": \"Define generator or storage system. 0 unit is a storage device, 1 unit is a generator\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"PerOp_Flag\",\n                    \"comment\": \"Defines operation of permisible region in VRT characteristic. 0 for cease, 1 for continuous operation\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Recon_Flag\",\n                    \"comment\": \"Defines if DER can reconnect after voltage ride-through disconnection\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Int\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"Trv\",\n                    \"comment\": \"Voltage measurement transducer's time constant, in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"VV_pnts\",\n                    \"comment\": \"Y-axis Volt-var curve points (V1,V2,V3,V4)\",\n                    \"null_value\": \"(V1=0.0, V2=0.0, V3=0.0, V4=0.0)\",\n                    \"data_type\": \"NamedTuple{(:V1, :V2, :V3, :V4), Tuple{Float64, Float64, Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"Q_lim\",\n                    \"comment\": \"Reactive power limits in pu (Q_min, Q_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Tp\",\n                    \"comment\": \"Power measurement transducer's time constant, in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"e_lim\",\n                    \"comment\": \"Error limit in PI controller for q control (e_min, e_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kpq\",\n                    \"comment\": \"PI controller proportional gain for q control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kiq\",\n                    \"comment\": \"PI controller integral gain for q control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Iqr_lim\",\n                    \"comment\": \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"I_max\",\n                    \"comment\": \"Max. inverter's current\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Tg\",\n                    \"comment\": \"Current control's time constant, in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"kWh_Cap\",\n                    \"comment\": \"BESS capacity in kWh\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"SOC_ini\",\n                    \"comment\": \"Initial state of charge (SOC) in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": 1\n                    }\n                },\n                {\n                    \"name\": \"SOC_lim\",\n                    \"comment\": \"Battery's SOC limits (SOC_min, SOC_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Trf\",\n                    \"comment\": \"Time constant to estimate system frequency, in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fdbd_pnts\",\n                    \"comment\": \"Frequency error dead band thresholds `(fdbd1, fdbd2)`\",\n                    \"null_value\": \"(fdbd1=0.0, fdbd2=0.0)\",\n                    \"data_type\": \"NamedTuple{(:fdbd1, :fdbd2), Tuple{Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"D_dn\",\n                    \"comment\": \"reciprocal of droop for over-frequency conditions, in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"D_up\",\n                    \"comment\": \"reciprocal of droop for under-frequency conditions, in pu\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"fe_lim\",\n                    \"comment\": \"Frequency error limits in pu (fe_min, fe_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Kpp\",\n                    \"comment\": \"PI controller proportional gain for p control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Kip\",\n                    \"comment\": \"PI controller integral gain for p control\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_lim\",\n                    \"comment\": \"Active power limits in pu (P_min, P_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"dP_lim\",\n                    \"comment\": \"Ramp rate limits for active power in pu/s (dP_min, dP_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"T_pord\",\n                    \"comment\": \"Power filter time constant in s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"rrpwr\",\n                    \"comment\": \"Ramp rate for real power increase following a fault, in pu/s\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"VRT_pnts\",\n                    \"comment\": \"Voltage ride through v points (vrt1,vrt2,vrt3,vrt4,vrt5)\",\n                    \"null_value\": \"(vrt1=0.0, vrt2=0.0, vrt3=0.0, vrt4=0.0, vrt5=0.0)\",\n                    \"data_type\": \"NamedTuple{(:vrt1, :vrt2, :vrt3, :vrt4, :vrt5), Tuple{Float64, Float64, Float64, Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"TVRT_pnts\",\n                    \"comment\": \"Voltage ride through time points (tvrt1,tvrt2,tvrt3)\",\n                    \"null_value\": \"(tvrt1=0.0, tvrt2=0.0, tvrt3=0.0)\",\n                    \"data_type\": \"NamedTuple{(:tvrt1, :tvrt2, :tvrt3), Tuple{Float64, Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"tV_delay\",\n                    \"comment\": \"Time delay for reconnection after voltage ride-through disconnection\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"VES_lim\",\n                    \"comment\": \"Min and max voltage for entering service (VES_min,VES_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"FRT_pnts\",\n                    \"comment\": \"Frequency ride through v points (frt1,frt2,frt3,frt4)\",\n                    \"null_value\": \"(frt1=0.0, frt2=0.0, frt3=0.0, frt4=0.0)\",\n                    \"data_type\": \"NamedTuple{(:frt1, :frt2, :frt3, :frt4), Tuple{Float64, Float64, Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"TFRT_pnts\",\n                    \"comment\": \"Frequency ride through time points (tfrt1,tfrt2)\",\n                    \"null_value\": \"(tfrt1=0.0, tfrt2=0.0)\",\n                    \"data_type\": \"NamedTuple{(:tfrt1, :tfrt2), Tuple{Float64, Float64}}\"\n                },\n                {\n                    \"name\": \"tF_delay\",\n                    \"comment\": \"Time delay for reconnection after frequency ride-through disconnection\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"FES_lim\",\n                    \"comment\": \"Min and max frequency for entering service (FES_min,FES_max)\",\n                    \"null_value\": \"(min=0.0, max=0.0)\",\n                    \"data_type\": \"MinMax\"\n                },\n                {\n                    \"name\": \"Pfa_ref\",\n                    \"comment\": \"Reference power factor\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"Q_ref\",\n                    \"comment\": \"Reference reactive power, in pu\",\n                    \"null_value\": 0,\n                    \"default\": \"0.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"P_ref\",\n                    \"comment\": \"Reference active power, in pu\",\n                    \"null_value\": 0,\n                    \"default\": \"1.0\",\n                    \"data_type\": \"Float64\",\n                    \"valid_range\": {\n                        \"min\": 0,\n                        \"max\": null\n                    }\n                },\n                {\n                    \"name\": \"base_power\",\n                    \"comment\": \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\",\n                    \"null_value\": 0,\n                    \"data_type\": \"Float64\",\n                    \"default\": \"100.0\"\n                },\n                {\n                    \"name\": \"states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\",\n                    \"internal_default\": \"PowerSystems.get_GenericDER_states(Qref_Flag)[1]\",\n                    \"data_type\": \"Vector{Symbol}\"\n                },\n                {\n                    \"name\": \"n_states\",\n                    \"exclude_setter\": true,\n                    \"comment\": \"(**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\",\n                    \"internal_default\": \"PowerSystems.get_GenericDER_states(Qref_Flag)[2]\",\n                    \"data_type\": \"Int\"\n                },\n                {\n                    \"name\": \"ext\",\n                    \"comment\": \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\",\n                    \"data_type\": \"Dict{String, Any}\",\n                    \"null_value\": \"Dict{String, Any}()\",\n                    \"default\": \"Dict{String, Any}()\"\n                },\n                {\n                    \"name\": \"internal\",\n                    \"comment\": \"(**Do not modify.**) PowerSystems.jl internal reference\",\n                    \"data_type\": \"InfrastructureSystemsInternal\",\n                    \"internal_default\": \"InfrastructureSystemsInternal()\",\n                    \"exclude_setter\": true\n                }\n            ],\n            \"supertype\": \"DynamicInjection\"\n        }\n    ],\n    \"struct_validation_descriptors\": [\n        {\n            \"struct_name\": \"DynamicGenerator\",\n            \"docstring\": \"\",\n            \"fields\": [\n                {\n                    \"name\": \"name\"\n                },\n                {\n                    \"name\": \"ω_ref\"\n                },\n                {\n                    \"name\": \"machine\"\n                },\n                {\n                    \"name\": \"shaft\"\n                },\n                {\n                    \"name\": \"avr\"\n                },\n                {\n                    \"name\": \"prime_mover\"\n                },\n                {\n                    \"name\": \"pss\"\n                },\n                {\n                    \"name\": \"base_power\"\n                },\n                {\n                    \"name\": \"n_states\"\n                },\n                {\n                    \"name\": \"states\"\n                },\n                {\n                    \"name\": \"ext\"\n                },\n                {\n                    \"name\": \"internal\"\n                }\n            ]\n        },\n        {\n            \"struct_name\": \"DynamicInverter\",\n            \"docstring\": \"\",\n            \"fields\": [\n                {\n                    \"name\": \"name\"\n                },\n                {\n                    \"name\": \"ω_ref\"\n                },\n                {\n                    \"name\": \"converter\"\n                },\n                {\n                    \"name\": \"outer_control\"\n                },\n                {\n                    \"name\": \"inner_control\"\n                },\n                {\n                    \"name\": \"dc_source\"\n                },\n                {\n                    \"name\": \"freq_estimator\"\n                },\n                {\n                    \"name\": \"filter\"\n                },\n                {\n                    \"name\": \"limiter\"\n                },\n                {\n                    \"name\": \"base_power\"\n                },\n                {\n                    \"name\": \"n_states\"\n                },\n                {\n                    \"name\": \"states\"\n                },\n                {\n                    \"name\": \"ext\"\n                },\n                {\n                    \"name\": \"internal\"\n                }\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "src/get_components_interface.jl",
    "content": "# The longstanding status quo in Sienna has been for `PSY.get_components` to be distinct\n# from `IS.get_components`, mostly so that PowerSystems users aren't confused by all the\n# InfrastructureSystems methods. This lack of a unified interface on \"things with\n# components\" has begun to cause problems, most notably for ComponentSelector. Therefore,\n# the new plan is:\n#   1. Implement, wherever relevant, methods of the IS `get_components`-like functions\n#      listed below on PSY data structures.\n#   2. Add, in this file, methods of the PSY `get_components`-like functions that purely\n#      redirect to the IS versions and have the documentation PSY users should see. Never\n#      add actual functionality in these PSY methods; they must only redirect to the IS\n#      versions. Purely to facilitate neater documentation, add `ComponentSelector`-related\n#      methods in the follow-on file `component_selector_interface.jl` instead.\n#   3. In downstream Sienna packages like PowerSimulations that seek to add their own\n#      `get_components`-like methods on their own data structures that show up in\n#      user-friendly documentation, do the same thing: add the implementation in the IS\n#      method and add a PSY method that purely redirects.\n#   4. Internal code designed to work with all \"things with components\" should use the IS\n#      functions, not the PSY ones.\n\n# This design preserves the simplified interface presented to the casual PSY user while\n# allowing for better cross-package integration behind the scenes. It also enables a quick\n# switch to a design where we no longer maintain two versions of each `get_components`-like\n# function at the cost of slightly more confusing documentation -- simply import the IS\n# versions into PowerSystems and delete this file (and analogous redirects in downstream\n# packages). See https://github.com/Sienna-Platform/InfrastructureSystems.jl/issues/388.\n\n# Here is the current list of \"`get_components`-like functions\" to which this plan applies:\n#  - `get_components`\n#  - `get_component`\n#  - `get_available_components`\n#  - `get_available_component`\n#  - `get_groups`\n#  - `get_available_groups`\n\n# get_components\n\"\"\"\nReturn an iterator of components of a given `Type` from a [`System`](@ref).\n\n`T` can be a concrete or abstract [`Component`](@ref) type from the [Type Tree](@ref).\nCall collect on the result if an array is desired.\n\n# Examples\n```julia\niter = get_components(ThermalStandard, sys)\niter = get_components(Generator, sys)\ngenerators = collect(get_components(Generator, sys))\n```\n\nSee also: [`iterate_components`](@ref), [`get_components` with a filter](@ref get_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component}),\n[`get_available_components`](@ref), [`get_buses`](@ref)\n\"\"\"\nget_components(::Type{T}, sys::System; subsystem_name = nothing) where {T <: Component} =\n    IS.get_components(T, sys; subsystem_name = subsystem_name)\n\n\"\"\"\nReturn a vector of components that are attached to the supplemental attribute.\n\n# Arguments\n- `sys::System`: the `System` to search\n- `attribute::SupplementalAttribute`: Only return components associated with this attribute.\n- `component_type::Union{Nothing, <:Component}`: Optional type of the components to return.\n  Can be concrete or abstract. If not provided, all components associated with the attribute\n  will be returned.\n\"\"\"\nfunction get_associated_components(\n    sys::System,\n    attribute::SupplementalAttribute;\n    component_type::Union{Nothing, Type{<:Component}} = nothing,\n)\n    return IS.get_associated_components(\n        sys.data,\n        attribute;\n        component_type = component_type,\n    )\nend\n\n@deprecate get_components(sys::System, attribute::SupplementalAttribute) get_associated_components(\n    sys,\n    attribute,\n)\n\n\"\"\"\nReturn a vector of components that are associated to one or more supplemental attributes of\nthe given type.\n\"\"\"\nfunction get_associated_components(\n    sys::System,\n    attribute_type::Type{<:SupplementalAttribute};\n    component_type::Union{Nothing, Type{<:Component}} = nothing,\n)\n    return IS.get_associated_components(\n        sys.data,\n        attribute_type;\n        component_type = component_type,\n    )\nend\n\n\"\"\"\nReturn an iterator of components of a given `Type` from a [`System`](@ref), using an\nadditional filter\n\n`T` can be a concrete or abstract [`Component`](@ref) type from the [Type Tree](@ref).\nCall collect on the result if an array is desired.\n\n# Examples\n```julia\niter_coal = get_components(x -> get_fuel(x) == ThermalFuels.COAL, Generator, sys)\npv_gens =\n    collect(get_components(x -> get_prime_mover_type(x) == PrimeMovers.PVe, Generator, sys))\n```\n\nSee also: [`get_components`](@ref get_components(\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component}), [`get_available_components`](@ref),\n[`get_buses`](@ref)\n\"\"\"\nget_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component} =\n    IS.get_components(filter_func, T, sys; subsystem_name = subsystem_name)\n\n# get_component\n\"\"\"\nGet the component by UUID.\n\"\"\"\nget_component(sys::System, uuid::Base.UUID) = IS.get_component(sys, uuid)\nget_component(sys::System, uuid::String) = IS.get_component(sys, uuid)\n\n\"\"\"\nGet the component of type T with name. Returns nothing if no component matches. If T is an abstract\ntype then the names of components across all subtypes of T must be unique.\n\nSee [`get_components_by_name`](@ref) for abstract types with non-unique names across subtypes.\n\nThrows ArgumentError if T is not a concrete type and there is more than one component with\n    requested name\n\"\"\"\nget_component(::Type{T}, sys::System, name::AbstractString) where {T <: Component} =\n    IS.get_component(T, sys, name)\n\n# get_available_components\n\"\"\"\nLike [`get_components`](@ref get_components(\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n    ) where {T <: Component}\n) but returns only components that are [`get_available`](@ref).\n```\n\"\"\"\nget_available_components(\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component} =\n    IS.get_available_components(T, sys; subsystem_name = subsystem_name)\n\n\"\"\"\nLike [`get_components`](@ref get_components(\n    sys::System,\n    attribute::SupplementalAttribute\n) but returns only components that are [`get_available`](@ref).\n\"\"\"\nget_available_components(sys::System, attribute::SupplementalAttribute) =\n    IS.get_available_components(sys, attribute)\n\n\"\"\"\nLike [`get_components`](@ref get_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n    ) where {T <: Component}\n) but returns only components that are [`get_available`](@ref).\n\"\"\"\nget_available_components(\n    filter_func::Function,\n    ::Type{T},\n    sys::System;\n    subsystem_name = nothing,\n) where {T <: Component} =\n    IS.get_available_components(filter_func, T, sys; subsystem_name = subsystem_name)\n\n# get_available_component\n\"\"\"\nGet the available component by UUID.\n\"\"\"\nget_available_component(sys::System, uuid::Base.UUID) =\n    IS.get_available_component(sys, uuid)\nget_available_component(sys::System, uuid::String) = IS.get_available_component(sys, uuid)\n\n\"\"\"\nLike [`get_component`](@ref) but also returns `nothing` if the component is not [`get_available`](@ref).\n\"\"\"\nget_available_component(::Type{T}, sys::System, args...; kwargs...) where {T <: Component} =\n    IS.get_available_component(T, sys, args...; kwargs...)\n"
  },
  {
    "path": "src/impedance_correction.jl",
    "content": "\"\"\"\nAttribute that contains information regarding the Impedance Correction Table (ICT) rows defined in the Table.\n\n# Arguments\n- `table_number::Int64`: Row number of the ICT to be linked with a specific Transformer component.\n- `impedance_correction_curve::`[`PiecewiseLinearData`](@extref InfrastructureSystems.PiecewiseLinearData): Function to define intervals (tap ratio/angle shift) in the Transformer component.\n- `transformer_winding::`[`WindingCategory`](@ref): Indicates the winding to which the ICT is linked to for a Transformer component.\n- `transformer_control_mode::`[`ImpedanceCorrectionTransformerControlMode`](@ref): Defines the control modes of the Transformer, whether is for off-nominal turns ratio or phase angle shifts.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct ImpedanceCorrectionData <: SupplementalAttribute\n    table_number::Int64\n    impedance_correction_curve::PiecewiseLinearData\n    transformer_winding::WindingCategory\n    transformer_control_mode::ImpedanceCorrectionTransformerControlMode\n    internal::InfrastructureSystemsInternal\nend\n\n\"\"\"\n    ImpedanceCorrectionData(; table_number, impedance_correction_curve, transformer_winding, transformer_control_mode, internal)\n\nConstruct an [`ImpedanceCorrectionData`](@ref).\n\n# Arguments\n- `table_number::Int64`: Row number of the ICT to be linked with a specific Transformer component.\n- `impedance_correction_curve::`[`PiecewiseLinearData`](@extref  InfrastructureSystems.PiecewiseLinearData): Function to define intervals (tap ratio/angle shift) in the Transformer component.\n- `transformer_winding::`[`WindingCategory`](@ref): Indicates the winding to which the ICT is linked to for a Transformer component.\n- `transformer_control_mode::`[`ImpedanceCorrectionTransformerControlMode`](@ref): Defines the control modes of the Transformer, whether is for off-nominal turns ratio or phase angle shifts.\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction ImpedanceCorrectionData(;\n    table_number,\n    impedance_correction_curve,\n    transformer_winding,\n    transformer_control_mode,\n    internal = InfrastructureSystemsInternal(),\n)\n    return ImpedanceCorrectionData(\n        table_number,\n        impedance_correction_curve,\n        transformer_winding,\n        transformer_control_mode,\n        internal,\n    )\nend\n\n\"\"\"Get [`ImpedanceCorrectionData`](@ref) `table_number`.\"\"\"\nget_table_number(value::ImpedanceCorrectionData) = value.table_number\n\"\"\"Get [`ImpedanceCorrectionData`](@ref) `function_data`.\"\"\"\nget_impedance_correction_curve(value::ImpedanceCorrectionData) =\n    value.impedance_correction_curve\n\"\"\"Get [`ImpedanceCorrectionData`](@ref) `transformer_winding`.\"\"\"\nget_transformer_winding(value::ImpedanceCorrectionData) = value.transformer_winding\n\"\"\"Get [`ImpedanceCorrectionData`](@ref) `transformer_control_mode`.\"\"\"\nget_transformer_control_mode(value::ImpedanceCorrectionData) =\n    value.transformer_control_mode\n\"\"\"Get [`ImpedanceCorrectionData`](@ref) `internal`.\"\"\"\nget_internal(value::ImpedanceCorrectionData) = value.internal\n"
  },
  {
    "path": "src/models/HybridSystem.jl",
    "content": "\"\"\"\n    mutable struct HybridSystem <: StaticInjectionSubsystem\n        name::String\n        available::Bool\n        status::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        base_power::Float64\n        operation_cost::MarketBidCost\n        thermal_unit::Union{Nothing, ThermalGen}\n        electric_load::Union{Nothing, ElectricLoad}\n        storage::Union{Nothing, Storage}\n        renewable_unit::Union{Nothing, RenewableGen}\n        interconnection_impedance::ComplexF64\n        interconnection_rating::Union{Nothing, Float64}\n        input_active_power_limits::Union{Nothing, MinMax}\n        output_active_power_limits::Union{Nothing, MinMax}\n        reactive_power_limits::Union{Nothing, MinMax}\n        interconnection_efficiency::Union{\n            Nothing,\n            NamedTuple{(:in, :out), Tuple{Float64, Float64}},\n        }\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA Hybrid System that includes a combination of renewable generation, load, thermal\ngeneration and/or energy storage.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `status::Bool`: Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR)\n- `base_power::Float64`: Base power of the unit (MVA) for per unitization, which is commonly the same as `rating`\n- `operation_cost::MarketBidCost`: Market bid cost to operate, [`MarketBidCost`](@ref)\n- `thermal_unit::Union{Nothing, ThermalGen}`: A thermal generator with supertype [`ThermalGen`](@ref)\n- `electric_load::Union{Nothing, ElectricLoad}`: A load with supertype [`ElectricLoad`](@ref)\n- `storage::Union{Nothing, Storage}`: An energy storage system with supertype [`Storage`](@ref)\n- `renewable_unit::Union{Nothing, RenewableGen}`: A renewable generator with supertype [`RenewableGen`](@ref)\n- `interconnection_impedance::ComplexF64`: Impedance (typically in p.u.) between the hybrid system and the grid interconnection\n- `interconnection_rating::Union{Nothing, Float64}`: Maximum rating of the hybrid system's interconnection with the transmission network (MVA)\n- `input_active_power_limits::MinMax`: Minimum and maximum stable input active power levels (MW)\n- `output_active_power_limits::MinMax`: Minimum and maximum stable output active power levels (MW)\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits (MVAR). Set to `Nothing` if not applicable.\n- `interconnection_efficiency::Union{Nothing, NamedTuple{(:in, :out), Tuple{Float64, Float64}},}`: Efficiency [0, 1.0] at the grid interconnection to model losses `in` and `out` of the common DC-side conversion\n- `services::Vector{Service}`: (optional) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (optional) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (optional) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference.\n\"\"\"\nmutable struct HybridSystem <: StaticInjectionSubsystem\n    name::String\n    available::Bool\n    status::Bool\n    bus::ACBus\n    active_power::Float64\n    reactive_power::Float64\n    base_power::Float64\n    operation_cost::MarketBidCost\n    thermal_unit::Union{Nothing, ThermalGen}\n    electric_load::Union{Nothing, ElectricLoad}\n    storage::Union{Nothing, Storage}\n    renewable_unit::Union{Nothing, RenewableGen}\n    # interconnection Data\n    \"Thermal limited MVA Power Output of the unit. <= Capacity\"\n    interconnection_impedance::ComplexF64\n    interconnection_rating::Union{Nothing, Float64}\n    input_active_power_limits::Union{Nothing, MinMax}\n    output_active_power_limits::Union{Nothing, MinMax}\n    reactive_power_limits::Union{Nothing, MinMax}\n    interconnection_efficiency::Union{\n        Nothing,\n        NamedTuple{(:in, :out), Tuple{Float64, Float64}},\n    }\n    \"corresponding dynamic injection device\"\n    services::Vector{Service}\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    ext::Dict{String, Any}\n    \"internal forecast storage\"\n    \"power system internal reference, do not modify\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HybridSystem(;\n    name = \"init\",\n    available = false,\n    status = false,\n    bus = ACBus(nothing),\n    active_power = 0.0,\n    reactive_power = 0.0,\n    base_power = 100.0,\n    operation_cost = MarketBidCost(nothing),\n    thermal_unit = nothing,\n    electric_load = nothing,\n    storage = nothing,\n    renewable_unit = nothing,\n    interconnection_impedance = 0.0,\n    interconnection_rating = nothing,\n    input_active_power_limits = nothing,\n    output_active_power_limits = nothing,\n    reactive_power_limits = nothing,\n    interconnection_efficiency = nothing,\n    services = Service[],\n    dynamic_injector = nothing,\n    ext = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    return HybridSystem(\n        name,\n        available,\n        status,\n        bus,\n        active_power,\n        reactive_power,\n        base_power,\n        operation_cost,\n        thermal_unit,\n        electric_load,\n        storage,\n        renewable_unit,\n        interconnection_impedance,\n        interconnection_rating,\n        input_active_power_limits,\n        output_active_power_limits,\n        reactive_power_limits,\n        interconnection_efficiency,\n        services,\n        dynamic_injector,\n        ext,\n        internal,\n    )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HybridSystem(::Nothing)\n    return HybridSystem(;\n        name = \"init\",\n        available = false,\n        status = false,\n        bus = ACBus(nothing),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        base_power = 100.0,\n        operation_cost = MarketBidCost(nothing),\n        thermal_unit = ThermalStandard(nothing),\n        electric_load = PowerLoad(nothing),\n        storage = EnergyReservoirStorage(nothing),\n        renewable_unit = RenewableDispatch(nothing),\n        interconnection_impedance = 0.0,\n        interconnection_rating = nothing,\n        input_active_power_limits = nothing,\n        output_active_power_limits = nothing,\n        reactive_power_limits = nothing,\n        interconnection_efficiency = nothing,\n        services = Service[],\n        dynamic_injector = nothing,\n        ext = Dict{String, Any}(),\n        internal = InfrastructureSystemsInternal(),\n    )\nend\n\nget_name(value::HybridSystem) = value.name\n\nfunction _get_components(value::HybridSystem)\n    components =\n        [value.thermal_unit, value.electric_load, value.storage, value.renewable_unit]\n    filter!(x -> !isnothing(x), components)\n    return components\nend\n\nfunction set_units_setting!(value::HybridSystem, settings::SystemUnitsSettings)\n    set_units_info!(get_internal(value), settings)\n    for component in _get_components(value)\n        set_units_info!(get_internal(component), settings)\n    end\n    return\nend\n\n\"\"\"Get [`HybridSystem`](@ref) `available`.\"\"\"\nget_available(value::HybridSystem) = value.available\n\"\"\"Get [`HybridSystem`](@ref) `status`.\"\"\"\nget_status(value::HybridSystem) = value.status\n\"\"\"Get [`HybridSystem`](@ref) `bus`.\"\"\"\nget_bus(value::HybridSystem) = value.bus\n\"\"\"Get [`HybridSystem`](@ref) `active_power`.\"\"\"\nget_active_power(value::HybridSystem) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`HybridSystem`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::HybridSystem) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`HybridSystem`](@ref) thermal unit\"\"\"\nget_thermal_unit(value::HybridSystem) = value.thermal_unit\n\"\"\"Get [`HybridSystem`](@ref) load\"\"\"\nget_electric_load(value::HybridSystem) = value.electric_load\n\"\"\"Get [`HybridSystem`](@ref) storage unit\"\"\"\nget_storage(value::HybridSystem) = value.storage\n\"\"\"Get [`HybridSystem`](@ref) renewable unit\"\"\"\nget_renewable_unit(value::HybridSystem) = value.renewable_unit\n\"\"\"Get [`HybridSystem`](@ref) `interconnection_rating`.\"\"\"\nget_interconnection_rating(value::HybridSystem) =\n    get_value(value, Val(:interconnection_rating), Val(:mva))\n\"\"\"get [`HybridSystem`](@ref) interconnection impedance\"\"\"\nget_interconnection_impedance(value::HybridSystem) = value.interconnection_impedance\n\"\"\"Get [`HybridSystem`](@ref) `input_active_power_limits`.\"\"\"\nget_input_active_power_limits(value::HybridSystem) =\n    get_value(value, Val(:input_active_power_limits), Val(:mva))\n\"\"\"Get [`HybridSystem`](@ref) `output_active_power_limits`.\"\"\"\nget_output_active_power_limits(value::HybridSystem) =\n    get_value(value, Val(:output_active_power_limits), Val(:mva))\n\"\"\"Get [`HybridSystem`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::HybridSystem) =\n    get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"get [`HybridSystem`](@ref) interconnection efficiency\"\"\"\nget_interconnection_efficiency(value::HybridSystem) = value.interconnection_efficiency\n\"\"\"Get [`HybridSystem`](@ref) `base_power`.\"\"\"\nget_base_power(value::HybridSystem) = value.base_power\n\"\"\"Get [`HybridSystem`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::HybridSystem) = value.operation_cost\n\"\"\"Get [`HybridSystem`](@ref) `services`.\"\"\"\nget_services(value::HybridSystem) = value.services\n\"\"\"Get [`HybridSystem`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::HybridSystem) = value.dynamic_injector\n\"\"\"Get [`HybridSystem`](@ref) `ext`.\"\"\"\nget_ext(value::HybridSystem) = value.ext\n\n\"\"\"Get [`HybridSystem`](@ref) `internal`.\"\"\"\nget_internal(value::HybridSystem) = value.internal\n\n\"\"\"Set [`HybridSystem`](@ref) `available`.\"\"\"\nset_available!(value::HybridSystem, val) = value.available = val\n\"\"\"Get [`HybridSystem`](@ref) `status`.\"\"\"\nset_status!(value::HybridSystem, val) = value.status = val\n\"\"\"Set [`HybridSystem`](@ref) `bus`.\"\"\"\nset_bus!(value::HybridSystem, val) = value.bus = val\n\"\"\"Set [`HybridSystem`](@ref) `interconnection_rating`.\"\"\"\nset_interconnection_rating!(value::HybridSystem, val) = value.interconnection_rating = val\n\"\"\"Set [`HybridSystem`](@ref) `active_power`.\"\"\"\nset_active_power!(value::HybridSystem, val) = value.active_power = val\n\"\"\"Set [`HybridSystem`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::HybridSystem, val) = value.reactive_power = val\n\"\"\"set [`HybridSystem`](@ref) interconnection impedance\"\"\"\nset_interconnection_impedance!(value::HybridSystem, val) =\n    value.interconnection_impedance = val\n\"\"\"Set [`HybridSystem`](@ref) `input_active_power_limits`.\"\"\"\nset_input_active_power_limits!(value::HybridSystem, val) =\n    value.input_active_power_limits = val\n\"\"\"Set [`HybridSystem`](@ref) `output_active_power_limits`.\"\"\"\nset_output_active_power_limits!(value::HybridSystem, val) =\n    value.output_active_power_limits = val\n\"\"\"Set [`HybridSystem`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::HybridSystem, val) = value.reactive_power_limits = val\n\"\"\"Set [`HybridSystem`](@ref) `interconnection_efficiency`.\"\"\"\nset_interconnection_efficiency!(value::HybridSystem, val) =\n    value.interconnection_rating = val\n\"\"\"Set [`HybridSystem`](@ref) `base_power`.\"\"\"\nset_base_power!(value::HybridSystem, val) = value.base_power = val\n\"\"\"Set [`HybridSystem`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::HybridSystem, val) = value.operation_cost = val\n\"\"\"Set [`HybridSystem`](@ref) `services`.\"\"\"\nset_services!(value::HybridSystem, val) = value.services = val\n\"\"\"Set [`HybridSystem`](@ref) `ext`.\"\"\"\nset_ext!(value::HybridSystem, val) = value.ext = val\n\n\"\"\"\nReturn an iterator over the subcomponents in the HybridSystem.\n\n# Examples\n```julia\nfor subcomponent in get_subcomponents(hybrid_sys)\n    @show subcomponent\nend\nsubcomponents = collect(get_subcomponents(hybrid_sys))\n```\n\"\"\"\nfunction get_subcomponents(hybrid::HybridSystem)\n    Channel() do channel\n        for field in (:thermal_unit, :electric_load, :storage, :renewable_unit)\n            subcomponent = getfield(hybrid, field)\n            if subcomponent !== nothing\n                put!(channel, subcomponent)\n            end\n        end\n    end\nend\n\n\"\"\"Set [`HybridSystem`](@ref) thermal unit\"\"\"\nfunction set_thermal_unit!(hybrid::HybridSystem, val::ThermalGen)\n    _raise_if_attached_to_system(hybrid)\n    hybrid.thermal_unit = val\n    return\nend\n\n\"\"\"Set [`HybridSystem`](@ref) load\"\"\"\nfunction set_electric_load!(hybrid::HybridSystem, val::ElectricLoad)\n    _raise_if_attached_to_system(hybrid)\n    value.electric_load = val\n    return\nend\n\n\"\"\"Set [`HybridSystem`](@ref) storage unit\"\"\"\nfunction set_storage!(hybrid::HybridSystem, val::Storage)\n    _raise_if_attached_to_system(hybrid)\n    value.storage = val\n    return\nend\n\n\"\"\"Set [`HybridSystem`](@ref) renewable unit\"\"\"\nfunction set_renewable_unit!(hybrid::HybridSystem, val::RenewableGen)\n    _raise_if_attached_to_system(hybrid)\n    value.renewable_unit = val\n    return\nend\n\nfunction _raise_if_attached_to_system(hybrid::HybridSystem)\n    if !isnothing(IS.get_time_series_manager(hybrid))\n        throw(\n            ArgumentError(\n                \"Operation not allowed because the HybridSystem is attached to a system\",\n            ),\n        )\n    end\n    return\nend\n"
  },
  {
    "path": "src/models/OuterControl.jl",
    "content": "\"\"\"\n    mutable struct OuterControl{\n        A <: ActivePowerControl,\n        R <: ReactivePowerControl\n    } <: DynamicInverterComponent\n        active_power_control::A\n        reactive_power_control::R\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\nParameters of a Outer-Loop controller using a active power controller and a reactive power droop controller.\n\n# Arguments\n- `A <: ActivePowerControl`: Active power controller (typically droop or virtual inertia).\n- `R <: ReactivePowerControl`: Reactive power controller (typically droop).\n- `ext::Dict{String, Any}`\n- `states::Vector{Symbol}`: Vector of states (will depend on the components).\n- `n_states::Int`: Number of states (will depend on the components).\n\"\"\"\nmutable struct OuterControl{A <: ActivePowerControl, R <: ReactivePowerControl} <:\n               DynamicInverterComponent\n    active_power_control::A\n    reactive_power_control::R\n    ext::Dict{String, Any}\n    states::Vector{Symbol}\n    n_states::Int\nend\n\nfunction OuterControl(\n    active_power_control::A,\n    reactive_power_control::R,\n    ext = Dict{String, Any}(),\n) where {A <: ActivePowerControl, R <: ReactivePowerControl}\n    return OuterControl(\n        active_power_control,\n        reactive_power_control,\n        ext,\n        vcat(active_power_control.states, reactive_power_control.states),\n        active_power_control.n_states + reactive_power_control.n_states,\n    )\nend\n\nfunction OuterControl(;\n    active_power_control,\n    reactive_power_control,\n    ext = Dict{String, Any}(),\n    states = nothing,\n    n_states = nothing,\n)\n    if states === nothing\n        @assert n_states === nothing\n        return OuterControl(active_power_control, reactive_power_control, ext)\n    end\n    @assert n_states !== nothing\n    return OuterControl(active_power_control, reactive_power_control, ext, states, n_states)\nend\n\n\"\"\"Get `active_power_control` from [`OuterControl`](@ref).\"\"\"\nget_active_power_control(value::OuterControl) = value.active_power_control\n\"\"\"Get `reactive_power_control` from [`OuterControl`](@ref).\"\"\"\nget_reactive_power_control(value::OuterControl) = value.reactive_power_control\n\"\"\"Get `ext` from [`OuterControl`](@ref).\"\"\"\nget_ext(value::OuterControl) = value.ext\n\"\"\"Get `states` from [`OuterControl`](@ref).\"\"\"\nget_states(value::OuterControl) = value.states\n\"\"\"Get `n_states` from [`OuterControl`](@ref).\"\"\"\nget_n_states(value::OuterControl) = value.n_states\n\"\"\"Set [`OuterControl`](@ref) `active_power_control`.\"\"\"\nset_active_power_control!(value::OuterControl, val) =\n    value.active_power_control = val\n\"\"\"Set [`OuterControl`](@ref) `reactive_power_control`.\"\"\"\nset_reactive_power_control!(value::OuterControl, val) =\n    value.reactive_power_control = val\n\"\"\"Set [`OuterControl`](@ref) `ext`.\"\"\"\nset_ext!(value::OuterControl, val) = value.ext = val\n"
  },
  {
    "path": "src/models/RoundRotorExponential.jl",
    "content": "\"\"\"\n    mutable struct RoundRotorExponential <: Machine\n        base_machine::RoundRotorMachine\n        saturation_coeffs::Tuple{Float64, Float64}\n\n4-states round-rotor synchronous machine with exponential saturation:\nIEEE Std 1110 §5.3.2 (Model 2.2). GENROE model in PSSE and PSLF.\n\n# Arguments\n- `base_machine::RoundRotorMachine`: Round Rotor Machine model.\n- `saturation_coeffs::Tuple{Float64, Float64}``: Saturation coefficients for exponential model.\n\"\"\"\nmutable struct RoundRotorExponential <: Machine\n    base_machine::RoundRotorMachine\n    saturation_coeffs::Tuple{Float64, Float64}\nend\n\nIS.@forward((RoundRotorExponential, :base_machine), RoundRotorMachine)\n\nfunction RoundRotorExponential(\n    R::Float64,\n    Td0_p::Float64,\n    Td0_pp::Float64,\n    Tq0_p::Float64,\n    Tq0_pp::Float64,\n    Xd::Float64,\n    Xq::Float64,\n    Xd_p::Float64,\n    Xq_p::Float64,\n    Xd_pp::Float64,\n    Xl::Float64,\n    Se::Tuple{Float64, Float64},\n)\n    saturation_coeffs = get_exponential_saturation(Se)\n    return RoundRotorExponential(\n        RoundRotorMachine(\n            R,\n            Td0_p,\n            Td0_pp,\n            Tq0_p,\n            Tq0_pp,\n            Xd,\n            Xq,\n            Xd_p,\n            Xq_p,\n            Xd_pp,\n            Xl,\n            Se,\n        ),\n        saturation_coeffs,\n    )\nend\n\nfunction RoundRotorExponential(;\n    R,\n    Td0_p,\n    Td0_pp,\n    Tq0_p,\n    Tq0_pp,\n    Xd,\n    Xq,\n    Xd_p,\n    Xq_p,\n    Xd_pp,\n    Xl,\n    Se,\n)\n    return RoundRotorExponential(\n        R,\n        Td0_p,\n        Td0_pp,\n        Tq0_p,\n        Tq0_pp,\n        Xd,\n        Xq,\n        Xd_p,\n        Xq_p,\n        Xd_pp,\n        Xl,\n        Se,\n    )\nend\n\nfunction RoundRotorExponential(::Nothing)\n    return RoundRotorExponential(;\n        R = 0.0,\n        Td0_p = 0.0,\n        Td0_pp = 0.0,\n        Tq0_p = 0.0,\n        Tq0_pp = 0.0,\n        Xd = 0.0,\n        Xq = 0.0,\n        Xd_p = 0.0,\n        Xq_p = 0.0,\n        Xd_pp = 0.0,\n        Xl = 0.0,\n        Se = (0.0, 0.0),\n    )\nend\n\nget_base_machine(value::RoundRotorExponential) = value.base_machine\nget_saturation_coeffs(value::RoundRotorExponential) = value.saturation_coeffs\nset_base_machine!(value::RoundRotorExponential, val::RoundRotorMachine) =\n    value.base_machine = val\nset_saturation_coeffs!(value::RoundRotorExponential, val::Tuple{Float64, Float64}) =\n    value.saturation_coeffs = val\n\nfunction IS.deserialize_struct(::Type{RoundRotorExponential}, data::Dict)\n    vals = IS.deserialize_to_dict(RoundRotorExponential, data)\n    return RoundRotorExponential(vals[:base_machine], vals[:saturation_coeffs])\nend\n"
  },
  {
    "path": "src/models/RoundRotorQuadratic.jl",
    "content": "\"\"\"\n    mutable struct RoundRotorQuadratic <: Machine\n        base_machine::RoundRotorMachine\n        saturation_coeffs::Tuple{Float64, Float64}\n\n4-states round-rotor synchronous machine with quadratic saturation:\nIEEE Std 1110 §5.3.2 (Model 2.2). GENROU model in PSSE and PSLF.\n\n# Arguments\n- `base_machine::RoundRotorMachine`: Round Rotor Machine model.\n- `saturation_coeffs::Tuple{Float64, Float64}``: Saturation coefficients for quadratic model.\n\"\"\"\nmutable struct RoundRotorQuadratic <: Machine\n    base_machine::RoundRotorMachine\n    saturation_coeffs::Tuple{Float64, Float64}\nend\nIS.@forward((RoundRotorQuadratic, :base_machine), RoundRotorMachine)\n\nfunction RoundRotorQuadratic(\n    R::Float64,\n    Td0_p::Float64,\n    Td0_pp::Float64,\n    Tq0_p::Float64,\n    Tq0_pp::Float64,\n    Xd::Float64,\n    Xq::Float64,\n    Xd_p::Float64,\n    Xq_p::Float64,\n    Xd_pp::Float64,\n    Xl::Float64,\n    Se::Tuple{Float64, Float64},\n)\n    saturation_coeffs = get_quadratic_saturation(Se)\n    return RoundRotorQuadratic(\n        RoundRotorMachine(\n            R,\n            Td0_p,\n            Td0_pp,\n            Tq0_p,\n            Tq0_pp,\n            Xd,\n            Xq,\n            Xd_p,\n            Xq_p,\n            Xd_pp,\n            Xl,\n            Se,\n        ),\n        saturation_coeffs,\n    )\nend\n\nfunction RoundRotorQuadratic(;\n    R,\n    Td0_p,\n    Td0_pp,\n    Tq0_p,\n    Tq0_pp,\n    Xd,\n    Xq,\n    Xd_p,\n    Xq_p,\n    Xd_pp,\n    Xl,\n    Se,\n)\n    return RoundRotorQuadratic(\n        R,\n        Td0_p,\n        Td0_pp,\n        Tq0_p,\n        Tq0_pp,\n        Xd,\n        Xq,\n        Xd_p,\n        Xq_p,\n        Xd_pp,\n        Xl,\n        Se,\n    )\nend\n\nfunction RoundRotorQuadratic(::Nothing)\n    return RoundRotorQuadratic(;\n        R = 0.0,\n        Td0_p = 0.0,\n        Td0_pp = 0.0,\n        Tq0_p = 0.0,\n        Tq0_pp = 0.0,\n        Xd = 0.0,\n        Xq = 0.0,\n        Xd_p = 0.0,\n        Xq_p = 0.0,\n        Xd_pp = 0.0,\n        Xl = 0.0,\n        Se = (0.0, 0.0),\n    )\nend\n\nget_base_machine(value::RoundRotorQuadratic) = value.base_machine\nget_saturation_coeffs(value::RoundRotorQuadratic) = value.saturation_coeffs\nset_base_machine!(value::RoundRotorQuadratic, val::RoundRotorMachine) =\n    value.base_machine = val\nset_saturation_coeffs!(value::RoundRotorQuadratic, val::Tuple{Float64, Float64}) =\n    value.saturation_coeffs = val\n\nfunction IS.deserialize_struct(::Type{RoundRotorQuadratic}, data::Dict)\n    vals = IS.deserialize_to_dict(RoundRotorQuadratic, data)\n    return RoundRotorQuadratic(vals[:base_machine], vals[:saturation_coeffs])\nend\n"
  },
  {
    "path": "src/models/SalientPoleExponential.jl",
    "content": "\"\"\"\n    mutable struct SalientPoleExponential <: Machine\n        base_machine::SalientPoleMachine\n        saturation_coeffs::Tuple{Float64, Float64}\n\n3-states salient-pole synchronous machine with exponential saturation:\nIEEE Std 1110 §5.3.2 (Model 2.1). GENSAE in PSSE and PSLF.\n\n# Arguments:\n- `base_machine::SalientPoleMachine`: Salient Pole Machine model.\n- `saturation_coeffs::Tuple{Float64, Float64}``: Saturation coefficients for exponential model.\n\"\"\"\nmutable struct SalientPoleExponential <: Machine\n    base_machine::SalientPoleMachine\n    saturation_coeffs::Tuple{Float64, Float64}\nend\nIS.@forward((SalientPoleExponential, :base_machine), SalientPoleMachine)\n\nfunction SalientPoleExponential(\n    R::Float64,\n    Td0_p::Float64,\n    Td0_pp::Float64,\n    Tq0_pp::Float64,\n    Xd::Float64,\n    Xq::Float64,\n    Xd_p::Float64,\n    Xd_pp::Float64,\n    Xl::Float64,\n    Se::Tuple{Float64, Float64},\n)\n    saturation_coeffs = get_exponential_saturation(Se)\n    return SalientPoleExponential(\n        SalientPoleMachine(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se),\n        saturation_coeffs,\n    )\nend\n\nfunction SalientPoleExponential(; R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se)\n    return SalientPoleExponential(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se)\nend\n\nfunction SalientPoleExponential(::Nothing)\n    return SalientPoleExponential(;\n        R = 0.0,\n        Td0_p = 0.0,\n        Td0_pp = 0.0,\n        Tq0_pp = 0.0,\n        Xd = 0.0,\n        Xq = 0.0,\n        Xd_p = 0.0,\n        Xd_pp = 0.0,\n        Xl = 0.0,\n        Se = (0.0, 0.0),\n    )\nend\n\nget_base_machine(value::SalientPoleExponential) = value.base_machine\nget_saturation_coeffs(value::SalientPoleExponential) = value.saturation_coeffs\n\nset_base_machine!(value::SalientPoleExponential, val::SalientPoleMachine) =\n    value.base_machine = val\nset_saturation_coeffs!(value::SalientPoleExponential, val::Tuple{Float64, Float64}) =\n    value.saturation_coeffs = val\n\nfunction IS.deserialize_struct(::Type{SalientPoleExponential}, data::Dict)\n    vals = IS.deserialize_to_dict(SalientPoleExponential, data)\n    return SalientPoleExponential(vals[:base_machine], vals[:saturation_coeffs])\nend\n"
  },
  {
    "path": "src/models/SalientPoleQuadratic.jl",
    "content": "\"\"\"\n    mutable struct SalientPoleQuadratic <: Machine\n        base_machine::SalientPoleMachine\n        saturation_coeffs::Tuple{Float64, Float64}\n\n3-states salient-pole synchronous machine with exponential saturation:\nIEEE Std 1110 §5.3.2 (Model 2.1). GENSAL in PSSE and PSLF.\n\n# Arguments:\n- `base_machine::SalientPoleMachine`: Salient Pole Machine model.\n- `saturation_coeffs::Tuple{Float64, Float64}``: Saturation coefficients for quadratic model.\n\"\"\"\nmutable struct SalientPoleQuadratic <: Machine\n    base_machine::SalientPoleMachine\n    saturation_coeffs::Tuple{Float64, Float64}\nend\nIS.@forward((SalientPoleQuadratic, :base_machine), SalientPoleMachine)\n\nfunction SalientPoleQuadratic(\n    R::Float64,\n    Td0_p::Float64,\n    Td0_pp::Float64,\n    Tq0_pp::Float64,\n    Xd::Float64,\n    Xq::Float64,\n    Xd_p::Float64,\n    Xd_pp::Float64,\n    Xl::Float64,\n    Se::Tuple{Float64, Float64},\n)\n    saturation_coeffs = get_quadratic_saturation(Se)\n    return SalientPoleQuadratic(\n        SalientPoleMachine(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se),\n        saturation_coeffs,\n    )\nend\n\nfunction SalientPoleQuadratic(; R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se)\n    return SalientPoleQuadratic(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se)\nend\n\nfunction SalientPoleQuadratic(::Nothing)\n    return SalientPoleQuadratic(;\n        R = 0.0,\n        Td0_p = 0.0,\n        Td0_pp = 0.0,\n        Tq0_pp = 0.0,\n        Xd = 0.0,\n        Xq = 0.0,\n        Xd_p = 0.0,\n        Xd_pp = 0.0,\n        Xl = 0.0,\n        Se = (0.0, 0.0),\n    )\nend\n\nget_base_machine(value::SalientPoleQuadratic) = value.base_machine\nget_saturation_coeffs(value::SalientPoleQuadratic) = value.saturation_coeffs\nset_base_machine!(value::SalientPoleQuadratic, val::SalientPoleMachine) =\n    value.base_machine = val\nset_saturation_coeffs!(value::SalientPoleQuadratic, val::Tuple{Float64, Float64}) =\n    value.saturation_coeffs = val\n\nfunction IS.deserialize_struct(::Type{SalientPoleQuadratic}, data::Dict)\n    vals = IS.deserialize_to_dict(SalientPoleQuadratic, data)\n    return SalientPoleQuadratic(vals[:base_machine], vals[:saturation_coeffs])\nend\n"
  },
  {
    "path": "src/models/branches.jl",
    "content": "\"\"\" Supertype for all branches\"\"\"\nabstract type Branch <: Device end\n\n\"\"\" Supertype for all AC branches (branches connecting AC nodes or Areas)\"\"\"\nabstract type ACBranch <: Branch end\n\n\"\"\" Supertype for all AC transmission devices (devices connecting AC nodes only)\"\"\"\nabstract type ACTransmission <: ACBranch end\n\n\"\"\" Supertype for all Two Winding Transformer types\"\"\"\nabstract type TwoWindingTransformer <: ACTransmission end\n\n\"\"\" Supertype for all Three Winding Transformer types\"\"\"\nabstract type ThreeWindingTransformer <: ACTransmission end\n\n\"\"\" Supertype for all Two Terminal HVDC transmission devices between AC Buses. Not to be confused with [DCBranch](@ref)\"\"\"\nabstract type TwoTerminalHVDC <: ACBranch end\n\n\"\"\" Supertype for all DC branches (branches that connect only DC nodes)\"\"\"\nabstract type DCBranch <: Branch end\n\nfunction supports_services(::ACBranch)\n    return true\nend\n\nget_from_bus(b::T) where {T <: Branch} = b.arc.from\nget_to_bus(b::T) where {T <: Branch} = b.arc.to\n"
  },
  {
    "path": "src/models/components.jl",
    "content": "function get_system_base_power(c::Component)\n    return get_internal(c).units_info.base_value\nend\n\n\"\"\"\nDefault behavior of a component. If there is no base_power field, assume is in the system's base power.\n\"\"\"\nget_base_power(c::Component) = get_system_base_power(c)\n\n_get_multiplier(c::T, conversion_unit) where {T <: Component} =\n    _get_multiplier(c, get_internal(c).units_info, conversion_unit)\n\n_get_multiplier(::T, ::Nothing, conversion_unit) where {T <: Component} =\n    1.0\n_get_multiplier(\n    c::T,\n    setting::IS.SystemUnitsSettings,\n    conversion_unit,\n) where {T <: Component} =\n    _get_multiplier(c, setting, Val(setting.unit_system), conversion_unit)\n\n# PERF: dispatching on the UnitSystem values instead of comparing with if/else avoids the\n# performance hit associated with consulting the dictionary that backs the @scoped_enum --\n# i.e., IS.UnitSystem.NATURAL_UNITS by itself isn't treated as a constant, it's a dictionary\n# lookup each time.\n_get_multiplier(\n    ::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.DEVICE_BASE},\n    ::Any,\n) where {T <: Component} =\n    1.0\n###############\n#### Power ####\n###############\n_get_multiplier(\n    c::T,\n    setting::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    ::Val{:mva},\n) where {T <: Component} =\n    get_base_power(c) / setting.base_value\n_get_multiplier(\n    c::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    ::Val{:mva},\n) where {T <: Component} =\n    get_base_power(c)\n\n###############\n#### Ohms #####\n###############\n# Z_device / Z_sys = (V_device^2 / S_device) / (V_device^2 / S_sys) = S_sys / S_device \n_get_multiplier(\n    c::T,\n    setting::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    ::Val{:ohm},\n) where {T <: Branch} =\n    setting.base_value / get_base_power(c)\nfunction _get_multiplier(\n    c::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    ::Val{:ohm},\n) where {T <: Branch}\n    base_voltage = get_base_voltage(get_arc(c).from)\n    if isnothing(base_voltage)\n        error(\"Base voltage is not defined for $(summary(c)).\")\n    end\n    return get_base_voltage(get_arc(c).from)^2 / get_base_power(c)\nend\nfunction _get_multiplier(\n    c::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    ::Val{:ohm},\n) where {T <: TwoWindingTransformer}\n    base_voltage = get_base_voltage_primary(c)\n    if isnothing(base_voltage)\n        error(\"Base voltage is not defined for $(summary(c)).\")\n    end\n    return base_voltage^2 / get_base_power(c)\nend\n\n##################\n#### Siemens #####\n##################\n# Y_device / Y_sys = (S_device / V_device^2) / (S_sys / S_sys^2) = S_device / S_sys \n_get_multiplier(\n    c::T,\n    setting::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    ::Val{:siemens},\n) where {T <: Branch} =\n    get_base_power(c) / setting.base_value\nfunction _get_multiplier(\n    c::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    ::Val{:siemens},\n) where {T <: Branch}\n    base_voltage = get_base_voltage(get_arc(c).from)\n    if isnothing(base_voltage)\n        @warn \"Base voltage is not set for $(c.name). Returning in DEVICE_BASE units.\"\n        return 1.0\n    end\n    return get_base_power(c) / get_base_voltage(get_arc(c).from)^2\nend\nfunction _get_multiplier(\n    c::T,\n    ::IS.SystemUnitsSettings,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    ::Val{:siemens},\n) where {T <: TwoWindingTransformer}\n    base_voltage = get_base_voltage_primary(c)\n    if isnothing(base_voltage)\n        @warn \"Base voltage is not set for $(c.name). Returning in DEVICE_BASE units.\"\n        return 1.0\n    end\n    return get_base_power(c) / base_voltage^2\nend\n\n_get_multiplier(::T, ::IS.SystemUnitsSettings, _, _) where {T <: Component} =\n    error(\"Undefined Conditional\")\n\nfunction get_value(c::Component, ::Val{T}, conversion_unit) where {T}\n    value = Base.getproperty(c, T)\n    return _get_value(c, value, conversion_unit)\nend\n\nfunction _get_value(c::Component, value::Float64, conversion_unit)::Float64\n    return _get_multiplier(c, conversion_unit) * value\nend\n\nfunction _get_value(c::Component, value::ComplexF64, conversion_unit)::ComplexF64\n    return _get_multiplier(c, conversion_unit) * value\nend\n\nfunction _get_value(c::Component, value::MinMax, conversion_unit)::MinMax\n    m = _get_multiplier(c, conversion_unit)\n    return (min = value.min * m, max = value.max * m)\nend\n\nfunction _get_value(\n    c::Component,\n    value::StartUpShutDown,\n    conversion_unit,\n)::StartUpShutDown\n    m = _get_multiplier(c, conversion_unit)\n    return (startup = value.startup * m, shutdown = value.shutdown * m)\nend\n\nfunction _get_value(c::Component, value::UpDown, conversion_unit)::UpDown\n    m = _get_multiplier(c, conversion_unit)\n    return (up = value.up * m, down = value.down * m)\nend\n\nfunction _get_value(c::Component, value::FromTo_ToFrom, conversion_unit)::FromTo_ToFrom\n    m = _get_multiplier(c, conversion_unit)\n    return (from_to = value.from_to * m, to_from = value.to_from * m)\nend\n\nfunction _get_value(c::Component, value::FromTo, conversion_unit)::FromTo\n    m = _get_multiplier(c, conversion_unit)\n    return (from = value.from * m, to = value.to * m)\nend\n\nfunction _get_value(::Component, ::Nothing, _)\n    return nothing\nend\n\nfunction _get_value(::T, value::V, _) where {T <: Component, V}\n    @warn(\"conversion not implemented for $(V) in component $(T)\")\n    return value::V\nend\n\nfunction _get_value(::Nothing, _, _)\n    return\nend\n\nfunction set_value(c::Component, _, val, conversion_unit)\n    return _set_value(c, val, conversion_unit)\nend\n\nfunction _set_value(c::Component, value::Float64, conversion_unit)::Float64\n    return (1 / _get_multiplier(c, conversion_unit)) * value\nend\n\nfunction _set_value(c::Component, value::MinMax, conversion_unit)::MinMax\n    m = 1 / _get_multiplier(c, conversion_unit)\n    return (min = value.min * m, max = value.max * m)\nend\n\nfunction _set_value(\n    c::Component,\n    value::StartUpShutDown,\n    conversion_unit,\n)::StartUpShutDown\n    m = 1 / _get_multiplier(c, conversion_unit)\n    return (startup = value.startup * m, shutdown = value.shutdown * m)\nend\n\nfunction _set_value(c::Component, value::UpDown, conversion_unit)::UpDown\n    m = 1 / _get_multiplier(c, conversion_unit)\n    return (up = value.up * m, down = value.down * m)\nend\n\nfunction _set_value(c::Component, value::FromTo_ToFrom, conversion_unit)::FromTo_ToFrom\n    m = 1 / _get_multiplier(c, conversion_unit)\n    return (from_to = value.from_to * m, to_from = value.to_from * m)\nend\n\nfunction _set_value(c::Component, value::FromTo, conversion_unit)::FromTo\n    m = 1 / _get_multiplier(c, conversion_unit)\n    return (from = value.from * m, to = value.to * m)\nend\n\nfunction _set_value(::Component, ::Nothing, _)\n    return nothing\nend\n\nfunction _set_value(c::T, value::V, _) where {T <: Component, V}\n    @warn(\"conversion not implemented for $(V) in component $(T)\")\n    return value::V\nend\n\nfunction _set_value(::Nothing, _, _)\n    return\nend\n\n######################################\n########### Transformer 3W ###########\n######################################\n\nPrimaryImpedances = Union{\n    Val{:r_primary},\n    Val{:x_primary},\n    Val{:r_12},\n    Val{:x_12},\n}\n\nPrimaryAdmittances = Union{\n    Val{:g},\n    Val{:b},\n}\n\nPrimaryPower = Union{\n    Val{:active_power_flow_primary},\n    Val{:reactive_power_flow_primary},\n    Val{:rating},\n    Val{:rating_primary},\n}\n\nSecondaryImpedances = Union{\n    Val{:r_secondary},\n    Val{:x_secondary},\n    Val{:r_23},\n    Val{:x_23},\n}\n\nSecondaryPower = Union{\n    Val{:active_power_flow_secondary},\n    Val{:reactive_power_flow_secondary},\n    Val{:rating_secondary},\n}\n\nTertiaryImpedances = Union{\n    Val{:r_tertiary},\n    Val{:x_tertiary},\n    Val{:r_13},\n    Val{:x_13},\n}\n\nTertiaryPower = Union{\n    Val{:active_power_flow_tertiary},\n    Val{:reactive_power_flow_tertiary},\n    Val{:rating_tertiary},\n}\n\n###### Multipliers ######\n\n_get_winding_base_power(\n    c::ThreeWindingTransformer,\n    ::Union{PrimaryImpedances, PrimaryAdmittances, PrimaryPower},\n) = get_base_power_12(c)\n_get_winding_base_power(\n    c::ThreeWindingTransformer,\n    ::Union{SecondaryImpedances, SecondaryPower},\n) =\n    get_base_power_23(c)\n_get_winding_base_power(\n    c::ThreeWindingTransformer,\n    ::Union{TertiaryImpedances, TertiaryPower},\n) =\n    get_base_power_13(c)\n\nfunction _get_winding_base_voltage(\n    c::ThreeWindingTransformer,\n    ::Union{PrimaryImpedances, PrimaryAdmittances},\n)\n    base_voltage = get_base_voltage_primary(c)\n    if isnothing(base_voltage)\n        error(\"Base voltage is not defined for $(summary(c)).\")\n    end\n    return base_voltage\nend\n\nfunction _get_winding_base_voltage(\n    c::ThreeWindingTransformer,\n    ::SecondaryImpedances,\n)\n    base_voltage = get_base_voltage_secondary(c)\n    if isnothing(base_voltage)\n        error(\"Base voltage is not defined for $(summary(c)).\")\n    end\n    return base_voltage\nend\n\nfunction _get_winding_base_voltage(\n    c::ThreeWindingTransformer,\n    ::TertiaryImpedances,\n)\n    base_voltage = get_base_voltage_tertiary(c)\n    if isnothing(base_voltage)\n        error(\"Base voltage is not defined for $(summary(c)).\")\n    end\n    return base_voltage\nend\n\n# DEVICE_BASE\nfunction _get_multiplier(\n    ::ThreeWindingTransformer,\n    ::Any,\n    ::Val{IS.UnitSystem.DEVICE_BASE},\n    ::Float64,\n    ::Any,\n)\n    return 1.0\nend\n\n###########\n## Power ##\n###########\n\n# SYSTEM_BASE\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    base_mva::Float64,\n    ::Val{:mva},\n)\n    return _get_winding_base_power(c, field) / base_mva\nend\n\n# NATURAL_UNITS\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    base_mva::Float64,\n    ::Val{:mva},\n)\n    return _get_winding_base_power(c, field)\nend\n\n############\n### Ohms ###\n############\n\n# SYSTEM_BASE\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    base_mva::Float64,\n    ::Val{:ohm},\n)\n    return base_mva / _get_winding_base_power(c, field)\nend\n\n# NATURAL_UNITS\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    base_mva::Float64,\n    ::Val{:ohm},\n)\n    return _get_winding_base_voltage(c, field)^2 / _get_winding_base_power(c, field)\nend\n\n#############\n## Siemens ##\n#############\n\n# SYSTEM_BASE\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.SYSTEM_BASE},\n    base_mva::Float64,\n    ::Val{:siemens},\n)\n    return _get_winding_base_power(c, field) / base_mva\nend\n\n# NATURAL_UNITS\nfunction _get_multiplier(\n    c::ThreeWindingTransformer,\n    field::Any,\n    ::Val{IS.UnitSystem.NATURAL_UNITS},\n    base_mva::Float64,\n    ::Val{:siemens},\n)\n    return _get_winding_base_power(c, field) / _get_winding_base_voltage(c, field)^2\nend\n\nfunction get_value(\n    c::ThreeWindingTransformer,\n    field::Val{T},\n    conversion_unit,\n) where {T}\n    value = Base.getproperty(c, T)\n    if isnothing(value)\n        return nothing\n    end\n    settings = get_internal(c).units_info\n    if isnothing(settings)\n        return value\n    end\n    unit_system = settings.unit_system\n    base_mva = settings.base_value\n    multiplier = _get_multiplier(c, field, Val(unit_system), base_mva, conversion_unit)\n    return value * multiplier\nend\n\nfunction set_value(\n    c::ThreeWindingTransformer,\n    field,\n    val::Float64,\n    conversion_unit,\n)\n    settings = get_internal(c).units_info\n    if isnothing(settings)\n        return val\n    end\n    unit_system = settings.unit_system\n    base_mva = settings.base_value\n    multiplier = _get_multiplier(c, field, Val(unit_system), base_mva, conversion_unit)\n    return val / multiplier\nend\n"
  },
  {
    "path": "src/models/cost_function_timeseries.jl",
    "content": "# VALIDATORS\nfunction _validate_market_bid_cost(cost, context)\n    (cost isa MarketBidCost) || throw(TypeError(\n        StackTraces.stacktrace()[2].func, context, MarketBidCost, cost))\nend\n\nfunction _validate_import_export_cost(cost, context)\n    (cost isa ImportExportCost) || throw(TypeError(\n        StackTraces.stacktrace()[2].func, context, ImportExportCost, cost))\nend\n\nfunction _validate_reserve_demand_curve(\n    cost::CostCurve{PiecewiseIncrementalCurve},\n    name::String,\n)\n    value_curve = get_value_curve(cost)\n    function_data = get_function_data(value_curve)\n    x_coords = get_x_coords(function_data)\n    slopes = get_y_coords(function_data)\n    if first(x_coords) != 0\n        error(\n            \"Reserve demand curve from $name is starting at $(first(x_coords)) and must start at zero.\",\n        )\n    end\n    for ix in 1:(length(slopes) - 1)\n        if slopes[ix + 1] > slopes[ix]\n            error(\n                \"Reserve demand curve from $name has increasing derivatives and should be non-increasing.\",\n            )\n        end\n    end\nend\n\nfunction _validate_reserve_demand_curve(cost::T, name::String) where {T <: CostCurve}\n    throw(\n        ArgumentError(\n            \"Reserve curve of type $(typeof(cost)) on $name cannot represent an ORDC curve, use CostCurve{PiecewiseIncrementalCurve} instead\",\n        ),\n    )\nend\n\nfunction _validate_fuel_curve(component::Component)\n    op_cost = get_operation_cost(component)\n    var_cost = get_variable(op_cost)\n    !(var_cost isa FuelCurve) && throw(\n        ArgumentError(\n            \"Variable cost of type $(typeof(var_cost)) cannot represent a fuel cost, use FuelCurve instead\",\n        ),\n    )\n    return var_cost\nend\n\n\"\"\"\nValidates if a device is eligible to contribute to a service.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `service::Service,`: Service for which the device is eligible to contribute\n\"\"\"\nfunction verify_device_eligibility(\n    sys::System,\n    component::StaticInjection,\n    service::Service,\n)\n    if !has_service(component, service)\n        error(\n            \"Device $(get_name(component)) isn't eligible to contribute to service $(get_name(service)).\",\n        )\n    end\n    return\nend\n\n# GETTER HELPER FUNCTIONS\n\"\"\"\nCall get_time_series_array on the given time series and return a TimeArray of the results,\nvalues mapped by `transform_fn` if it is not nothing\n\"\"\"\nfunction read_and_convert_ts(\n    ts::IS.TimeSeriesData,\n    component::Component,\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n    transform_fn = nothing,\n)\n    isnothing(start_time) && (start_time = IS.get_initial_timestamp(ts))\n    isnothing(transform_fn) && (transform_fn = (x -> x))\n    data = IS.get_time_series_array(component, ts; start_time = start_time, len = len)\n    time_stamps = TimeSeries.timestamp(data)\n    return TimeSeries.TimeArray(\n        time_stamps,\n        map(transform_fn, TimeSeries.values(data)),\n    )\nend\n\n\"\"\"\nHelper function for cost getters.\n\n# Arguments\n- `T`: type/eltype we expect\n- `component::Component`: the component\n- `cost`: the data: either a single element of type `T` or a `TimeSeriesKey`\n- `transform_fn`: a function to apply to the elements of the time series\n- `start_time`: as in `get_time_series`\n- `len`: as in `get_time_series`\n\"\"\"\nfunction _process_get_cost(::Type{T}, _, cost::T, transform_fn,\n    start_time::Union{Nothing, Dates.DateTime},\n    len::Union{Nothing, Int},\n) where {T}\n    !isnothing(start_time) &&\n        throw(ArgumentError(\"Got non-nothing start_time but this cost is a scalar\"))\n    !isnothing(len) &&\n        throw(ArgumentError(\"Got non-nothing len but this cost is a scalar\"))\n    return cost\nend\n\nfunction _process_get_cost(::Type{T}, component::Component, cost::TimeSeriesKey,\n    transform_fn,\n    start_time::Union{Nothing, Dates.DateTime},\n    len::Union{Nothing, Int},\n) where {T}\n    ts = get_time_series(component, cost; start_time = start_time, len = len, count = 1)\n    converted = read_and_convert_ts(ts, component, start_time, len, transform_fn)\n    return converted\nend\n\n# GETTER IMPLEMENTATIONS\n\"\"\"\nRetrieve the variable cost bid for a `StaticInjection` device with a `MarketBidCost`. If any\nof the relevant fields (`incremental_offer_curves`, `incremental_initial_input`,\n`no_load_cost`) are time series, the user may specify `start_time` and `len` and the\nfunction returns a `TimeArray` of `CostCurve{PiecewiseIncrementalCurve}`s; if the field is\nnot a time series, the function returns a single `CostCurve{PiecewiseIncrementalCurve}`.\n\"\"\"\nfunction get_variable_cost(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    if typeof(get_incremental_offer_curves(cost)) <: CostCurve\n        return get_incremental_offer_curves(cost)\n    end\n    function_data = if (get_incremental_offer_curves(cost) isa TimeSeriesKey)\n        get_incremental_offer_curves(device, cost; start_time = start_time, len = len)\n    else\n        get_incremental_offer_curves(device, cost)\n    end\n    initial_input = if (get_incremental_initial_input(cost) isa TimeSeriesKey)\n        get_incremental_initial_input(device, cost; start_time = start_time, len = len)\n    else\n        get_incremental_initial_input(device, cost)\n    end\n    input_at_zero = if (get_no_load_cost(cost) isa TimeSeriesKey)\n        get_no_load_cost(device, cost; start_time = start_time, len = len)\n    else\n        get_no_load_cost(device, cost)\n    end\n    params::Vector{Any} = [function_data, initial_input, input_at_zero]\n    all(isnothing.(params)) && return nothing\n    first_time_series = findfirst(isa.(params, TimeSeries.TimeArray))\n    if !isnothing(first_time_series)\n        timestamps = TimeSeries.timestamp(params[first_time_series])\n        for (i, param) in enumerate(params)\n            if !(param isa TimeSeries.TimeArray)\n                params[i] =\n                    TimeSeries.TimeArray(timestamps, fill(param, length(timestamps)))\n            end\n        end\n        !allequal(TimeSeries.timestamp.(params)) &&\n            throw(\n                ArgumentError(\n                    \"Time series mismatch between incremental_offer_curves, incremental_initial_input, and no_load_cost\",\n                ),\n            )\n        #@show collect(zip(collect.(TimeSeries.values.(params))...)) |> length\n        #@show first(collect(zip(collect.(TimeSeries.values.(params))...)))\n        return TimeSeries.TimeArray(TimeSeries.timestamp(function_data),\n            [\n                _make_market_bid_curve(fd; initial_input = ii, input_at_zero = iaz) for\n                (fd, ii, iaz) in collect(zip(collect.(TimeSeries.values.(params))...))\n            ])\n    end\n    return make_market_bid_curve(\n        function_data,\n        initial_input;\n        input_at_zero = input_at_zero,\n    )\nend\n\n\"\"\"\nRetrieve the incremental variable cost bid for a `StaticInjection` device with a\n`MarketBidCost`. If any of the relevant fields (`incremental_offer_curves`,\n`incremental_initial_input`, `no_load_cost`) are time series, the user may specify\n`start_time` and `len` and the function returns a `TimeArray` of\n`CostCurve{PiecewiseIncrementalCurve}`s; if the field is not a time series, the function\nreturns a single `CostCurve{PiecewiseIncrementalCurve}`.\n\"\"\"\nfunction get_incremental_variable_cost(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    return get_variable_cost(\n        device,\n        cost;\n        start_time = start_time,\n        len = len,\n    )\nend\n\n\"\"\"\nRetrieve the decremental variable cost bid for a `StaticInjection` device with a\n`MarketBidCost`. If any of the relevant fields (`decremental_offer_curves`,\n`decremental_initial_input`, `no_load_cost`) are time series, the user may specify\n`start_time` and `len` and the function returns a `TimeArray` of\n`CostCurve{PiecewiseIncrementalCurve}`s; if the field is not a time series, the function\nreturns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nfunction get_decremental_variable_cost(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    if typeof(get_decremental_offer_curves(cost)) <: CostCurve\n        return get_decremental_offer_curves(cost)\n    end\n    function_data = if (get_decremental_offer_curves(cost) isa TimeSeriesKey)\n        get_decremental_offer_curves(device, cost; start_time = start_time, len = len)\n    else\n        get_decremental_offer_curves(device, cost)\n    end\n    initial_input = if (get_decremental_initial_input(cost) isa TimeSeriesKey)\n        get_decremental_initial_input(device, cost; start_time = start_time, len = len)\n    else\n        get_decremental_initial_input(device, cost)\n    end\n    input_at_zero = if (get_no_load_cost(cost) isa TimeSeriesKey)\n        get_no_load_cost(device, cost; start_time = start_time, len = len)\n    else\n        get_no_load_cost(device, cost)\n    end\n    params::Vector{Any} = [function_data, initial_input, input_at_zero]\n    all(isnothing.(params)) && return nothing\n    first_time_series = findfirst(isa.(params, TimeSeries.TimeArray))\n    if !isnothing(first_time_series)\n        timestamps = TimeSeries.timestamp(params[first_time_series])\n        for (i, param) in enumerate(params)\n            if !(param isa TimeSeries.TimeArray)\n                params[i] =\n                    TimeSeries.TimeArray(timestamps, fill(param, length(timestamps)))\n            end\n        end\n        !allequal(TimeSeries.timestamp.(params)) &&\n            throw(\n                ArgumentError(\n                    \"Time series mismatch between incremental_offer_curves, incremental_initial_input, and no_load_cost\",\n                ),\n            )\n        #@show collect(zip(collect.(TimeSeries.values.(params))...)) |> length\n        #@show first(collect(zip(collect.(TimeSeries.values.(params))...)))\n        return TimeSeries.TimeArray(TimeSeries.timestamp(function_data),\n            [\n                _make_market_bid_curve(fd; initial_input = ii, input_at_zero = iaz) for\n                (fd, ii, iaz) in collect(zip(collect.(TimeSeries.values.(params))...))\n            ])\n    end\n\n    return make_market_bid_curve(\n        function_data,\n        initial_input;\n        input_at_zero = input_at_zero,\n    )\nend\n\n\"\"\"\nRetrieve the import variable cost bid for a `StaticInjection` device with an\n`ImportExportCost`. If `import_offer_curves` is a time series, the user may specify\n`start_time` and `len` and the function returns a `TimeArray` of\n`CostCurve{PiecewiseIncrementalCurve}`s; if the field is not a time series, the function\nreturns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nfunction get_import_variable_cost(\n    device::StaticInjection,\n    cost::ImportExportCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    get_import_offer_curves(cost) isa CostCurve &&\n        return get_import_offer_curves(cost)\n    function_data =\n        get_import_offer_curves(device, cost; start_time = start_time, len = len)\n    return TimeSeries.TimeArray(TimeSeries.timestamp(function_data),\n        [make_import_export_curve(fd) for fd in TimeSeries.values(function_data)])\nend\n\n\"\"\"\nRetrieve the export variable cost bid for a `StaticInjection` device with an\n`ImportExportCost`. If `export_offer_curves` is a time series, the user may specify\n`start_time` and `len` and the function returns a `TimeArray` of\n`CostCurve{PiecewiseIncrementalCurve}`s; if the field is not a time series, the function\nreturns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nfunction get_export_variable_cost(\n    device::StaticInjection,\n    cost::ImportExportCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    get_export_offer_curves(cost) isa CostCurve &&\n        return get_export_offer_curves(cost)\n    function_data =\n        get_export_offer_curves(device, cost; start_time = start_time, len = len)\n    return TimeSeries.TimeArray(TimeSeries.timestamp(function_data),\n        [make_import_export_curve(fd) for fd in TimeSeries.values(function_data)])\nend\n\n\"\"\"\nRetrieve the variable cost data for a `ReserveDemandCurve`. The user may specify\n`start_time` and `len` and the function returns a `TimeArray` of `CostCurve`s.\n\"\"\"\nget_variable_cost(\n    service::ReserveDemandCurve;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(CostCurve{PiecewiseIncrementalCurve}, service, get_variable(service),\n    _make_market_bid_curve, start_time, len)\n\n\"\"\"\nReturn service bid time series data for a `StaticInjection` device with a `MarketBidCost`.\nThe user may specify `start_time` and `len` and the function returns a `TimeArray` of\n`CostCurve`s.\n\"\"\"\nfunction get_services_bid(\n    device::StaticInjection,\n    cost::MarketBidCost,\n    service::Service;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    variable_ts_key = get_incremental_offer_curves(cost)\n    ts = get_time_series(\n        variable_ts_key.time_series_type,\n        device,\n        get_name(service);\n        start_time = start_time,\n        len = len,\n        count = 1,\n    )\n    converted = read_and_convert_ts(ts, service, start_time, len, _make_market_bid_curve)\n    return converted\nend\n\n\"\"\"\nGet the fuel cost of a [`HybridSystem`](@ref)'s thermal subunit.\n\n[`HybridSystem`](@ref) is a [`StaticInjectionSubsystem`](@ref) that aggregates subunits; fuel cost\nfor thermal power comes from the [`ThermalGen`](@ref) subcomponent, not the hybrid's top-level\n[`MarketBidCost`](@ref). This method delegates to [`get_fuel_cost`](@ref get_fuel_cost(component::StaticInjection))\non the thermal subunit when present.\n\n# Arguments\n- `component::HybridSystem`: The hybrid system\n- `start_time`: Optional start time for time series lookup\n- `len`: Optional length for time series lookup\n\n# Returns\nThe fuel cost from the thermal subunit (scalar or time series per [`get_fuel_cost`](@ref get_fuel_cost(component::StaticInjection))).\n\n# Throws\n- `ArgumentError` if the hybrid has no thermal unit (`get_thermal_unit(component) === nothing`).\n\"\"\"\nfunction get_fuel_cost(component::HybridSystem;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    thermal = get_thermal_unit(component)\n    if isnothing(thermal)\n        throw(\n            ArgumentError(\n                \"HybridSystem $(get_name(component)) has no thermal unit; fuel cost is undefined.\",\n            ),\n        )\n    end\n    return get_fuel_cost(thermal; start_time = start_time, len = len)\nend\n\n\"Get the fuel cost of the component's variable cost, which must be a `FuelCurve`.\"\nfunction get_fuel_cost(component::StaticInjection;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n)\n    var_cost = _validate_fuel_curve(component)\n    return _process_get_cost(\n        Float64,\n        component,\n        get_fuel_cost(var_cost),\n        nothing,\n        start_time,\n        len,\n    )\nend\n\n\"\"\"\nRetrieve the `incremental_offer_curves` for a `StaticInjection` device with a\n`MarketBidCost`. If this field is a time series, the user may specify `start_time` and `len`\nand the function returns a `TimeArray` of `PiecewiseStepData`s; if the field is not a time\nseries, the function returns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nget_incremental_offer_curves(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(\n    Union{PiecewiseStepData, CostCurve{PiecewiseIncrementalCurve}, Nothing},\n    device, get_incremental_offer_curves(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the `decremental_offer_curves` for a `StaticInjection` device with a\n`MarketBidCost`. If this field is a time series, the user may specify `start_time` and `len`\nand the function returns a `TimeArray` of `PiecewiseStepData`s; if the field is not a time\nseries, the function returns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nget_decremental_offer_curves(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(\n    Union{PiecewiseStepData, CostCurve{PiecewiseIncrementalCurve}, Nothing},\n    device, get_decremental_offer_curves(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the `import_offer_curves` for a `StaticInjection` device with a `ImportExportCost`.\nIf this field is a time series, the user may specify `start_time` and `len` and the function\nreturns a `TimeArray` of `PiecewiseStepData`s; if the field is not a time series, the\nfunction returns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nget_import_offer_curves(\n    device::StaticInjection,\n    cost::ImportExportCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Union{PiecewiseStepData, CostCurve{PiecewiseIncrementalCurve}},\n    device, get_import_offer_curves(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the `export_offer_curves` for a `StaticInjection` device with a `ImportExportCost`.\nIf this field is a time series, the user may specify `start_time` and `len` and the function\nreturns a `TimeArray` of `PiecewiseStepData`s; if the field is not a time series, the\nfunction returns a single `CostCurve{PiecewiseIncrementalCurve}` or `nothing`.\n\"\"\"\nget_export_offer_curves(\n    device::StaticInjection,\n    cost::ImportExportCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Union{PiecewiseStepData, CostCurve{PiecewiseIncrementalCurve}},\n    device, get_export_offer_curves(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the no-load cost data for a `StaticInjection` device with a `MarketBidCost`. If\nthis field is a time series, the user may specify `start_time` and `len` and the function\nreturns a `TimeArray` of `Float64`s; if the field is not a time series, the function\nreturns a single `Float64` or `nothing`.\n\"\"\"\nget_no_load_cost(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Union{Nothing, Float64}, device,\n    get_no_load_cost(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the `incremental_initial_input` for a `StaticInjection` device with a\n`MarketBidCost`. If this field is a time series, the user may specify `start_time` and `len`\nand the function returns a `TimeArray` of `Float64`s; if the field is not a time series, the\nfunction returns a single `Float64` or `nothing`.\n\"\"\"\nget_incremental_initial_input(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Union{Nothing, Float64}, device,\n    get_incremental_initial_input(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the `decremental_initial_input` for a `StaticInjection` device with a\n`MarketBidCost`. If this field is a time series, the user may specify `start_time` and `len`\nand the function returns a `TimeArray` of `Float64`s; if the field is not a time series, the\nfunction returns a single `Float64` or `nothing`.\n\"\"\"\nget_decremental_initial_input(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Union{Nothing, Float64}, device,\n    get_decremental_initial_input(cost), nothing, start_time, len)\n\n\"\"\"\nRetrieve the startup cost data for a `StaticInjection` device with a `MarketBidCost`. If\nthis field is a time series, the user may specify `start_time` and `len` and the function\nreturns a `TimeArray` of `StartUpStages`s; if the field is not a time series, the function\nreturns a single `StartUpStages`.\n\"\"\"\nget_start_up(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(StartUpStages, device,\n    get_start_up(cost), StartUpStages, start_time, len)\n\n\"\"\"\nRetrieve the shutdown cost data for a `StaticInjection` device with a `MarketBidCost`. If\nthis field is a time series, the user may specify `start_time` and `len` and the function\nreturns a `TimeArray` of `Float64`s; if the field is not a time series, the function\nreturns a single `Float64`.\n\"\"\"\nget_shut_down(\n    device::StaticInjection,\n    cost::MarketBidCost;\n    start_time::Union{Nothing, Dates.DateTime} = nothing,\n    len::Union{Nothing, Int} = nothing,\n) = _process_get_cost(Float64, device,\n    get_shut_down(cost), Float64, start_time, len)\n\n# SETTER HELPER FUNCTIONS\n\"\"\"\nHelper function for cost setters.\n\n# Arguments\n- `T1`: type we expect if it's not a time series\n- `T2`: eltype we expect if it is a time series\n- `sys::System`: the system\n- `component::Component`: the component\n- `cost`: the data: either a single element of type `T1` or a `IS.TimeSeriesData` of eltype `T2`\n\"\"\"\n_process_set_cost(_, _, _, _, ::Nothing) = nothing\n\n_process_set_cost(::Type{T}, _, _, _, cost::T) where {T} = cost\n\nfunction _process_set_cost(\n    ::Type{_},\n    ::Type{T},\n    sys::System,\n    component::Component,\n    cost::IS.TimeSeriesData,\n) where {_, T}\n    data_type = IS.eltype_data(cost)\n    !(data_type <: T) && throw(TypeError(_process_set_cost, T, data_type))\n    key = add_time_series!(sys, component, cost)\n    return key\nend\n\n# SETTER IMPLEMENTATIONS\n\"\"\"\nSet the incremental variable cost bid for a `StaticInjection` device with a `MarketBidCost`.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Nothing, IS.TimeSeriesData,\n  CostCurve{PiecewiseIncrementalCurve}},`: the data. If using a time series, must be of eltype\n  `PiecewiseStepData`. `PiecewiseIncrementalCurve` is only accepted for single CostCurve and\n  not accepted for time series data.\n- `power_units::UnitSystem`: Units to be used for data. Must be NATURAL_UNITS.\n\"\"\"\nfunction set_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n    power_units::UnitSystem,\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    if (typeof(data) <: CostCurve{PiecewiseIncrementalCurve}) &&\n       (data.power_units != power_units)\n        throw(\n            ArgumentError(\n                \"Units specified in CostCurve data differs from the units specified in the set cost.\",\n            ),\n        )\n    end\n    if (typeof(data) <: IS.TimeSeriesData) && (power_units != UnitSystem.NATURAL_UNITS)\n        throw(ArgumentError(\"Time Series data for MarketBidCost must be in NATURAL_UNITS.\"))\n    end\n    to_set = _process_set_cost(\n        CostCurve{PiecewiseIncrementalCurve},\n        PiecewiseStepData,\n        sys,\n        component,\n        data,\n    )\n\n    set_incremental_offer_curves!(market_bid_cost, to_set)\n    return\nend\n\nfunction set_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n)\n    @warn \"Variable Cost UnitSystem not specificied for $(get_name(component)). set_variable_cost! assumes data is in UnitSystem.NATURAL_UNITS\"\n    set_variable_cost!(sys, component, data, UnitSystem.NATURAL_UNITS)\n    return\nend\n\n\"\"\"\nSet the incremental variable cost bid for a `StaticInjection` device with a `MarketBidCost`.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Nothing, IS.TimeSeriesData,\n  CostCurve{PiecewiseIncrementalCurve}},`: the data. If using a time series, must be of eltype\n  `PiecewiseStepData`. `PiecewiseIncrementalCurve` is only accepted for single CostCurve and\n  not accepted for time series data.\n- `power_units::UnitSystem`: Units to be used for data.\n\"\"\"\nfunction set_incremental_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n    power_units::UnitSystem,\n)\n    set_variable_cost!(sys, component, data, power_units)\n    return\nend\n\n\"\"\"\nSet the decremental variable cost bid for a `StaticInjection` device with a `MarketBidCost`.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Nothing, IS.TimeSeriesData,\n  CostCurve{PiecewiseIncrementalCurve}},`: the data. If using a time series, must be of eltype\n  `PiecewiseStepData`. `PiecewiseIncrementalCurve` is only accepted for single CostCurve and\n  not accepted for time series data.\n- `power_units::UnitSystem`: Units to be used for data.\n\"\"\"\nfunction set_decremental_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n    power_units::UnitSystem,\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n\n    if (typeof(data) <: CostCurve{PiecewiseIncrementalCurve}) &&\n       (data.power_units != power_units)\n        throw(\n            ArgumentError(\n                \"Units specified in CostCurve data differs from the units specified in the set cost.\",\n            ),\n        )\n    end\n    if (typeof(data) <: IS.TimeSeriesData) && (power_units != UnitSystem.NATURAL_UNITS)\n        throw(ArgumentError(\"Time Series data for MarketBidCost must be in NATURAL_UNITS.\"))\n    end\n    to_set = _process_set_cost(\n        CostCurve{PiecewiseIncrementalCurve},\n        PiecewiseStepData,\n        sys,\n        component,\n        data,\n    )\n\n    set_decremental_offer_curves!(market_bid_cost, to_set)\n    return\nend\n\n\"\"\"\nSet the import variable cost bid for a `StaticInjection` device with an `ImportExportCost`.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}}`: the data. \n  If using a time series, must be of eltype `PiecewiseStepData`. `PiecewiseIncrementalCurve` \n  is only accepted for single CostCurve and not accepted for time series data.\n- `power_units::UnitSystem`: Units to be used for data.\n\"\"\"\nfunction set_import_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n    power_units::UnitSystem,\n)\n    import_export_cost = get_operation_cost(component)\n    _validate_import_export_cost(import_export_cost, \"get_operation_cost(component)\")\n\n    if (typeof(data) <: CostCurve{PiecewiseIncrementalCurve}) &&\n       (data.power_units != power_units)\n        throw(\n            ArgumentError(\n                \"Units specified in CostCurve data differs from the units specified in the set cost.\",\n            ),\n        )\n    end\n    if (typeof(data) <: IS.TimeSeriesData) && (power_units != UnitSystem.NATURAL_UNITS)\n        throw(\n            ArgumentError(\n                \"Time Series data for ImportExportCost must be in NATURAL_UNITS.\",\n            ),\n        )\n    end\n    to_set = _process_set_cost(\n        CostCurve{PiecewiseIncrementalCurve},\n        PiecewiseStepData,\n        sys,\n        component,\n        data,\n    )\n\n    set_import_offer_curves!(import_export_cost, to_set)\n    return\nend\n\n\"\"\"\nSet the export variable cost bid for a `StaticInjection` device with an `ImportExportCost`.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}}`: the data. \n  If using a time series, must be of eltype `PiecewiseStepData`. `PiecewiseIncrementalCurve` \n  is only accepted for single CostCurve and not accepted for time series data.\n- `power_units::UnitSystem`: Units to be used for data.\n\"\"\"\nfunction set_export_variable_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Nothing, IS.TimeSeriesData, CostCurve{PiecewiseIncrementalCurve}},\n    power_units::UnitSystem,\n)\n    import_export_cost = get_operation_cost(component)\n    _validate_import_export_cost(import_export_cost, \"get_operation_cost(component)\")\n\n    if (typeof(data) <: CostCurve{PiecewiseIncrementalCurve}) &&\n       (data.power_units != power_units)\n        throw(\n            ArgumentError(\n                \"Units specified in CostCurve data differs from the units specified in the set cost.\",\n            ),\n        )\n    end\n    if (typeof(data) <: IS.TimeSeriesData) && (power_units != UnitSystem.NATURAL_UNITS)\n        throw(\n            ArgumentError(\n                \"Time Series data for ImportExportCost must be in NATURAL_UNITS.\",\n            ),\n        )\n    end\n    to_set = _process_set_cost(\n        CostCurve{PiecewiseIncrementalCurve},\n        PiecewiseStepData,\n        sys,\n        component,\n        data,\n    )\n\n    set_export_offer_curves!(import_export_cost, to_set)\n    return\nend\n\n\"\"\"\nAdds energy market bids time-series to the ReserveDemandCurve.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::ReserveDemandCurve`: the curve\n- `time_series_data::IS.TimeSeriesData`: TimeSeriesData\n\"\"\"\nfunction set_variable_cost!(\n    sys::System,\n    component::ReserveDemandCurve,\n    data::Union{Nothing, IS.TimeSeriesData},\n)\n    # TODO what type checking should be enforced on this time series?\n    to_set = _process_set_cost(Any, Any, sys, component, data)\n    set_variable!(component, to_set)\nend\n\n\"\"\"\nAdds fixed energy market bids to the ReserveDemandCurve.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::ReserveDemandCurve`: the curve\n- `time_series_data::CostCurve{PiecewiseIncrementalCurve}\n\"\"\"\nfunction set_variable_cost!(\n    ::System,\n    component::ReserveDemandCurve,\n    data::CostCurve{PiecewiseIncrementalCurve},\n)\n    name = get_name(component)\n    _validate_reserve_demand_curve(data, name)\n    set_variable!(component, data)\nend\n\n\"Set the fuel cost of the component's variable cost, which must be a `FuelCurve`.\"\nfunction set_fuel_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, IS.TimeSeriesData},\n)\n    var_cost = _validate_fuel_curve(component)\n    to_set = _process_set_cost(Float64, Float64, sys, component, data)\n    op_cost = get_operation_cost(component)\n    new_var_cost =\n        FuelCurve(\n            get_value_curve(var_cost),\n            get_power_units(var_cost),\n            to_set,\n            get_startup_fuel_offtake(var_cost),\n            get_vom_cost(var_cost),\n        )\n    set_variable!(op_cost, new_var_cost)\nend\n\n\"\"\"\nSet the no-load cost for a `StaticInjection` device with a `MarketBidCost` to either a scalar or a time series.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Float64, IS.TimeSeriesData},`: the data. If a time series, must be of eltype `Float64`.\n\"\"\"\nfunction set_no_load_cost!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, IS.TimeSeriesData},\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    to_set = _process_set_cost(Union{Float64, Nothing}, Float64, sys, component, data)\n    set_no_load_cost!(market_bid_cost, to_set)\nend\n\n\"\"\"\nSet the `incremental_initial_input` for a `StaticInjection` device with a `MarketBidCost` to either a scalar or a time series.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Float64, IS.TimeSeriesData},`: the data. If a time series, must be of eltype `Float64`.\n\"\"\"\nfunction set_incremental_initial_input!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, IS.TimeSeriesData},\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    to_set = _process_set_cost(Union{Float64, Nothing}, Float64, sys, component, data)\n    set_incremental_initial_input!(market_bid_cost, to_set)\nend\n\n\"\"\"\nSet the `decremental_initial_input` for a `StaticInjection` device with a `MarketBidCost` to either a scalar or a time series.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `time_series_data::Union{Float64, IS.TimeSeriesData},`: the data. If a time series, must be of eltype `Float64`.\n\"\"\"\nfunction set_decremental_initial_input!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, IS.TimeSeriesData},\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    to_set = _process_set_cost(Union{Float64, Nothing}, Float64, sys, component, data)\n    set_decremental_initial_input!(market_bid_cost, to_set)\nend\n\n\"\"\"\nSet the startup cost for a `StaticInjection` device with a `MarketBidCost` to either a\nsingle number, a single `StartUpStages`, or a time series.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `data::Union{Float64, StartUpStages, IS.TimeSeriesData},`: the data. If a time series,\n  must be of eltype `NTuple{3, Float64}` -- to represent a single value in a time series,\n  use `(value, 0.0, 0.0)`.\n\"\"\"\nfunction set_start_up!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, StartUpStages, IS.TimeSeriesData},\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    to_set = _process_set_cost(\n        Union{Float64, StartUpStages},\n        NTuple{3, Float64},\n        sys,\n        component,\n        data,\n    )\n    set_start_up!(market_bid_cost, to_set)\nend\n\n\"\"\"\nSet the shutdown cost for a `StaticInjection` device with a `MarketBidCost` to either a\nsingle number or a time series.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `data::Union{Float64, IS.TimeSeriesData},`: the data. If a time series, must be of eltype\n  `Float64`.\n\"\"\"\nfunction set_shut_down!(\n    sys::System,\n    component::StaticInjection,\n    data::Union{Float64, IS.TimeSeriesData},\n)\n    market_bid_cost = get_operation_cost(component)\n    _validate_market_bid_cost(market_bid_cost, \"get_operation_cost(component)\")\n    to_set = _process_set_cost(\n        Float64,\n        Float64,\n        sys,\n        component,\n        data,\n    )\n    set_shut_down!(market_bid_cost, to_set)\nend\n\n\"\"\"\nAdds service bids time-series data to the MarketBidCost.\n\n# Arguments\n- `sys::System`: PowerSystem System\n- `component::StaticInjection`: Static injection device\n- `service::Service,`: Service for which the device is eligible to contribute\n- `time_series_data::IS.TimeSeriesData`: TimeSeriesData\n\"\"\"\nfunction set_service_bid!(\n    sys::System,\n    component::StaticInjection,\n    service::Service,\n    time_series_data::IS.TimeSeriesData,\n    power_units::UnitSystem,\n)\n    data_type = IS.eltype_data(time_series_data)\n    !(data_type <: PiecewiseStepData) &&\n        throw(TypeError(set_service_bid!, PiecewiseStepData, data_type))\n    _validate_market_bid_cost(\n        get_operation_cost(component),\n        \"get_operation_cost(component)\",\n    )\n    if get_name(time_series_data) != get_name(service)\n        error(\n            \"Name provided in the TimeSeries Data $(get_name(time_series_data)), doesn't match the Service $(get_name(service)).\",\n        )\n    end\n    if power_units != UnitSystem.NATURAL_UNITS\n        throw(\n            ArgumentError(\n                \"Power Unit specified for service market bids must be NATURAL_UNITS\",\n            ),\n        )\n    end\n    verify_device_eligibility(sys, component, service)\n    add_time_series!(sys, component, time_series_data)\n    ancillary_service_offers = get_ancillary_service_offers(get_operation_cost(component))\n    push!(ancillary_service_offers, service)\n    return\nend\n"
  },
  {
    "path": "src/models/cost_functions/HydroGenerationCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    HydroGenerationCost(variable, fixed)\n    HydroGenerationCost(; variable, fixed)\n\nAn operational cost of a hydropower generator which includes fixed and\nvariable cost. Variable costs can be used to represent the cost of curtailment if negative\nvalues are used or the opportunity cost of water if the costs are positive. It also supports\nfuel curves to model specific water intake. \n\nThe `variable` cost is a required parameter, but `zero(CostCurve)` can be used to set it to 0.\n\"\"\"\n@kwdef mutable struct HydroGenerationCost <: OperationalCost\n    \"Production variable cost represented by a `FuelCurve`, where the fuel is water,\n    or a `CostCurve` in currency.\"\n    variable::ProductionVariableCostCurve\n    \"(default: 0) Fixed cost of keeping the unit online. For some cost represenations this\n    field can be duplicative\"\n    fixed::Float64\nend\n\n# Constructor for demo purposes; non-functional.\nHydroGenerationCost(::Nothing) = HydroGenerationCost(zero(CostCurve), 0.0)\n\n\"\"\"Get [`HydroGenerationCost`](@ref) `variable`.\"\"\"\nget_variable(value::HydroGenerationCost) = value.variable\n\"\"\"Get [`HydroGenerationCost`](@ref) `fixed`.\"\"\"\nget_fixed(value::HydroGenerationCost) = value.fixed\n\n\"\"\"Set [`HydroGenerationCost`](@ref) `variable`.\"\"\"\nset_variable!(value::HydroGenerationCost, val) = value.variable = val\n\"\"\"Set [`HydroGenerationCost`](@ref) `fixed`.\"\"\"\nset_fixed!(value::HydroGenerationCost, val) = value.fixed = val\n"
  },
  {
    "path": "src/models/cost_functions/HydroReservoirCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    HydroReservoirCost(level_shortage_cost, level_surplus_cost, spillage_cost)\n    StorageCost(; level_shortage_cost, level_surplus_cost, spillage_cost)\n\nAn operational cost for hydro reservoirs including shortage and surplus costs for\nreservoir levels and spillage costs.\n\"\"\"\n@kwdef mutable struct HydroReservoirCost <: OperationalCost\n    \"(default: 0) Cost incurred by the model for being short of the reservoir level target\"\n    level_shortage_cost::Float64 = 0.0\n    \"(default: 0) Cost incurred by the model for surplus of the reservoir level target\"\n    level_surplus_cost::Float64 = 0.0\n    \"(default: 0) Cost incurred by the model for spillage of the reservoir\"\n    spillage_cost::Float64 = 0.0\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroReservoirCost(::Nothing)\n    HydroReservoirCost()\nend\n\n\"\"\"Get [`HydroReservoirCost`](@ref) `level_shortage_cost`.\"\"\"\nget_level_shortage_cost(value::HydroReservoirCost) = value.level_shortage_cost\n\"\"\"Get [`HydroReservoirCost`](@ref) `level_surplus_cost`.\"\"\"\nget_level_surplus_cost(value::HydroReservoirCost) = value.level_surplus_cost\n\"\"\"Get [`HydroReservoirCost`](@ref) `spillage_cost`.\"\"\"\nget_spillage_cost(value::HydroReservoirCost) = value.spillage_cost\n\n\"\"\"Set [`HydroReservoirCost`](@ref) `level_shortage_cost`.\"\"\"\nset_level_shortage_cost!(value::HydroReservoirCost, val) =\n    value.level_shortage_cost = val\n\"\"\"Set [`HydroReservoirCost`](@ref) `level_surplus_cost`.\"\"\"\nset_level_surplus_cost!(value::HydroReservoirCost, val) =\n    value.level_surplus_cost = val\n\"\"\"Set [`HydroReservoirCost`](@ref) `spillage_cost`.\"\"\"\nset_spillage_cost!(value::HydroReservoirCost, val) =\n    value.spillage_cost = val\n"
  },
  {
    "path": "src/models/cost_functions/ImportExportCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    ImportExportCost(import_offer_curves, export_offer_curves, energy_import_weekly_limit, energy_export_weekly_limits, ancillary_service_offers)\n    ImportExportCost(; import_offer_curves, export_offer_curves, energy_export_weekly_limits, ancillary_service_offers)\n\nAn operating cost for imports/exports and ancillary services from neighboring areas. The data model\nemploys a CostCurve{PiecewiseIncrementalCurve} with an implied zero cost at zero power.\n\"\"\"\nmutable struct ImportExportCost <: OfferCurveCost\n    \"Buy Price Curves data to import power, which can be a time series of [`PiecewiseStepData`] or a\n    [`CostCurve`](@ref) of [`PiecewiseIncrementalCurve`](@ref)\"\n    import_offer_curves::Union{\n        Nothing,\n        TimeSeriesKey,  # piecewise step data\n        CostCurve{PiecewiseIncrementalCurve},\n    }\n    \"Sell Price Curves data to export power, which can be a time series of `PiecewiseStepData` or a\n    [`CostCurve`](@ref) of [`PiecewiseIncrementalCurve`](@ref)\"\n    export_offer_curves::Union{\n        Nothing,\n        TimeSeriesKey,\n        CostCurve{PiecewiseIncrementalCurve},\n    }\n    \"Weekly limit on the amount of energy that can be imported, defined in system base p.u-hours.\"\n    energy_import_weekly_limit::Float64\n    \"Weekly limit on the amount of energy that can be exported, defined in system base p.u-hours.\"\n    energy_export_weekly_limit::Float64\n    \"Bids to buy or sell ancillary services in the interconnection\"\n    ancillary_service_offers::Vector{Service}\nend\n\nImportExportCost(;\n    import_offer_curves = nothing,\n    export_offer_curves = nothing,\n    energy_import_weekly_limit = INFINITE_BOUND,\n    energy_export_weekly_limit = INFINITE_BOUND,\n    ancillary_service_offers = Vector{Service}(),\n) = ImportExportCost(\n    import_offer_curves,\n    export_offer_curves,\n    energy_import_weekly_limit,\n    energy_export_weekly_limit,\n    ancillary_service_offers,\n)\n\n# Constructor for demo purposes; non-functional.\nfunction ImportExportCost(::Nothing)\n    ImportExportCost()\nend\n\n\"\"\"Get [`ImportExportCost`](@ref) `import_offer_curves`.\"\"\"\nget_import_offer_curves(value::ImportExportCost) = value.import_offer_curves\n\"\"\"Get [`ImportExportCost`](@ref) `export_offer_curves`.\"\"\"\nget_export_offer_curves(value::ImportExportCost) = value.export_offer_curves\n\"\"\"Get [`ImportExportCost`](@ref) `ancillary_service_offers`.\"\"\"\nget_ancillary_service_offers(value::ImportExportCost) = value.ancillary_service_offers\n\"\"\"Get [`ImportExportCost`](@ref) `energy_import_weekly_limit`.\"\"\"\nget_energy_import_weekly_limit(value::ImportExportCost) = value.energy_import_weekly_limit\n\"\"\"Get [`ImportExportCost`](@ref) `energy_export_weekly_limits`.\"\"\"\nget_energy_export_weekly_limit(value::ImportExportCost) = value.energy_export_weekly_limit\n\n\"\"\"Set [`ImportExportCost`](@ref) `import_offer_curves`.\"\"\"\nset_import_offer_curves!(value::ImportExportCost, val) =\n    value.import_offer_curves = val\n\"\"\"Set [`ImportExportCost`](@ref) `export_offer_curves`.\"\"\"\nset_export_offer_curves!(value::ImportExportCost, val) =\n    value.export_offer_curves = val\n\"\"\"Set [`ImportExportCost`](@ref) `ancillary_service_offers`.\"\"\"\nset_ancillary_service_offers!(value::ImportExportCost, val) =\n    value.ancillary_service_offers = val\n\"\"\"Set [`ImportExportCost`](@ref) `energy_import_weekly_limit`.\"\"\"\nset_energy_import_weekly_limit!(value::ImportExportCost, val) =\n    value.energy_import_weekly_limit = val\n\"\"\"Set [`ImportExportCost`](@ref) `energy_export_weekly_limits`.\"\"\"\nset_energy_export_weekly_limit!(value::ImportExportCost, val) =\n    value.energy_export_weekly_limit = val\n\nfunction is_import_export_curve(curve::ProductionVariableCostCurve)\n    return (curve isa CostCurve{PiecewiseIncrementalCurve}) &&\n           iszero(get_initial_input(get_value_curve(curve))) &&\n           iszero(get_input_at_zero(get_value_curve(curve))) &&\n           iszero(first(get_x_coords(get_value_curve(curve))))\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in a ImportExportCost from\nthe FunctionData that might be used to store such a cost curve in a time series.\n\"\"\"\nfunction make_import_export_curve(\n    curve::PiecewiseStepData,\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    cc = CostCurve(\n        PiecewiseIncrementalCurve(curve, 0.0, 0.0),\n        power_units,\n    )\n    @assert is_import_export_curve(cc)\n    return cc\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in an ImportExportCost from a\nvector of power values, a vector of costs, and an optional units system.\n\n# Examples\n```julia\niec = make_import_export_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0])\niec1 = make_import_export_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0]; power_units = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_import_export_curve(\n    powers::Vector{Float64},\n    prices::Vector{Float64},\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    valid_data = (length(powers) == length(prices) + 1)\n    if valid_data\n        curve = PiecewiseStepData(powers, prices)\n        return make_import_export_curve(\n            curve,\n            power_units,\n        )\n    else\n        throw(\n            ArgumentError(\n                \"Must specify exactly one more number of powers points than prices\",\n            ),\n        )\n    end\nend\n\nfunction make_import_export_curve(\n    max_power::Float64,\n    price::Float64,\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    return make_import_export_curve(\n        [0.0, max_power],\n        [price],\n        power_units,\n    )\nend\n\nfunction make_import_export_curve(;\n    powers,\n    prices,\n    power_units = UnitSystem.NATURAL_UNITS,\n)\n    return make_import_export_curve(\n        powers,\n        prices,\n        power_units,\n    )\nend\n\n\"\"\"\nMake an import CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in an ImportExportCost from a\nvector of power values, a vector of costs, and an optional units system.\n\n# Examples\n```julia\nic = make_import_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0])\nic1 = make_import_curve(power = [0.0, 100.0, 105.0, 120.0, 130.0], price = [25.0, 26.0, 28.0, 30.0], power_units = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_import_curve(\n    power::Vector{Float64},\n    price::Vector{Float64},\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    curve = PiecewiseStepData(power, price)\n    convex = is_convex(curve)\n    if convex\n        return make_import_export_curve(\n            power,\n            price,\n            power_units,\n        )\n    else\n        throw(\n            ArgumentError(\n                \"Import Curve does not have incremental slopes. Check slopes.\",\n            ),\n        )\n    end\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} from suitable for inclusion in an ImportExportCost from\na max import power, a single price and an optional units system. Assume the minimum import is 0.0\n\n# Examples\n```julia\nic = make_import_curve(power = 100.0, price = 25.0)\nic1 = make_import_curve(power = 100.0, price = 25.0, power_units = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_import_curve(\n    power::Float64,\n    price::Float64,\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    return make_import_export_curve(\n        power,\n        price,\n        power_units,\n    )\nend\n\nfunction make_import_curve(;\n    power,\n    price,\n    power_units = UnitSystem.NATURAL_UNITS,\n)\n    return make_import_curve(\n        power,\n        price,\n        power_units,\n    )\nend\n\n\"\"\"\nMake an export CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in an ImportExportCost from a\nvector of power values, a vector of costs, and an optional units system.\n\n# Examples\n```julia\nec = make_export_curve([0.0, 100.0, 105.0, 120.0, 130.0], [30.0, 28.0, 26.0, 25.0])\nec1 = make_export_curve(power = [0.0, 100.0, 105.0, 120.0, 130.0], price = [30.0, 28.0, 26.0, 25.0], power_units = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_export_curve(\n    power::Vector{Float64},\n    price::Vector{Float64},\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    curve = PiecewiseStepData(power, price)\n    concave = is_concave(curve)\n    if concave\n        return make_import_export_curve(\n            power,\n            price,\n            power_units,\n        )\n    else\n        throw(\n            ArgumentError(\n                \"Export Curve does not have decremental slopes. Check slopes.\",\n            ),\n        )\n    end\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} from suitable for inclusion in an ImportExportCost from a\na max export power, a single price and an optional units system. Assume the minimum export is 0.0.\n\n# Examples\n```julia\nec = make_export_curve(power = 100.0, price = 30.0)\nec1 = make_export_curve(power = 100.0, price = 30.0, power_units = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_export_curve(\n    power::Float64,\n    price::Float64,\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n)\n    return make_import_export_curve(\n        power,\n        price,\n        power_units,\n    )\nend\n\nfunction make_export_curve(;\n    power,\n    price,\n    power_units = UnitSystem.NATURAL_UNITS,\n)\n    return make_export_curve(\n        power,\n        price,\n        power_units,\n    )\nend\n"
  },
  {
    "path": "src/models/cost_functions/LoadCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    LoadCost(variable, fixed)\n    LoadCost(; variable, fixed)\n\nAn operational cost for controllable loads (e.g., InterruptiblePowerLoad), including\nfixed and variable cost components.\n\nThe `variable` cost is a required parameter, but `zero(CostCurve)` can be used to set it to 0.\n\"\"\"\n@kwdef mutable struct LoadCost <: OperationalCost\n    \"Variable cost represented as a [`CostCurve`](@ref)\"\n    variable::CostCurve\n    \"(default: 0) Fixed cost. For some cost represenations this field can be\n    duplicative\"\n    fixed::Float64\nend\n\n# Constructor for demo purposes; non-functional.\nLoadCost(::Nothing) = LoadCost(zero(CostCurve), 0.0)\n\n\"\"\"Get [`LoadCost`](@ref) `variable`.\"\"\"\nget_variable(value::LoadCost) = value.variable\n\"\"\"Get [`LoadCost`](@ref) `fixed`.\"\"\"\nget_fixed(value::LoadCost) = value.fixed\n\n\"\"\"Set [`LoadCost`](@ref) `variable`.\"\"\"\nset_variable!(value::LoadCost, val) = value.variable = val\n\"\"\"Set [`LoadCost`](@ref) `fixed`.\"\"\"\nset_fixed!(value::LoadCost, val) = value.fixed = val\n"
  },
  {
    "path": "src/models/cost_functions/MarketBidCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    MarketBidCost(no_load_cost, start_up, shut_down, incremental_offer_curves, decremental_offer_curves, ancillary_service_offers)\n    MarketBidCost(; no_load_cost, start_up, shut_down, incremental_offer_curves, decremental_offer_curves, ancillary_service_offers)\n    MarketBidCost(no_load_cost, start_up::Real, shut_down, incremental_offer_curves, decremental_offer_curves, ancillary_service_offers)\n\nAn operating cost for market bids of energy and ancilliary services for any asset.\nCompatible with most US Market bidding mechanisms that support demand and generation side.\n\"\"\"\nmutable struct MarketBidCost <: OfferCurveCost\n    \"No load cost\"\n    no_load_cost::Union{TimeSeriesKey, Nothing, Float64}\n    \"Start-up cost at different stages of the thermal cycle as the unit cools after a\n    shutdown (e.g., *hot*, *warm*, or *cold* starts). Warm is also referred to as\n    intermediate in some markets. Can also accept a single value if there is only one\n    start-up cost\"\n    start_up::Union{TimeSeriesKey, StartUpStages}\n    \"Shut-down cost\"\n    shut_down::Union{TimeSeriesKey, Float64}\n    \"Sell Offer Curves data, which can be a time series of `PiecewiseStepData` or a\n    [`CostCurve`](@ref) of [`PiecewiseIncrementalCurve`](@ref)\"\n    incremental_offer_curves::Union{\n        Nothing,\n        TimeSeriesKey,  # piecewise step data\n        CostCurve{PiecewiseIncrementalCurve},\n    }\n    \"Buy Offer Curves data, which can be a time series of `PiecewiseStepData` or a\n    [`CostCurve`](@ref) of [`PiecewiseIncrementalCurve`](@ref)\"\n    decremental_offer_curves::Union{\n        Nothing,\n        TimeSeriesKey,\n        CostCurve{PiecewiseIncrementalCurve},\n    }\n    \"If using a time series for incremental_offer_curves, this is a time series of `Float64` representing the `initial_input`\"\n    incremental_initial_input::Union{Nothing, TimeSeriesKey}\n    \"If using a time series for decremental_offer_curves, this is a time series of `Float64` representing the `initial_input`\"\n    decremental_initial_input::Union{Nothing, TimeSeriesKey}\n    \"Bids for the ancillary services\"\n    ancillary_service_offers::Vector{Service}\nend\n\n\"Auxiliary constructor for shut_down::Integer\"\nMarketBidCost(\n    no_load_cost::Union{TimeSeriesKey, Nothing, Float64},\n    start_up::Union{TimeSeriesKey, StartUpStages},\n    shut_down::Integer,\n    incremental_offer_curves,\n    decremental_offer_curves,\n    incremental_initial_input,\n    decremental_initial_input,\n    ancillary_service_offers,\n) = MarketBidCost(\n    no_load_cost,\n    start_up,\n    Float64(shut_down),\n    incremental_offer_curves,\n    decremental_offer_curves,\n    incremental_initial_input,\n    decremental_initial_input,\n    ancillary_service_offers,\n)\n\n\"Auxiliary constructor for no_load_cost::Integer\"\nMarketBidCost(\n    no_load_cost::Integer,\n    start_up::Union{TimeSeriesKey, StartUpStages},\n    shut_down::Union{TimeSeriesKey, Float64},\n    incremental_offer_curves,\n    decremental_offer_curves,\n    incremental_initial_input,\n    decremental_initial_input,\n    ancillary_service_offers,\n) =\n    MarketBidCost(\n        Float64(no_load_cost),\n        start_up,\n        shut_down,\n        incremental_offer_curves,\n        decremental_offer_curves,\n        incremental_initial_input,\n        decremental_initial_input,\n        ancillary_service_offers,\n    )\n\n\"\"\"Auxiliary Constructor for TestData\"\"\"\nMarketBidCost(\n    no_load_cost::Float64,\n    start_up::Union{TimeSeriesKey, StartUpStages},\n    shut_down::Union{TimeSeriesKey, Float64},\n    incremental_offer_curves,\n    decremental_offer_curves,\n    ancillary_service_offers,\n) =\n    MarketBidCost(\n        Float64(no_load_cost),\n        start_up,\n        shut_down,\n        incremental_offer_curves,\n        decremental_offer_curves,\n        nothing,\n        nothing,\n        ancillary_service_offers,\n    )\n\n# Constructor that sets the startup cost to a small constant and the rest to 0.0.\nfunction MarketBidCost(::Nothing)\n    MarketBidCost(;\n        no_load_cost = nothing,\n        start_up = (hot = START_COST, warm = START_COST, cold = START_COST),\n        shut_down = 0.0,\n    )\nend\n\nMarketBidCost(;\n    no_load_cost = nothing,\n    start_up,\n    shut_down,\n    incremental_offer_curves = nothing,\n    decremental_offer_curves = nothing,\n    incremental_initial_input = nothing,\n    decremental_initial_input = nothing,\n    ancillary_service_offers = Vector{Service}(),\n) = MarketBidCost(\n    no_load_cost, start_up, shut_down, incremental_offer_curves,\n    decremental_offer_curves, incremental_initial_input, decremental_initial_input,\n    ancillary_service_offers,\n)\n\n\"\"\"\nAccepts a single `start_up` value to use as the `hot` value, with `warm` and `cold` set to\n`0.0`.\n\"\"\"\nfunction MarketBidCost(\n    no_load_cost,\n    start_up::Real,\n    shut_down;\n    incremental_offer_curves = nothing,\n    decremental_offer_curves = nothing,\n    incremental_initial_input = nothing,\n    decremental_initial_input = nothing,\n    ancillary_service_offers = Vector{Service}(),\n)\n    # Intended for use with generators that are not multi-start (e.g. ThermalStandard).\n    # Operators use `hot` when they don’t have multiple stages.\n    start_up_multi = single_start_up_to_stages(start_up)\n    return MarketBidCost(;\n        no_load_cost = no_load_cost,\n        start_up = start_up_multi,\n        shut_down = shut_down,\n        incremental_offer_curves = incremental_offer_curves,\n        decremental_offer_curves = decremental_offer_curves,\n        incremental_initial_input = incremental_initial_input,\n        decremental_initial_input = decremental_initial_input,\n        ancillary_service_offers = ancillary_service_offers,\n    )\nend\n\n\"\"\"Get [`MarketBidCost`](@ref) `no_load_cost`.\"\"\"\nget_no_load_cost(value::MarketBidCost) = value.no_load_cost\n\"\"\"Get [`MarketBidCost`](@ref) `start_up`.\"\"\"\nget_start_up(value::MarketBidCost) = value.start_up\n\"\"\"Get [`MarketBidCost`](@ref) `shut_down`.\"\"\"\nget_shut_down(value::MarketBidCost) = value.shut_down\n\"\"\"Get [`MarketBidCost`](@ref) `incremental_offer_curves`.\"\"\"\nget_incremental_offer_curves(value::MarketBidCost) = value.incremental_offer_curves\n\"\"\"Get [`MarketBidCost`](@ref) `decremental_offer_curves`.\"\"\"\nget_decremental_offer_curves(value::MarketBidCost) = value.decremental_offer_curves\n\"\"\"Get [`MarketBidCost`](@ref) `incremental_initial_input`.\"\"\"\nget_incremental_initial_input(value::MarketBidCost) = value.incremental_initial_input\n\"\"\"Get [`MarketBidCost`](@ref) `decremental_initial_input`.\"\"\"\nget_decremental_initial_input(value::MarketBidCost) = value.decremental_initial_input\n\"\"\"Get [`MarketBidCost`](@ref) `ancillary_service_offers`.\"\"\"\nget_ancillary_service_offers(value::MarketBidCost) = value.ancillary_service_offers\n\n\"\"\"Set [`MarketBidCost`](@ref) `no_load_cost`.\"\"\"\nset_no_load_cost!(value::MarketBidCost, val) = value.no_load_cost = val\n\"\"\"Set [`MarketBidCost`](@ref) `start_up`.\"\"\"\nset_start_up!(value::MarketBidCost, val) = value.start_up = val\n\"\"\"Set [`MarketBidCost`](@ref) `shut_down`.\"\"\"\nset_shut_down!(value::MarketBidCost, val) = value.shut_down = val\n\"\"\"Set [`MarketBidCost`](@ref) `incremental_offer_curves`.\"\"\"\nset_incremental_offer_curves!(value::MarketBidCost, val) =\n    value.incremental_offer_curves = val\n\"\"\"Set [`MarketBidCost`](@ref) `incremental_initial_input`.\"\"\"\nset_incremental_initial_input!(value::MarketBidCost, val) =\n    value.incremental_initial_input = val\n\"\"\"Set [`MarketBidCost`](@ref) `incremental_offer_curves`.\"\"\"\nset_decremental_offer_curves!(value::MarketBidCost, val) =\n    value.decremental_offer_curves = val\n\"\"\"Set [`MarketBidCost`](@ref) `decremental_initial_input`.\"\"\"\nset_decremental_initial_input!(value::MarketBidCost, val) =\n    value.decremental_initial_input = val\n\"\"\"Set [`MarketBidCost`](@ref) `ancillary_service_offers`.\"\"\"\nset_ancillary_service_offers!(value::MarketBidCost, val) =\n    value.ancillary_service_offers = val\n\n\"\"\"Auxiliary Method for setting up start up that are not multi-start\"\"\"\nfunction set_start_up!(value::MarketBidCost, val::Real)\n    start_up_multi = single_start_up_to_stages(val)\n    set_start_up!(value, start_up_multi)\nend\n\n\"\"\"\nReturn `true` if the given [`ProductionVariableCostCurve`](@ref) is a market bid curve\n(a `CostCurve{PiecewiseIncrementalCurve}` as used in [`MarketBidCost`](@ref)).\n\"\"\"\nfunction is_market_bid_curve(curve::ProductionVariableCostCurve)\n    return (curve isa CostCurve{PiecewiseIncrementalCurve})\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in a MarketBidCost from a\nvector of power values, a vector of marginal costs, a float of initial input, and an optional units system and input at zero.\n\n# Examples\n```julia\nmbc = make_market_bid_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0], 10.0)\nmbc2 = make_market_bid_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0], 10.0; input_at_zero = 10.0)\nmbc3 = make_market_bid_curve([0.0, 100.0, 105.0, 120.0, 130.0], [25.0, 26.0, 28.0, 30.0], 10.0; power_inputs = UnitSystem.NATURAL_UNITS)\n```\n\"\"\"\nfunction make_market_bid_curve(powers::Vector{Float64},\n    marginal_costs::Vector{Float64},\n    initial_input::Float64;\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n    input_at_zero::Union{Nothing, Float64} = nothing)\n    if length(powers) == length(marginal_costs) + 1\n        fd = PiecewiseStepData(powers, marginal_costs)\n        return make_market_bid_curve(\n            fd,\n            initial_input;\n            power_units = power_units,\n            input_at_zero,\n        )\n    else\n        throw(\n            ArgumentError(\n                \"Must specify exactly one more number of powers ($(length(powers))) than marginal_costs ($(length(marginal_costs)))\",\n            ),\n        )\n    end\nend\n\n\"\"\"\nMake a CostCurve{PiecewiseIncrementalCurve} suitable for inclusion in a MarketBidCost from\nthe FunctionData that might be used to store such a cost curve in a time series.\n\"\"\"\nfunction make_market_bid_curve(data::PiecewiseStepData,\n    initial_input::Float64;\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n    input_at_zero::Union{Nothing, Float64} = nothing)\n    cc = CostCurve(IncrementalCurve(data, initial_input, input_at_zero), power_units)\n    @assert is_market_bid_curve(cc)\n    return cc\nend\n\n\"\"\"\nAuxiliary make market bid curve for timeseries with nothing inputs.\n\"\"\"\nfunction _make_market_bid_curve(data::PiecewiseStepData;\n    initial_input::Union{Nothing, Float64} = nothing,\n    power_units::UnitSystem = UnitSystem.NATURAL_UNITS,\n    input_at_zero::Union{Nothing, Float64} = nothing)\n    cc = CostCurve(IncrementalCurve(data, initial_input, input_at_zero), power_units)\n    @assert is_market_bid_curve(cc)\n    return cc\nend\n"
  },
  {
    "path": "src/models/cost_functions/OfferCurveCost.jl",
    "content": "\"\"\"\n    OfferCurveCost\n\nAbstract type for representing cost curves used in market bidding and offer mechanisms.\n\nThis serves as the base type for various cost curve implementations including:\n- [`MarketBidCost`](@ref)\n- [`ImportExportCost`](@ref)\n\nAll concrete subtypes must implement the required interface methods for cost calculation\nand curve evaluation in power system market operations.\n\"\"\"\nabstract type OfferCurveCost <: OperationalCost end\n"
  },
  {
    "path": "src/models/cost_functions/RenewableGenerationCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    RenewableGenerationCost(variable, curtailment_cost, fixed)\n    RenewableGenerationCost(; variable, curtailment_cost, fixed)\n\nAn operational cost of renewable generators which includes the variable cost of energy\n(like a [PPA](@ref P)), the cost of curtailing power, and a fixed cost of keeping the unit online.\nFor example, curtailment costs can be used to represent the loss of tax incentives.\n\nThe `variable` cost is a required parameter, but `zero(CostCurve)` can be used to set it to 0.\n\"\"\"\n@kwdef mutable struct RenewableGenerationCost <: OperationalCost\n    \"Variable cost represented as a [`CostCurve`](@ref)\"\n    variable::CostCurve\n    \"(default of 0) Cost of curtailing power represented as a [`CostCurve`](@ref)\"\n    curtailment_cost::CostCurve = zero(CostCurve)\n    \"Fixed cost of keeping the unit online. For some cost representations this field can be duplicative with respect to the data in the VOM field.\"\n    fixed::Float64 = 0.0\nend\n\nRenewableGenerationCost(variable) = RenewableGenerationCost(; variable)\n\n# Constructor for demo purposes; non-functional.\nRenewableGenerationCost(::Nothing) = RenewableGenerationCost(zero(CostCurve))\n\n\"\"\"Get [`RenewableGenerationCost`](@ref) `variable`.\"\"\"\nget_variable(value::RenewableGenerationCost) = value.variable\n\"\"\"Get [`RenewableGenerationCost`](@ref) `curtailment_cost`.\"\"\"\nget_curtailment_cost(value::RenewableGenerationCost) = value.curtailment_cost\n\"\"\"Get [`RenewableGenerationCost`](@ref) `fixed`.\"\"\"\nget_fixed(value::RenewableGenerationCost) = value.fixed\n\n\"\"\"Set [`RenewableGenerationCost`](@ref) `variable`.\"\"\"\nset_variable!(value::RenewableGenerationCost, val) = value.variable = val\n\"\"\"Set [`RenewableGenerationCost`](@ref) `curtailment_cost`.\"\"\"\nset_curtailment_cost!(value::RenewableGenerationCost, val) = value.curtailment_cost = val\n\"\"\"Set [`RenewableGenerationCost`](@ref) `fixed`.\"\"\"\nset_fixed!(value::RenewableGenerationCost, val) = value.fixed = val\n"
  },
  {
    "path": "src/models/cost_functions/StorageCost.jl",
    "content": "const STORAGE_OPERATION_MODES = NamedTuple{(:charge, :discharge), NTuple{2, Float64}}\n\n\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    StorageCost(charge_variable_cost, discharge_variable_cost, fixed, start_up, shut_down, energy_shortage_cost, energy_surplus_cost)\n    StorageCost(; charge_variable_cost, discharge_variable_cost, fixed, start_up, shut_down, energy_shortage_cost, energy_surplus_cost)\n\nAn operational cost for storage units including fixed costs and variable costs to charge\nor discharge.\n\nThis data structure is not intended to represent market storage systems market operations\nlike the submission of buy/sell bids -- see [`MarketBidCost`](@ref) instead.\n\"\"\"\n@kwdef mutable struct StorageCost <: OperationalCost\n    \"(default of 0) Variable cost of charging represented as a [`CostCurve`](@ref)\"\n    charge_variable_cost::CostCurve = zero(CostCurve)\n    \"(default of 0) Variable cost of discharging represented as a [`CostCurve`](@ref)\"\n    discharge_variable_cost::CostCurve = zero(CostCurve)\n    \"(default: 0) Fixed cost of operating the storage system\"\n    fixed::Float64 = 0.0\n    \"(default: 0) Start-up cost\"\n    start_up::Union{STORAGE_OPERATION_MODES, Float64} = 0.0\n    \"(default: 0) Shut-down cost\"\n    shut_down::Float64 = 0.0\n    \"(default: 0) Cost incurred by the model for being short of the energy target\"\n    energy_shortage_cost::Float64 = 0.0\n    \"(default: 0) Cost incurred by the model for surplus energy stored\"\n    energy_surplus_cost::Float64 = 0.0\nend\n\nStorageCost(\n    charge_variable_cost::CostCurve,\n    discharge_variable_cost::CostCurve,\n    fixed::Float64,\n    start_up::Real,\n    shut_down::Float64,\n    energy_shortage_cost::Float64,\n    energy_surplus_cost::Float64,\n) =\n    StorageCost(\n        charge_variable_cost,\n        discharge_variable_cost,\n        fixed,\n        Float64(start_up),\n        shut_down,\n        energy_shortage_cost,\n        energy_surplus_cost,\n    )\n\n# Constructor for demo purposes; non-functional.\nfunction StorageCost(::Nothing)\n    StorageCost()\nend\n\n\"\"\"Get [`StorageCost`](@ref) `charge_variable_cost`.\"\"\"\nget_charge_variable_cost(value::StorageCost) = value.charge_variable_cost\n\"\"\"Get [`StorageCost`](@ref) `discharge_variable_cost`.\"\"\"\nget_discharge_variable_cost(value::StorageCost) = value.discharge_variable_cost\n\"\"\"Get [`StorageCost`](@ref) `fixed`.\"\"\"\nget_fixed(value::StorageCost) = value.fixed\n\"\"\"Get [`StorageCost`](@ref) `start_up`.\"\"\"\nget_start_up(value::StorageCost) = value.start_up\n\"\"\"Get [`StorageCost`](@ref) `shut_down`.\"\"\"\nget_shut_down(value::StorageCost) = value.shut_down\n\"\"\"Get [`StorageCost`](@ref) `energy_shortage_cost`.\"\"\"\nget_energy_shortage_cost(value::StorageCost) = value.energy_shortage_cost\n\"\"\"Get [`StorageCost`](@ref) `energy_surplus_cost`.\"\"\"\nget_energy_surplus_cost(value::StorageCost) = value.energy_surplus_cost\n\n\"\"\"Set [`StorageCost`](@ref) `charge_variable_cost`.\"\"\"\nset_charge_variable_cost!(value::StorageCost, val) = value.charge_variable_cost = val\n\"\"\"Set [`StorageCost`](@ref) `discharge_variable_cost`.\"\"\"\nset_discharge_variable_cost!(value::StorageCost, val) = value.discharge_variable_cost = val\n\"\"\"Set [`StorageCost`](@ref) `fixed`.\"\"\"\nset_fixed!(value::StorageCost, val) = value.fixed = val\n\"\"\"Set [`StorageCost`](@ref) `start_up`.\"\"\"\nset_start_up!(value::StorageCost, val) = value.start_up = val\n\"\"\"Set [`StorageCost`](@ref) `shut_down`.\"\"\"\nset_shut_down!(value::StorageCost, val) = value.shut_down = val\n\"\"\"Set [`StorageCost`](@ref) `energy_shortage_cost`.\"\"\"\nset_energy_shortage_cost!(value::StorageCost, val) =\n    value.energy_shortage_cost = val\n\"\"\"Set [`StorageCost`](@ref) `energy_surplus_cost`.\"\"\"\nset_energy_surplus_cost!(value::StorageCost, val) =\n    value.energy_surplus_cost = val\n"
  },
  {
    "path": "src/models/cost_functions/ThermalGenerationCost.jl",
    "content": "\"\"\"\n$(TYPEDEF)\n$(TYPEDFIELDS)\n\n    ThermalGenerationCost(variable, fixed, start_up, shut_down)\n    ThermalGenerationCost(; variable, fixed, start_up, shut_down)\n\nAn operational cost for thermal generators which includes fixed cost, variable cost, shut-down\ncost, and  multiple options for start up costs.\n\"\"\"\n@kwdef mutable struct ThermalGenerationCost <: OperationalCost\n    \"Variable production cost. Can take a [`CostCurve`](@ref) or [`FuelCurve`](@ref)\"\n    variable::ProductionVariableCostCurve\n    \"Fixed cost of keeping the unit online. For some cost represenations this field can be\n    duplicative\"\n    fixed::Float64\n    \"Start-up cost can take linear or multi-stage cost\"\n    start_up::Union{StartUpStages, Float64}\n    \"Cost to turn the unit off\"\n    shut_down::Float64\nend\n\nThermalGenerationCost(variable, fixed, start_up::Integer, shut_down) =\n    ThermalGenerationCost(variable, fixed, convert(Float64, start_up), shut_down)\n\n# Constructor for demo purposes; non-functional.\nfunction ThermalGenerationCost(::Nothing)\n    ThermalGenerationCost(;\n        variable = zero(CostCurve),\n        fixed = 0.0,\n        start_up = 0.0,\n        shut_down = 0.0,\n    )\nend\n\n\"\"\"Get [`ThermalGenerationCost`](@ref) `variable`.\"\"\"\nget_variable(value::ThermalGenerationCost) = value.variable\n\"\"\"Get [`ThermalGenerationCost`](@ref) `fixed`.\"\"\"\nget_fixed(value::ThermalGenerationCost) = value.fixed\n\"\"\"Get [`ThermalGenerationCost`](@ref) `start_up`.\"\"\"\nget_start_up(value::ThermalGenerationCost) = value.start_up\n\"\"\"Get [`ThermalGenerationCost`](@ref) `shut_down`.\"\"\"\nget_shut_down(value::ThermalGenerationCost) = value.shut_down\n\n\"\"\"Set [`ThermalGenerationCost`](@ref) `variable`.\"\"\"\nset_variable!(value::ThermalGenerationCost, val) = value.variable = val\n\"\"\"Set [`ThermalGenerationCost`](@ref) `fixed`.\"\"\"\nset_fixed!(value::ThermalGenerationCost, val) = value.fixed = val\n\"\"\"Set [`ThermalGenerationCost`](@ref) `start_up`.\"\"\"\nset_start_up!(value::ThermalGenerationCost, val) = value.start_up = val\n\"\"\"Set [`ThermalGenerationCost`](@ref) `shut_down`.\"\"\"\nset_shut_down!(value::ThermalGenerationCost, val) = value.shut_down = val\n"
  },
  {
    "path": "src/models/cost_functions/operational_cost.jl",
    "content": "\"\"\"\nSupertype for operational cost representations\n\nCurrent abstract type for representing operational costs associated with power system devices.\n- [`OfferCurveCost`](@ref)\n\nCurrent concrete types include:\n- [`ThermalGenerationCost`](@ref)\n- [`HydroGenerationCost`](@ref)\n- [`RenewableGenerationCost`](@ref)\n- [`StorageCost`](@ref)\n- [`LoadCost`](@ref)\n- [`ImportExportCost`](@ref)\n- [`MarketBidCost`](@ref)\n\"\"\"\nabstract type OperationalCost <: DeviceParameter end\n\nIS.serialize(val::OperationalCost) = IS.serialize_struct(val)\nIS.deserialize(T::Type{<:OperationalCost}, val::Dict) = IS.deserialize_struct(T, val)\n# NOTE MarketBidCost serialization is handled in serialization.jl\n"
  },
  {
    "path": "src/models/devices.jl",
    "content": "\"\"\"\nThis function add a service to the component without checking if the component and the service are attached to the same system\n\"\"\"\nfunction add_service_internal!(device::Device, service::Service)\n    services = get_services(device)\n    for _service in services\n        if IS.get_uuid(service) == IS.get_uuid(_service)\n            throw(\n                ArgumentError(\n                    \"service $(get_name(service)) is already attached to $(get_name(device))\",\n                ),\n            )\n        end\n    end\n\n    push!(services, service)\n    @debug \"Add $service to $(get_name(device))\" _group = IS.LOG_GROUP_SYSTEM\nend\n\nfunction add_service_internal!(device::AGC, service::Service)\n    reserves = get_reserves(device)\n    for _reserve in reserves\n        if IS.get_uuid(service) == IS.get_uuid(_reserve)\n            throw(\n                ArgumentError(\n                    \"service $(get_name(service)) is already attached to $(get_name(device))\",\n                ),\n            )\n        end\n    end\n\n    push!(reserves, service)\n    @debug \"Add $service to $(get_name(device))\" _group = IS.LOG_GROUP_SYSTEM\nend\n\n\"\"\"\nRemove a service from a device.\n\nThrows ArgumentError if the service is not attached to the device.\n\"\"\"\nfunction remove_service!(device::Device, service::Service)\n    if !_remove_service!(device, service)\n        throw(\n            ArgumentError(\n                \"service $(get_name(service)) was not attached to $(get_name(device))\",\n            ),\n        )\n    end\nend\n\n\"\"\"\nReturn true if the service is attached to the device.\n\"\"\"\nfunction has_service(device::Device, service::Service)\n    for _service in get_services(device)\n        if IS.get_uuid(_service) == IS.get_uuid(service)\n            return true\n        end\n    end\n\n    return false\nend\n\n\"\"\"\nReturn true if a service with type T is attached to the device.\n\"\"\"\nfunction has_service(device::Device, ::Type{T}) where {T <: Service}\n    if !supports_services(device)\n        return false\n    end\n    for _service in get_services(device)\n        if isa(_service, T)\n            return true\n        end\n    end\n\n    return false\nend\n\nhas_service(T::Type{<:Service}, device::Device) = has_service(device, T)\n\n\"\"\"\nRemove service from device if it is attached.\n\"\"\"\nfunction _remove_service!(device::Device, service::Service)\n    removed = false\n    services = get_services(device)\n\n    # The expectation is that there won't be many services in each device, and so\n    # a faster lookup method is not needed.\n    for (i, _service) in enumerate(services)\n        if IS.get_uuid(_service) == IS.get_uuid(service)\n            deleteat!(services, i)\n            removed = true\n            @debug \"Removed service $(get_name(service)) from $(get_name(device))\" _group =\n                IS.LOG_GROUP_SYSTEM\n            break\n        end\n    end\n\n    return removed\nend\n\n\"\"\"\nRemove all services attached to the device.\n\"\"\"\nfunction clear_services!(device::Device)\n    if !supports_services(device)\n        return\n    end\n    @debug \"Clearing all services from $(get_name(device))\" _group = IS.LOG_GROUP_SYSTEM\n    services = get_services(device)\n    empty!(services)\n    return\nend\n\n\"\"\" Ensures that reservoirs cannot provide services \"\"\"\nsupports_services(::HydroReservoir) = false\n\n\"\"\"\nRemove a reservoir from a device.\n\nThrows ArgumentError if the reservoir is not attached to the device.\n\"\"\"\nfunction remove_turbine!(reservoir::HydroReservoir, device::HydroTurbine)\n    if !_remove_turbine!(reservoir, device)\n        throw(\n            ArgumentError(\n                \"turbine $(get_name(device)) was not attached to $(get_name(reservoir))\",\n            ),\n        )\n    end\nend\n\n\"\"\"\nReturn true if the reservoir has attached the upstream turbine.\n\"\"\"\nfunction has_upstream_turbine(reservoir::HydroReservoir, turbine::HydroUnit)\n    for _turbine in get_upstream_turbines(reservoir)\n        if IS.get_uuid(_turbine) == IS.get_uuid(turbine)\n            return true\n        end\n    end\n\n    return false\nend\n\n\"\"\"\nReturn true if the reservoir has attached the upstream turbine.\n\"\"\"\nfunction has_downstream_turbine(reservoir::HydroReservoir, turbine::HydroUnit)\n    for _turbine in get_downstream_turbines(reservoir)\n        if IS.get_uuid(_turbine) == IS.get_uuid(turbine)\n            return true\n        end\n    end\n\n    return false\nend\n\n\"\"\"\nReturn true if any upstream hydro unit is attached to the reservoir.\n\"\"\"\nfunction has_upstream_turbine(reservoir::HydroReservoir)\n    return !isempty(get_upstream_turbines(reservoir))\nend\n\n\"\"\"\nReturn true if any downstream hydro unit is attached to the reservoir.\n\"\"\"\nfunction has_downstream_turbine(reservoir::HydroReservoir)\n    return !isempty(get_downstream_turbines(reservoir))\nend\n\n\"\"\"\nRemove turbine from reservoir if it is attached.\n\"\"\"\nfunction _remove_turbine!(reservoir::HydroReservoir, device::HydroUnit)\n    removed = false\n    up_turbines = get_upstream_turbines(reservoir)\n    down_turbines = get_downstream_turbines(reservoir)\n\n    # The expectation is that there won't be many services in each device, and so\n    # a faster lookup method is not needed.\n    for (i, _turbine) in enumerate(down_turbines)\n        if IS.get_uuid(_turbine) == IS.get_uuid(device)\n            deleteat!(down_turbines, i)\n            removed = true\n            @debug \"Removed turbine $(get_name(_turbine)) from $(get_name(reservoir))\" _group =\n                IS.LOG_GROUP_SYSTEM\n            break\n        end\n    end\n\n    if !removed\n        for (i, _turbine) in enumerate(up_turbines)\n            if IS.get_uuid(_turbine) == IS.get_uuid(device)\n                deleteat!(up_turbines, i)\n                removed = true\n                @debug \"Removed turbine $(get_name(_turbine)) from $(get_name(reservoir))\" _group =\n                    IS.LOG_GROUP_SYSTEM\n                break\n            end\n        end\n    end\n\n    return removed\nend\n\n\"\"\"\nRemove all turbines attached to the reservoir.\n\"\"\"\nfunction clear_turbines!(device::HydroReservoir)\n    turbines = get_upstream_turbines(device)\n    empty!(turbines)\n    turbines = get_downstream_turbines(device)\n    empty!(turbines)\n    return\nend\n"
  },
  {
    "path": "src/models/dynamic_branch.jl",
    "content": "\"\"\"\nExtends the branch type to add the information required for dynamic modeling of branches. Includes the fields for the states and the number of states\n\n\n# Arguments\n- `branch::ACTransmission`\n\"\"\"\nmutable struct DynamicBranch <: ACTransmission\n    branch::ACTransmission\n    n_states::Int\n    states::Vector{Symbol}\n    internal::IS.InfrastructureSystemsInternal\n\n    function DynamicBranch(branch, n_states, states, internal)\n        @assert length(states) == n_states\n        new(branch, n_states, states, internal)\n    end\nend\n\nconst DEFAULT_DYNAMIC_BRANCH_STATES = [:Il_R, :Il_I]\n\nfunction DynamicBranch(\n    branch::T;\n    internal = IS.InfrastructureSystemsInternal(),\n) where {T <: ACTransmission}\n    states = DEFAULT_DYNAMIC_BRANCH_STATES\n    n_states = length(states)\n    return DynamicBranch(branch, n_states, states, internal)\nend\n\nfunction DynamicBranch(;\n    branch,\n    n_states = length(DEFAULT_DYNAMIC_BRANCH_STATES),\n    states = DEFAULT_DYNAMIC_BRANCH_STATES,\n    internal = IS.InfrastructureSystemsInternal(),\n)\n    return DynamicBranch(branch, n_states, states, internal)\nend\n\nfunction DynamicBranch(::Nothing)\n    return DynamicBranch(Line(nothing))\nend\n\n\"Get branch\"\nget_branch(value::DynamicBranch) = value.branch\n\"Get n_states\"\nget_n_states(value::DynamicBranch) = value.n_states\n\"Get states\"\nget_states(value::DynamicBranch) = value.states\n\"\"\"Get DynamicBranch internal.\"\"\"\nget_internal(value::DynamicBranch) = value.internal\n\nget_name(value::DynamicBranch) = IS.get_name(value.branch)\n\"\"\"Get DynamicBranch available.\"\"\"\nget_available(value::DynamicBranch) = get_available(value.branch)\n\"\"\"Get DynamicBranch active_power_flow.\"\"\"\nget_active_power_flow(value::DynamicBranch) = get_active_power(value.branch)\n\"\"\"Get DynamicBranch reactive_power_flow.\"\"\"\nget_reactive_power_flow(value::DynamicBranch) = get_reactive_power(value.branch)\n\"\"\"Get DynamicBranch arc.\"\"\"\nget_arc(value::DynamicBranch) = get_arc(value.branch)\n\"\"\"Get DynamicBranch r.\"\"\"\nget_r(value::DynamicBranch) = get_r(value.branch)\n\"\"\"Get DynamicBranch x.\"\"\"\nget_x(value::DynamicBranch) = get_x(value.branch)\n\"\"\"Get DynamicBranch b.\"\"\"\nget_b(value::DynamicBranch) = get_b(value.branch)\n\"\"\"Get DynamicBranch A rating.\"\"\"\nget_rating(value::DynamicBranch) = get_rating(value.branch)\n\"\"\"Get DynamicBranch angle_limits.\"\"\"\nget_angle_limits(value::DynamicBranch) = get_angle_limits(value.branch)\n\"\"\"Get DynamicBranch B rating.\"\"\"\nget_rating_b(value::DynamicBranch) = get_rating_b(value.branch)\n\"\"\"Get DynamicBranch C rating.\"\"\"\nget_rating_c(value::DynamicBranch) = get_rating_c(value.branch)\n\"\"\"Get DynamicBranch services.\"\"\"\nget_services(value::DynamicBranch) = get_services(value.branch)\n\"\"\"Get DynamicBranch ext.\"\"\"\nget_ext(value::DynamicBranch) = get_ext(value.branch)\n\n\"\"\"Set DynamicBranch available.\"\"\"\nset_available!(value::DynamicBranch, val::Bool) = set_available!(value.branch, val)\n\"\"\"Set DynamicBranch active_power_flow.\"\"\"\nset_active_power_flow!(value::DynamicBranch, val::Float64) =\n    set_active_power_flow!(value.branch, val)\n\"\"\"Set DynamicBranch reactive_power_flow.\"\"\"\nset_reactive_power_flow!(value::DynamicBranch, val::Float64) =\n    set_reactive_power_flow!(value.branch, val)\n\"\"\"Set DynamicBranch arc.\"\"\"\nset_arc!(value::DynamicBranch, val::Arc) = set_arc!(value.branch, val)\n\"\"\"Set DynamicBranch r.\"\"\"\nset_r!(value::DynamicBranch, val::Float64) = set_r!(value.branch, val)\n\"\"\"Set DynamicBranch x.\"\"\"\nset_x!(value::DynamicBranch, val::Float64) = set_x!(value.branch, val)\n\"\"\"Set DynamicBranch b.\"\"\"\nset_b!(value::DynamicBranch, val) = set_b!(value.branch, val)\n\"\"\"Set DynamicBranch rating.\"\"\"\nset_rating!(value::DynamicBranch, val::Float64) = set_rating!(value.branch, val)\n\"\"\"Set DynamicBranch angle_limits.\"\"\"\nset_angle_limits!(\n    value::DynamicBranch,\n    val::NamedTuple{(:min, :max), Tuple{Float64, Float64}},\n) = set_angle_limits!(value.branch, val)\n\"\"\"Set DynamicBranch services.\"\"\"\nset_services!(value::DynamicBranch, val::Vector{Service}) = set_services!(value.branch, val)\n\"\"\"Set DynamicBranch ext.\"\"\"\nset_ext!(value::DynamicBranch, val::Dict{String, Any}) = set_ext!(value.branch, val)\n\n\"Set branch\"\nset_branch!(value::DynamicBranch, val::ACTransmission) = value.branch = val\n\"Set n_states\"\nset_n_states!(value::DynamicBranch, val::Int) = value.n_states = val\n\"Set states\"\nset_states!(value::DynamicBranch, val::Vector{Symbol}) = value.states = val\n"
  },
  {
    "path": "src/models/dynamic_generator.jl",
    "content": "\"\"\"\n    mutable struct DynamicGenerator{\n        M <: Machine,\n        S <: Shaft,\n        A <: AVR,\n        TG <: TurbineGov,\n        P <: PSS,\n    } <: DynamicInjection\n        name::String\n        ω_ref::Float64\n        machine::M\n        shaft::S\n        avr::A\n        prime_mover::TG\n        pss::P\n        base_power::Float64\n        n_states::Int\n        states::Vector{Symbol}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA dynamic generator with the necessary data for modeling the dynamic response of a generator\nin a phasor or electromagnetic transient simulation.\n\nDynamic generator is composed by 5 components, namely a [Machine](@ref), a [Shaft](@ref),\nan Automatic Voltage Regulator ([AVR](@ref)), a\n[Prime Mover and Turbine Governor](@ref \"TurbineGov\"),\nand Power System Stabilizer ([PSS](@ref)). It must be attached to a\n[`StaticInjection`](@ref) device using [`add_component!`](@ref add_component!(\n    sys::System,\n    dyn_injector::DynamicInjection,\n    static_injector::StaticInjection;\n    kwargs...,\n)), which contains all the rest of the generator's data that isn't specific to its dynamic\nresponse.\n\n# Arguments\n- `name::String`: Name of generator.\n- `ω_ref::Float64`: Frequency reference set-point in pu.\n- `machine <: Machine`: [Machine](@ref) model for modeling the electro-magnetic phenomena.\n- `shaft <: Shaft`: [Shaft](@ref) model for modeling the electro-mechanical phenomena.\n- `avr <: AVR`: [AVR](@ref) model of the excitacion system.\n- `prime_mover <: TurbineGov`: [Prime Mover and Turbine Governor model](@ref \"TurbineGov\") for mechanical power.\n- `pss <: PSS`: [PSS](@ref) model.\n- `base_power::Float64`: (default: `100.0`) Base power of the unit (MVA) for [per unitization](@ref per_unit). Although this has a default, in almost all cases `base_power` should be updated to equal the `base_power` field of the [`StaticInjection`](@ref) device that this dynamic generator will be attached to.\n- `n_states::Int`: (**Do not modify.**)  Number of states (will depend on the inputs above).\n- `states::Vector{Symbol}`: (**Do not modify.**) Vector of states (will depend on the inputs above).\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DynamicGenerator{\n    M <: Machine,\n    S <: Shaft,\n    A <: AVR,\n    TG <: TurbineGov,\n    P <: PSS,\n} <: DynamicInjection\n    name::String\n    ω_ref::Float64\n    machine::M\n    shaft::S\n    avr::A\n    prime_mover::TG\n    pss::P\n    base_power::Float64\n    n_states::Int\n    states::Vector{Symbol}\n    ext::Dict{String, Any}\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DynamicGenerator(\n    name::String,\n    ω_ref::Float64,\n    machine::M,\n    shaft::S,\n    avr::A,\n    prime_mover::TG,\n    pss::P,\n    base_power::Float64 = 100.0,\n    ext::Dict{String, Any} = Dict{String, Any}(),\n) where {M <: Machine, S <: Shaft, A <: AVR, TG <: TurbineGov, P <: PSS}\n    n_states = _calc_n_states(machine, shaft, avr, prime_mover, pss)\n    states = _calc_states(machine, shaft, avr, prime_mover, pss)\n\n    return DynamicGenerator{M, S, A, TG, P}(\n        name,\n        ω_ref,\n        machine,\n        shaft,\n        avr,\n        prime_mover,\n        pss,\n        base_power,\n        n_states,\n        states,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\nfunction DynamicGenerator(;\n    name::String,\n    ω_ref::Float64,\n    machine::M,\n    shaft::S,\n    avr::A,\n    prime_mover::TG,\n    pss::P,\n    base_power::Float64 = 100.0,\n    n_states = _calc_n_states(machine, shaft, avr, prime_mover, pss),\n    states = _calc_states(machine, shaft, avr, prime_mover, pss),\n    ext::Dict{String, Any} = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n) where {M <: Machine, S <: Shaft, A <: AVR, TG <: TurbineGov, P <: PSS}\n    return DynamicGenerator(\n        name,\n        ω_ref,\n        machine,\n        shaft,\n        avr,\n        prime_mover,\n        pss,\n        base_power,\n        n_states,\n        states,\n        ext,\n        internal,\n    )\nend\n\nget_name(device::DynamicGenerator) = device.name\nget_states(device::DynamicGenerator) = device.states\nget_n_states(device::DynamicGenerator) = device.n_states\nget_ω_ref(device::DynamicGenerator) = device.ω_ref\n\"\"\"Get the [`Machine`](@ref) component of a [`DynamicGenerator`](@ref).\"\"\"\nget_machine(device::DynamicGenerator) = device.machine\n\"\"\"Get the [`Shaft`](@ref) component of a [`DynamicGenerator`](@ref).\"\"\"\nget_shaft(device::DynamicGenerator) = device.shaft\n\"\"\"Get the [`AVR`](@ref) component of a [`DynamicGenerator`](@ref).\"\"\"\nget_avr(device::DynamicGenerator) = device.avr\n\"\"\"Get the [`TurbineGov`](@ref) (prime mover) component of a [`DynamicGenerator`](@ref).\"\"\"\nget_prime_mover(device::DynamicGenerator) = device.prime_mover\n\"\"\"Get the [`PSS`](@ref) component of a [`DynamicGenerator`](@ref).\"\"\"\nget_pss(device::DynamicGenerator) = device.pss\nget_base_power(device::DynamicGenerator) = device.base_power\nget_ext(device::DynamicGenerator) = device.ext\nget_internal(device::DynamicGenerator) = device.internal\nget_V_ref(value::DynamicGenerator) = get_V_ref(get_avr(value))\nget_P_ref(value::DynamicGenerator) = get_P_ref(get_prime_mover(value))\n\nset_base_power!(value::DynamicGenerator, val) = value.base_power = val\n\nfunction _calc_n_states(machine, shaft, avr, prime_mover, pss)\n    return get_n_states(machine) +\n           get_n_states(shaft) +\n           get_n_states(avr) +\n           get_n_states(prime_mover) +\n           get_n_states(pss)\nend\n\nfunction _calc_states(machine, shaft, avr, prime_mover, pss)\n    return vcat(\n        get_states(machine),\n        get_states(shaft),\n        get_states(avr),\n        get_states(prime_mover),\n        get_states(pss),\n    )\nend\n\nfunction get_degov1_states(droop_flag::Int)\n    if droop_flag == 0\n        return [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5], 5\n    elseif droop_flag == 1\n        return [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6], 6\n    else\n        error(\"Unsupported value of droop_flag on DEGOV1\")\n    end\nend\n\n\"\"\"\nGet the frequency droop parameter from the prime mover of a [`DynamicGenerator`](@ref).\n\"\"\"\nfunction get_frequency_droop(dyn_gen::DynamicGenerator)\n    return get_frequency_droop(get_prime_mover(dyn_gen))\nend\n\nfunction get_frequency_droop(::V) where {V <: TurbineGov}\n    throw(\n        ArgumentError(\n            \"get_frequency_droop not implemented for prime mover $V.\",\n        ),\n    )\nend\n\nget_frequency_droop(pm::DEGOV) = 1 / get_K(pm)\nget_frequency_droop(pm::DEGOV1) = get_R(pm)\nget_frequency_droop(pm::GasTG) = get_R(pm)\nget_frequency_droop(pm::GeneralGovModel) = get_R(pm)\nget_frequency_droop(pm::HydroTurbineGov) = get_R(pm)\nget_frequency_droop(pm::IEEETurbineGov1) = 1 / get_K(pm)\nget_frequency_droop(pm::PIDGOV) = 1 / get_Rperm(pm)\nget_frequency_droop(pm::SteamTurbineGov1) = get_R(pm)\nget_frequency_droop(pm::TGSimple) = 1 / d_t(pm)\nget_frequency_droop(pm::TGTypeI) = get_R(pm)\nget_frequency_droop(pm::TGTypeII) = get_R(pm)\nget_frequency_droop(pm::WPIDHY) = 1 / get_reg(pm)\n"
  },
  {
    "path": "src/models/dynamic_generator_components.jl",
    "content": "abstract type DynamicGeneratorComponent <: DynamicComponent end\n\n\"\"\"\nSupertype for all Automatic Voltage Regulator (AVR) models for\n[`DynamicGenerator`](@ref) components.\n\nConcrete subtypes include [`AVRFixed`](@ref), [`AVRSimple`](@ref), [`AVRTypeI`](@ref),\n[`AVRTypeII`](@ref), [`IEEET1`](@ref), [`ESDC1A`](@ref), [`ESAC1A`](@ref),\n[`SEXS`](@ref), [`SCRX`](@ref), and others.\n\"\"\"\nabstract type AVR <: DynamicGeneratorComponent end\n\n\"\"\"\nSupertype for all synchronous machine models for [`DynamicGenerator`](@ref) components.\n\nConcrete subtypes include [`BaseMachine`](@ref), [`OneDOneQMachine`](@ref),\n[`SauerPaiMachine`](@ref), [`MarconatoMachine`](@ref), [`RoundRotorMachine`](@ref),\n[`SalientPoleMachine`](@ref), [`AndersonFouadMachine`](@ref), [`FullMachine`](@ref),\nand others.\n\"\"\"\nabstract type Machine <: DynamicGeneratorComponent end\n\n\"\"\"\nSupertype for all Power System Stabilizer (PSS) models for\n[`DynamicGenerator`](@ref) components.\n\nConcrete subtypes include [`PSSFixed`](@ref), [`PSSSimple`](@ref), [`IEEEST`](@ref),\n[`PSS2A`](@ref), [`PSS2B`](@ref), [`PSS2C`](@ref), [`STAB1`](@ref), and [`CSVGN1`](@ref).\n\"\"\"\nabstract type PSS <: DynamicGeneratorComponent end\n\n\"\"\"\nSupertype for all shaft and rotor models for [`DynamicGenerator`](@ref) components.\n\nConcrete subtypes include [`SingleMass`](@ref) and [`FiveMassShaft`](@ref).\n\"\"\"\nabstract type Shaft <: DynamicGeneratorComponent end\n\n\"\"\"\nSupertype for all turbine governor models for [`DynamicGenerator`](@ref) components.\n\nConcrete subtypes include [`TGFixed`](@ref), [`TGTypeI`](@ref), [`TGTypeII`](@ref),\n[`GasTG`](@ref), [`GeneralGovModel`](@ref), [`HydroTurbineGov`](@ref),\n[`IEEETurbineGov1`](@ref), [`SteamTurbineGov1`](@ref), [`DEGOV`](@ref),\n[`DEGOV1`](@ref), and others.\n\"\"\"\nabstract type TurbineGov <: DynamicGeneratorComponent end\n\n\"\"\"\nObtain coefficients (A, B) of the function Se(x) = B(x - A)^2/x for\nSe(E1) = B(E1 - A)^2/E1 and Se(E2) = B(E2 - A)^2/E2\nand uses the negative solution of the quadratic equation \n\"\"\"\nfunction calculate_saturation_coefficients(\n    E::Tuple{Float64, Float64},\n    Se::Tuple{Float64, Float64},\n)\n    if ((E[1] == 0.0) || (E[2] == 0.0)) || ((Se[1] == 0.0) || (Se[2] == 0.0))\n        return (0.0, 0.0)\n    end\n    if (E[2] <= E[1]) || (Se[2] <= Se[1])\n        throw(\n            IS.ConflictingInputsError(\n                \"E2 <= E1 or Se1 <= Se2. Saturation data is inconsistent.\",\n            ),\n        )\n    end\n    A =\n        (1.0 / (Se[2] * E[2] - Se[1] * E[1])) * (\n            E[1] * E[2] * (Se[2] - Se[1]) -\n            sqrt(E[1] * E[2] * Se[1] * Se[2] * (E[1] - E[2])^2)\n        )\n    B = Se[2] * E[2] / (E[2] - A)^2\n\n    @assert abs(B - Se[1] * E[1] / (E[1] - A)^2) <= 1e-2\n    return (A, B)\nend\n\n\"\"\"\nObtain coefficients for an AVR \n\"\"\"\nfunction get_avr_saturation(E::Tuple{Float64, Float64}, Se::Tuple{Float64, Float64})\n    return calculate_saturation_coefficients(E, Se)\nend\n"
  },
  {
    "path": "src/models/dynamic_inverter.jl",
    "content": "abstract type InverterComponent <: DynamicComponent end\n\n\"\"\"\n    mutable struct DynamicInverter{\n        C <: Converter,\n        O <: OuterControl,\n        IC <: InnerControl,\n        DC <: DCSource,\n        P <: FrequencyEstimator,\n        F <: Filter,\n    } <: DynamicInjection\n        name::String\n        ω_ref::Float64\n        converter::C\n        outer_control::O\n        inner_control::IC\n        dc_source::DC\n        freq_estimator::P\n        filter::F\n        limiter::Union{nothing, OutputCurrentLimiter}\n        base_power::Float64\n        n_states::Int\n        states::Vector{Symbol}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA dynamic inverter with the necessary data for modeling the dynamic response of an inverter\nin a phasor or electromagnetic transient simulation.\n\nA dynamic inverter is composed by 6 components, namely a [Converter](@ref),\n[Outer Loop Control](@ref OuterControl), [Inner Loop Control](@ref InnerControl),\na [DC Source](@ref DCSource), a [Frequency Estimator](@ref FrequencyEstimator) and a\n[Filter](@ref).\n\nIt must be attached to a\n[`StaticInjection`](@ref) device using [`add_component!`](@ref add_component!(\n    sys::System,\n    dyn_injector::DynamicInjection,\n    static_injector::StaticInjection;\n    kwargs...,\n)), which contains all the rest of the generator's data that isn't specific to its dynamic\nresponse.\n\n# Arguments\n- `name::String`: Name of inverter.\n- `ω_ref::Float64`: Frequency reference set-point in pu.\n- `converter <: Converter`: Converter model for the PWM transformation.\n- `outer_control <: OuterControl`: An [OuterControl](@ref) controller model.\n- `inner_control <: InnerControl`: An [InnerControl](@ref) controller model.\n- `dc_source <: DCSource`: [DCSource](@ref) model.\n- `freq_estimator <: FrequencyEstimator`: a [FrequencyEstimator](@ref) (typically a [PLL](@ref P)) model.\n- `filter <: Filter`: [Filter](@ref) model.\n- `limiter <: Union{nothing, OutputCurrentLimiter}`: (default: nothing) Inner Control [Current Limiter](@ref OutputCurrentLimiter) model\n- `base_power::Float64`: (default: `100.0`) Base power of the unit (MVA) for [per unitization](@ref per_unit). Although this has a default, in almost all cases `base_power` should be updated to equal the `base_power` field of the [`StaticInjection`](@ref) device that this dynamic generator will be attached to.\n- `n_states::Int`: (**Do not modify.**)  Number of states (will depend on the inputs above).\n- `states::Vector{Symbol}`: (**Do not modify.**) Vector of states (will depend on the inputs above).\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DynamicInverter{\n    C <: Converter,\n    O <: OuterControl,\n    IC <: InnerControl,\n    DC <: DCSource,\n    P <: FrequencyEstimator,\n    F <: Filter,\n    L <: Union{Nothing, OutputCurrentLimiter},\n} <: DynamicInjection\n    name::String\n    ω_ref::Float64\n    converter::C\n    outer_control::O\n    inner_control::IC\n    dc_source::DC\n    freq_estimator::P\n    filter::F\n    limiter::L\n    base_power::Float64\n    n_states::Int\n    states::Vector{Symbol}\n    ext::Dict{String, Any}\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DynamicInverter(\n    name::String,\n    ω_ref::Float64,\n    converter::C,\n    outer_control::O,\n    inner_control::IC,\n    dc_source::DC,\n    freq_estimator::P,\n    filter::F,\n    limiter::L = nothing,\n    base_power::Float64 = 100.0,\n    ext::Dict{String, Any} = Dict{String, Any}(),\n) where {\n    C <: Converter,\n    O <: OuterControl,\n    IC <: InnerControl,\n    DC <: DCSource,\n    P <: FrequencyEstimator,\n    F <: Filter,\n    L <: Union{Nothing, OutputCurrentLimiter},\n}\n    n_states = _calc_n_states(\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n    )\n    states = _calc_states(\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n    )\n\n    return DynamicInverter{C, O, IC, DC, P, F, L}(\n        name,\n        ω_ref,\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n        limiter,\n        base_power,\n        n_states,\n        states,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\nfunction DynamicInverter(;\n    name::String,\n    ω_ref::Float64,\n    converter::C,\n    outer_control::O,\n    inner_control::IC,\n    dc_source::DC,\n    freq_estimator::P,\n    filter::F,\n    limiter::L = nothing,\n    base_power::Float64 = 100.0,\n    n_states = _calc_n_states(\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n    ),\n    states = _calc_states(\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n    ),\n    ext::Dict{String, Any} = Dict{String, Any}(),\n    internal = IS.InfrastructureSystemsInternal(),\n) where {\n    C <: Converter,\n    O <: OuterControl,\n    IC <: InnerControl,\n    DC <: DCSource,\n    P <: FrequencyEstimator,\n    F <: Filter,\n    L <: Union{Nothing, OutputCurrentLimiter},\n}\n    return DynamicInverter(\n        name,\n        ω_ref,\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        filter,\n        limiter,\n        base_power,\n        n_states,\n        states,\n        ext,\n        internal,\n    )\nend\n\nfunction DynamicInverter(\n    name::String,\n    ω_ref::Float64,\n    converter::C,\n    active_power_control::AC,\n    reactive_power_control::RC,\n    inner_control::IC,\n    dc_source::DC,\n    freq_estimator::P,\n    ac_filter::F,\n) where {\n    C <: Converter,\n    AC <: ActivePowerControl,\n    RC <: ReactivePowerControl,\n    IC <: InnerControl,\n    DC <: DCSource,\n    P <: FrequencyEstimator,\n    F <: Filter,\n}\n    outer_control = OuterControl(active_power_control, reactive_power_control)\n    return DynamicInverter(\n        name,\n        ω_ref,\n        converter,\n        outer_control,\n        inner_control,\n        dc_source,\n        freq_estimator,\n        ac_filter,\n    )\nend\n\nget_name(device::DynamicInverter) = device.name\nget_ω_ref(device::DynamicInverter) = device.ω_ref\nget_ext(device::DynamicInverter) = device.ext\nget_states(device::DynamicInverter) = device.states\nget_n_states(device::DynamicInverter) = device.n_states\n\"\"\"Get the [`Converter`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_converter(device::DynamicInverter) = device.converter\n\"\"\"Get the [`OuterControl`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_outer_control(device::DynamicInverter) = device.outer_control\n\"\"\"Get the [`InnerControl`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_inner_control(device::DynamicInverter) = device.inner_control\n\"\"\"Get the [`DCSource`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_dc_source(device::DynamicInverter) = device.dc_source\n\"\"\"Get the [`FrequencyEstimator`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_freq_estimator(device::DynamicInverter) = device.freq_estimator\n\"\"\"Get the [`Filter`](@ref) component of a [`DynamicInverter`](@ref).\"\"\"\nget_filter(device::DynamicInverter) = device.filter\nget_limiter(device::DynamicInverter) = device.limiter\nget_base_power(device::DynamicInverter) = device.base_power\nget_internal(device::DynamicInverter) = device.internal\nget_P_ref(value::DynamicInverter) =\n    get_P_ref(get_active_power_control(get_outer_control(value)))\nget_V_ref(value::DynamicInverter) =\n    get_V_ref(get_reactive_power_control(get_outer_control(value)))\n\nset_base_power!(value::DynamicInverter, val) = value.base_power = val\n\nfunction _calc_n_states(\n    converter,\n    outer_control,\n    inner_control,\n    dc_source,\n    freq_estimator,\n    filter,\n)\n    return converter.n_states +\n           outer_control.n_states +\n           inner_control.n_states +\n           dc_source.n_states +\n           freq_estimator.n_states +\n           filter.n_states\nend\n\nfunction _calc_states(\n    converter,\n    outer_control,\n    inner_control,\n    dc_source,\n    freq_estimator,\n    filter,\n)\n    return vcat(\n        converter.states,\n        outer_control.states,\n        inner_control.states,\n        dc_source.states,\n        freq_estimator.states,\n        filter.states,\n    )\nend\n\nfunction get_REControlB_states(Q_Flag::Int)\n    if Q_Flag == 0\n        return [:Vt_filt, :I_icv]\n    elseif Q_Flag == 1\n        return [:Vt_filt, :ξ_icv]\n    else\n        error(\"Unsupported value of Q_Flag\")\n    end\nend\n\nfunction get_activeRETypeAB_states(Freq_Flag::Int)\n    if Freq_Flag == 1\n        return [:p_flt, :ξ_P, :p_ext, :p_ord], 4\n    elseif Freq_Flag == 0\n        return [:p_ord], 1\n    else\n        error(\"Unsupported value of Freq_Flag\")\n    end\nend\n\nfunction get_reactiveRETypeAB_states(Ref_Flag::Int, PF_Flag::Int, V_Flag::Int)\n    if (Ref_Flag == 0) && ((PF_Flag == 1) && (V_Flag == 1))\n        return [:pr_flt, :ξ_Q], 2\n    elseif (Ref_Flag == 0) && ((PF_Flag == 1) && (V_Flag == 0))\n        return [:pr_flt], 1\n    elseif (Ref_Flag == 0) && ((PF_Flag == 0) && (V_Flag == 1))\n        return [:q_flt, :ξq_oc, :q_LL, :ξ_Q], 4\n    elseif (Ref_Flag == 0) && ((PF_Flag == 0) && (V_Flag == 0))\n        return [:q_flt, :ξq_oc, :q_LL], 3\n    elseif (Ref_Flag == 1) && ((PF_Flag == 1) && (V_Flag == 1))\n        return [:pr_flt, :ξ_Q], 2\n    elseif (Ref_Flag == 1) && ((PF_Flag == 1) && (V_Flag == 0))\n        return [:pr_flt], 1\n    elseif (Ref_Flag == 1) && ((PF_Flag == 0) && (V_Flag == 1))\n        return [:V_cflt, :ξq_oc, :q_LL, :ξ_Q], 4\n    elseif (Ref_Flag == 1) && ((PF_Flag == 0) && (V_Flag == 0))\n        return [:V_cflt, :ξq_oc, :q_LL], 3\n    else\n        error(\"Unsupported value of Ref_Flag, PF_Flag or V_Flag\")\n    end\nend\n"
  },
  {
    "path": "src/models/dynamic_inverter_components.jl",
    "content": "abstract type DynamicInverterComponent <: DynamicComponent end\n\n\"\"\"\nSupertype for all power electronic converter models for\n[`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`AverageConverter`](@ref),\n[`RenewableEnergyConverterTypeA`](@ref), and\n[`RenewableEnergyVoltageConverterTypeA`](@ref).\n\"\"\"\nabstract type Converter <: DynamicInverterComponent end\n\n\"\"\"\nSupertype for all DC source models for [`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`FixedDCSource`](@ref) and [`ZeroOrderBESS`](@ref).\n\"\"\"\nabstract type DCSource <: DynamicInverterComponent end\n\n\"\"\"\nSupertype for all output filter models for [`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`LCLFilter`](@ref), [`LCFilter`](@ref), and [`RLFilter`](@ref).\n\"\"\"\nabstract type Filter <: DynamicInverterComponent end\n\n\"\"\"\nSupertype for all frequency estimator models for\n[`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`KauraPLL`](@ref), [`ReducedOrderPLL`](@ref), and\n[`FixedFrequency`](@ref).\n\"\"\"\nabstract type FrequencyEstimator <: DynamicInverterComponent end\n\n\"\"\"\nSupertype for all inner control loop models for\n[`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`VoltageModeControl`](@ref), [`CurrentModeControl`](@ref),\nand [`RECurrentControlB`](@ref).\n\"\"\"\nabstract type InnerControl <: DynamicInverterComponent end\n\n\"\"\"\nSupertype for all output current limiter models for\n[`DynamicInverter`](@ref) components.\n\nConcrete subtypes include [`MagnitudeOutputCurrentLimiter`](@ref),\n[`InstantaneousOutputCurrentLimiter`](@ref), [`PriorityOutputCurrentLimiter`](@ref),\n[`SaturationOutputCurrentLimiter`](@ref), and [`HybridOutputCurrentLimiter`](@ref).\n\"\"\"\nabstract type OutputCurrentLimiter <: DynamicInverterComponent end\n\nabstract type ActivePowerControl <: DeviceParameter end\nabstract type ReactivePowerControl <: DeviceParameter end\n"
  },
  {
    "path": "src/models/dynamic_loads.jl",
    "content": "function get_GenericDER_states(Qref_Flag::Int)\n    if Qref_Flag == 1\n        return [:x1, :x2, :x3, :x4, :x5, :x6, :x7, :x8, :x9], 9\n    elseif Qref_Flag == 2 || Qref_Flag == 3\n        return [:x2, :x3, :x4, :x5, :x6, :x7, :x8, :x9], 8\n    else\n        error(\"Unsupported value of Qref_Flag\")\n    end\nend\n\nfunction get_AggregateDistributedGenerationA_states(Freq_Flag::Int)\n    if Freq_Flag == 0\n        return [:Vmeas, :Pmeas, :Q_V, :Iq, :Mult, :Fmeas, :Ip], 7\n    elseif Freq_Flag == 1\n        return [:Vmeas, :Pmeas, :Q_V, :Iq, :Mult, :Fmeas, :Power_PI, :dPord, :Pord, :Ip], 10\n    else\n        error(\"Unsupported value of Freq_Flag\")\n    end\nend\n\nfunction calculate_IM_torque_params(A::Float64, B::Float64)\n    C = 1.0 - A - B\n    if A < 0.0 || B < 0.0 || C < 0.0\n        error(\n            \"Unsupported values of A = $(A), B = $(B) or C = $(C). A, B and C must be positive and add up to 1.0\",\n        )\n    end\n    return C\nend\n"
  },
  {
    "path": "src/models/dynamic_machines.jl",
    "content": "\"\"\"\nObtain coefficients (A, B) of the function Se = B(x - A)^2/x for\nSe(1.2) = B(1.2 - A)^2/1.2 and Se(1.0) = B(1.0 - A)^2/1.0 as:\nSe(1.0) = (Se(1.2) * 1.2) /(1.2 - A)^2 * (1.0 - A)^2/1.0 that yields\n(1.2 - A)^2 Se(1.0) = Se(1.2) * 1.2 * (1.0 - A)^2 or expanding:\n(1.2 * Se(1.2) - Se(1.0)) A^2 + (2.4 Se(1.0) - 2 * 1.2 * Se(1.2)) A + (1.2 * Se(1.2) - 1.44 Se(1.0)) = 0\nand uses the negative solution of the quadratic equation.\n\"\"\"\nfunction get_quadratic_saturation(Se::Tuple{Float64, Float64})\n    return calculate_saturation_coefficients((1.0, 1.2), Se)\nend\n\n\"\"\"\nObtain coefficients (A, B) of the function Se = Bx^A for\nSe(1.2) = B(1.2)^A and Se(1.0) = B(1.0)^A as:\nB = Se(1.0) and hence\n(1.2)^A = Se(1.2)/B -> A = log(Se(1.2)/B) / log(1.2)\n\"\"\"\nfunction get_exponential_saturation(Se::Tuple{Float64, Float64})\n    if Se[1] == 0.0 || Se[2] == 0.0\n        @warn \"$(Se[1]) or $(Se[2]) equals to zero. Ignoring saturation.\"\n        return (0.0, 0.0)\n    end\n    if Se[2] <= Se[1]\n        throw(\n            IS.ConflictingInputsError(\n                \"Se(1.2) <= Se(1.0). Saturation data is inconsistent.\",\n            ),\n        )\n    end\n    B = Se[1]\n    A = log(Se[2] / B) / log(1.2)\n\n    return (A, B)\nend\n"
  },
  {
    "path": "src/models/dynamic_models.jl",
    "content": "\"\"\"\nAbstract type for all components used to compose a [`DynamicInjection`](@ref) device\n\"\"\"\nabstract type DynamicComponent <: DeviceParameter end\n\n\"\"\"\nAbstract type for all [Dynamic Devices](@ref)\n\nA [dynamic](@ref D) [injection](@ref I) is the continuous time response of a generator,\ntypically modeled with differential equations. \n    \n`DynamicInjection` components can added on to [`StaticInjection`](@ref) components,\nwhich together define all the information needed to model the device in a dynamic\nsimulation.\n\"\"\"\nabstract type DynamicInjection <: Device end\n\n\"\"\"\nReturn all the dynamic components of a [`DynamicInjection`](@ref) device\n\"\"\"\nfunction get_dynamic_components(device::T) where {T <: DynamicInjection}\n    return (\n        getfield(device, x) for\n        (x, y) in zip(fieldnames(T), fieldtypes(T)) if y <: DynamicComponent\n    )\nend\n\nsupports_services(::DynamicInjection) = false\nget_states(::DynamicInjection) = Vector{Symbol}()\n\"\"\"\n    Default implementation of get_state_types for dynamic components. Assumes all states are\n    Differential\n\"\"\"\nfunction get_states_types(d::DynamicComponent)\n    return fill(StateTypes.Differential, get_n_states(d))\nend\n\nfunction get_frequency_droop(::V) where {V <: DynamicInjection}\n    throw(\n        ArgumentError(\n            \"get_frequency_droop not implemented for type $V.\",\n        ),\n    )\nend\n"
  },
  {
    "path": "src/models/generated/ACBus.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ACBus <: Bus\n        number::Int\n        name::String\n        available::Bool\n        bustype::Union{Nothing, ACBusTypes}\n        angle::Union{Nothing, Float64}\n        magnitude::Union{Nothing, Float64}\n        voltage_limits::Union{Nothing, MinMax}\n        base_voltage::Union{Nothing, Float64}\n        area::Union{Nothing, Area}\n        load_zone::Union{Nothing, LoadZone}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAn AC bus\n\n# Arguments\n- `number::Int`: A unique bus identification number (positive integer)\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations. This field should not be confused with the ISOLATED enum value (@ref acbustypes_list)\n- `bustype::Union{Nothing, ACBusTypes}`: Used to describe the connectivity and behavior of this bus. [Options are listed here.](@ref acbustypes_list)\n- `angle::Union{Nothing, Float64}`: angle of the bus in radians\n- `magnitude::Union{Nothing, Float64}`: voltage as a multiple of `base_voltage`, validation range: `voltage_limits`\n- `voltage_limits::Union{Nothing, MinMax}`: limits on the voltage variation as multiples of `base_voltage`\n- `base_voltage::Union{Nothing, Float64}`: the base voltage in kV, validation range: `(0, nothing)`\n- `area::Union{Nothing, Area}`: (default: `nothing`) the area containing the bus\n- `load_zone::Union{Nothing, LoadZone}`: (default: `nothing`) the load zone containing the bus\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ACBus <: Bus\n    \"A unique bus identification number (positive integer)\"\n    number::Int\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations. This field should not be confused with the ISOLATED enum value (@ref acbustypes_list)\"\n    available::Bool\n    \"Used to describe the connectivity and behavior of this bus. [Options are listed here.](@ref acbustypes_list)\"\n    bustype::Union{Nothing, ACBusTypes}\n    \"angle of the bus in radians\"\n    angle::Union{Nothing, Float64}\n    \"voltage as a multiple of `base_voltage`\"\n    magnitude::Union{Nothing, Float64}\n    \"limits on the voltage variation as multiples of `base_voltage`\"\n    voltage_limits::Union{Nothing, MinMax}\n    \"the base voltage in kV\"\n    base_voltage::Union{Nothing, Float64}\n    \"the area containing the bus\"\n    area::Union{Nothing, Area}\n    \"the load zone containing the bus\"\n    load_zone::Union{Nothing, LoadZone}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\n\n    function ACBus(number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area, load_zone, ext, internal, )\n        (number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area, load_zone, ext, internal, ) = check_bus_params(\n            number,\n            name,\n            available,\n            bustype,\n            angle,\n            magnitude,\n            voltage_limits,\n            base_voltage,\n            area,\n            load_zone,\n            ext,\n            internal,\n        )\n        new(number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area, load_zone, ext, internal, )\n    end\nend\n\nfunction ACBus(number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area=nothing, load_zone=nothing, ext=Dict{String, Any}(), )\n    ACBus(number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area, load_zone, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ACBus(; number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area=nothing, load_zone=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ACBus(number, name, available, bustype, angle, magnitude, voltage_limits, base_voltage, area, load_zone, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ACBus(::Nothing)\n    ACBus(;\n        number=0,\n        name=\"init\",\n        available=false,\n        bustype=nothing,\n        angle=0.0,\n        magnitude=0.0,\n        voltage_limits=(min=0.0, max=0.0),\n        base_voltage=nothing,\n        area=nothing,\n        load_zone=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ACBus`](@ref) `number`.\"\"\"\nget_number(value::ACBus) = value.number\n\"\"\"Get [`ACBus`](@ref) `name`.\"\"\"\nget_name(value::ACBus) = value.name\n\"\"\"Get [`ACBus`](@ref) `available`.\"\"\"\nget_available(value::ACBus) = value.available\n\"\"\"Get [`ACBus`](@ref) `bustype`.\"\"\"\nget_bustype(value::ACBus) = value.bustype\n\"\"\"Get [`ACBus`](@ref) `angle`.\"\"\"\nget_angle(value::ACBus) = value.angle\n\"\"\"Get [`ACBus`](@ref) `magnitude`.\"\"\"\nget_magnitude(value::ACBus) = value.magnitude\n\"\"\"Get [`ACBus`](@ref) `voltage_limits`.\"\"\"\nget_voltage_limits(value::ACBus) = value.voltage_limits\n\"\"\"Get [`ACBus`](@ref) `base_voltage`.\"\"\"\nget_base_voltage(value::ACBus) = value.base_voltage\n\"\"\"Get [`ACBus`](@ref) `area`.\"\"\"\nget_area(value::ACBus) = value.area\n\"\"\"Get [`ACBus`](@ref) `load_zone`.\"\"\"\nget_load_zone(value::ACBus) = value.load_zone\n\"\"\"Get [`ACBus`](@ref) `ext`.\"\"\"\nget_ext(value::ACBus) = value.ext\n\"\"\"Get [`ACBus`](@ref) `internal`.\"\"\"\nget_internal(value::ACBus) = value.internal\n\n\"\"\"Set [`ACBus`](@ref) `available`.\"\"\"\nset_available!(value::ACBus, val) = value.available = val\n\"\"\"Set [`ACBus`](@ref) `bustype`.\"\"\"\nset_bustype!(value::ACBus, val) = value.bustype = val\n\"\"\"Set [`ACBus`](@ref) `angle`.\"\"\"\nset_angle!(value::ACBus, val) = value.angle = val\n\"\"\"Set [`ACBus`](@ref) `magnitude`.\"\"\"\nset_magnitude!(value::ACBus, val) = value.magnitude = val\n\"\"\"Set [`ACBus`](@ref) `voltage_limits`.\"\"\"\nset_voltage_limits!(value::ACBus, val) = value.voltage_limits = val\n\"\"\"Set [`ACBus`](@ref) `base_voltage`.\"\"\"\nset_base_voltage!(value::ACBus, val) = value.base_voltage = val\n\"\"\"Set [`ACBus`](@ref) `area`.\"\"\"\nset_area!(value::ACBus, val) = value.area = val\n\"\"\"Set [`ACBus`](@ref) `load_zone`.\"\"\"\nset_load_zone!(value::ACBus, val) = value.load_zone = val\n\"\"\"Set [`ACBus`](@ref) `ext`.\"\"\"\nset_ext!(value::ACBus, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AGC.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AGC <: Service\n        name::String\n        available::Bool\n        bias::Float64\n        K_p::Float64\n        K_i::Float64\n        K_d::Float64\n        delta_t::Float64\n        area::Union{Nothing, Area}\n        initial_ace::Float64\n        reserves::Vector{Reserve}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAutomatic generation control (AGC) for the system or a certain `Area` within the system.\n\nThis model uses a proportional–integral–derivative (PID) control to simulate a \"smooth\" response of the AGC to the area control error (ACE). Refer to [\"AGC Simulation Model for Large Renewable Energy Penetration Studies.\"](https://doi.org/10.1109/NAPS50074.2021.9449687)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bias::Float64`: Area frequency bias in MW/Hz\n- `K_p::Float64`: PID Proportional Constant\n- `K_i::Float64`: PID Integral Constant\n- `K_d::Float64`: PID Derivative Constant\n- `delta_t::Float64`: PID Discretization period [Seconds]\n- `area::Union{Nothing, Area}`: (default: `nothing`) the area controlled by the AGC\n- `initial_ace::Float64`: (default: `0.0`) Initial condition for ACE\n- `reserves::Vector{Reserve}`: (default: `Device[]`) Reserves that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AGC <: Service\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Area frequency bias in MW/Hz\"\n    bias::Float64\n    \"PID Proportional Constant\"\n    K_p::Float64\n    \"PID Integral Constant\"\n    K_i::Float64\n    \"PID Derivative Constant\"\n    K_d::Float64\n    \"PID Discretization period [Seconds]\"\n    delta_t::Float64\n    \"the area controlled by the AGC\"\n    area::Union{Nothing, Area}\n    \"Initial condition for ACE\"\n    initial_ace::Float64\n    \"Reserves that this device contributes to\"\n    reserves::Vector{Reserve}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AGC(name, available, bias, K_p, K_i, K_d, delta_t, area=nothing, initial_ace=0.0, reserves=Device[], ext=Dict{String, Any}(), )\n    AGC(name, available, bias, K_p, K_i, K_d, delta_t, area, initial_ace, reserves, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction AGC(; name, available, bias, K_p, K_i, K_d, delta_t, area=nothing, initial_ace=0.0, reserves=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    AGC(name, available, bias, K_p, K_i, K_d, delta_t, area, initial_ace, reserves, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AGC(::Nothing)\n    AGC(;\n        name=\"init\",\n        available=false,\n        bias=0.0,\n        K_p=0.0,\n        K_i=0.0,\n        K_d=0.0,\n        delta_t=0.0,\n        area=Area(nothing),\n        initial_ace=0.0,\n        reserves=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AGC`](@ref) `name`.\"\"\"\nget_name(value::AGC) = value.name\n\"\"\"Get [`AGC`](@ref) `available`.\"\"\"\nget_available(value::AGC) = value.available\n\"\"\"Get [`AGC`](@ref) `bias`.\"\"\"\nget_bias(value::AGC) = value.bias\n\"\"\"Get [`AGC`](@ref) `K_p`.\"\"\"\nget_K_p(value::AGC) = value.K_p\n\"\"\"Get [`AGC`](@ref) `K_i`.\"\"\"\nget_K_i(value::AGC) = value.K_i\n\"\"\"Get [`AGC`](@ref) `K_d`.\"\"\"\nget_K_d(value::AGC) = value.K_d\n\"\"\"Get [`AGC`](@ref) `delta_t`.\"\"\"\nget_delta_t(value::AGC) = value.delta_t\n\"\"\"Get [`AGC`](@ref) `area`.\"\"\"\nget_area(value::AGC) = value.area\n\"\"\"Get [`AGC`](@ref) `initial_ace`.\"\"\"\nget_initial_ace(value::AGC) = value.initial_ace\n\"\"\"Get [`AGC`](@ref) `reserves`.\"\"\"\nget_reserves(value::AGC) = value.reserves\n\"\"\"Get [`AGC`](@ref) `ext`.\"\"\"\nget_ext(value::AGC) = value.ext\n\"\"\"Get [`AGC`](@ref) `internal`.\"\"\"\nget_internal(value::AGC) = value.internal\n\n\"\"\"Set [`AGC`](@ref) `available`.\"\"\"\nset_available!(value::AGC, val) = value.available = val\n\"\"\"Set [`AGC`](@ref) `bias`.\"\"\"\nset_bias!(value::AGC, val) = value.bias = val\n\"\"\"Set [`AGC`](@ref) `K_p`.\"\"\"\nset_K_p!(value::AGC, val) = value.K_p = val\n\"\"\"Set [`AGC`](@ref) `K_i`.\"\"\"\nset_K_i!(value::AGC, val) = value.K_i = val\n\"\"\"Set [`AGC`](@ref) `K_d`.\"\"\"\nset_K_d!(value::AGC, val) = value.K_d = val\n\"\"\"Set [`AGC`](@ref) `delta_t`.\"\"\"\nset_delta_t!(value::AGC, val) = value.delta_t = val\n\"\"\"Set [`AGC`](@ref) `area`.\"\"\"\nset_area!(value::AGC, val) = value.area = val\n\"\"\"Set [`AGC`](@ref) `initial_ace`.\"\"\"\nset_initial_ace!(value::AGC, val) = value.initial_ace = val\n\"\"\"Set [`AGC`](@ref) `reserves`.\"\"\"\nset_reserves!(value::AGC, val) = value.reserves = val\n\"\"\"Set [`AGC`](@ref) `ext`.\"\"\"\nset_ext!(value::AGC, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AVRFixed.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AVRFixed <: AVR\n        Vf::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a AVR that returns a fixed voltage to the rotor winding\n\n# Arguments\n- `Vf::Float64`: Fixed voltage field applied to the rotor winding in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) Fixed AVR has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) Fixed AVR has no [states](@ref S)\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) Fixed AVR has no [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AVRFixed <: AVR\n    \"Fixed voltage field applied to the rotor winding in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    Vf::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\"\n    n_states::Int\n    \"(**Do not modify.**) Fixed AVR has no [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AVRFixed(Vf, V_ref=1.0, ext=Dict{String, Any}(), )\n    AVRFixed(Vf, V_ref, ext, Vector{Symbol}(), 0, Vector{StateTypes}(), InfrastructureSystemsInternal(), )\nend\n\nfunction AVRFixed(; Vf, V_ref=1.0, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, states_types=Vector{StateTypes}(), internal=InfrastructureSystemsInternal(), )\n    AVRFixed(Vf, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AVRFixed(::Nothing)\n    AVRFixed(;\n        Vf=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AVRFixed`](@ref) `Vf`.\"\"\"\nget_Vf(value::AVRFixed) = value.Vf\n\"\"\"Get [`AVRFixed`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::AVRFixed) = value.V_ref\n\"\"\"Get [`AVRFixed`](@ref) `ext`.\"\"\"\nget_ext(value::AVRFixed) = value.ext\n\"\"\"Get [`AVRFixed`](@ref) `states`.\"\"\"\nget_states(value::AVRFixed) = value.states\n\"\"\"Get [`AVRFixed`](@ref) `n_states`.\"\"\"\nget_n_states(value::AVRFixed) = value.n_states\n\"\"\"Get [`AVRFixed`](@ref) `states_types`.\"\"\"\nget_states_types(value::AVRFixed) = value.states_types\n\"\"\"Get [`AVRFixed`](@ref) `internal`.\"\"\"\nget_internal(value::AVRFixed) = value.internal\n\n\"\"\"Set [`AVRFixed`](@ref) `Vf`.\"\"\"\nset_Vf!(value::AVRFixed, val) = value.Vf = val\n\"\"\"Set [`AVRFixed`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::AVRFixed, val) = value.V_ref = val\n\"\"\"Set [`AVRFixed`](@ref) `ext`.\"\"\"\nset_ext!(value::AVRFixed, val) = value.ext = val\n\"\"\"Set [`AVRFixed`](@ref) `states_types`.\"\"\"\nset_states_types!(value::AVRFixed, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/AVRSimple.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AVRSimple <: AVR\n        Kv::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a simple proportional AVR in the derivative of EMF\ni.e. an integrator controller on EMF\n\n# Arguments\n- `Kv::Float64`: Proportional Gain, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVf: field voltage\n- `n_states::Int`: (**Do not modify.**) Fixed AVR has 1 [state](@ref S)\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) Simple AVR has 1 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AVRSimple <: AVR\n    \"Proportional Gain\"\n    Kv::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVf: field voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) Fixed AVR has 1 [state](@ref S)\"\n    n_states::Int\n    \"(**Do not modify.**) Simple AVR has 1 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AVRSimple(Kv, V_ref=1.0, ext=Dict{String, Any}(), )\n    AVRSimple(Kv, V_ref, ext, [:Vf], 1, [StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction AVRSimple(; Kv, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vf], n_states=1, states_types=[StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    AVRSimple(Kv, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AVRSimple(::Nothing)\n    AVRSimple(;\n        Kv=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AVRSimple`](@ref) `Kv`.\"\"\"\nget_Kv(value::AVRSimple) = value.Kv\n\"\"\"Get [`AVRSimple`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::AVRSimple) = value.V_ref\n\"\"\"Get [`AVRSimple`](@ref) `ext`.\"\"\"\nget_ext(value::AVRSimple) = value.ext\n\"\"\"Get [`AVRSimple`](@ref) `states`.\"\"\"\nget_states(value::AVRSimple) = value.states\n\"\"\"Get [`AVRSimple`](@ref) `n_states`.\"\"\"\nget_n_states(value::AVRSimple) = value.n_states\n\"\"\"Get [`AVRSimple`](@ref) `states_types`.\"\"\"\nget_states_types(value::AVRSimple) = value.states_types\n\"\"\"Get [`AVRSimple`](@ref) `internal`.\"\"\"\nget_internal(value::AVRSimple) = value.internal\n\n\"\"\"Set [`AVRSimple`](@ref) `Kv`.\"\"\"\nset_Kv!(value::AVRSimple, val) = value.Kv = val\n\"\"\"Set [`AVRSimple`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::AVRSimple, val) = value.V_ref = val\n\"\"\"Set [`AVRSimple`](@ref) `ext`.\"\"\"\nset_ext!(value::AVRSimple, val) = value.ext = val\n\"\"\"Set [`AVRSimple`](@ref) `states_types`.\"\"\"\nset_states_types!(value::AVRSimple, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/AVRTypeI.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AVRTypeI <: AVR\n        Ka::Float64\n        Ke::Float64\n        Kf::Float64\n        Ta::Float64\n        Te::Float64\n        Tf::Float64\n        Tr::Float64\n        Va_lim::MinMax\n        Ae::Float64\n        Be::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of an Automatic Voltage Regulator Type I - Resembles IEEE Type DC1\n\n# Arguments\n- `Ka::Float64`: Amplifier Gain, validation range: `(0, nothing)`\n- `Ke::Float64`: Field circuit integral deviation, validation range: `(0, nothing)`\n- `Kf::Float64`: Stabilizer Gain in s * pu/pu, validation range: `(0, nothing)`\n- `Ta::Float64`: Amplifier Time Constant in s, validation range: `(0, nothing)`\n- `Te::Float64`: Field Circuit Time Constant in s, validation range: `(0, nothing)`\n- `Tf::Float64`: Stabilizer Time Constant in s, validation range: `(0, nothing)`\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, nothing)`\n- `Va_lim::MinMax`: Limits for pi controler `(Va_min, Va_max)`\n- `Ae::Float64`: 1st ceiling coefficient, validation range: `(0, nothing)`\n- `Be::Float64`: 2nd ceiling coefficient, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVf: Voltage field,\n\tVr1: Amplifier State,\n\tVr2: Stabilizing Feedback State,\n\tVm: Measured voltage\n- `n_states::Int`: (**Do not modify.**) The AVR Type I has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) AVR Type I has 4 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AVRTypeI <: AVR\n    \"Amplifier Gain\"\n    Ka::Float64\n    \"Field circuit integral deviation\"\n    Ke::Float64\n    \"Stabilizer Gain in s * pu/pu\"\n    Kf::Float64\n    \"Amplifier Time Constant in s\"\n    Ta::Float64\n    \"Field Circuit Time Constant in s\"\n    Te::Float64\n    \"Stabilizer Time Constant in s\"\n    Tf::Float64\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Limits for pi controler `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"1st ceiling coefficient\"\n    Ae::Float64\n    \"2nd ceiling coefficient\"\n    Be::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVf: Voltage field,\n\tVr1: Amplifier State,\n\tVr2: Stabilizing Feedback State,\n\tVm: Measured voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The AVR Type I has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) AVR Type I has 4 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AVRTypeI(Ka, Ke, Kf, Ta, Te, Tf, Tr, Va_lim, Ae, Be, V_ref=1.0, ext=Dict{String, Any}(), )\n    AVRTypeI(Ka, Ke, Kf, Ta, Te, Tf, Tr, Va_lim, Ae, Be, V_ref, ext, [:Vf, :Vr1, :Vr2, :Vm], 4, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction AVRTypeI(; Ka, Ke, Kf, Ta, Te, Tf, Tr, Va_lim, Ae, Be, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vf, :Vr1, :Vr2, :Vm], n_states=4, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    AVRTypeI(Ka, Ke, Kf, Ta, Te, Tf, Tr, Va_lim, Ae, Be, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AVRTypeI(::Nothing)\n    AVRTypeI(;\n        Ka=0,\n        Ke=0,\n        Kf=0,\n        Ta=0,\n        Te=0,\n        Tf=0,\n        Tr=0,\n        Va_lim=(min=0.0, max=0.0),\n        Ae=0,\n        Be=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AVRTypeI`](@ref) `Ka`.\"\"\"\nget_Ka(value::AVRTypeI) = value.Ka\n\"\"\"Get [`AVRTypeI`](@ref) `Ke`.\"\"\"\nget_Ke(value::AVRTypeI) = value.Ke\n\"\"\"Get [`AVRTypeI`](@ref) `Kf`.\"\"\"\nget_Kf(value::AVRTypeI) = value.Kf\n\"\"\"Get [`AVRTypeI`](@ref) `Ta`.\"\"\"\nget_Ta(value::AVRTypeI) = value.Ta\n\"\"\"Get [`AVRTypeI`](@ref) `Te`.\"\"\"\nget_Te(value::AVRTypeI) = value.Te\n\"\"\"Get [`AVRTypeI`](@ref) `Tf`.\"\"\"\nget_Tf(value::AVRTypeI) = value.Tf\n\"\"\"Get [`AVRTypeI`](@ref) `Tr`.\"\"\"\nget_Tr(value::AVRTypeI) = value.Tr\n\"\"\"Get [`AVRTypeI`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::AVRTypeI) = value.Va_lim\n\"\"\"Get [`AVRTypeI`](@ref) `Ae`.\"\"\"\nget_Ae(value::AVRTypeI) = value.Ae\n\"\"\"Get [`AVRTypeI`](@ref) `Be`.\"\"\"\nget_Be(value::AVRTypeI) = value.Be\n\"\"\"Get [`AVRTypeI`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::AVRTypeI) = value.V_ref\n\"\"\"Get [`AVRTypeI`](@ref) `ext`.\"\"\"\nget_ext(value::AVRTypeI) = value.ext\n\"\"\"Get [`AVRTypeI`](@ref) `states`.\"\"\"\nget_states(value::AVRTypeI) = value.states\n\"\"\"Get [`AVRTypeI`](@ref) `n_states`.\"\"\"\nget_n_states(value::AVRTypeI) = value.n_states\n\"\"\"Get [`AVRTypeI`](@ref) `states_types`.\"\"\"\nget_states_types(value::AVRTypeI) = value.states_types\n\"\"\"Get [`AVRTypeI`](@ref) `internal`.\"\"\"\nget_internal(value::AVRTypeI) = value.internal\n\n\"\"\"Set [`AVRTypeI`](@ref) `Ka`.\"\"\"\nset_Ka!(value::AVRTypeI, val) = value.Ka = val\n\"\"\"Set [`AVRTypeI`](@ref) `Ke`.\"\"\"\nset_Ke!(value::AVRTypeI, val) = value.Ke = val\n\"\"\"Set [`AVRTypeI`](@ref) `Kf`.\"\"\"\nset_Kf!(value::AVRTypeI, val) = value.Kf = val\n\"\"\"Set [`AVRTypeI`](@ref) `Ta`.\"\"\"\nset_Ta!(value::AVRTypeI, val) = value.Ta = val\n\"\"\"Set [`AVRTypeI`](@ref) `Te`.\"\"\"\nset_Te!(value::AVRTypeI, val) = value.Te = val\n\"\"\"Set [`AVRTypeI`](@ref) `Tf`.\"\"\"\nset_Tf!(value::AVRTypeI, val) = value.Tf = val\n\"\"\"Set [`AVRTypeI`](@ref) `Tr`.\"\"\"\nset_Tr!(value::AVRTypeI, val) = value.Tr = val\n\"\"\"Set [`AVRTypeI`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::AVRTypeI, val) = value.Va_lim = val\n\"\"\"Set [`AVRTypeI`](@ref) `Ae`.\"\"\"\nset_Ae!(value::AVRTypeI, val) = value.Ae = val\n\"\"\"Set [`AVRTypeI`](@ref) `Be`.\"\"\"\nset_Be!(value::AVRTypeI, val) = value.Be = val\n\"\"\"Set [`AVRTypeI`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::AVRTypeI, val) = value.V_ref = val\n\"\"\"Set [`AVRTypeI`](@ref) `ext`.\"\"\"\nset_ext!(value::AVRTypeI, val) = value.ext = val\n\"\"\"Set [`AVRTypeI`](@ref) `states_types`.\"\"\"\nset_states_types!(value::AVRTypeI, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/AVRTypeII.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AVRTypeII <: AVR\n        K0::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        Te::Float64\n        Tr::Float64\n        Va_lim::MinMax\n        Ae::Float64\n        Be::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of an Automatic Voltage Regulator Type II -  Typical static exciter model\n\n# Arguments\n- `K0::Float64`: Regulator Gain, validation range: `(0, nothing)`\n- `T1::Float64`: First Pole in s, validation range: `(0, nothing)`\n- `T2::Float64`: First zero in s, validation range: `(0, nothing)`\n- `T3::Float64`: First Pole in s, validation range: `(0, nothing)`\n- `T4::Float64`: First zero in s, validation range: `(0, nothing)`\n- `Te::Float64`: Field Circuit Time Constant in s, validation range: `(0, nothing)`\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, nothing)`\n- `Va_lim::MinMax`: Limits for pi controler `(Va_min, Va_max)`\n- `Ae::Float64`: 1st ceiling coefficient, validation range: `(0, nothing)`\n- `Be::Float64`: 2nd ceiling coefficient, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVf: Voltage field,\n\tVr1: First Lead-Lag state,\n\tVr2: Second lead-lag state,\n\tVm: Measured voltage\n- `n_states::Int`: (**Do not modify.**) AVR Type II has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) AVR Type II has 4 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AVRTypeII <: AVR\n    \"Regulator Gain\"\n    K0::Float64\n    \"First Pole in s\"\n    T1::Float64\n    \"First zero in s\"\n    T2::Float64\n    \"First Pole in s\"\n    T3::Float64\n    \"First zero in s\"\n    T4::Float64\n    \"Field Circuit Time Constant in s\"\n    Te::Float64\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Limits for pi controler `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"1st ceiling coefficient\"\n    Ae::Float64\n    \"2nd ceiling coefficient\"\n    Be::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVf: Voltage field,\n\tVr1: First Lead-Lag state,\n\tVr2: Second lead-lag state,\n\tVm: Measured voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) AVR Type II has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) AVR Type II has 4 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AVRTypeII(K0, T1, T2, T3, T4, Te, Tr, Va_lim, Ae, Be, V_ref=1.0, ext=Dict{String, Any}(), )\n    AVRTypeII(K0, T1, T2, T3, T4, Te, Tr, Va_lim, Ae, Be, V_ref, ext, [:Vf, :Vr1, :Vr2, :Vm], 4, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction AVRTypeII(; K0, T1, T2, T3, T4, Te, Tr, Va_lim, Ae, Be, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vf, :Vr1, :Vr2, :Vm], n_states=4, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    AVRTypeII(K0, T1, T2, T3, T4, Te, Tr, Va_lim, Ae, Be, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AVRTypeII(::Nothing)\n    AVRTypeII(;\n        K0=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        Te=0,\n        Tr=0,\n        Va_lim=(min=0.0, max=0.0),\n        Ae=0,\n        Be=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AVRTypeII`](@ref) `K0`.\"\"\"\nget_K0(value::AVRTypeII) = value.K0\n\"\"\"Get [`AVRTypeII`](@ref) `T1`.\"\"\"\nget_T1(value::AVRTypeII) = value.T1\n\"\"\"Get [`AVRTypeII`](@ref) `T2`.\"\"\"\nget_T2(value::AVRTypeII) = value.T2\n\"\"\"Get [`AVRTypeII`](@ref) `T3`.\"\"\"\nget_T3(value::AVRTypeII) = value.T3\n\"\"\"Get [`AVRTypeII`](@ref) `T4`.\"\"\"\nget_T4(value::AVRTypeII) = value.T4\n\"\"\"Get [`AVRTypeII`](@ref) `Te`.\"\"\"\nget_Te(value::AVRTypeII) = value.Te\n\"\"\"Get [`AVRTypeII`](@ref) `Tr`.\"\"\"\nget_Tr(value::AVRTypeII) = value.Tr\n\"\"\"Get [`AVRTypeII`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::AVRTypeII) = value.Va_lim\n\"\"\"Get [`AVRTypeII`](@ref) `Ae`.\"\"\"\nget_Ae(value::AVRTypeII) = value.Ae\n\"\"\"Get [`AVRTypeII`](@ref) `Be`.\"\"\"\nget_Be(value::AVRTypeII) = value.Be\n\"\"\"Get [`AVRTypeII`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::AVRTypeII) = value.V_ref\n\"\"\"Get [`AVRTypeII`](@ref) `ext`.\"\"\"\nget_ext(value::AVRTypeII) = value.ext\n\"\"\"Get [`AVRTypeII`](@ref) `states`.\"\"\"\nget_states(value::AVRTypeII) = value.states\n\"\"\"Get [`AVRTypeII`](@ref) `n_states`.\"\"\"\nget_n_states(value::AVRTypeII) = value.n_states\n\"\"\"Get [`AVRTypeII`](@ref) `states_types`.\"\"\"\nget_states_types(value::AVRTypeII) = value.states_types\n\"\"\"Get [`AVRTypeII`](@ref) `internal`.\"\"\"\nget_internal(value::AVRTypeII) = value.internal\n\n\"\"\"Set [`AVRTypeII`](@ref) `K0`.\"\"\"\nset_K0!(value::AVRTypeII, val) = value.K0 = val\n\"\"\"Set [`AVRTypeII`](@ref) `T1`.\"\"\"\nset_T1!(value::AVRTypeII, val) = value.T1 = val\n\"\"\"Set [`AVRTypeII`](@ref) `T2`.\"\"\"\nset_T2!(value::AVRTypeII, val) = value.T2 = val\n\"\"\"Set [`AVRTypeII`](@ref) `T3`.\"\"\"\nset_T3!(value::AVRTypeII, val) = value.T3 = val\n\"\"\"Set [`AVRTypeII`](@ref) `T4`.\"\"\"\nset_T4!(value::AVRTypeII, val) = value.T4 = val\n\"\"\"Set [`AVRTypeII`](@ref) `Te`.\"\"\"\nset_Te!(value::AVRTypeII, val) = value.Te = val\n\"\"\"Set [`AVRTypeII`](@ref) `Tr`.\"\"\"\nset_Tr!(value::AVRTypeII, val) = value.Tr = val\n\"\"\"Set [`AVRTypeII`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::AVRTypeII, val) = value.Va_lim = val\n\"\"\"Set [`AVRTypeII`](@ref) `Ae`.\"\"\"\nset_Ae!(value::AVRTypeII, val) = value.Ae = val\n\"\"\"Set [`AVRTypeII`](@ref) `Be`.\"\"\"\nset_Be!(value::AVRTypeII, val) = value.Be = val\n\"\"\"Set [`AVRTypeII`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::AVRTypeII, val) = value.V_ref = val\n\"\"\"Set [`AVRTypeII`](@ref) `ext`.\"\"\"\nset_ext!(value::AVRTypeII, val) = value.ext = val\n\"\"\"Set [`AVRTypeII`](@ref) `states_types`.\"\"\"\nset_states_types!(value::AVRTypeII, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ActiveConstantPowerLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ActiveConstantPowerLoad <: DynamicInjection\n        name::String\n        r_load::Float64\n        c_dc::Float64\n        rf::Float64\n        lf::Float64\n        cf::Float64\n        rg::Float64\n        lg::Float64\n        kp_pll::Float64\n        ki_pll::Float64\n        kpv::Float64\n        kiv::Float64\n        kpc::Float64\n        kic::Float64\n        base_power::Float64\n        ext::Dict{String, Any}\n        P_ref::Float64\n        Q_ref::Float64\n        V_ref::Float64\n        ω_ref::Float64\n        is_filter_differential::Int\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 12-[states](@ref S) active power load based on the paper, [\"Dynamic Stability of a Microgrid With an Active Load.\"](https://doi.org/10.1109/TPEL.2013.2241455)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `r_load::Float64`: DC-side resistor, validation range: `(0, nothing)`\n- `c_dc::Float64`: DC-side capacitor, validation range: `(0, nothing)`\n- `rf::Float64`: Converter side filter resistance, validation range: `(0, nothing)`\n- `lf::Float64`: Converter side filter inductance, validation range: `(0, nothing)`\n- `cf::Float64`: AC Converter filter capacitance, validation range: `(0, nothing)`\n- `rg::Float64`: Network side filter resistance, validation range: `(0, nothing)`\n- `lg::Float64`: Network side filter inductance, validation range: `(0, nothing)`\n- `kp_pll::Float64`: Proportional constant for PI-PLL block, validation range: `(0, nothing)`\n- `ki_pll::Float64`: Integral constant for PI-PLL block, validation range: `(0, nothing)`\n- `kpv::Float64`: Proportional constant for Voltage Control block, validation range: `(0, nothing)`\n- `kiv::Float64`: Integral constant for Voltage Control block, validation range: `(0, nothing)`\n- `kpc::Float64`: Proportional constant for Current Control block, validation range: `(0, nothing)`\n- `kic::Float64`: Integral constant for Current Control block, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `P_ref::Float64`: Reference active power (pu)\n- `Q_ref::Float64`: Reference reactive power (pu)\n- `V_ref::Float64`: Reference voltage (pu)\n- `ω_ref::Float64`: Reference frequency (pu)\n- `is_filter_differential::Int`: Boolean to decide if filter [states](@ref S) are differential or algebraic\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tθ_pll: PLL deviation angle, \n\tϵ_pll: PLL integrator state, \n\tη: DC-voltage controller integrator state, \n\tv_dc: DC voltage at the capacitor, \n\tγd: d-axis Current controller integrator state, \n\tγq: q-axis Current controller integrator state, \n\tir_cnv: Real current out of the converter,\n\tii_cnv: Imaginary current out of the converter,\n\tvr_filter: Real voltage at the filter's capacitor,\n\tvi_filter: Imaginary voltage at the filter's capacitor,\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\n- `n_states::Int`: (**Do not modify.**) ActiveConstantPowerLoad has 12 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ActiveConstantPowerLoad <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"DC-side resistor\"\n    r_load::Float64\n    \"DC-side capacitor\"\n    c_dc::Float64\n    \"Converter side filter resistance\"\n    rf::Float64\n    \"Converter side filter inductance\"\n    lf::Float64\n    \"AC Converter filter capacitance\"\n    cf::Float64\n    \"Network side filter resistance\"\n    rg::Float64\n    \"Network side filter inductance\"\n    lg::Float64\n    \"Proportional constant for PI-PLL block\"\n    kp_pll::Float64\n    \"Integral constant for PI-PLL block\"\n    ki_pll::Float64\n    \"Proportional constant for Voltage Control block\"\n    kpv::Float64\n    \"Integral constant for Voltage Control block\"\n    kiv::Float64\n    \"Proportional constant for Current Control block\"\n    kpc::Float64\n    \"Integral constant for Current Control block\"\n    kic::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"Reference active power (pu)\"\n    P_ref::Float64\n    \"Reference reactive power (pu)\"\n    Q_ref::Float64\n    \"Reference voltage (pu)\"\n    V_ref::Float64\n    \"Reference frequency (pu)\"\n    ω_ref::Float64\n    \"Boolean to decide if filter [states](@ref S) are differential or algebraic\"\n    is_filter_differential::Int\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tθ_pll: PLL deviation angle, \n\tϵ_pll: PLL integrator state, \n\tη: DC-voltage controller integrator state, \n\tv_dc: DC voltage at the capacitor, \n\tγd: d-axis Current controller integrator state, \n\tγq: q-axis Current controller integrator state, \n\tir_cnv: Real current out of the converter,\n\tii_cnv: Imaginary current out of the converter,\n\tvr_filter: Real voltage at the filter's capacitor,\n\tvi_filter: Imaginary voltage at the filter's capacitor,\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ActiveConstantPowerLoad has 12 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ActiveConstantPowerLoad(name, r_load, c_dc, rf, lf, cf, rg, lg, kp_pll, ki_pll, kpv, kiv, kpc, kic, base_power, ext=Dict{String, Any}(), )\n    ActiveConstantPowerLoad(name, r_load, c_dc, rf, lf, cf, rg, lg, kp_pll, ki_pll, kpv, kiv, kpc, kic, base_power, ext, 1.0, 1.0, 1.0, 1.0, 1, [:θ_pll, :ϵ_pll, :η, :v_dc, :γd, :γq, :ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter], 12, InfrastructureSystemsInternal(), )\nend\n\nfunction ActiveConstantPowerLoad(; name, r_load, c_dc, rf, lf, cf, rg, lg, kp_pll, ki_pll, kpv, kiv, kpc, kic, base_power, ext=Dict{String, Any}(), P_ref=1.0, Q_ref=1.0, V_ref=1.0, ω_ref=1.0, is_filter_differential=1, states=[:θ_pll, :ϵ_pll, :η, :v_dc, :γd, :γq, :ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter], n_states=12, internal=InfrastructureSystemsInternal(), )\n    ActiveConstantPowerLoad(name, r_load, c_dc, rf, lf, cf, rg, lg, kp_pll, ki_pll, kpv, kiv, kpc, kic, base_power, ext, P_ref, Q_ref, V_ref, ω_ref, is_filter_differential, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ActiveConstantPowerLoad(::Nothing)\n    ActiveConstantPowerLoad(;\n        name=\"init\",\n        r_load=0,\n        c_dc=0,\n        rf=0,\n        lf=0,\n        cf=0,\n        rg=0,\n        lg=0,\n        kp_pll=0,\n        ki_pll=0,\n        kpv=0,\n        kiv=0,\n        kpc=0,\n        kic=0,\n        base_power=100,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `name`.\"\"\"\nget_name(value::ActiveConstantPowerLoad) = value.name\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `r_load`.\"\"\"\nget_r_load(value::ActiveConstantPowerLoad) = value.r_load\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `c_dc`.\"\"\"\nget_c_dc(value::ActiveConstantPowerLoad) = value.c_dc\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `rf`.\"\"\"\nget_rf(value::ActiveConstantPowerLoad) = value.rf\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `lf`.\"\"\"\nget_lf(value::ActiveConstantPowerLoad) = value.lf\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `cf`.\"\"\"\nget_cf(value::ActiveConstantPowerLoad) = value.cf\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `rg`.\"\"\"\nget_rg(value::ActiveConstantPowerLoad) = value.rg\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `lg`.\"\"\"\nget_lg(value::ActiveConstantPowerLoad) = value.lg\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `kp_pll`.\"\"\"\nget_kp_pll(value::ActiveConstantPowerLoad) = value.kp_pll\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `ki_pll`.\"\"\"\nget_ki_pll(value::ActiveConstantPowerLoad) = value.ki_pll\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `kpv`.\"\"\"\nget_kpv(value::ActiveConstantPowerLoad) = value.kpv\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `kiv`.\"\"\"\nget_kiv(value::ActiveConstantPowerLoad) = value.kiv\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `kpc`.\"\"\"\nget_kpc(value::ActiveConstantPowerLoad) = value.kpc\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `kic`.\"\"\"\nget_kic(value::ActiveConstantPowerLoad) = value.kic\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::ActiveConstantPowerLoad) = value.base_power\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `ext`.\"\"\"\nget_ext(value::ActiveConstantPowerLoad) = value.ext\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::ActiveConstantPowerLoad) = value.P_ref\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::ActiveConstantPowerLoad) = value.Q_ref\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ActiveConstantPowerLoad) = value.V_ref\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `ω_ref`.\"\"\"\nget_ω_ref(value::ActiveConstantPowerLoad) = value.ω_ref\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `is_filter_differential`.\"\"\"\nget_is_filter_differential(value::ActiveConstantPowerLoad) = value.is_filter_differential\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `states`.\"\"\"\nget_states(value::ActiveConstantPowerLoad) = value.states\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `n_states`.\"\"\"\nget_n_states(value::ActiveConstantPowerLoad) = value.n_states\n\"\"\"Get [`ActiveConstantPowerLoad`](@ref) `internal`.\"\"\"\nget_internal(value::ActiveConstantPowerLoad) = value.internal\n\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `r_load`.\"\"\"\nset_r_load!(value::ActiveConstantPowerLoad, val) = value.r_load = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `c_dc`.\"\"\"\nset_c_dc!(value::ActiveConstantPowerLoad, val) = value.c_dc = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `rf`.\"\"\"\nset_rf!(value::ActiveConstantPowerLoad, val) = value.rf = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `lf`.\"\"\"\nset_lf!(value::ActiveConstantPowerLoad, val) = value.lf = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `cf`.\"\"\"\nset_cf!(value::ActiveConstantPowerLoad, val) = value.cf = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `rg`.\"\"\"\nset_rg!(value::ActiveConstantPowerLoad, val) = value.rg = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `lg`.\"\"\"\nset_lg!(value::ActiveConstantPowerLoad, val) = value.lg = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `kp_pll`.\"\"\"\nset_kp_pll!(value::ActiveConstantPowerLoad, val) = value.kp_pll = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `ki_pll`.\"\"\"\nset_ki_pll!(value::ActiveConstantPowerLoad, val) = value.ki_pll = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `kpv`.\"\"\"\nset_kpv!(value::ActiveConstantPowerLoad, val) = value.kpv = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `kiv`.\"\"\"\nset_kiv!(value::ActiveConstantPowerLoad, val) = value.kiv = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `kpc`.\"\"\"\nset_kpc!(value::ActiveConstantPowerLoad, val) = value.kpc = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `kic`.\"\"\"\nset_kic!(value::ActiveConstantPowerLoad, val) = value.kic = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::ActiveConstantPowerLoad, val) = value.base_power = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::ActiveConstantPowerLoad, val) = value.ext = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::ActiveConstantPowerLoad, val) = value.P_ref = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::ActiveConstantPowerLoad, val) = value.Q_ref = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ActiveConstantPowerLoad, val) = value.V_ref = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `ω_ref`.\"\"\"\nset_ω_ref!(value::ActiveConstantPowerLoad, val) = value.ω_ref = val\n\"\"\"Set [`ActiveConstantPowerLoad`](@ref) `is_filter_differential`.\"\"\"\nset_is_filter_differential!(value::ActiveConstantPowerLoad, val) = value.is_filter_differential = val\n"
  },
  {
    "path": "src/models/generated/ActivePowerDroop.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ActivePowerDroop <: ActivePowerControl\n        Rp::Float64\n        ωz::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of an Active Power droop controller\n\n# Arguments\n- `Rp::Float64`: Droop Gain, validation range: `(0, nothing)`\n- `ωz::Float64`: filter frequency cutoff, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ActivePowerDroop model are:\n\tθ_oc: Phase angle displacement of the inverter model,\n\tp_oc: Measured active power of the inverter model\n- `n_states::Int`: (**Do not modify.**) ActivePowerDroop has two states\n\"\"\"\nmutable struct ActivePowerDroop <: ActivePowerControl\n    \"Droop Gain\"\n    Rp::Float64\n    \"filter frequency cutoff\"\n    ωz::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ActivePowerDroop model are:\n\tθ_oc: Phase angle displacement of the inverter model,\n\tp_oc: Measured active power of the inverter model\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ActivePowerDroop has two states\"\n    n_states::Int\nend\n\nfunction ActivePowerDroop(Rp, ωz, P_ref=1.0, ext=Dict{String, Any}(), )\n    ActivePowerDroop(Rp, ωz, P_ref, ext, [:θ_oc, :p_oc], 2, )\nend\n\nfunction ActivePowerDroop(; Rp, ωz, P_ref=1.0, ext=Dict{String, Any}(), states=[:θ_oc, :p_oc], n_states=2, )\n    ActivePowerDroop(Rp, ωz, P_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ActivePowerDroop(::Nothing)\n    ActivePowerDroop(;\n        Rp=0,\n        ωz=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ActivePowerDroop`](@ref) `Rp`.\"\"\"\nget_Rp(value::ActivePowerDroop) = value.Rp\n\"\"\"Get [`ActivePowerDroop`](@ref) `ωz`.\"\"\"\nget_ωz(value::ActivePowerDroop) = value.ωz\n\"\"\"Get [`ActivePowerDroop`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::ActivePowerDroop) = value.P_ref\n\"\"\"Get [`ActivePowerDroop`](@ref) `ext`.\"\"\"\nget_ext(value::ActivePowerDroop) = value.ext\n\"\"\"Get [`ActivePowerDroop`](@ref) `states`.\"\"\"\nget_states(value::ActivePowerDroop) = value.states\n\"\"\"Get [`ActivePowerDroop`](@ref) `n_states`.\"\"\"\nget_n_states(value::ActivePowerDroop) = value.n_states\n\n\"\"\"Set [`ActivePowerDroop`](@ref) `Rp`.\"\"\"\nset_Rp!(value::ActivePowerDroop, val) = value.Rp = val\n\"\"\"Set [`ActivePowerDroop`](@ref) `ωz`.\"\"\"\nset_ωz!(value::ActivePowerDroop, val) = value.ωz = val\n\"\"\"Set [`ActivePowerDroop`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::ActivePowerDroop, val) = value.P_ref = val\n\"\"\"Set [`ActivePowerDroop`](@ref) `ext`.\"\"\"\nset_ext!(value::ActivePowerDroop, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ActivePowerPI.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ActivePowerPI <: ActivePowerControl\n        Kp_p::Float64\n        Ki_p::Float64\n        ωz::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Proportional-Integral Active Power controller for a specified power reference\n\n# Arguments\n- `Kp_p::Float64`: Proportional Gain, validation range: `(0, nothing)`\n- `Ki_p::Float64`: Integral Gain, validation range: `(0, nothing)`\n- `ωz::Float64`: filter frequency cutoff, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ActivePowerPI model are:\n\tσp_oc: Integrator state of the PI Controller,\n\tp_oc: Measured active power of the inverter model\n- `n_states::Int`: (**Do not modify.**) ActivePowerPI has two states\n\"\"\"\nmutable struct ActivePowerPI <: ActivePowerControl\n    \"Proportional Gain\"\n    Kp_p::Float64\n    \"Integral Gain\"\n    Ki_p::Float64\n    \"filter frequency cutoff\"\n    ωz::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ActivePowerPI model are:\n\tσp_oc: Integrator state of the PI Controller,\n\tp_oc: Measured active power of the inverter model\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ActivePowerPI has two states\"\n    n_states::Int\nend\n\nfunction ActivePowerPI(Kp_p, Ki_p, ωz, P_ref=1.0, ext=Dict{String, Any}(), )\n    ActivePowerPI(Kp_p, Ki_p, ωz, P_ref, ext, [:σp_oc, :p_oc], 2, )\nend\n\nfunction ActivePowerPI(; Kp_p, Ki_p, ωz, P_ref=1.0, ext=Dict{String, Any}(), states=[:σp_oc, :p_oc], n_states=2, )\n    ActivePowerPI(Kp_p, Ki_p, ωz, P_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ActivePowerPI(::Nothing)\n    ActivePowerPI(;\n        Kp_p=0,\n        Ki_p=0,\n        ωz=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ActivePowerPI`](@ref) `Kp_p`.\"\"\"\nget_Kp_p(value::ActivePowerPI) = value.Kp_p\n\"\"\"Get [`ActivePowerPI`](@ref) `Ki_p`.\"\"\"\nget_Ki_p(value::ActivePowerPI) = value.Ki_p\n\"\"\"Get [`ActivePowerPI`](@ref) `ωz`.\"\"\"\nget_ωz(value::ActivePowerPI) = value.ωz\n\"\"\"Get [`ActivePowerPI`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::ActivePowerPI) = value.P_ref\n\"\"\"Get [`ActivePowerPI`](@ref) `ext`.\"\"\"\nget_ext(value::ActivePowerPI) = value.ext\n\"\"\"Get [`ActivePowerPI`](@ref) `states`.\"\"\"\nget_states(value::ActivePowerPI) = value.states\n\"\"\"Get [`ActivePowerPI`](@ref) `n_states`.\"\"\"\nget_n_states(value::ActivePowerPI) = value.n_states\n\n\"\"\"Set [`ActivePowerPI`](@ref) `Kp_p`.\"\"\"\nset_Kp_p!(value::ActivePowerPI, val) = value.Kp_p = val\n\"\"\"Set [`ActivePowerPI`](@ref) `Ki_p`.\"\"\"\nset_Ki_p!(value::ActivePowerPI, val) = value.Ki_p = val\n\"\"\"Set [`ActivePowerPI`](@ref) `ωz`.\"\"\"\nset_ωz!(value::ActivePowerPI, val) = value.ωz = val\n\"\"\"Set [`ActivePowerPI`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::ActivePowerPI, val) = value.P_ref = val\n\"\"\"Set [`ActivePowerPI`](@ref) `ext`.\"\"\"\nset_ext!(value::ActivePowerPI, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ActiveRenewableControllerAB.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ActiveRenewableControllerAB <: ActivePowerControl\n        bus_control::Int\n        from_branch_control::Int\n        to_branch_control::Int\n        branch_id_control::String\n        Freq_Flag::Int\n        K_pg::Float64\n        K_ig::Float64\n        T_p::Float64\n        fdbd_pnts::Tuple{Float64, Float64}\n        fe_lim::MinMax\n        P_lim::MinMax\n        T_g::Float64\n        D_dn::Float64\n        D_up::Float64\n        dP_lim::MinMax\n        P_lim_inner::MinMax\n        T_pord::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of Active Power Controller including REPCA1 and REECB1\n\n# Arguments\n- `bus_control::Int`: ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component, validation range: `(0, nothing)`\n- `from_branch_control::Int`: Monitored branch FROM bus number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`\n- `to_branch_control::Int`: Monitored branch TO bus number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`\n- `branch_id_control::String`: Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\n- `Freq_Flag::Int`: Frequency Flag for REPCA1: 0: disable, 1:enable, validation range: `(0, 1)`\n- `K_pg::Float64`: Active power PI control proportional gain, validation range: `(0, nothing)`\n- `K_ig::Float64`: Active power PI control integral gain, validation range: `(0, nothing)`\n- `T_p::Float64`: Real power measurement filter time constant (s), validation range: `(0, nothing)`\n- `fdbd_pnts::Tuple{Float64, Float64}`: Frequency error dead band thresholds `(fdbd1, fdbd2)`\n- `fe_lim::MinMax`: Upper/Lower limit on frequency error `(fe_min, fe_max)`\n- `P_lim::MinMax`: Upper/Lower limit on power reference `(P_min, P_max)`\n- `T_g::Float64`: Power Controller lag time constant, validation range: `(0, nothing)`\n- `D_dn::Float64`: Droop for over-frequency conditions, validation range: `(nothing, 0)`\n- `D_up::Float64`: Droop for under-frequency conditions, validation range: `(0, nothing)`\n- `dP_lim::MinMax`: Upper/Lower limit on power reference ramp rates`(dP_min, dP_max)`\n- `P_lim_inner::MinMax`: Upper/Lower limit on power reference for REECB`(P_min_inner, P_max_inner)`\n- `T_pord::Float64`: Power filter time constant REECB time constant, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ActiveRenewableControllerAB model depends on the Flag\n- `n_states::Int`: (**Do not modify.**) The states of the ActiveRenewableControllerAB model depends on the Flag\n\"\"\"\nmutable struct ActiveRenewableControllerAB <: ActivePowerControl\n    \"ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component\"\n    bus_control::Int\n    \"Monitored branch FROM bus number for line drop compensation (if 0 generator power will be used)\"\n    from_branch_control::Int\n    \"Monitored branch TO bus number for line drop compensation (if 0 generator power will be used)\"\n    to_branch_control::Int\n    \"Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\"\n    branch_id_control::String\n    \"Frequency Flag for REPCA1: 0: disable, 1:enable\"\n    Freq_Flag::Int\n    \"Active power PI control proportional gain\"\n    K_pg::Float64\n    \"Active power PI control integral gain\"\n    K_ig::Float64\n    \"Real power measurement filter time constant (s)\"\n    T_p::Float64\n    \"Frequency error dead band thresholds `(fdbd1, fdbd2)`\"\n    fdbd_pnts::Tuple{Float64, Float64}\n    \"Upper/Lower limit on frequency error `(fe_min, fe_max)`\"\n    fe_lim::MinMax\n    \"Upper/Lower limit on power reference `(P_min, P_max)`\"\n    P_lim::MinMax\n    \"Power Controller lag time constant\"\n    T_g::Float64\n    \"Droop for over-frequency conditions\"\n    D_dn::Float64\n    \"Droop for under-frequency conditions\"\n    D_up::Float64\n    \"Upper/Lower limit on power reference ramp rates`(dP_min, dP_max)`\"\n    dP_lim::MinMax\n    \"Upper/Lower limit on power reference for REECB`(P_min_inner, P_max_inner)`\"\n    P_lim_inner::MinMax\n    \"Power filter time constant REECB time constant\"\n    T_pord::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ActiveRenewableControllerAB model depends on the Flag\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The states of the ActiveRenewableControllerAB model depends on the Flag\"\n    n_states::Int\nend\n\nfunction ActiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, Freq_Flag, K_pg, K_ig, T_p, fdbd_pnts, fe_lim, P_lim, T_g, D_dn, D_up, dP_lim, P_lim_inner, T_pord, P_ref=1.0, ext=Dict{String, Any}(), )\n    ActiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, Freq_Flag, K_pg, K_ig, T_p, fdbd_pnts, fe_lim, P_lim, T_g, D_dn, D_up, dP_lim, P_lim_inner, T_pord, P_ref, ext, PowerSystems.get_activeRETypeAB_states(Freq_Flag)[1], PowerSystems.get_activeRETypeAB_states(Freq_Flag)[2], )\nend\n\nfunction ActiveRenewableControllerAB(; bus_control, from_branch_control, to_branch_control, branch_id_control, Freq_Flag, K_pg, K_ig, T_p, fdbd_pnts, fe_lim, P_lim, T_g, D_dn, D_up, dP_lim, P_lim_inner, T_pord, P_ref=1.0, ext=Dict{String, Any}(), states=PowerSystems.get_activeRETypeAB_states(Freq_Flag)[1], n_states=PowerSystems.get_activeRETypeAB_states(Freq_Flag)[2], )\n    ActiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, Freq_Flag, K_pg, K_ig, T_p, fdbd_pnts, fe_lim, P_lim, T_g, D_dn, D_up, dP_lim, P_lim_inner, T_pord, P_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ActiveRenewableControllerAB(::Nothing)\n    ActiveRenewableControllerAB(;\n        bus_control=0,\n        from_branch_control=0,\n        to_branch_control=0,\n        branch_id_control=\"0\",\n        Freq_Flag=0,\n        K_pg=0,\n        K_ig=0,\n        T_p=0,\n        fdbd_pnts=(0.0, 0.0),\n        fe_lim=(min=0.0, max=0.0),\n        P_lim=(min=0.0, max=0.0),\n        T_g=0,\n        D_dn=0,\n        D_up=0,\n        dP_lim=(min=0.0, max=0.0),\n        P_lim_inner=(min=0.0, max=0.0),\n        T_pord=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `bus_control`.\"\"\"\nget_bus_control(value::ActiveRenewableControllerAB) = value.bus_control\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `from_branch_control`.\"\"\"\nget_from_branch_control(value::ActiveRenewableControllerAB) = value.from_branch_control\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `to_branch_control`.\"\"\"\nget_to_branch_control(value::ActiveRenewableControllerAB) = value.to_branch_control\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `branch_id_control`.\"\"\"\nget_branch_id_control(value::ActiveRenewableControllerAB) = value.branch_id_control\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `Freq_Flag`.\"\"\"\nget_Freq_Flag(value::ActiveRenewableControllerAB) = value.Freq_Flag\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `K_pg`.\"\"\"\nget_K_pg(value::ActiveRenewableControllerAB) = value.K_pg\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `K_ig`.\"\"\"\nget_K_ig(value::ActiveRenewableControllerAB) = value.K_ig\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `T_p`.\"\"\"\nget_T_p(value::ActiveRenewableControllerAB) = value.T_p\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `fdbd_pnts`.\"\"\"\nget_fdbd_pnts(value::ActiveRenewableControllerAB) = value.fdbd_pnts\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `fe_lim`.\"\"\"\nget_fe_lim(value::ActiveRenewableControllerAB) = value.fe_lim\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `P_lim`.\"\"\"\nget_P_lim(value::ActiveRenewableControllerAB) = value.P_lim\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `T_g`.\"\"\"\nget_T_g(value::ActiveRenewableControllerAB) = value.T_g\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `D_dn`.\"\"\"\nget_D_dn(value::ActiveRenewableControllerAB) = value.D_dn\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `D_up`.\"\"\"\nget_D_up(value::ActiveRenewableControllerAB) = value.D_up\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `dP_lim`.\"\"\"\nget_dP_lim(value::ActiveRenewableControllerAB) = value.dP_lim\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `P_lim_inner`.\"\"\"\nget_P_lim_inner(value::ActiveRenewableControllerAB) = value.P_lim_inner\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `T_pord`.\"\"\"\nget_T_pord(value::ActiveRenewableControllerAB) = value.T_pord\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::ActiveRenewableControllerAB) = value.P_ref\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `ext`.\"\"\"\nget_ext(value::ActiveRenewableControllerAB) = value.ext\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `states`.\"\"\"\nget_states(value::ActiveRenewableControllerAB) = value.states\n\"\"\"Get [`ActiveRenewableControllerAB`](@ref) `n_states`.\"\"\"\nget_n_states(value::ActiveRenewableControllerAB) = value.n_states\n\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `bus_control`.\"\"\"\nset_bus_control!(value::ActiveRenewableControllerAB, val) = value.bus_control = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `from_branch_control`.\"\"\"\nset_from_branch_control!(value::ActiveRenewableControllerAB, val) = value.from_branch_control = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `to_branch_control`.\"\"\"\nset_to_branch_control!(value::ActiveRenewableControllerAB, val) = value.to_branch_control = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `branch_id_control`.\"\"\"\nset_branch_id_control!(value::ActiveRenewableControllerAB, val) = value.branch_id_control = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `Freq_Flag`.\"\"\"\nset_Freq_Flag!(value::ActiveRenewableControllerAB, val) = value.Freq_Flag = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `K_pg`.\"\"\"\nset_K_pg!(value::ActiveRenewableControllerAB, val) = value.K_pg = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `K_ig`.\"\"\"\nset_K_ig!(value::ActiveRenewableControllerAB, val) = value.K_ig = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `T_p`.\"\"\"\nset_T_p!(value::ActiveRenewableControllerAB, val) = value.T_p = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `fdbd_pnts`.\"\"\"\nset_fdbd_pnts!(value::ActiveRenewableControllerAB, val) = value.fdbd_pnts = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `fe_lim`.\"\"\"\nset_fe_lim!(value::ActiveRenewableControllerAB, val) = value.fe_lim = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `P_lim`.\"\"\"\nset_P_lim!(value::ActiveRenewableControllerAB, val) = value.P_lim = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `T_g`.\"\"\"\nset_T_g!(value::ActiveRenewableControllerAB, val) = value.T_g = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `D_dn`.\"\"\"\nset_D_dn!(value::ActiveRenewableControllerAB, val) = value.D_dn = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `D_up`.\"\"\"\nset_D_up!(value::ActiveRenewableControllerAB, val) = value.D_up = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `dP_lim`.\"\"\"\nset_dP_lim!(value::ActiveRenewableControllerAB, val) = value.dP_lim = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `P_lim_inner`.\"\"\"\nset_P_lim_inner!(value::ActiveRenewableControllerAB, val) = value.P_lim_inner = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `T_pord`.\"\"\"\nset_T_pord!(value::ActiveRenewableControllerAB, val) = value.T_pord = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::ActiveRenewableControllerAB, val) = value.P_ref = val\n\"\"\"Set [`ActiveRenewableControllerAB`](@ref) `ext`.\"\"\"\nset_ext!(value::ActiveRenewableControllerAB, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ActiveVirtualOscillator.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ActiveVirtualOscillator <: ActivePowerControl\n        k1::Float64\n        ψ::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of an Active Virtual Oscillator controller. Model is based on [\"Model Reduction for Inverters with Current Limiting and Dispatchable Virtual Oscillator Control.\"](https://doi.org/10.1109/TEC.2021.3083488)\n\n# Arguments\n- `k1::Float64`: VOC Synchronization Gain, validation range: `(0, nothing)`\n- `ψ::Float64`: Rotation angle of the controller, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ActiveVirtualOscillator model are:\n\tθ_oc: Phase angle displacement of the inverter model\n- `n_states::Int`: (**Do not modify.**) ActiveVirtualOscillator has one state\n\"\"\"\nmutable struct ActiveVirtualOscillator <: ActivePowerControl\n    \"VOC Synchronization Gain\"\n    k1::Float64\n    \"Rotation angle of the controller\"\n    ψ::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ActiveVirtualOscillator model are:\n\tθ_oc: Phase angle displacement of the inverter model\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ActiveVirtualOscillator has one state\"\n    n_states::Int\nend\n\nfunction ActiveVirtualOscillator(k1, ψ, P_ref=1.0, ext=Dict{String, Any}(), )\n    ActiveVirtualOscillator(k1, ψ, P_ref, ext, [:θ_oc], 1, )\nend\n\nfunction ActiveVirtualOscillator(; k1, ψ, P_ref=1.0, ext=Dict{String, Any}(), states=[:θ_oc], n_states=1, )\n    ActiveVirtualOscillator(k1, ψ, P_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ActiveVirtualOscillator(::Nothing)\n    ActiveVirtualOscillator(;\n        k1=0,\n        ψ=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `k1`.\"\"\"\nget_k1(value::ActiveVirtualOscillator) = value.k1\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `ψ`.\"\"\"\nget_ψ(value::ActiveVirtualOscillator) = value.ψ\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::ActiveVirtualOscillator) = value.P_ref\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `ext`.\"\"\"\nget_ext(value::ActiveVirtualOscillator) = value.ext\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `states`.\"\"\"\nget_states(value::ActiveVirtualOscillator) = value.states\n\"\"\"Get [`ActiveVirtualOscillator`](@ref) `n_states`.\"\"\"\nget_n_states(value::ActiveVirtualOscillator) = value.n_states\n\n\"\"\"Set [`ActiveVirtualOscillator`](@ref) `k1`.\"\"\"\nset_k1!(value::ActiveVirtualOscillator, val) = value.k1 = val\n\"\"\"Set [`ActiveVirtualOscillator`](@ref) `ψ`.\"\"\"\nset_ψ!(value::ActiveVirtualOscillator, val) = value.ψ = val\n\"\"\"Set [`ActiveVirtualOscillator`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::ActiveVirtualOscillator, val) = value.P_ref = val\n\"\"\"Set [`ActiveVirtualOscillator`](@ref) `ext`.\"\"\"\nset_ext!(value::ActiveVirtualOscillator, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AggregateDistributedGenerationA.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AggregateDistributedGenerationA <: DynamicInjection\n        name::String\n        Pf_Flag::Int\n        Freq_Flag::Int\n        PQ_Flag::Int\n        Gen_Flag::Int\n        Vtrip_Flag::Int\n        Ftrip_Flag::Int\n        T_rv::Float64\n        Trf::Float64\n        dbd_pnts::Tuple{Float64, Float64}\n        K_qv::Float64\n        Tp::Float64\n        T_iq::Float64\n        D_dn::Float64\n        D_up::Float64\n        fdbd_pnts::Tuple{Float64, Float64}\n        fe_lim::MinMax\n        P_lim::MinMax\n        dP_lim::MinMax\n        Tpord::Float64\n        Kpg::Float64\n        Kig::Float64\n        I_max::Float64\n        vl_pnts::Vector{Tuple{Float64,Float64}}\n        vh_pnts::Vector{Tuple{Float64,Float64}}\n        Vrfrac::Float64\n        fl::Float64\n        fh::Float64\n        tfl::Float64\n        tfh::Float64\n        Tg::Float64\n        rrpwr::Float64\n        Tv::Float64\n        Vpr::Float64\n        Iq_lim::MinMax\n        V_ref::Float64\n        Pfa_ref::Float64\n        ω_ref::Float64\n        Q_ref::Float64\n        P_ref::Float64\n        base_power::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of the DERA1 model in PSS/E\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `Pf_Flag::Int`: Flag for Power Factor Control, validation range: `(0, 1)`\n- `Freq_Flag::Int`: Flag to enable/disable frequency control, validation range: `(0, 1)`\n- `PQ_Flag::Int`: Flag used to enforce maximum current, validation range: `(0, 1)`\n- `Gen_Flag::Int`: Flag to specify generator or storage, validation range: `(0, 1)`\n- `Vtrip_Flag::Int`: Flag to enable/disable voltage trip logic, validation range: `(0, 1)`\n- `Ftrip_Flag::Int`: Flag to enable/disable frequency trip logic, validation range: `(0, 1)`\n- `T_rv::Float64`: Voltage measurement transducer time constant, validation range: `(0, nothing)`\n- `Trf::Float64`: Frequency measurement transducer time constant, validation range: `(0, nothing)`\n- `dbd_pnts::Tuple{Float64, Float64}`: Voltage deadband thresholds `(dbd1, dbd2)`\n- `K_qv::Float64`: Proportional voltage control gain (pu), validation range: `(0, nothing)`\n- `Tp::Float64`: Power measurement transducer time constant, validation range: `(0, nothing)`\n- `T_iq::Float64`: Time constant for low-pass filter for state q_V when QFlag = 0, validation range: `(0, nothing)`\n- `D_dn::Float64`: Reciprocal of droop for over-frequency conditions (>0) (pu), validation range: `(0, nothing)`\n- `D_up::Float64`: Reciprocal of droop for under-frequency conditions <=0) (pu), validation range: `(0, nothing)`\n- `fdbd_pnts::Tuple{Float64, Float64}`: Frequency control deadband thresholds `(fdbd1, fdbd2)`\n- `fe_lim::MinMax`: Frequency error limits (femin, femax)\n- `P_lim::MinMax`: Power limits (Pmin, Pmax)\n- `dP_lim::MinMax`: Power reference ramp rate limits (dPmin, dPmax)\n- `Tpord::Float64`: Power filter time constant, validation range: `(0, nothing)`\n- `Kpg::Float64`: PI controller proportional gain (pu), validation range: `(0, nothing)`\n- `Kig::Float64`: PI controller integral gain (pu), validation range: `(0, nothing)`\n- `I_max::Float64`: Maximum limit on total converter current (pu), validation range: `(0, nothing)`\n- `vl_pnts::Vector{Tuple{Float64,Float64}}`: Low voltage cutout points `[(tv10, vl0), (tv11, vl1)]`\n- `vh_pnts::Vector{Tuple{Float64,Float64}}`: High voltage cutout points `[(tvh0, vh0), (tvh1, vh1)]`\n- `Vrfrac::Float64`: Fraction of device that recovers after voltage comes back to within vl1 < V < vh1 (0 <= Vrfrac <= 1), validation range: `(0, 1)`\n- `fl::Float64`: Inverter frequency break-point for low frequency cut-out (Hz), validation range: `(0, nothing)`\n- `fh::Float64`: Inverter frequency break-point for high frequency cut-out (Hz), validation range: `(0, nothing)`\n- `tfl::Float64`: Low frequency cut-out timer corresponding to frequency fl (s), validation range: `(0, nothing)`\n- `tfh::Float64`: High frequency cut-out timer corresponding to frequency fh (s), validation range: `(0, nothing)`\n- `Tg::Float64`: Current control time constant (to represent behavior of inner control loops) (> 0) (s), validation range: `(0, nothing)`\n- `rrpwr::Float64`: Ramp rate for real power increase following a fault (pu/s), validation range: `(0, nothing)`\n- `Tv::Float64`: Time constant on the output of the multiplier (s), validation range: `(0, nothing)`\n- `Vpr::Float64`: Voltage below which frequency tripping is disabled (pu), validation range: `(0, nothing)`\n- `Iq_lim::MinMax`: Reactive current injection limits (Iqll, Iqhl)\n- `V_ref::Float64`: (default: `1.0`) User defined voltage reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage, validation range: `(0, nothing)`\n- `Pfa_ref::Float64`: (default: `0.0`) Reference power factor, validation range: `(0, nothing)`\n- `ω_ref::Float64`: (default: `1.0`) Reference Frequency (pu), validation range: `(0, nothing)`\n- `Q_ref::Float64`: (default: `0.0`) Reference reactive power, in pu, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference active power, in pu, validation range: `(0, nothing)`\n- `base_power::Float64`: (default: `100.0`) Base power (MVA) for [per unitization](@ref per_unit)\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of AggregateDistributedGenerationA depends on the Flags\n- `n_states::Int`: (**Do not modify.**) The states of AggregateDistributedGenerationA depends on the Flags\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AggregateDistributedGenerationA <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Flag for Power Factor Control\"\n    Pf_Flag::Int\n    \"Flag to enable/disable frequency control\"\n    Freq_Flag::Int\n    \"Flag used to enforce maximum current\"\n    PQ_Flag::Int\n    \"Flag to specify generator or storage\"\n    Gen_Flag::Int\n    \"Flag to enable/disable voltage trip logic\"\n    Vtrip_Flag::Int\n    \"Flag to enable/disable frequency trip logic\"\n    Ftrip_Flag::Int\n    \"Voltage measurement transducer time constant\"\n    T_rv::Float64\n    \"Frequency measurement transducer time constant\"\n    Trf::Float64\n    \"Voltage deadband thresholds `(dbd1, dbd2)`\"\n    dbd_pnts::Tuple{Float64, Float64}\n    \"Proportional voltage control gain (pu)\"\n    K_qv::Float64\n    \"Power measurement transducer time constant\"\n    Tp::Float64\n    \"Time constant for low-pass filter for state q_V when QFlag = 0\"\n    T_iq::Float64\n    \"Reciprocal of droop for over-frequency conditions (>0) (pu)\"\n    D_dn::Float64\n    \"Reciprocal of droop for under-frequency conditions <=0) (pu)\"\n    D_up::Float64\n    \"Frequency control deadband thresholds `(fdbd1, fdbd2)`\"\n    fdbd_pnts::Tuple{Float64, Float64}\n    \"Frequency error limits (femin, femax)\"\n    fe_lim::MinMax\n    \"Power limits (Pmin, Pmax)\"\n    P_lim::MinMax\n    \"Power reference ramp rate limits (dPmin, dPmax)\"\n    dP_lim::MinMax\n    \"Power filter time constant\"\n    Tpord::Float64\n    \"PI controller proportional gain (pu)\"\n    Kpg::Float64\n    \"PI controller integral gain (pu)\"\n    Kig::Float64\n    \"Maximum limit on total converter current (pu)\"\n    I_max::Float64\n    \"Low voltage cutout points `[(tv10, vl0), (tv11, vl1)]`\"\n    vl_pnts::Vector{Tuple{Float64,Float64}}\n    \"High voltage cutout points `[(tvh0, vh0), (tvh1, vh1)]`\"\n    vh_pnts::Vector{Tuple{Float64,Float64}}\n    \"Fraction of device that recovers after voltage comes back to within vl1 < V < vh1 (0 <= Vrfrac <= 1)\"\n    Vrfrac::Float64\n    \"Inverter frequency break-point for low frequency cut-out (Hz)\"\n    fl::Float64\n    \"Inverter frequency break-point for high frequency cut-out (Hz)\"\n    fh::Float64\n    \"Low frequency cut-out timer corresponding to frequency fl (s)\"\n    tfl::Float64\n    \"High frequency cut-out timer corresponding to frequency fh (s)\"\n    tfh::Float64\n    \"Current control time constant (to represent behavior of inner control loops) (> 0) (s)\"\n    Tg::Float64\n    \"Ramp rate for real power increase following a fault (pu/s)\"\n    rrpwr::Float64\n    \"Time constant on the output of the multiplier (s)\"\n    Tv::Float64\n    \"Voltage below which frequency tripping is disabled (pu)\"\n    Vpr::Float64\n    \"Reactive current injection limits (Iqll, Iqhl)\"\n    Iq_lim::MinMax\n    \"User defined voltage reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage\"\n    V_ref::Float64\n    \"Reference power factor\"\n    Pfa_ref::Float64\n    \"Reference Frequency (pu)\"\n    ω_ref::Float64\n    \"Reference reactive power, in pu\"\n    Q_ref::Float64\n    \"Reference active power, in pu\"\n    P_ref::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of AggregateDistributedGenerationA depends on the Flags\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The states of AggregateDistributedGenerationA depends on the Flags\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AggregateDistributedGenerationA(name, Pf_Flag, Freq_Flag, PQ_Flag, Gen_Flag, Vtrip_Flag, Ftrip_Flag, T_rv, Trf, dbd_pnts, K_qv, Tp, T_iq, D_dn, D_up, fdbd_pnts, fe_lim, P_lim, dP_lim, Tpord, Kpg, Kig, I_max, vl_pnts, vh_pnts, Vrfrac, fl, fh, tfl, tfh, Tg, rrpwr, Tv, Vpr, Iq_lim, V_ref=1.0, Pfa_ref=0.0, ω_ref=1.0, Q_ref=0.0, P_ref=1.0, base_power=100.0, ext=Dict{String, Any}(), )\n    AggregateDistributedGenerationA(name, Pf_Flag, Freq_Flag, PQ_Flag, Gen_Flag, Vtrip_Flag, Ftrip_Flag, T_rv, Trf, dbd_pnts, K_qv, Tp, T_iq, D_dn, D_up, fdbd_pnts, fe_lim, P_lim, dP_lim, Tpord, Kpg, Kig, I_max, vl_pnts, vh_pnts, Vrfrac, fl, fh, tfl, tfh, Tg, rrpwr, Tv, Vpr, Iq_lim, V_ref, Pfa_ref, ω_ref, Q_ref, P_ref, base_power, ext, PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[1], PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[2], InfrastructureSystemsInternal(), )\nend\n\nfunction AggregateDistributedGenerationA(; name, Pf_Flag, Freq_Flag, PQ_Flag, Gen_Flag, Vtrip_Flag, Ftrip_Flag, T_rv, Trf, dbd_pnts, K_qv, Tp, T_iq, D_dn, D_up, fdbd_pnts, fe_lim, P_lim, dP_lim, Tpord, Kpg, Kig, I_max, vl_pnts, vh_pnts, Vrfrac, fl, fh, tfl, tfh, Tg, rrpwr, Tv, Vpr, Iq_lim, V_ref=1.0, Pfa_ref=0.0, ω_ref=1.0, Q_ref=0.0, P_ref=1.0, base_power=100.0, ext=Dict{String, Any}(), states=PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[1], n_states=PowerSystems.get_AggregateDistributedGenerationA_states(Freq_Flag)[2], internal=InfrastructureSystemsInternal(), )\n    AggregateDistributedGenerationA(name, Pf_Flag, Freq_Flag, PQ_Flag, Gen_Flag, Vtrip_Flag, Ftrip_Flag, T_rv, Trf, dbd_pnts, K_qv, Tp, T_iq, D_dn, D_up, fdbd_pnts, fe_lim, P_lim, dP_lim, Tpord, Kpg, Kig, I_max, vl_pnts, vh_pnts, Vrfrac, fl, fh, tfl, tfh, Tg, rrpwr, Tv, Vpr, Iq_lim, V_ref, Pfa_ref, ω_ref, Q_ref, P_ref, base_power, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AggregateDistributedGenerationA(::Nothing)\n    AggregateDistributedGenerationA(;\n        name=\"init\",\n        Pf_Flag=0,\n        Freq_Flag=0,\n        PQ_Flag=0,\n        Gen_Flag=0,\n        Vtrip_Flag=0,\n        Ftrip_Flag=0,\n        T_rv=0,\n        Trf=0,\n        dbd_pnts=(0.0, 0.0),\n        K_qv=0,\n        Tp=0,\n        T_iq=0,\n        D_dn=0,\n        D_up=0,\n        fdbd_pnts=(0.0, 0.0),\n        fe_lim=(min=0.0, max=0.0),\n        P_lim=(min=0.0, max=0.0),\n        dP_lim=(min=0.0, max=0.0),\n        Tpord=0,\n        Kpg=0,\n        Kig=0,\n        I_max=0,\n        vl_pnts=[(0.0, 0.0), (0.0, 0.0)],\n        vh_pnts=[(0.0, 0.0), (0.0, 0.0)],\n        Vrfrac=0,\n        fl=0,\n        fh=0,\n        tfl=0,\n        tfh=0,\n        Tg=0,\n        rrpwr=0,\n        Tv=0,\n        Vpr=0,\n        Iq_lim=(min=0.0, max=0.0),\n        V_ref=0,\n        Pfa_ref=0,\n        ω_ref=0,\n        Q_ref=0,\n        P_ref=0,\n        base_power=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `name`.\"\"\"\nget_name(value::AggregateDistributedGenerationA) = value.name\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Pf_Flag`.\"\"\"\nget_Pf_Flag(value::AggregateDistributedGenerationA) = value.Pf_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Freq_Flag`.\"\"\"\nget_Freq_Flag(value::AggregateDistributedGenerationA) = value.Freq_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `PQ_Flag`.\"\"\"\nget_PQ_Flag(value::AggregateDistributedGenerationA) = value.PQ_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Gen_Flag`.\"\"\"\nget_Gen_Flag(value::AggregateDistributedGenerationA) = value.Gen_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Vtrip_Flag`.\"\"\"\nget_Vtrip_Flag(value::AggregateDistributedGenerationA) = value.Vtrip_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Ftrip_Flag`.\"\"\"\nget_Ftrip_Flag(value::AggregateDistributedGenerationA) = value.Ftrip_Flag\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `T_rv`.\"\"\"\nget_T_rv(value::AggregateDistributedGenerationA) = value.T_rv\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Trf`.\"\"\"\nget_Trf(value::AggregateDistributedGenerationA) = value.Trf\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `dbd_pnts`.\"\"\"\nget_dbd_pnts(value::AggregateDistributedGenerationA) = value.dbd_pnts\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `K_qv`.\"\"\"\nget_K_qv(value::AggregateDistributedGenerationA) = value.K_qv\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Tp`.\"\"\"\nget_Tp(value::AggregateDistributedGenerationA) = value.Tp\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `T_iq`.\"\"\"\nget_T_iq(value::AggregateDistributedGenerationA) = value.T_iq\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `D_dn`.\"\"\"\nget_D_dn(value::AggregateDistributedGenerationA) = value.D_dn\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `D_up`.\"\"\"\nget_D_up(value::AggregateDistributedGenerationA) = value.D_up\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `fdbd_pnts`.\"\"\"\nget_fdbd_pnts(value::AggregateDistributedGenerationA) = value.fdbd_pnts\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `fe_lim`.\"\"\"\nget_fe_lim(value::AggregateDistributedGenerationA) = value.fe_lim\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `P_lim`.\"\"\"\nget_P_lim(value::AggregateDistributedGenerationA) = value.P_lim\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `dP_lim`.\"\"\"\nget_dP_lim(value::AggregateDistributedGenerationA) = value.dP_lim\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Tpord`.\"\"\"\nget_Tpord(value::AggregateDistributedGenerationA) = value.Tpord\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Kpg`.\"\"\"\nget_Kpg(value::AggregateDistributedGenerationA) = value.Kpg\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Kig`.\"\"\"\nget_Kig(value::AggregateDistributedGenerationA) = value.Kig\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `I_max`.\"\"\"\nget_I_max(value::AggregateDistributedGenerationA) = value.I_max\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `vl_pnts`.\"\"\"\nget_vl_pnts(value::AggregateDistributedGenerationA) = value.vl_pnts\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `vh_pnts`.\"\"\"\nget_vh_pnts(value::AggregateDistributedGenerationA) = value.vh_pnts\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Vrfrac`.\"\"\"\nget_Vrfrac(value::AggregateDistributedGenerationA) = value.Vrfrac\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `fl`.\"\"\"\nget_fl(value::AggregateDistributedGenerationA) = value.fl\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `fh`.\"\"\"\nget_fh(value::AggregateDistributedGenerationA) = value.fh\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `tfl`.\"\"\"\nget_tfl(value::AggregateDistributedGenerationA) = value.tfl\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `tfh`.\"\"\"\nget_tfh(value::AggregateDistributedGenerationA) = value.tfh\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Tg`.\"\"\"\nget_Tg(value::AggregateDistributedGenerationA) = value.Tg\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `rrpwr`.\"\"\"\nget_rrpwr(value::AggregateDistributedGenerationA) = value.rrpwr\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Tv`.\"\"\"\nget_Tv(value::AggregateDistributedGenerationA) = value.Tv\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Vpr`.\"\"\"\nget_Vpr(value::AggregateDistributedGenerationA) = value.Vpr\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Iq_lim`.\"\"\"\nget_Iq_lim(value::AggregateDistributedGenerationA) = value.Iq_lim\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::AggregateDistributedGenerationA) = value.V_ref\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Pfa_ref`.\"\"\"\nget_Pfa_ref(value::AggregateDistributedGenerationA) = value.Pfa_ref\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `ω_ref`.\"\"\"\nget_ω_ref(value::AggregateDistributedGenerationA) = value.ω_ref\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::AggregateDistributedGenerationA) = value.Q_ref\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::AggregateDistributedGenerationA) = value.P_ref\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `base_power`.\"\"\"\nget_base_power(value::AggregateDistributedGenerationA) = value.base_power\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `ext`.\"\"\"\nget_ext(value::AggregateDistributedGenerationA) = value.ext\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `states`.\"\"\"\nget_states(value::AggregateDistributedGenerationA) = value.states\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `n_states`.\"\"\"\nget_n_states(value::AggregateDistributedGenerationA) = value.n_states\n\"\"\"Get [`AggregateDistributedGenerationA`](@ref) `internal`.\"\"\"\nget_internal(value::AggregateDistributedGenerationA) = value.internal\n\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Pf_Flag`.\"\"\"\nset_Pf_Flag!(value::AggregateDistributedGenerationA, val) = value.Pf_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Freq_Flag`.\"\"\"\nset_Freq_Flag!(value::AggregateDistributedGenerationA, val) = value.Freq_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `PQ_Flag`.\"\"\"\nset_PQ_Flag!(value::AggregateDistributedGenerationA, val) = value.PQ_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Gen_Flag`.\"\"\"\nset_Gen_Flag!(value::AggregateDistributedGenerationA, val) = value.Gen_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Vtrip_Flag`.\"\"\"\nset_Vtrip_Flag!(value::AggregateDistributedGenerationA, val) = value.Vtrip_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Ftrip_Flag`.\"\"\"\nset_Ftrip_Flag!(value::AggregateDistributedGenerationA, val) = value.Ftrip_Flag = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `T_rv`.\"\"\"\nset_T_rv!(value::AggregateDistributedGenerationA, val) = value.T_rv = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Trf`.\"\"\"\nset_Trf!(value::AggregateDistributedGenerationA, val) = value.Trf = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `dbd_pnts`.\"\"\"\nset_dbd_pnts!(value::AggregateDistributedGenerationA, val) = value.dbd_pnts = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `K_qv`.\"\"\"\nset_K_qv!(value::AggregateDistributedGenerationA, val) = value.K_qv = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Tp`.\"\"\"\nset_Tp!(value::AggregateDistributedGenerationA, val) = value.Tp = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `T_iq`.\"\"\"\nset_T_iq!(value::AggregateDistributedGenerationA, val) = value.T_iq = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `D_dn`.\"\"\"\nset_D_dn!(value::AggregateDistributedGenerationA, val) = value.D_dn = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `D_up`.\"\"\"\nset_D_up!(value::AggregateDistributedGenerationA, val) = value.D_up = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `fdbd_pnts`.\"\"\"\nset_fdbd_pnts!(value::AggregateDistributedGenerationA, val) = value.fdbd_pnts = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `fe_lim`.\"\"\"\nset_fe_lim!(value::AggregateDistributedGenerationA, val) = value.fe_lim = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `P_lim`.\"\"\"\nset_P_lim!(value::AggregateDistributedGenerationA, val) = value.P_lim = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `dP_lim`.\"\"\"\nset_dP_lim!(value::AggregateDistributedGenerationA, val) = value.dP_lim = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Tpord`.\"\"\"\nset_Tpord!(value::AggregateDistributedGenerationA, val) = value.Tpord = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Kpg`.\"\"\"\nset_Kpg!(value::AggregateDistributedGenerationA, val) = value.Kpg = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Kig`.\"\"\"\nset_Kig!(value::AggregateDistributedGenerationA, val) = value.Kig = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `I_max`.\"\"\"\nset_I_max!(value::AggregateDistributedGenerationA, val) = value.I_max = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `vl_pnts`.\"\"\"\nset_vl_pnts!(value::AggregateDistributedGenerationA, val) = value.vl_pnts = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `vh_pnts`.\"\"\"\nset_vh_pnts!(value::AggregateDistributedGenerationA, val) = value.vh_pnts = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Vrfrac`.\"\"\"\nset_Vrfrac!(value::AggregateDistributedGenerationA, val) = value.Vrfrac = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `fl`.\"\"\"\nset_fl!(value::AggregateDistributedGenerationA, val) = value.fl = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `fh`.\"\"\"\nset_fh!(value::AggregateDistributedGenerationA, val) = value.fh = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `tfl`.\"\"\"\nset_tfl!(value::AggregateDistributedGenerationA, val) = value.tfl = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `tfh`.\"\"\"\nset_tfh!(value::AggregateDistributedGenerationA, val) = value.tfh = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Tg`.\"\"\"\nset_Tg!(value::AggregateDistributedGenerationA, val) = value.Tg = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `rrpwr`.\"\"\"\nset_rrpwr!(value::AggregateDistributedGenerationA, val) = value.rrpwr = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Tv`.\"\"\"\nset_Tv!(value::AggregateDistributedGenerationA, val) = value.Tv = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Vpr`.\"\"\"\nset_Vpr!(value::AggregateDistributedGenerationA, val) = value.Vpr = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Iq_lim`.\"\"\"\nset_Iq_lim!(value::AggregateDistributedGenerationA, val) = value.Iq_lim = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::AggregateDistributedGenerationA, val) = value.V_ref = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Pfa_ref`.\"\"\"\nset_Pfa_ref!(value::AggregateDistributedGenerationA, val) = value.Pfa_ref = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `ω_ref`.\"\"\"\nset_ω_ref!(value::AggregateDistributedGenerationA, val) = value.ω_ref = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::AggregateDistributedGenerationA, val) = value.Q_ref = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::AggregateDistributedGenerationA, val) = value.P_ref = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `base_power`.\"\"\"\nset_base_power!(value::AggregateDistributedGenerationA, val) = value.base_power = val\n\"\"\"Set [`AggregateDistributedGenerationA`](@ref) `ext`.\"\"\"\nset_ext!(value::AggregateDistributedGenerationA, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AndersonFouadMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AndersonFouadMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xq_pp::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 6-[states](@ref S) synchronous machine: Anderson-Fouad model\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\n- `n_states::Int`: (**Do not modify.**) The states AndersonFouadMachine has 6 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AndersonFouadMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit\"\n    Xd_pp::Float64\n    \"Sub-Transient reactance after EMF in q-axis per unit\"\n    Xq_pp::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The states AndersonFouadMachine has 6 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AndersonFouadMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), )\n    AndersonFouadMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, [:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp], 6, InfrastructureSystemsInternal(), )\nend\n\nfunction AndersonFouadMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), states=[:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp], n_states=6, internal=InfrastructureSystemsInternal(), )\n    AndersonFouadMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AndersonFouadMachine(::Nothing)\n    AndersonFouadMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xq_pp=0,\n        Td0_p=0,\n        Tq0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AndersonFouadMachine`](@ref) `R`.\"\"\"\nget_R(value::AndersonFouadMachine) = value.R\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::AndersonFouadMachine) = value.Xd\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::AndersonFouadMachine) = value.Xq\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::AndersonFouadMachine) = value.Xd_p\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::AndersonFouadMachine) = value.Xq_p\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::AndersonFouadMachine) = value.Xd_pp\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Xq_pp`.\"\"\"\nget_Xq_pp(value::AndersonFouadMachine) = value.Xq_pp\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::AndersonFouadMachine) = value.Td0_p\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::AndersonFouadMachine) = value.Tq0_p\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::AndersonFouadMachine) = value.Td0_pp\n\"\"\"Get [`AndersonFouadMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::AndersonFouadMachine) = value.Tq0_pp\n\"\"\"Get [`AndersonFouadMachine`](@ref) `ext`.\"\"\"\nget_ext(value::AndersonFouadMachine) = value.ext\n\"\"\"Get [`AndersonFouadMachine`](@ref) `states`.\"\"\"\nget_states(value::AndersonFouadMachine) = value.states\n\"\"\"Get [`AndersonFouadMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::AndersonFouadMachine) = value.n_states\n\"\"\"Get [`AndersonFouadMachine`](@ref) `internal`.\"\"\"\nget_internal(value::AndersonFouadMachine) = value.internal\n\n\"\"\"Set [`AndersonFouadMachine`](@ref) `R`.\"\"\"\nset_R!(value::AndersonFouadMachine, val) = value.R = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::AndersonFouadMachine, val) = value.Xd = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::AndersonFouadMachine, val) = value.Xq = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::AndersonFouadMachine, val) = value.Xd_p = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::AndersonFouadMachine, val) = value.Xq_p = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::AndersonFouadMachine, val) = value.Xd_pp = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Xq_pp`.\"\"\"\nset_Xq_pp!(value::AndersonFouadMachine, val) = value.Xq_pp = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::AndersonFouadMachine, val) = value.Td0_p = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::AndersonFouadMachine, val) = value.Tq0_p = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::AndersonFouadMachine, val) = value.Td0_pp = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::AndersonFouadMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`AndersonFouadMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::AndersonFouadMachine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/Arc.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Arc <: Topology\n        from::Bus\n        to::Bus\n        internal::InfrastructureSystemsInternal\n    end\n\nA topological directed edge connecting two buses.\n\nArcs are used to define the `from` and `to` buses when defining a line or transformer\n\n# Arguments\n- `from::Bus`: The initial bus\n- `to::Bus`: The terminal bus\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Arc <: Topology\n    \"The initial bus\"\n    from::Bus\n    \"The terminal bus\"\n    to::Bus\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Arc(from, to, )\n    Arc(from, to, InfrastructureSystemsInternal(), )\nend\n\nfunction Arc(; from, to, internal=InfrastructureSystemsInternal(), )\n    Arc(from, to, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Arc(::Nothing)\n    Arc(;\n        from=ACBus(nothing),\n        to=ACBus(nothing),\n    )\nend\n\n\"\"\"Get [`Arc`](@ref) `from`.\"\"\"\nget_from(value::Arc) = value.from\n\"\"\"Get [`Arc`](@ref) `to`.\"\"\"\nget_to(value::Arc) = value.to\n\"\"\"Get [`Arc`](@ref) `internal`.\"\"\"\nget_internal(value::Arc) = value.internal\n\n\"\"\"Set [`Arc`](@ref) `from`.\"\"\"\nset_from!(value::Arc, val) = value.from = val\n\"\"\"Set [`Arc`](@ref) `to`.\"\"\"\nset_to!(value::Arc, val) = value.to = val\n\nget_name(arc::Arc) = (get_name ∘ get_from)(arc) * \" -> \" * (get_name ∘ get_to)(arc)\n"
  },
  {
    "path": "src/models/generated/Area.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Area <: AggregationTopology\n        name::String\n        peak_active_power::Float64\n        peak_reactive_power::Float64\n        load_response::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA collection of buses for control purposes.\n\nThe `Area` can be specified when defining each [`ACBus`](@ref) or [`DCBus`](@ref) in the area\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `peak_active_power::Float64`: (default: `0.0`) Peak active power in the area\n- `peak_reactive_power::Float64`: (default: `0.0`) Peak reactive power in the area\n- `load_response::Float64`: (default: `0.0`) Load-frequency damping parameter modeling how much the load in the area changes due to changes in frequency (MW/Hz). [Example here.](https://doi.org/10.1109/NAPS50074.2021.9449687)\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Area <: AggregationTopology\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Peak active power in the area\"\n    peak_active_power::Float64\n    \"Peak reactive power in the area\"\n    peak_reactive_power::Float64\n    \"Load-frequency damping parameter modeling how much the load in the area changes due to changes in frequency (MW/Hz). [Example here.](https://doi.org/10.1109/NAPS50074.2021.9449687)\"\n    load_response::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Area(name, peak_active_power=0.0, peak_reactive_power=0.0, load_response=0.0, ext=Dict{String, Any}(), )\n    Area(name, peak_active_power, peak_reactive_power, load_response, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction Area(; name, peak_active_power=0.0, peak_reactive_power=0.0, load_response=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    Area(name, peak_active_power, peak_reactive_power, load_response, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Area(::Nothing)\n    Area(;\n        name=\"init\",\n        peak_active_power=0.0,\n        peak_reactive_power=0.0,\n        load_response=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`Area`](@ref) `name`.\"\"\"\nget_name(value::Area) = value.name\n\"\"\"Get [`Area`](@ref) `peak_active_power`.\"\"\"\nget_peak_active_power(value::Area) = get_value(value, Val(:peak_active_power), Val(:mva))\n\"\"\"Get [`Area`](@ref) `peak_reactive_power`.\"\"\"\nget_peak_reactive_power(value::Area) = get_value(value, Val(:peak_reactive_power), Val(:mva))\n\"\"\"Get [`Area`](@ref) `load_response`.\"\"\"\nget_load_response(value::Area) = value.load_response\n\"\"\"Get [`Area`](@ref) `ext`.\"\"\"\nget_ext(value::Area) = value.ext\n\"\"\"Get [`Area`](@ref) `internal`.\"\"\"\nget_internal(value::Area) = value.internal\n\n\"\"\"Set [`Area`](@ref) `peak_active_power`.\"\"\"\nset_peak_active_power!(value::Area, val) = value.peak_active_power = set_value(value, Val(:peak_active_power), val, Val(:mva))\n\"\"\"Set [`Area`](@ref) `peak_reactive_power`.\"\"\"\nset_peak_reactive_power!(value::Area, val) = value.peak_reactive_power = set_value(value, Val(:peak_reactive_power), val, Val(:mva))\n\"\"\"Set [`Area`](@ref) `load_response`.\"\"\"\nset_load_response!(value::Area, val) = value.load_response = val\n\"\"\"Set [`Area`](@ref) `ext`.\"\"\"\nset_ext!(value::Area, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AreaInterchange.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AreaInterchange <: Branch\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        from_area::Area\n        to_area::Area\n        flow_limits::FromTo_ToFrom\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nFlow exchanged between Areas. This Interchange is agnostic to the lines connecting the areas. It does not substitute Interface which is the total flow across a group of lines\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `from_area::Area`: Area from which the power is extracted\n- `to_area::Area`: Area to which the power is injected\n- `flow_limits::FromTo_ToFrom`: Max flow between the areas. It ignores lines and other branches totals\n- `services::Vector{Service}`: (default: `Service[]`) Service interfaces that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct AreaInterchange <: Branch\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Area from which the power is extracted\"\n    from_area::Area\n    \"Area to which the power is injected\"\n    to_area::Area\n    \"Max flow between the areas. It ignores lines and other branches totals\"\n    flow_limits::FromTo_ToFrom\n    \"Service interfaces that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction AreaInterchange(name, available, active_power_flow, from_area, to_area, flow_limits, services=Service[], ext=Dict{String, Any}(), )\n    AreaInterchange(name, available, active_power_flow, from_area, to_area, flow_limits, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction AreaInterchange(; name, available, active_power_flow, from_area, to_area, flow_limits, services=Service[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    AreaInterchange(name, available, active_power_flow, from_area, to_area, flow_limits, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AreaInterchange(::Nothing)\n    AreaInterchange(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        from_area=Area(nothing),\n        to_area=Area(nothing),\n        flow_limits=(from_to=0.0, to_from=0.0),\n        services=Service[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AreaInterchange`](@ref) `name`.\"\"\"\nget_name(value::AreaInterchange) = value.name\n\"\"\"Get [`AreaInterchange`](@ref) `available`.\"\"\"\nget_available(value::AreaInterchange) = value.available\n\"\"\"Get [`AreaInterchange`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::AreaInterchange) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`AreaInterchange`](@ref) `from_area`.\"\"\"\nget_from_area(value::AreaInterchange) = value.from_area\n\"\"\"Get [`AreaInterchange`](@ref) `to_area`.\"\"\"\nget_to_area(value::AreaInterchange) = value.to_area\n\"\"\"Get [`AreaInterchange`](@ref) `flow_limits`.\"\"\"\nget_flow_limits(value::AreaInterchange) = get_value(value, Val(:flow_limits), Val(:mva))\n\"\"\"Get [`AreaInterchange`](@ref) `services`.\"\"\"\nget_services(value::AreaInterchange) = value.services\n\"\"\"Get [`AreaInterchange`](@ref) `ext`.\"\"\"\nget_ext(value::AreaInterchange) = value.ext\n\"\"\"Get [`AreaInterchange`](@ref) `internal`.\"\"\"\nget_internal(value::AreaInterchange) = value.internal\n\n\"\"\"Set [`AreaInterchange`](@ref) `available`.\"\"\"\nset_available!(value::AreaInterchange, val) = value.available = val\n\"\"\"Set [`AreaInterchange`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::AreaInterchange, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`AreaInterchange`](@ref) `from_area`.\"\"\"\nset_from_area!(value::AreaInterchange, val) = value.from_area = val\n\"\"\"Set [`AreaInterchange`](@ref) `to_area`.\"\"\"\nset_to_area!(value::AreaInterchange, val) = value.to_area = val\n\"\"\"Set [`AreaInterchange`](@ref) `flow_limits`.\"\"\"\nset_flow_limits!(value::AreaInterchange, val) = value.flow_limits = set_value(value, Val(:flow_limits), val, Val(:mva))\n\"\"\"Set [`AreaInterchange`](@ref) `services`.\"\"\"\nset_services!(value::AreaInterchange, val) = value.services = val\n\"\"\"Set [`AreaInterchange`](@ref) `ext`.\"\"\"\nset_ext!(value::AreaInterchange, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/AverageConverter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct AverageConverter <: Converter\n        rated_voltage::Float64\n        rated_current::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of an average converter model\n\n# Arguments\n- `rated_voltage::Float64`: Rated voltage (V), validation range: `(0, nothing)`\n- `rated_current::Float64`: Rated current (A), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) AverageConverter has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) AverageConverter has no states\n\"\"\"\nmutable struct AverageConverter <: Converter\n    \"Rated voltage (V)\"\n    rated_voltage::Float64\n    \"Rated current (A)\"\n    rated_current::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) AverageConverter has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) AverageConverter has no states\"\n    n_states::Int\nend\n\nfunction AverageConverter(rated_voltage, rated_current, ext=Dict{String, Any}(), )\n    AverageConverter(rated_voltage, rated_current, ext, Vector{Symbol}(), 0, )\nend\n\nfunction AverageConverter(; rated_voltage, rated_current, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, )\n    AverageConverter(rated_voltage, rated_current, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction AverageConverter(::Nothing)\n    AverageConverter(;\n        rated_voltage=0,\n        rated_current=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`AverageConverter`](@ref) `rated_voltage`.\"\"\"\nget_rated_voltage(value::AverageConverter) = value.rated_voltage\n\"\"\"Get [`AverageConverter`](@ref) `rated_current`.\"\"\"\nget_rated_current(value::AverageConverter) = value.rated_current\n\"\"\"Get [`AverageConverter`](@ref) `ext`.\"\"\"\nget_ext(value::AverageConverter) = value.ext\n\"\"\"Get [`AverageConverter`](@ref) `states`.\"\"\"\nget_states(value::AverageConverter) = value.states\n\"\"\"Get [`AverageConverter`](@ref) `n_states`.\"\"\"\nget_n_states(value::AverageConverter) = value.n_states\n\n\"\"\"Set [`AverageConverter`](@ref) `rated_voltage`.\"\"\"\nset_rated_voltage!(value::AverageConverter, val) = value.rated_voltage = val\n\"\"\"Set [`AverageConverter`](@ref) `rated_current`.\"\"\"\nset_rated_current!(value::AverageConverter, val) = value.rated_current = val\n\"\"\"Set [`AverageConverter`](@ref) `ext`.\"\"\"\nset_ext!(value::AverageConverter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/BaseMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct BaseMachine <: Machine\n        R::Float64\n        Xd_p::Float64\n        eq_p::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Classic Machine: GENCLS in PSSE and PSLF\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Reactance after EMF in machine per unit, validation range: `(0, nothing)`\n- `eq_p::Float64`: Fixed EMF behind the impedance, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) BaseMachine has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) BaseMachine has no states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct BaseMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in machine per unit\"\n    Xd_p::Float64\n    \"Fixed EMF behind the impedance\"\n    eq_p::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) BaseMachine has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) BaseMachine has no states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction BaseMachine(R, Xd_p, eq_p, ext=Dict{String, Any}(), )\n    BaseMachine(R, Xd_p, eq_p, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )\nend\n\nfunction BaseMachine(; R, Xd_p, eq_p, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )\n    BaseMachine(R, Xd_p, eq_p, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction BaseMachine(::Nothing)\n    BaseMachine(;\n        R=0,\n        Xd_p=0,\n        eq_p=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`BaseMachine`](@ref) `R`.\"\"\"\nget_R(value::BaseMachine) = value.R\n\"\"\"Get [`BaseMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::BaseMachine) = value.Xd_p\n\"\"\"Get [`BaseMachine`](@ref) `eq_p`.\"\"\"\nget_eq_p(value::BaseMachine) = value.eq_p\n\"\"\"Get [`BaseMachine`](@ref) `ext`.\"\"\"\nget_ext(value::BaseMachine) = value.ext\n\"\"\"Get [`BaseMachine`](@ref) `states`.\"\"\"\nget_states(value::BaseMachine) = value.states\n\"\"\"Get [`BaseMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::BaseMachine) = value.n_states\n\"\"\"Get [`BaseMachine`](@ref) `internal`.\"\"\"\nget_internal(value::BaseMachine) = value.internal\n\n\"\"\"Set [`BaseMachine`](@ref) `R`.\"\"\"\nset_R!(value::BaseMachine, val) = value.R = val\n\"\"\"Set [`BaseMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::BaseMachine, val) = value.Xd_p = val\n\"\"\"Set [`BaseMachine`](@ref) `eq_p`.\"\"\"\nset_eq_p!(value::BaseMachine, val) = value.eq_p = val\n\"\"\"Set [`BaseMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::BaseMachine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/CSVGN1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct CSVGN1 <: DynamicInjection\n        name::String\n        K::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        T5::Float64\n        Rmin::Float64\n        Vmax::Float64\n        Vmin::Float64\n        CBase::Float64\n        base_power::Float64\n        ext::Dict{String, Any}\n        R_th::Float64\n        X_th::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of static shunt compensator: CSVGN1 in PSSE\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `K::Float64`: Gain in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `T1::Float64`: Time constant in s, validation range: `(0, nothing)`\n- `T2::Float64`: Time constant in s, validation range: `(0, nothing)`\n- `T3::Float64`: Time constant in s, validation range: `(eps(), nothing)`\n- `T4::Float64`: Time constant in s, validation range: `(0, nothing)`\n- `T5::Float64`: Time constant in s, validation range: `(0, nothing)`\n- `Rmin::Float64`: Reactor minimum Mvar, validation range: `(0, nothing)`\n- `Vmax::Float64`: Maximum voltage in pu, validation range: `(0, nothing)`\n- `Vmin::Float64`: Minimum voltage in pu, validation range: `(0, nothing)`\n- `CBase::Float64`: Capacitor (MVAR), validation range: `(0, nothing)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `R_th::Float64`: Source Thevenin resistance\n- `X_th::Float64`: Source Thevenin reactance\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tthy: thyristor,\n\tvr1: regulator output 1,\n\tvr2: regulator output 2\n- `n_states::Int`: (**Do not modify.**) CSVGN1 has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct CSVGN1 <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Gain in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    K::Float64\n    \"Time constant in s\"\n    T1::Float64\n    \"Time constant in s\"\n    T2::Float64\n    \"Time constant in s\"\n    T3::Float64\n    \"Time constant in s\"\n    T4::Float64\n    \"Time constant in s\"\n    T5::Float64\n    \"Reactor minimum Mvar\"\n    Rmin::Float64\n    \"Maximum voltage in pu\"\n    Vmax::Float64\n    \"Minimum voltage in pu\"\n    Vmin::Float64\n    \"Capacitor (MVAR)\"\n    CBase::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"Source Thevenin resistance\"\n    R_th::Float64\n    \"Source Thevenin reactance\"\n    X_th::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tthy: thyristor,\n\tvr1: regulator output 1,\n\tvr2: regulator output 2\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) CSVGN1 has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction CSVGN1(name, K, T1, T2, T3, T4, T5, Rmin, Vmax, Vmin, CBase, base_power, ext=Dict{String, Any}(), )\n    CSVGN1(name, K, T1, T2, T3, T4, T5, Rmin, Vmax, Vmin, CBase, base_power, ext, 0.0, 0.0, [:thy, :vr1, :vr2], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction CSVGN1(; name, K, T1, T2, T3, T4, T5, Rmin, Vmax, Vmin, CBase, base_power, ext=Dict{String, Any}(), R_th=0.0, X_th=0.0, states=[:thy, :vr1, :vr2], n_states=3, internal=InfrastructureSystemsInternal(), )\n    CSVGN1(name, K, T1, T2, T3, T4, T5, Rmin, Vmax, Vmin, CBase, base_power, ext, R_th, X_th, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction CSVGN1(::Nothing)\n    CSVGN1(;\n        name=\"init\",\n        K=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        T5=0,\n        Rmin=0,\n        Vmax=0,\n        Vmin=0,\n        CBase=0,\n        base_power=100,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`CSVGN1`](@ref) `name`.\"\"\"\nget_name(value::CSVGN1) = value.name\n\"\"\"Get [`CSVGN1`](@ref) `K`.\"\"\"\nget_K(value::CSVGN1) = value.K\n\"\"\"Get [`CSVGN1`](@ref) `T1`.\"\"\"\nget_T1(value::CSVGN1) = value.T1\n\"\"\"Get [`CSVGN1`](@ref) `T2`.\"\"\"\nget_T2(value::CSVGN1) = value.T2\n\"\"\"Get [`CSVGN1`](@ref) `T3`.\"\"\"\nget_T3(value::CSVGN1) = value.T3\n\"\"\"Get [`CSVGN1`](@ref) `T4`.\"\"\"\nget_T4(value::CSVGN1) = value.T4\n\"\"\"Get [`CSVGN1`](@ref) `T5`.\"\"\"\nget_T5(value::CSVGN1) = value.T5\n\"\"\"Get [`CSVGN1`](@ref) `Rmin`.\"\"\"\nget_Rmin(value::CSVGN1) = value.Rmin\n\"\"\"Get [`CSVGN1`](@ref) `Vmax`.\"\"\"\nget_Vmax(value::CSVGN1) = value.Vmax\n\"\"\"Get [`CSVGN1`](@ref) `Vmin`.\"\"\"\nget_Vmin(value::CSVGN1) = value.Vmin\n\"\"\"Get [`CSVGN1`](@ref) `CBase`.\"\"\"\nget_CBase(value::CSVGN1) = value.CBase\n\"\"\"Get [`CSVGN1`](@ref) `base_power`.\"\"\"\nget_base_power(value::CSVGN1) = value.base_power\n\"\"\"Get [`CSVGN1`](@ref) `ext`.\"\"\"\nget_ext(value::CSVGN1) = value.ext\n\"\"\"Get [`CSVGN1`](@ref) `R_th`.\"\"\"\nget_R_th(value::CSVGN1) = value.R_th\n\"\"\"Get [`CSVGN1`](@ref) `X_th`.\"\"\"\nget_X_th(value::CSVGN1) = value.X_th\n\"\"\"Get [`CSVGN1`](@ref) `states`.\"\"\"\nget_states(value::CSVGN1) = value.states\n\"\"\"Get [`CSVGN1`](@ref) `n_states`.\"\"\"\nget_n_states(value::CSVGN1) = value.n_states\n\"\"\"Get [`CSVGN1`](@ref) `internal`.\"\"\"\nget_internal(value::CSVGN1) = value.internal\n\n\"\"\"Set [`CSVGN1`](@ref) `K`.\"\"\"\nset_K!(value::CSVGN1, val) = value.K = val\n\"\"\"Set [`CSVGN1`](@ref) `T1`.\"\"\"\nset_T1!(value::CSVGN1, val) = value.T1 = val\n\"\"\"Set [`CSVGN1`](@ref) `T2`.\"\"\"\nset_T2!(value::CSVGN1, val) = value.T2 = val\n\"\"\"Set [`CSVGN1`](@ref) `T3`.\"\"\"\nset_T3!(value::CSVGN1, val) = value.T3 = val\n\"\"\"Set [`CSVGN1`](@ref) `T4`.\"\"\"\nset_T4!(value::CSVGN1, val) = value.T4 = val\n\"\"\"Set [`CSVGN1`](@ref) `T5`.\"\"\"\nset_T5!(value::CSVGN1, val) = value.T5 = val\n\"\"\"Set [`CSVGN1`](@ref) `Rmin`.\"\"\"\nset_Rmin!(value::CSVGN1, val) = value.Rmin = val\n\"\"\"Set [`CSVGN1`](@ref) `Vmax`.\"\"\"\nset_Vmax!(value::CSVGN1, val) = value.Vmax = val\n\"\"\"Set [`CSVGN1`](@ref) `Vmin`.\"\"\"\nset_Vmin!(value::CSVGN1, val) = value.Vmin = val\n\"\"\"Set [`CSVGN1`](@ref) `CBase`.\"\"\"\nset_CBase!(value::CSVGN1, val) = value.CBase = val\n\"\"\"Set [`CSVGN1`](@ref) `base_power`.\"\"\"\nset_base_power!(value::CSVGN1, val) = value.base_power = val\n\"\"\"Set [`CSVGN1`](@ref) `ext`.\"\"\"\nset_ext!(value::CSVGN1, val) = value.ext = val\n\"\"\"Set [`CSVGN1`](@ref) `R_th`.\"\"\"\nset_R_th!(value::CSVGN1, val) = value.R_th = val\n\"\"\"Set [`CSVGN1`](@ref) `X_th`.\"\"\"\nset_X_th!(value::CSVGN1, val) = value.X_th = val\n"
  },
  {
    "path": "src/models/generated/ConstantReserve.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ConstantReserve{T <: ReserveDirection} <: Reserve{T}\n        name::String\n        available::Bool\n        time_frame::Float64\n        requirement::Float64\n        sustained_time::Float64\n        max_output_fraction::Float64\n        max_participation_factor::Float64\n        deployed_fraction::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA reserve product with a constant procurement requirement, such as 3% of the system base power at all times.\n\nThis reserve product includes online generators that can respond right away after an unexpected contingency, such as a transmission line or generator outage. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `time_frame::Float64`: the saturation time_frame in minutes to provide reserve contribution, validation range: `(0, nothing)`\n- `requirement::Float64`: the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `sustained_time::Float64`: (default: `3600.0`) the time in seconds reserve contribution must sustained at a specified level, validation range: `(0, nothing)`\n- `max_output_fraction::Float64`: (default: `1.0`) the maximum fraction of each device's output that can be assigned to the service, validation range: `(0, 1)`\n- `max_participation_factor::Float64`: (default: `1.0`) the maximum portion [0, 1.0] of the reserve that can be contributed per device, validation range: `(0, 1)`\n- `deployed_fraction::Float64`: (default: `0.0`) Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0, validation range: `(0, 1)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ConstantReserve{T <: ReserveDirection} <: Reserve{T}\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the saturation time_frame in minutes to provide reserve contribution\"\n    time_frame::Float64\n    \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    requirement::Float64\n    \"the time in seconds reserve contribution must sustained at a specified level\"\n    sustained_time::Float64\n    \"the maximum fraction of each device's output that can be assigned to the service\"\n    max_output_fraction::Float64\n    \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\"\n    max_participation_factor::Float64\n    \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\"\n    deployed_fraction::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ConstantReserve{T}(name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), ) where T <: ReserveDirection\n    ConstantReserve{T}(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ConstantReserve{T}(; name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), ) where T <: ReserveDirection\n    ConstantReserve{T}(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ConstantReserve{T}(::Nothing) where T <: ReserveDirection\n    ConstantReserve{T}(;\n        name=\"init\",\n        available=false,\n        time_frame=0.0,\n        requirement=0.0,\n        sustained_time=0.0,\n        max_output_fraction=1.0,\n        max_participation_factor=1.0,\n        deployed_fraction=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ConstantReserve`](@ref) `name`.\"\"\"\nget_name(value::ConstantReserve) = value.name\n\"\"\"Get [`ConstantReserve`](@ref) `available`.\"\"\"\nget_available(value::ConstantReserve) = value.available\n\"\"\"Get [`ConstantReserve`](@ref) `time_frame`.\"\"\"\nget_time_frame(value::ConstantReserve) = value.time_frame\n\"\"\"Get [`ConstantReserve`](@ref) `requirement`.\"\"\"\nget_requirement(value::ConstantReserve) = get_value(value, Val(:requirement), Val(:mva))\n\"\"\"Get [`ConstantReserve`](@ref) `sustained_time`.\"\"\"\nget_sustained_time(value::ConstantReserve) = value.sustained_time\n\"\"\"Get [`ConstantReserve`](@ref) `max_output_fraction`.\"\"\"\nget_max_output_fraction(value::ConstantReserve) = value.max_output_fraction\n\"\"\"Get [`ConstantReserve`](@ref) `max_participation_factor`.\"\"\"\nget_max_participation_factor(value::ConstantReserve) = value.max_participation_factor\n\"\"\"Get [`ConstantReserve`](@ref) `deployed_fraction`.\"\"\"\nget_deployed_fraction(value::ConstantReserve) = value.deployed_fraction\n\"\"\"Get [`ConstantReserve`](@ref) `ext`.\"\"\"\nget_ext(value::ConstantReserve) = value.ext\n\"\"\"Get [`ConstantReserve`](@ref) `internal`.\"\"\"\nget_internal(value::ConstantReserve) = value.internal\n\n\"\"\"Set [`ConstantReserve`](@ref) `available`.\"\"\"\nset_available!(value::ConstantReserve, val) = value.available = val\n\"\"\"Set [`ConstantReserve`](@ref) `time_frame`.\"\"\"\nset_time_frame!(value::ConstantReserve, val) = value.time_frame = val\n\"\"\"Set [`ConstantReserve`](@ref) `requirement`.\"\"\"\nset_requirement!(value::ConstantReserve, val) = value.requirement = set_value(value, Val(:requirement), val, Val(:mva))\n\"\"\"Set [`ConstantReserve`](@ref) `sustained_time`.\"\"\"\nset_sustained_time!(value::ConstantReserve, val) = value.sustained_time = val\n\"\"\"Set [`ConstantReserve`](@ref) `max_output_fraction`.\"\"\"\nset_max_output_fraction!(value::ConstantReserve, val) = value.max_output_fraction = val\n\"\"\"Set [`ConstantReserve`](@ref) `max_participation_factor`.\"\"\"\nset_max_participation_factor!(value::ConstantReserve, val) = value.max_participation_factor = val\n\"\"\"Set [`ConstantReserve`](@ref) `deployed_fraction`.\"\"\"\nset_deployed_fraction!(value::ConstantReserve, val) = value.deployed_fraction = val\n\"\"\"Set [`ConstantReserve`](@ref) `ext`.\"\"\"\nset_ext!(value::ConstantReserve, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ConstantReserveGroup.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ConstantReserveGroup{T <: ReserveDirection} <: Service\n        name::String\n        available::Bool\n        requirement::Float64\n        ext::Dict{String, Any}\n        contributing_services::Vector{Service}\n        internal::InfrastructureSystemsInternal\n    end\n\nA reserve product met by a group of individual reserves.\n\nThe group reserve requirement is added in addition to any individual reserve requirements, and devices that contribute to individual reserves within the group can also contribute to the overarching group reserve requirement. Example: A group of spinning and non-spinning reserves, where online generators providing spinning reserves can also contribute to the non-spinning reserve requirement.\n\nThis model has a constant procurement requirement, such as 3% of the system base power at all times. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `requirement::Float64`: the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `contributing_services::Vector{Service}`: (default: `Vector{Service}()`) Services that contribute to this group requirement. Services must be added for this constraint to have an effect when conducting simulations in [`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/latest/)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ConstantReserveGroup{T <: ReserveDirection} <: Service\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    requirement::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"Services that contribute to this group requirement. Services must be added for this constraint to have an effect when conducting simulations in [`PowerSimulations.jl`](https://sienna-platform.github.io/PowerSimulations.jl/latest/)\"\n    contributing_services::Vector{Service}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ConstantReserveGroup{T}(name, available, requirement, ext=Dict{String, Any}(), contributing_services=Vector{Service}(), ) where T <: ReserveDirection\n    ConstantReserveGroup{T}(name, available, requirement, ext, contributing_services, InfrastructureSystemsInternal(), )\nend\n\nfunction ConstantReserveGroup{T}(; name, available, requirement, ext=Dict{String, Any}(), contributing_services=Vector{Service}(), internal=InfrastructureSystemsInternal(), ) where T <: ReserveDirection\n    ConstantReserveGroup{T}(name, available, requirement, ext, contributing_services, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ConstantReserveGroup{T}(::Nothing) where T <: ReserveDirection\n    ConstantReserveGroup{T}(;\n        name=\"init\",\n        available=false,\n        requirement=0.0,\n        ext=Dict{String, Any}(),\n        contributing_services=Vector{Service}(),\n    )\nend\n\n\"\"\"Get [`ConstantReserveGroup`](@ref) `name`.\"\"\"\nget_name(value::ConstantReserveGroup) = value.name\n\"\"\"Get [`ConstantReserveGroup`](@ref) `available`.\"\"\"\nget_available(value::ConstantReserveGroup) = value.available\n\"\"\"Get [`ConstantReserveGroup`](@ref) `requirement`.\"\"\"\nget_requirement(value::ConstantReserveGroup) = get_value(value, Val(:requirement), Val(:mva))\n\"\"\"Get [`ConstantReserveGroup`](@ref) `ext`.\"\"\"\nget_ext(value::ConstantReserveGroup) = value.ext\n\"\"\"Get [`ConstantReserveGroup`](@ref) `contributing_services`.\"\"\"\nget_contributing_services(value::ConstantReserveGroup) = value.contributing_services\n\"\"\"Get [`ConstantReserveGroup`](@ref) `internal`.\"\"\"\nget_internal(value::ConstantReserveGroup) = value.internal\n\n\"\"\"Set [`ConstantReserveGroup`](@ref) `available`.\"\"\"\nset_available!(value::ConstantReserveGroup, val) = value.available = val\n\"\"\"Set [`ConstantReserveGroup`](@ref) `requirement`.\"\"\"\nset_requirement!(value::ConstantReserveGroup, val) = value.requirement = set_value(value, Val(:requirement), val, Val(:mva))\n\"\"\"Set [`ConstantReserveGroup`](@ref) `ext`.\"\"\"\nset_ext!(value::ConstantReserveGroup, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ConstantReserveNonSpinning.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ConstantReserveNonSpinning <: ReserveNonSpinning\n        name::String\n        available::Bool\n        time_frame::Float64\n        requirement::Float64\n        sustained_time::Float64\n        max_output_fraction::Float64\n        max_participation_factor::Float64\n        deployed_fraction::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA non-spinning reserve product with a constant procurement requirement, such as 3% of the system base power at all times.\n\nThis reserve product includes back-up generators that might not be currently synchronized with the power system, but can come online quickly after an unexpected contingency, such as a transmission line or generator outage. This is only an upwards reserve. For faster-responding upwards or downwards reserves from components already synchronized with the system, see [`ConstantReserve`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `time_frame::Float64`: the saturation time frame in minutes that a participating device must provide its reserve contribution, validation range: `(0, nothing)`\n- `requirement::Float64`: the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `sustained_time::Float64`: (default: `3600.0`) the time in seconds reserve contribution must sustained at a specified level, validation range: `(0, nothing)`\n- `max_output_fraction::Float64`: (default: `1.0`) the maximum fraction of each device's output that can be assigned to the service, validation range: `(0, 1)`\n- `max_participation_factor::Float64`: (default: `1.0`) the maximum portion [0, 1.0] of the reserve that can be contributed per device, validation range: `(0, 1)`\n- `deployed_fraction::Float64`: (default: `0.0`) Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0, validation range: `(0, 1)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ConstantReserveNonSpinning <: ReserveNonSpinning\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the saturation time frame in minutes that a participating device must provide its reserve contribution\"\n    time_frame::Float64\n    \"the value of required reserves in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    requirement::Float64\n    \"the time in seconds reserve contribution must sustained at a specified level\"\n    sustained_time::Float64\n    \"the maximum fraction of each device's output that can be assigned to the service\"\n    max_output_fraction::Float64\n    \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\"\n    max_participation_factor::Float64\n    \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\"\n    deployed_fraction::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ConstantReserveNonSpinning(name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), )\n    ConstantReserveNonSpinning(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ConstantReserveNonSpinning(; name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ConstantReserveNonSpinning(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ConstantReserveNonSpinning(::Nothing)\n    ConstantReserveNonSpinning(;\n        name=\"init\",\n        available=false,\n        time_frame=0.0,\n        requirement=0.0,\n        sustained_time=0.0,\n        max_output_fraction=1.0,\n        max_participation_factor=1.0,\n        deployed_fraction=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `name`.\"\"\"\nget_name(value::ConstantReserveNonSpinning) = value.name\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `available`.\"\"\"\nget_available(value::ConstantReserveNonSpinning) = value.available\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `time_frame`.\"\"\"\nget_time_frame(value::ConstantReserveNonSpinning) = value.time_frame\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `requirement`.\"\"\"\nget_requirement(value::ConstantReserveNonSpinning) = get_value(value, Val(:requirement), Val(:mva))\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `sustained_time`.\"\"\"\nget_sustained_time(value::ConstantReserveNonSpinning) = value.sustained_time\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `max_output_fraction`.\"\"\"\nget_max_output_fraction(value::ConstantReserveNonSpinning) = value.max_output_fraction\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `max_participation_factor`.\"\"\"\nget_max_participation_factor(value::ConstantReserveNonSpinning) = value.max_participation_factor\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `deployed_fraction`.\"\"\"\nget_deployed_fraction(value::ConstantReserveNonSpinning) = value.deployed_fraction\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `ext`.\"\"\"\nget_ext(value::ConstantReserveNonSpinning) = value.ext\n\"\"\"Get [`ConstantReserveNonSpinning`](@ref) `internal`.\"\"\"\nget_internal(value::ConstantReserveNonSpinning) = value.internal\n\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `available`.\"\"\"\nset_available!(value::ConstantReserveNonSpinning, val) = value.available = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `time_frame`.\"\"\"\nset_time_frame!(value::ConstantReserveNonSpinning, val) = value.time_frame = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `requirement`.\"\"\"\nset_requirement!(value::ConstantReserveNonSpinning, val) = value.requirement = set_value(value, Val(:requirement), val, Val(:mva))\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `sustained_time`.\"\"\"\nset_sustained_time!(value::ConstantReserveNonSpinning, val) = value.sustained_time = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `max_output_fraction`.\"\"\"\nset_max_output_fraction!(value::ConstantReserveNonSpinning, val) = value.max_output_fraction = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `max_participation_factor`.\"\"\"\nset_max_participation_factor!(value::ConstantReserveNonSpinning, val) = value.max_participation_factor = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `deployed_fraction`.\"\"\"\nset_deployed_fraction!(value::ConstantReserveNonSpinning, val) = value.deployed_fraction = val\n\"\"\"Set [`ConstantReserveNonSpinning`](@ref) `ext`.\"\"\"\nset_ext!(value::ConstantReserveNonSpinning, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/CurrentModeControl.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct CurrentModeControl <: InnerControl\n        kpc::Float64\n        kic::Float64\n        kffv::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of an inner loop proportional integral (PI) current control based on [\"Reduced-order Structure-preserving Model for Parallel-connected Three-phase Grid-tied Inverters.\"](https://doi.org/10.1109/COMPEL.2017.8013389)\n\n# Arguments\n- `kpc::Float64`: Current controller proportional gain, validation range: `(0, nothing)`\n- `kic::Float64`: Current controller integral gain, validation range: `(0, nothing)`\n- `kffv::Float64`: Gain to enable feed-forward gain of voltage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the CurrentModeControl model are:\n\tγd_ic: d-axis integrator state of the PI current controller,\n\tγq_ic: q-axis integrator state of the PI current controller\n- `n_states::Int`: (**Do not modify.**) CurrentControl has 2 states\n\"\"\"\nmutable struct CurrentModeControl <: InnerControl\n    \"Current controller proportional gain\"\n    kpc::Float64\n    \"Current controller integral gain\"\n    kic::Float64\n    \"Gain to enable feed-forward gain of voltage\"\n    kffv::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the CurrentModeControl model are:\n\tγd_ic: d-axis integrator state of the PI current controller,\n\tγq_ic: q-axis integrator state of the PI current controller\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) CurrentControl has 2 states\"\n    n_states::Int\nend\n\nfunction CurrentModeControl(kpc, kic, kffv, ext=Dict{String, Any}(), )\n    CurrentModeControl(kpc, kic, kffv, ext, [:γd_ic, :γq_ic], 2, )\nend\n\nfunction CurrentModeControl(; kpc, kic, kffv, ext=Dict{String, Any}(), states=[:γd_ic, :γq_ic], n_states=2, )\n    CurrentModeControl(kpc, kic, kffv, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction CurrentModeControl(::Nothing)\n    CurrentModeControl(;\n        kpc=0,\n        kic=0,\n        kffv=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`CurrentModeControl`](@ref) `kpc`.\"\"\"\nget_kpc(value::CurrentModeControl) = value.kpc\n\"\"\"Get [`CurrentModeControl`](@ref) `kic`.\"\"\"\nget_kic(value::CurrentModeControl) = value.kic\n\"\"\"Get [`CurrentModeControl`](@ref) `kffv`.\"\"\"\nget_kffv(value::CurrentModeControl) = value.kffv\n\"\"\"Get [`CurrentModeControl`](@ref) `ext`.\"\"\"\nget_ext(value::CurrentModeControl) = value.ext\n\"\"\"Get [`CurrentModeControl`](@ref) `states`.\"\"\"\nget_states(value::CurrentModeControl) = value.states\n\"\"\"Get [`CurrentModeControl`](@ref) `n_states`.\"\"\"\nget_n_states(value::CurrentModeControl) = value.n_states\n\n\"\"\"Set [`CurrentModeControl`](@ref) `kpc`.\"\"\"\nset_kpc!(value::CurrentModeControl, val) = value.kpc = val\n\"\"\"Set [`CurrentModeControl`](@ref) `kic`.\"\"\"\nset_kic!(value::CurrentModeControl, val) = value.kic = val\n\"\"\"Set [`CurrentModeControl`](@ref) `kffv`.\"\"\"\nset_kffv!(value::CurrentModeControl, val) = value.kffv = val\n\"\"\"Set [`CurrentModeControl`](@ref) `ext`.\"\"\"\nset_ext!(value::CurrentModeControl, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/DCBus.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct DCBus <: Bus\n        number::Int\n        name::String\n        available::Bool\n        magnitude::Union{Nothing, Float64}\n        voltage_limits::Union{Nothing, MinMax}\n        base_voltage::Union{Nothing, Float64}\n        area::Union{Nothing, Area}\n        load_zone::Union{Nothing, LoadZone}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA DC bus\n\n# Arguments\n- `number::Int`: A unique bus identification number (positive integer)\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations.\n- `magnitude::Union{Nothing, Float64}`: voltage as a multiple of `base_voltage`, validation range: `voltage_limits`\n- `voltage_limits::Union{Nothing, MinMax}`: limits on the voltage variation as multiples of `base_voltage`\n- `base_voltage::Union{Nothing, Float64}`: the base voltage in kV, validation range: `(0, nothing)`\n- `area::Union{Nothing, Area}`: (default: `nothing`) the area containing the DC bus\n- `load_zone::Union{Nothing, LoadZone}`: (default: `nothing`) the load zone containing the DC bus\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DCBus <: Bus\n    \"A unique bus identification number (positive integer)\"\n    number::Int\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations.\"\n    available::Bool\n    \"voltage as a multiple of `base_voltage`\"\n    magnitude::Union{Nothing, Float64}\n    \"limits on the voltage variation as multiples of `base_voltage`\"\n    voltage_limits::Union{Nothing, MinMax}\n    \"the base voltage in kV\"\n    base_voltage::Union{Nothing, Float64}\n    \"the area containing the DC bus\"\n    area::Union{Nothing, Area}\n    \"the load zone containing the DC bus\"\n    load_zone::Union{Nothing, LoadZone}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DCBus(number, name, available, magnitude, voltage_limits, base_voltage, area=nothing, load_zone=nothing, ext=Dict{String, Any}(), )\n    DCBus(number, name, available, magnitude, voltage_limits, base_voltage, area, load_zone, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction DCBus(; number, name, available, magnitude, voltage_limits, base_voltage, area=nothing, load_zone=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    DCBus(number, name, available, magnitude, voltage_limits, base_voltage, area, load_zone, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction DCBus(::Nothing)\n    DCBus(;\n        number=0,\n        name=\"init\",\n        available=false,\n        magnitude=0.0,\n        voltage_limits=(min=0.0, max=0.0),\n        base_voltage=nothing,\n        area=nothing,\n        load_zone=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`DCBus`](@ref) `number`.\"\"\"\nget_number(value::DCBus) = value.number\n\"\"\"Get [`DCBus`](@ref) `name`.\"\"\"\nget_name(value::DCBus) = value.name\n\"\"\"Get [`DCBus`](@ref) `available`.\"\"\"\nget_available(value::DCBus) = value.available\n\"\"\"Get [`DCBus`](@ref) `magnitude`.\"\"\"\nget_magnitude(value::DCBus) = value.magnitude\n\"\"\"Get [`DCBus`](@ref) `voltage_limits`.\"\"\"\nget_voltage_limits(value::DCBus) = value.voltage_limits\n\"\"\"Get [`DCBus`](@ref) `base_voltage`.\"\"\"\nget_base_voltage(value::DCBus) = value.base_voltage\n\"\"\"Get [`DCBus`](@ref) `area`.\"\"\"\nget_area(value::DCBus) = value.area\n\"\"\"Get [`DCBus`](@ref) `load_zone`.\"\"\"\nget_load_zone(value::DCBus) = value.load_zone\n\"\"\"Get [`DCBus`](@ref) `ext`.\"\"\"\nget_ext(value::DCBus) = value.ext\n\"\"\"Get [`DCBus`](@ref) `internal`.\"\"\"\nget_internal(value::DCBus) = value.internal\n\n\"\"\"Set [`DCBus`](@ref) `number`.\"\"\"\nset_number!(value::DCBus, val) = value.number = val\n\"\"\"Set [`DCBus`](@ref) `available`.\"\"\"\nset_available!(value::DCBus, val) = value.available = val\n\"\"\"Set [`DCBus`](@ref) `magnitude`.\"\"\"\nset_magnitude!(value::DCBus, val) = value.magnitude = val\n\"\"\"Set [`DCBus`](@ref) `voltage_limits`.\"\"\"\nset_voltage_limits!(value::DCBus, val) = value.voltage_limits = val\n\"\"\"Set [`DCBus`](@ref) `base_voltage`.\"\"\"\nset_base_voltage!(value::DCBus, val) = value.base_voltage = val\n\"\"\"Set [`DCBus`](@ref) `area`.\"\"\"\nset_area!(value::DCBus, val) = value.area = val\n\"\"\"Set [`DCBus`](@ref) `load_zone`.\"\"\"\nset_load_zone!(value::DCBus, val) = value.load_zone = val\n\"\"\"Set [`DCBus`](@ref) `ext`.\"\"\"\nset_ext!(value::DCBus, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/DEGOV.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct DEGOV <: TurbineGov\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        K::Float64\n        T4::Float64\n        T5::Float64\n        T6::Float64\n        Td::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters Woodward Diesel Governor Model. DEGOV in PowerWorld\n\n# Arguments\n- `T1::Float64`: Governor mechanism time constant, validation range: `(eps(), 100)`\n- `T2::Float64`: Turbine power time constant, validation range: `(eps(), 100)`\n- `T3::Float64`: Turbine exhaust temperature time constant, validation range: `(eps(), 100)`\n- `K::Float64`: Governor gain (reciprocal of droop), validation range: `(eps(), 100)`\n- `T4::Float64`: Governor lead time constant, validation range: `(eps(), 100)`\n- `T5::Float64`: Governor lag time constant, validation range: `(eps(), 100)`\n- `T6::Float64`: Actuator time constant, validation range: `(eps(), 100)`\n- `Td::Float64`: Engine time delay, validation range: `(eps(), 100)`\n- `P_ref::Float64`: (default: `1.0`) Reference Load Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the DEGOV model are:\n\tx_ecb1: Electric control box 1,\n\tx_ecb2: Electric control box 2,\n\tx_a1: Actuator 1,\n\tx_a2: Actuator 2,\n\tx_a3: Actuator 3,\n- `n_states::Int`: (**Do not modify.**) DEGOV has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) DEGOV has 5 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DEGOV <: TurbineGov\n    \"Governor mechanism time constant\"\n    T1::Float64\n    \"Turbine power time constant\"\n    T2::Float64\n    \"Turbine exhaust temperature time constant\"\n    T3::Float64\n    \"Governor gain (reciprocal of droop)\"\n    K::Float64\n    \"Governor lead time constant\"\n    T4::Float64\n    \"Governor lag time constant\"\n    T5::Float64\n    \"Actuator time constant\"\n    T6::Float64\n    \"Engine time delay\"\n    Td::Float64\n    \"Reference Load Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the DEGOV model are:\n\tx_ecb1: Electric control box 1,\n\tx_ecb2: Electric control box 2,\n\tx_a1: Actuator 1,\n\tx_a2: Actuator 2,\n\tx_a3: Actuator 3,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) DEGOV has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) DEGOV has 5 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DEGOV(T1, T2, T3, K, T4, T5, T6, Td, P_ref=1.0, ext=Dict{String, Any}(), )\n    DEGOV(T1, T2, T3, K, T4, T5, T6, Td, P_ref, ext, [:x_ecb1, :x_ecb2, :x_a1, :x_a2, :x_a3], 5, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction DEGOV(; T1, T2, T3, K, T4, T5, T6, Td, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_ecb1, :x_ecb2, :x_a1, :x_a2, :x_a3], n_states=5, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    DEGOV(T1, T2, T3, K, T4, T5, T6, Td, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction DEGOV(::Nothing)\n    DEGOV(;\n        T1=0,\n        T2=0,\n        T3=0,\n        K=0,\n        T4=0,\n        T5=0,\n        T6=0,\n        Td=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`DEGOV`](@ref) `T1`.\"\"\"\nget_T1(value::DEGOV) = value.T1\n\"\"\"Get [`DEGOV`](@ref) `T2`.\"\"\"\nget_T2(value::DEGOV) = value.T2\n\"\"\"Get [`DEGOV`](@ref) `T3`.\"\"\"\nget_T3(value::DEGOV) = value.T3\n\"\"\"Get [`DEGOV`](@ref) `K`.\"\"\"\nget_K(value::DEGOV) = value.K\n\"\"\"Get [`DEGOV`](@ref) `T4`.\"\"\"\nget_T4(value::DEGOV) = value.T4\n\"\"\"Get [`DEGOV`](@ref) `T5`.\"\"\"\nget_T5(value::DEGOV) = value.T5\n\"\"\"Get [`DEGOV`](@ref) `T6`.\"\"\"\nget_T6(value::DEGOV) = value.T6\n\"\"\"Get [`DEGOV`](@ref) `Td`.\"\"\"\nget_Td(value::DEGOV) = value.Td\n\"\"\"Get [`DEGOV`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::DEGOV) = value.P_ref\n\"\"\"Get [`DEGOV`](@ref) `ext`.\"\"\"\nget_ext(value::DEGOV) = value.ext\n\"\"\"Get [`DEGOV`](@ref) `states`.\"\"\"\nget_states(value::DEGOV) = value.states\n\"\"\"Get [`DEGOV`](@ref) `n_states`.\"\"\"\nget_n_states(value::DEGOV) = value.n_states\n\"\"\"Get [`DEGOV`](@ref) `states_types`.\"\"\"\nget_states_types(value::DEGOV) = value.states_types\n\"\"\"Get [`DEGOV`](@ref) `internal`.\"\"\"\nget_internal(value::DEGOV) = value.internal\n\n\"\"\"Set [`DEGOV`](@ref) `T1`.\"\"\"\nset_T1!(value::DEGOV, val) = value.T1 = val\n\"\"\"Set [`DEGOV`](@ref) `T2`.\"\"\"\nset_T2!(value::DEGOV, val) = value.T2 = val\n\"\"\"Set [`DEGOV`](@ref) `T3`.\"\"\"\nset_T3!(value::DEGOV, val) = value.T3 = val\n\"\"\"Set [`DEGOV`](@ref) `K`.\"\"\"\nset_K!(value::DEGOV, val) = value.K = val\n\"\"\"Set [`DEGOV`](@ref) `T4`.\"\"\"\nset_T4!(value::DEGOV, val) = value.T4 = val\n\"\"\"Set [`DEGOV`](@ref) `T5`.\"\"\"\nset_T5!(value::DEGOV, val) = value.T5 = val\n\"\"\"Set [`DEGOV`](@ref) `T6`.\"\"\"\nset_T6!(value::DEGOV, val) = value.T6 = val\n\"\"\"Set [`DEGOV`](@ref) `Td`.\"\"\"\nset_Td!(value::DEGOV, val) = value.Td = val\n\"\"\"Set [`DEGOV`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::DEGOV, val) = value.P_ref = val\n\"\"\"Set [`DEGOV`](@ref) `ext`.\"\"\"\nset_ext!(value::DEGOV, val) = value.ext = val\n\"\"\"Set [`DEGOV`](@ref) `states_types`.\"\"\"\nset_states_types!(value::DEGOV, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/DEGOV1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct DEGOV1 <: TurbineGov\n        droop_flag::Int\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        K::Float64\n        T4::Float64\n        T5::Float64\n        T6::Float64\n        Td::Float64\n        T_lim::Tuple{Float64, Float64}\n        R::Float64\n        Te::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters Woodward Diesel Governor Model. DEGOV1 in PSSE\n\n# Arguments\n- `droop_flag::Int`: Droop control Flag. 0 for throttle feedback and 1 for electric power feedback, validation range: `(0, 1)`\n- `T1::Float64`: Governor mechanism time constant in s, validation range: `(0, 100)`\n- `T2::Float64`: Turbine power time constant in s, validation range: `(0, 100)`\n- `T3::Float64`: Turbine exhaust temperature time constant in s, validation range: `(0, 100)`\n- `K::Float64`: Governor gain for actuator, validation range: `(0, 100)`\n- `T4::Float64`: Governor lead time constant in s, validation range: `(0, 100)`\n- `T5::Float64`: Governor lag time constant in s, validation range: `(0, 100)`\n- `T6::Float64`: Actuator time constant in s, validation range: `(0, 100)`\n- `Td::Float64`: Engine time delay in s, validation range: `(0, 100)`\n- `T_lim::Tuple{Float64, Float64}`: Operational control limits on actuator (T_min, T_max)\n- `R::Float64`: Steady state droop parameter, validation range: `(0, 100)`\n- `Te::Float64`: Power transducer time constant in s, validation range: `(0, 100)`\n- `P_ref::Float64`: (default: `1.0`) Reference Load Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the DEGOV1 model depends on the droop flag\n- `n_states::Int`: (**Do not modify.**) The number of [states](@ref S) of the DEGOV1 model depends on the droop flag\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DEGOV1 <: TurbineGov\n    \"Droop control Flag. 0 for throttle feedback and 1 for electric power feedback\"\n    droop_flag::Int\n    \"Governor mechanism time constant in s\"\n    T1::Float64\n    \"Turbine power time constant in s\"\n    T2::Float64\n    \"Turbine exhaust temperature time constant in s\"\n    T3::Float64\n    \"Governor gain for actuator\"\n    K::Float64\n    \"Governor lead time constant in s\"\n    T4::Float64\n    \"Governor lag time constant in s\"\n    T5::Float64\n    \"Actuator time constant in s\"\n    T6::Float64\n    \"Engine time delay in s\"\n    Td::Float64\n    \"Operational control limits on actuator (T_min, T_max)\"\n    T_lim::Tuple{Float64, Float64}\n    \"Steady state droop parameter\"\n    R::Float64\n    \"Power transducer time constant in s\"\n    Te::Float64\n    \"Reference Load Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the DEGOV1 model depends on the droop flag\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The number of [states](@ref S) of the DEGOV1 model depends on the droop flag\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DEGOV1(droop_flag, T1, T2, T3, K, T4, T5, T6, Td, T_lim, R, Te, P_ref=1.0, ext=Dict{String, Any}(), )\n    DEGOV1(droop_flag, T1, T2, T3, K, T4, T5, T6, Td, T_lim, R, Te, P_ref, ext, PowerSystems.get_degov1_states(droop_flag)[1], PowerSystems.get_degov1_states(droop_flag)[2], InfrastructureSystemsInternal(), )\nend\n\nfunction DEGOV1(; droop_flag, T1, T2, T3, K, T4, T5, T6, Td, T_lim, R, Te, P_ref=1.0, ext=Dict{String, Any}(), states=PowerSystems.get_degov1_states(droop_flag)[1], n_states=PowerSystems.get_degov1_states(droop_flag)[2], internal=InfrastructureSystemsInternal(), )\n    DEGOV1(droop_flag, T1, T2, T3, K, T4, T5, T6, Td, T_lim, R, Te, P_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction DEGOV1(::Nothing)\n    DEGOV1(;\n        droop_flag=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        K=0,\n        T4=0,\n        T5=0,\n        T6=0,\n        Td=0,\n        T_lim=(0.0, 0.0),\n        R=0,\n        Te=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`DEGOV1`](@ref) `droop_flag`.\"\"\"\nget_droop_flag(value::DEGOV1) = value.droop_flag\n\"\"\"Get [`DEGOV1`](@ref) `T1`.\"\"\"\nget_T1(value::DEGOV1) = value.T1\n\"\"\"Get [`DEGOV1`](@ref) `T2`.\"\"\"\nget_T2(value::DEGOV1) = value.T2\n\"\"\"Get [`DEGOV1`](@ref) `T3`.\"\"\"\nget_T3(value::DEGOV1) = value.T3\n\"\"\"Get [`DEGOV1`](@ref) `K`.\"\"\"\nget_K(value::DEGOV1) = value.K\n\"\"\"Get [`DEGOV1`](@ref) `T4`.\"\"\"\nget_T4(value::DEGOV1) = value.T4\n\"\"\"Get [`DEGOV1`](@ref) `T5`.\"\"\"\nget_T5(value::DEGOV1) = value.T5\n\"\"\"Get [`DEGOV1`](@ref) `T6`.\"\"\"\nget_T6(value::DEGOV1) = value.T6\n\"\"\"Get [`DEGOV1`](@ref) `Td`.\"\"\"\nget_Td(value::DEGOV1) = value.Td\n\"\"\"Get [`DEGOV1`](@ref) `T_lim`.\"\"\"\nget_T_lim(value::DEGOV1) = value.T_lim\n\"\"\"Get [`DEGOV1`](@ref) `R`.\"\"\"\nget_R(value::DEGOV1) = value.R\n\"\"\"Get [`DEGOV1`](@ref) `Te`.\"\"\"\nget_Te(value::DEGOV1) = value.Te\n\"\"\"Get [`DEGOV1`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::DEGOV1) = value.P_ref\n\"\"\"Get [`DEGOV1`](@ref) `ext`.\"\"\"\nget_ext(value::DEGOV1) = value.ext\n\"\"\"Get [`DEGOV1`](@ref) `states`.\"\"\"\nget_states(value::DEGOV1) = value.states\n\"\"\"Get [`DEGOV1`](@ref) `n_states`.\"\"\"\nget_n_states(value::DEGOV1) = value.n_states\n\"\"\"Get [`DEGOV1`](@ref) `internal`.\"\"\"\nget_internal(value::DEGOV1) = value.internal\n\n\"\"\"Set [`DEGOV1`](@ref) `droop_flag`.\"\"\"\nset_droop_flag!(value::DEGOV1, val) = value.droop_flag = val\n\"\"\"Set [`DEGOV1`](@ref) `T1`.\"\"\"\nset_T1!(value::DEGOV1, val) = value.T1 = val\n\"\"\"Set [`DEGOV1`](@ref) `T2`.\"\"\"\nset_T2!(value::DEGOV1, val) = value.T2 = val\n\"\"\"Set [`DEGOV1`](@ref) `T3`.\"\"\"\nset_T3!(value::DEGOV1, val) = value.T3 = val\n\"\"\"Set [`DEGOV1`](@ref) `K`.\"\"\"\nset_K!(value::DEGOV1, val) = value.K = val\n\"\"\"Set [`DEGOV1`](@ref) `T4`.\"\"\"\nset_T4!(value::DEGOV1, val) = value.T4 = val\n\"\"\"Set [`DEGOV1`](@ref) `T5`.\"\"\"\nset_T5!(value::DEGOV1, val) = value.T5 = val\n\"\"\"Set [`DEGOV1`](@ref) `T6`.\"\"\"\nset_T6!(value::DEGOV1, val) = value.T6 = val\n\"\"\"Set [`DEGOV1`](@ref) `Td`.\"\"\"\nset_Td!(value::DEGOV1, val) = value.Td = val\n\"\"\"Set [`DEGOV1`](@ref) `T_lim`.\"\"\"\nset_T_lim!(value::DEGOV1, val) = value.T_lim = val\n\"\"\"Set [`DEGOV1`](@ref) `R`.\"\"\"\nset_R!(value::DEGOV1, val) = value.R = val\n\"\"\"Set [`DEGOV1`](@ref) `Te`.\"\"\"\nset_Te!(value::DEGOV1, val) = value.Te = val\n\"\"\"Set [`DEGOV1`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::DEGOV1, val) = value.P_ref = val\n\"\"\"Set [`DEGOV1`](@ref) `ext`.\"\"\"\nset_ext!(value::DEGOV1, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/DiscreteControlledACBranch.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct DiscreteControlledACBranch <: ACTransmission\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        rating::Float64\n        discrete_branch_type::DiscreteControlledBranchType\n        branch_status::DiscreteControlledBranchStatus\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nUsed to represent switches and breakers connecting AC Buses\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow on the line (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `rating::Float64`: Thermal rating (MVA). Flow on the branch must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\n- `discrete_branch_type::DiscreteControlledBranchType`: (default: `DiscreteControlledBranchType.OTHER`) Type of discrete control\n- `branch_status::DiscreteControlledBranchStatus`: (default: `DiscreteControlledBranchStatus.CLOSED`) Open or Close status\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DiscreteControlledACBranch <: ACTransmission\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow on the line (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Thermal rating (MVA). Flow on the branch must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Float64\n    \"Type of discrete control\"\n    discrete_branch_type::DiscreteControlledBranchType\n    \"Open or Close status\"\n    branch_status::DiscreteControlledBranchStatus\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DiscreteControlledACBranch(name, available, active_power_flow, reactive_power_flow, arc, r, x, rating, discrete_branch_type=DiscreteControlledBranchType.OTHER, branch_status=DiscreteControlledBranchStatus.CLOSED, ext=Dict{String, Any}(), )\n    DiscreteControlledACBranch(name, available, active_power_flow, reactive_power_flow, arc, r, x, rating, discrete_branch_type, branch_status, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction DiscreteControlledACBranch(; name, available, active_power_flow, reactive_power_flow, arc, r, x, rating, discrete_branch_type=DiscreteControlledBranchType.OTHER, branch_status=DiscreteControlledBranchStatus.CLOSED, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    DiscreteControlledACBranch(name, available, active_power_flow, reactive_power_flow, arc, r, x, rating, discrete_branch_type, branch_status, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction DiscreteControlledACBranch(::Nothing)\n    DiscreteControlledACBranch(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        rating=0.0,\n        discrete_branch_type=DiscreteControlledBranchType.BREAKER,\n        branch_status=DiscreteControlledBranchStatus.CLOSED,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `name`.\"\"\"\nget_name(value::DiscreteControlledACBranch) = value.name\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `available`.\"\"\"\nget_available(value::DiscreteControlledACBranch) = value.available\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::DiscreteControlledACBranch) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::DiscreteControlledACBranch) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `arc`.\"\"\"\nget_arc(value::DiscreteControlledACBranch) = value.arc\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `r`.\"\"\"\nget_r(value::DiscreteControlledACBranch) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `x`.\"\"\"\nget_x(value::DiscreteControlledACBranch) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `rating`.\"\"\"\nget_rating(value::DiscreteControlledACBranch) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `discrete_branch_type`.\"\"\"\nget_discrete_branch_type(value::DiscreteControlledACBranch) = value.discrete_branch_type\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `branch_status`.\"\"\"\nget_branch_status(value::DiscreteControlledACBranch) = value.branch_status\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `ext`.\"\"\"\nget_ext(value::DiscreteControlledACBranch) = value.ext\n\"\"\"Get [`DiscreteControlledACBranch`](@ref) `internal`.\"\"\"\nget_internal(value::DiscreteControlledACBranch) = value.internal\n\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `available`.\"\"\"\nset_available!(value::DiscreteControlledACBranch, val) = value.available = val\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::DiscreteControlledACBranch, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::DiscreteControlledACBranch, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `arc`.\"\"\"\nset_arc!(value::DiscreteControlledACBranch, val) = value.arc = val\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `r`.\"\"\"\nset_r!(value::DiscreteControlledACBranch, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `x`.\"\"\"\nset_x!(value::DiscreteControlledACBranch, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `rating`.\"\"\"\nset_rating!(value::DiscreteControlledACBranch, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `discrete_branch_type`.\"\"\"\nset_discrete_branch_type!(value::DiscreteControlledACBranch, val) = value.discrete_branch_type = val\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `branch_status`.\"\"\"\nset_branch_status!(value::DiscreteControlledACBranch, val) = value.branch_status = val\n\"\"\"Set [`DiscreteControlledACBranch`](@ref) `ext`.\"\"\"\nset_ext!(value::DiscreteControlledACBranch, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/DynamicExponentialLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct DynamicExponentialLoad <: DynamicInjection\n        name::String\n        a::Float64\n        b::Float64\n        α::Float64\n        β::Float64\n        T_p::Float64\n        T_q::Float64\n        ext::Dict{String, Any}\n        base_power::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 2-states of a generic dynamic load model based on [\"Voltage stability analysis using generic dynamic load models.\"](https://doi.org/10.1109/59.317575)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `a::Float64`: Active power static exponential coefficient, validation range: `(0, nothing)`\n- `b::Float64`: Reactive power static exponential coefficient, validation range: `(0, nothing)`\n- `α::Float64`: Active power transient exponential coefficient, validation range: `(0, nothing)`\n- `β::Float64`: Reactive power transient exponential coefficient, validation range: `(0, nothing)`\n- `T_p::Float64`: Active Power Time Constant, validation range: `(0, nothing)`\n- `T_q::Float64`: Reactive Power Time Constant, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `base_power::Float64`: Base power of the load (MVA) for [per unitization](@ref per_unit)\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p: Integrator state of the active power,\n\tx_q: Integrator state of the reactive power,\n- `n_states::Int`: (**Do not modify.**) DynamicExponentialLoad has 2 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct DynamicExponentialLoad <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Active power static exponential coefficient\"\n    a::Float64\n    \"Reactive power static exponential coefficient\"\n    b::Float64\n    \"Active power transient exponential coefficient\"\n    α::Float64\n    \"Reactive power transient exponential coefficient\"\n    β::Float64\n    \"Active Power Time Constant\"\n    T_p::Float64\n    \"Reactive Power Time Constant\"\n    T_q::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"Base power of the load (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p: Integrator state of the active power,\n\tx_q: Integrator state of the reactive power,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) DynamicExponentialLoad has 2 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction DynamicExponentialLoad(name, a, b, α, β, T_p, T_q, ext=Dict{String, Any}(), )\n    DynamicExponentialLoad(name, a, b, α, β, T_p, T_q, ext, 100.0, [:x_p, :x_q], 2, InfrastructureSystemsInternal(), )\nend\n\nfunction DynamicExponentialLoad(; name, a, b, α, β, T_p, T_q, ext=Dict{String, Any}(), base_power=100.0, states=[:x_p, :x_q], n_states=2, internal=InfrastructureSystemsInternal(), )\n    DynamicExponentialLoad(name, a, b, α, β, T_p, T_q, ext, base_power, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction DynamicExponentialLoad(::Nothing)\n    DynamicExponentialLoad(;\n        name=\"init\",\n        a=0,\n        b=0,\n        α=0,\n        β=0,\n        T_p=0,\n        T_q=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `name`.\"\"\"\nget_name(value::DynamicExponentialLoad) = value.name\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `a`.\"\"\"\nget_a(value::DynamicExponentialLoad) = value.a\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `b`.\"\"\"\nget_b(value::DynamicExponentialLoad) = value.b\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `α`.\"\"\"\nget_α(value::DynamicExponentialLoad) = value.α\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `β`.\"\"\"\nget_β(value::DynamicExponentialLoad) = value.β\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `T_p`.\"\"\"\nget_T_p(value::DynamicExponentialLoad) = value.T_p\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `T_q`.\"\"\"\nget_T_q(value::DynamicExponentialLoad) = value.T_q\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `ext`.\"\"\"\nget_ext(value::DynamicExponentialLoad) = value.ext\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::DynamicExponentialLoad) = value.base_power\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `states`.\"\"\"\nget_states(value::DynamicExponentialLoad) = value.states\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `n_states`.\"\"\"\nget_n_states(value::DynamicExponentialLoad) = value.n_states\n\"\"\"Get [`DynamicExponentialLoad`](@ref) `internal`.\"\"\"\nget_internal(value::DynamicExponentialLoad) = value.internal\n\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `a`.\"\"\"\nset_a!(value::DynamicExponentialLoad, val) = value.a = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `b`.\"\"\"\nset_b!(value::DynamicExponentialLoad, val) = value.b = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `α`.\"\"\"\nset_α!(value::DynamicExponentialLoad, val) = value.α = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `β`.\"\"\"\nset_β!(value::DynamicExponentialLoad, val) = value.β = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `T_p`.\"\"\"\nset_T_p!(value::DynamicExponentialLoad, val) = value.T_p = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `T_q`.\"\"\"\nset_T_q!(value::DynamicExponentialLoad, val) = value.T_q = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::DynamicExponentialLoad, val) = value.ext = val\n\"\"\"Set [`DynamicExponentialLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::DynamicExponentialLoad, val) = value.base_power = val\n"
  },
  {
    "path": "src/models/generated/ESAC1A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESAC1A <: AVR\n        Tr::Float64\n        Tb::Float64\n        Tc::Float64\n        Ka::Float64\n        Ta::Float64\n        Va_lim::MinMax\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        Kc::Float64\n        Kd::Float64\n        Ke::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        Vr_lim::MinMax\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nThis excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\nParameters of IEEE Std 421.5 Type AC1A Excitacion System. This model corresponds to ESAC1A in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Tb::Float64`: Regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc::Float64`: Regulator numerator (lead) time constant in s, validation range: `(0, 20)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output time constant in s, validation range: `(0, 10)`\n- `Va_lim::MinMax`: Limits for regulator output `(Va_min, Va_max)`\n- `Te::Float64`: Exciter field time constant in s, validation range: `(eps(), 2)`\n- `Kf::Float64`: Rate feedback excitation system stabilizer gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Rate feedback time constant, validation range: `(eps(), 1.5)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Kd::Float64`: Demagnetizing factor, function of exciter alternator reactances, validation range: `(0, 1)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `Vr_lim::MinMax`: Limits for exciter field voltage: `(Vr_min, Vr_max)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) ESAC1A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ESAC1A has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESAC1A <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Regulator numerator (lead) time constant in s\"\n    Tc::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output time constant in s\"\n    Ta::Float64\n    \"Limits for regulator output `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"Exciter field time constant in s\"\n    Te::Float64\n    \"Rate feedback excitation system stabilizer gain\"\n    Kf::Float64\n    \"Rate feedback time constant\"\n    Tf::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Demagnetizing factor, function of exciter alternator reactances\"\n    Kd::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Limits for exciter field voltage: `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ESAC1A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ESAC1A has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    ESAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Ve, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction ESAC1A(; Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Ve, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    ESAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESAC1A(::Nothing)\n    ESAC1A(;\n        Tr=0,\n        Tb=0,\n        Tc=0,\n        Ka=0,\n        Ta=0,\n        Va_lim=(min=0.0, max=0.0),\n        Te=0,\n        Kf=0,\n        Tf=0,\n        Kc=0,\n        Kd=0,\n        Ke=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        Vr_lim=(min=0.0, max=0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESAC1A`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESAC1A) = value.Tr\n\"\"\"Get [`ESAC1A`](@ref) `Tb`.\"\"\"\nget_Tb(value::ESAC1A) = value.Tb\n\"\"\"Get [`ESAC1A`](@ref) `Tc`.\"\"\"\nget_Tc(value::ESAC1A) = value.Tc\n\"\"\"Get [`ESAC1A`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESAC1A) = value.Ka\n\"\"\"Get [`ESAC1A`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESAC1A) = value.Ta\n\"\"\"Get [`ESAC1A`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::ESAC1A) = value.Va_lim\n\"\"\"Get [`ESAC1A`](@ref) `Te`.\"\"\"\nget_Te(value::ESAC1A) = value.Te\n\"\"\"Get [`ESAC1A`](@ref) `Kf`.\"\"\"\nget_Kf(value::ESAC1A) = value.Kf\n\"\"\"Get [`ESAC1A`](@ref) `Tf`.\"\"\"\nget_Tf(value::ESAC1A) = value.Tf\n\"\"\"Get [`ESAC1A`](@ref) `Kc`.\"\"\"\nget_Kc(value::ESAC1A) = value.Kc\n\"\"\"Get [`ESAC1A`](@ref) `Kd`.\"\"\"\nget_Kd(value::ESAC1A) = value.Kd\n\"\"\"Get [`ESAC1A`](@ref) `Ke`.\"\"\"\nget_Ke(value::ESAC1A) = value.Ke\n\"\"\"Get [`ESAC1A`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::ESAC1A) = value.E_sat\n\"\"\"Get [`ESAC1A`](@ref) `Se`.\"\"\"\nget_Se(value::ESAC1A) = value.Se\n\"\"\"Get [`ESAC1A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESAC1A) = value.Vr_lim\n\"\"\"Get [`ESAC1A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESAC1A) = value.V_ref\n\"\"\"Get [`ESAC1A`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::ESAC1A) = value.saturation_coeffs\n\"\"\"Get [`ESAC1A`](@ref) `ext`.\"\"\"\nget_ext(value::ESAC1A) = value.ext\n\"\"\"Get [`ESAC1A`](@ref) `states`.\"\"\"\nget_states(value::ESAC1A) = value.states\n\"\"\"Get [`ESAC1A`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESAC1A) = value.n_states\n\"\"\"Get [`ESAC1A`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESAC1A) = value.states_types\n\"\"\"Get [`ESAC1A`](@ref) `internal`.\"\"\"\nget_internal(value::ESAC1A) = value.internal\n\n\"\"\"Set [`ESAC1A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESAC1A, val) = value.Tr = val\n\"\"\"Set [`ESAC1A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::ESAC1A, val) = value.Tb = val\n\"\"\"Set [`ESAC1A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::ESAC1A, val) = value.Tc = val\n\"\"\"Set [`ESAC1A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESAC1A, val) = value.Ka = val\n\"\"\"Set [`ESAC1A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESAC1A, val) = value.Ta = val\n\"\"\"Set [`ESAC1A`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::ESAC1A, val) = value.Va_lim = val\n\"\"\"Set [`ESAC1A`](@ref) `Te`.\"\"\"\nset_Te!(value::ESAC1A, val) = value.Te = val\n\"\"\"Set [`ESAC1A`](@ref) `Kf`.\"\"\"\nset_Kf!(value::ESAC1A, val) = value.Kf = val\n\"\"\"Set [`ESAC1A`](@ref) `Tf`.\"\"\"\nset_Tf!(value::ESAC1A, val) = value.Tf = val\n\"\"\"Set [`ESAC1A`](@ref) `Kc`.\"\"\"\nset_Kc!(value::ESAC1A, val) = value.Kc = val\n\"\"\"Set [`ESAC1A`](@ref) `Kd`.\"\"\"\nset_Kd!(value::ESAC1A, val) = value.Kd = val\n\"\"\"Set [`ESAC1A`](@ref) `Ke`.\"\"\"\nset_Ke!(value::ESAC1A, val) = value.Ke = val\n\"\"\"Set [`ESAC1A`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::ESAC1A, val) = value.E_sat = val\n\"\"\"Set [`ESAC1A`](@ref) `Se`.\"\"\"\nset_Se!(value::ESAC1A, val) = value.Se = val\n\"\"\"Set [`ESAC1A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESAC1A, val) = value.Vr_lim = val\n\"\"\"Set [`ESAC1A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESAC1A, val) = value.V_ref = val\n\"\"\"Set [`ESAC1A`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::ESAC1A, val) = value.saturation_coeffs = val\n\"\"\"Set [`ESAC1A`](@ref) `ext`.\"\"\"\nset_ext!(value::ESAC1A, val) = value.ext = val\n\"\"\"Set [`ESAC1A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESAC1A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESAC6A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESAC6A <: AVR\n        Tr::Float64\n        Ka::Float64\n        Ta::Float64\n        Tk::Float64\n        Tb::Float64\n        Tc::Float64\n        Va_lim::MinMax\n        Vr_lim::MinMax\n        Te::Float64\n        VFE_lim::Float64\n        Kh::Float64\n        VH_max::Float64\n        Th::Float64\n        Tj::Float64\n        Kc::Float64\n        Kd::Float64\n        Ke::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nModified AC6A. Used to represent field-controlled alternator-rectifier excitation systems with system-supplied electronic voltage regulators. \nParameters of IEEE Std 421.5 Type AC6A Excitacion System. ESAC6A in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output lag time constant in s, validation range: `(0, 10)`\n- `Tk::Float64`: Voltage Regulator lead time constant, validation range: `(0, 10)`\n- `Tb::Float64`: Regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc::Float64`: Regulator numerator (lead) time constant in s, validation range: `(0, 20)`\n- `Va_lim::MinMax`: Limits for regulator output `(Va_min, Va_max)`\n- `Vr_lim::MinMax`: Limits for exciter field voltage `(Vr_min, Vr_max)`\n- `Te::Float64`: Exciter field time constant, validation range: `(eps(), 2)`\n- `VFE_lim::Float64`: Exciter field current limiter reference, validation range: `(-5, 20)`\n- `Kh::Float64`: Exciter field current regulator feedback gain, validation range: `(0, 100)`\n- `VH_max::Float64`: Exciter field current limiter maximum output, validation range: `(0, 100)`\n- `Th::Float64`: Exciter field current limiter denominator (lag) time constant, validation range: `(0, 1)`\n- `Tj::Float64`: Exciter field current limiter numerator (lead) time constant, validation range: `(0, 1)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Kd::Float64`: Demagnetizing factor, function of exciter alternator reactances, validation range: `(0, 2)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 2)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) ESAC6A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ESAC6A has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESAC6A <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output lag time constant in s\"\n    Ta::Float64\n    \"Voltage Regulator lead time constant\"\n    Tk::Float64\n    \"Regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Regulator numerator (lead) time constant in s\"\n    Tc::Float64\n    \"Limits for regulator output `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"Limits for exciter field voltage `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Exciter field time constant\"\n    Te::Float64\n    \"Exciter field current limiter reference\"\n    VFE_lim::Float64\n    \"Exciter field current regulator feedback gain\"\n    Kh::Float64\n    \"Exciter field current limiter maximum output\"\n    VH_max::Float64\n    \"Exciter field current limiter denominator (lag) time constant\"\n    Th::Float64\n    \"Exciter field current limiter numerator (lead) time constant\"\n    Tj::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Demagnetizing factor, function of exciter alternator reactances\"\n    Kd::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ESAC6A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ESAC6A has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESAC6A(Tr, Ka, Ta, Tk, Tb, Tc, Va_lim, Vr_lim, Te, VFE_lim, Kh, VH_max, Th, Tj, Kc, Kd, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    ESAC6A(Tr, Ka, Ta, Tk, Tb, Tc, Va_lim, Vr_lim, Te, VFE_lim, Kh, VH_max, Th, Tj, Kc, Kd, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Ve, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction ESAC6A(; Tr, Ka, Ta, Tk, Tb, Tc, Va_lim, Vr_lim, Te, VFE_lim, Kh, VH_max, Th, Tj, Kc, Kd, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Ve, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    ESAC6A(Tr, Ka, Ta, Tk, Tb, Tc, Va_lim, Vr_lim, Te, VFE_lim, Kh, VH_max, Th, Tj, Kc, Kd, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESAC6A(::Nothing)\n    ESAC6A(;\n        Tr=0,\n        Ka=0,\n        Ta=0,\n        Tk=0,\n        Tb=0,\n        Tc=0,\n        Va_lim=(min=0.0, max=0.0),\n        Vr_lim=(min=0.0, max=0.0),\n        Te=0,\n        VFE_lim=0,\n        Kh=0,\n        VH_max=0,\n        Th=0,\n        Tj=0,\n        Kc=0,\n        Kd=0,\n        Ke=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESAC6A`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESAC6A) = value.Tr\n\"\"\"Get [`ESAC6A`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESAC6A) = value.Ka\n\"\"\"Get [`ESAC6A`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESAC6A) = value.Ta\n\"\"\"Get [`ESAC6A`](@ref) `Tk`.\"\"\"\nget_Tk(value::ESAC6A) = value.Tk\n\"\"\"Get [`ESAC6A`](@ref) `Tb`.\"\"\"\nget_Tb(value::ESAC6A) = value.Tb\n\"\"\"Get [`ESAC6A`](@ref) `Tc`.\"\"\"\nget_Tc(value::ESAC6A) = value.Tc\n\"\"\"Get [`ESAC6A`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::ESAC6A) = value.Va_lim\n\"\"\"Get [`ESAC6A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESAC6A) = value.Vr_lim\n\"\"\"Get [`ESAC6A`](@ref) `Te`.\"\"\"\nget_Te(value::ESAC6A) = value.Te\n\"\"\"Get [`ESAC6A`](@ref) `VFE_lim`.\"\"\"\nget_VFE_lim(value::ESAC6A) = value.VFE_lim\n\"\"\"Get [`ESAC6A`](@ref) `Kh`.\"\"\"\nget_Kh(value::ESAC6A) = value.Kh\n\"\"\"Get [`ESAC6A`](@ref) `VH_max`.\"\"\"\nget_VH_max(value::ESAC6A) = value.VH_max\n\"\"\"Get [`ESAC6A`](@ref) `Th`.\"\"\"\nget_Th(value::ESAC6A) = value.Th\n\"\"\"Get [`ESAC6A`](@ref) `Tj`.\"\"\"\nget_Tj(value::ESAC6A) = value.Tj\n\"\"\"Get [`ESAC6A`](@ref) `Kc`.\"\"\"\nget_Kc(value::ESAC6A) = value.Kc\n\"\"\"Get [`ESAC6A`](@ref) `Kd`.\"\"\"\nget_Kd(value::ESAC6A) = value.Kd\n\"\"\"Get [`ESAC6A`](@ref) `Ke`.\"\"\"\nget_Ke(value::ESAC6A) = value.Ke\n\"\"\"Get [`ESAC6A`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::ESAC6A) = value.E_sat\n\"\"\"Get [`ESAC6A`](@ref) `Se`.\"\"\"\nget_Se(value::ESAC6A) = value.Se\n\"\"\"Get [`ESAC6A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESAC6A) = value.V_ref\n\"\"\"Get [`ESAC6A`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::ESAC6A) = value.saturation_coeffs\n\"\"\"Get [`ESAC6A`](@ref) `ext`.\"\"\"\nget_ext(value::ESAC6A) = value.ext\n\"\"\"Get [`ESAC6A`](@ref) `states`.\"\"\"\nget_states(value::ESAC6A) = value.states\n\"\"\"Get [`ESAC6A`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESAC6A) = value.n_states\n\"\"\"Get [`ESAC6A`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESAC6A) = value.states_types\n\"\"\"Get [`ESAC6A`](@ref) `internal`.\"\"\"\nget_internal(value::ESAC6A) = value.internal\n\n\"\"\"Set [`ESAC6A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESAC6A, val) = value.Tr = val\n\"\"\"Set [`ESAC6A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESAC6A, val) = value.Ka = val\n\"\"\"Set [`ESAC6A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESAC6A, val) = value.Ta = val\n\"\"\"Set [`ESAC6A`](@ref) `Tk`.\"\"\"\nset_Tk!(value::ESAC6A, val) = value.Tk = val\n\"\"\"Set [`ESAC6A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::ESAC6A, val) = value.Tb = val\n\"\"\"Set [`ESAC6A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::ESAC6A, val) = value.Tc = val\n\"\"\"Set [`ESAC6A`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::ESAC6A, val) = value.Va_lim = val\n\"\"\"Set [`ESAC6A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESAC6A, val) = value.Vr_lim = val\n\"\"\"Set [`ESAC6A`](@ref) `Te`.\"\"\"\nset_Te!(value::ESAC6A, val) = value.Te = val\n\"\"\"Set [`ESAC6A`](@ref) `VFE_lim`.\"\"\"\nset_VFE_lim!(value::ESAC6A, val) = value.VFE_lim = val\n\"\"\"Set [`ESAC6A`](@ref) `Kh`.\"\"\"\nset_Kh!(value::ESAC6A, val) = value.Kh = val\n\"\"\"Set [`ESAC6A`](@ref) `VH_max`.\"\"\"\nset_VH_max!(value::ESAC6A, val) = value.VH_max = val\n\"\"\"Set [`ESAC6A`](@ref) `Th`.\"\"\"\nset_Th!(value::ESAC6A, val) = value.Th = val\n\"\"\"Set [`ESAC6A`](@ref) `Tj`.\"\"\"\nset_Tj!(value::ESAC6A, val) = value.Tj = val\n\"\"\"Set [`ESAC6A`](@ref) `Kc`.\"\"\"\nset_Kc!(value::ESAC6A, val) = value.Kc = val\n\"\"\"Set [`ESAC6A`](@ref) `Kd`.\"\"\"\nset_Kd!(value::ESAC6A, val) = value.Kd = val\n\"\"\"Set [`ESAC6A`](@ref) `Ke`.\"\"\"\nset_Ke!(value::ESAC6A, val) = value.Ke = val\n\"\"\"Set [`ESAC6A`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::ESAC6A, val) = value.E_sat = val\n\"\"\"Set [`ESAC6A`](@ref) `Se`.\"\"\"\nset_Se!(value::ESAC6A, val) = value.Se = val\n\"\"\"Set [`ESAC6A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESAC6A, val) = value.V_ref = val\n\"\"\"Set [`ESAC6A`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::ESAC6A, val) = value.saturation_coeffs = val\n\"\"\"Set [`ESAC6A`](@ref) `ext`.\"\"\"\nset_ext!(value::ESAC6A, val) = value.ext = val\n\"\"\"Set [`ESAC6A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESAC6A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESAC8B.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESAC8B <: AVR\n        Tr::Float64\n        Kp::Float64\n        Ki::Float64\n        Kd::Float64\n        Td::Float64\n        Ka::Float64\n        Ta::Float64\n        Vr_lim::MinMax\n        Te::Float64\n        Ke::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nExcitation System AC8B. Used to represent the Basler Digital Excitation Control System (DECS) with PID controller in PSSE.\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, nothing)`\n- `Kp::Float64`: Regulator proportional PID gain, validation range: `(0, nothing)`\n- `Ki::Float64`: Regulator integral PID gain, validation range: `(0, nothing)`\n- `Kd::Float64`: Regulator derivative PID gain, validation range: `(0, nothing)`\n- `Td::Float64`: Regulator derivative PID time constant., validation range: `(0, 10)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output lag time constant in s, validation range: `(0, 10)`\n- `Vr_lim::MinMax`: Limits for exciter field voltage `(Vr_min, Vr_max)`\n- `Te::Float64`: Exciter field time constant, validation range: `(eps(), 2)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 2)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_i: Internal PI-block state,\n\tx_d: Internal Derivative-block state,\n\tVr: Voltage regulator state,\n\tEfd: Exciter output state\n- `n_states::Int`: (**Do not modify.**) ESAC8B has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ESAC8B has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESAC8B <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator proportional PID gain\"\n    Kp::Float64\n    \"Regulator integral PID gain\"\n    Ki::Float64\n    \"Regulator derivative PID gain\"\n    Kd::Float64\n    \"Regulator derivative PID time constant.\"\n    Td::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output lag time constant in s\"\n    Ta::Float64\n    \"Limits for exciter field voltage `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Exciter field time constant\"\n    Te::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_i: Internal PI-block state,\n\tx_d: Internal Derivative-block state,\n\tVr: Voltage regulator state,\n\tEfd: Exciter output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ESAC8B has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ESAC8B has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESAC8B(Tr, Kp, Ki, Kd, Td, Ka, Ta, Vr_lim, Te, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    ESAC8B(Tr, Kp, Ki, Kd, Td, Ka, Ta, Vr_lim, Te, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vm, :x_i, :x_d, :Vr, :Efd], 5, [StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential, StateTypes.Hybrid, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction ESAC8B(; Tr, Kp, Ki, Kd, Td, Ka, Ta, Vr_lim, Te, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :x_i, :x_d, :Vr, :Efd], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential, StateTypes.Hybrid, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    ESAC8B(Tr, Kp, Ki, Kd, Td, Ka, Ta, Vr_lim, Te, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESAC8B(::Nothing)\n    ESAC8B(;\n        Tr=0,\n        Kp=0,\n        Ki=0,\n        Kd=0,\n        Td=0,\n        Ka=0,\n        Ta=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Te=0,\n        Ke=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESAC8B`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESAC8B) = value.Tr\n\"\"\"Get [`ESAC8B`](@ref) `Kp`.\"\"\"\nget_Kp(value::ESAC8B) = value.Kp\n\"\"\"Get [`ESAC8B`](@ref) `Ki`.\"\"\"\nget_Ki(value::ESAC8B) = value.Ki\n\"\"\"Get [`ESAC8B`](@ref) `Kd`.\"\"\"\nget_Kd(value::ESAC8B) = value.Kd\n\"\"\"Get [`ESAC8B`](@ref) `Td`.\"\"\"\nget_Td(value::ESAC8B) = value.Td\n\"\"\"Get [`ESAC8B`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESAC8B) = value.Ka\n\"\"\"Get [`ESAC8B`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESAC8B) = value.Ta\n\"\"\"Get [`ESAC8B`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESAC8B) = value.Vr_lim\n\"\"\"Get [`ESAC8B`](@ref) `Te`.\"\"\"\nget_Te(value::ESAC8B) = value.Te\n\"\"\"Get [`ESAC8B`](@ref) `Ke`.\"\"\"\nget_Ke(value::ESAC8B) = value.Ke\n\"\"\"Get [`ESAC8B`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::ESAC8B) = value.E_sat\n\"\"\"Get [`ESAC8B`](@ref) `Se`.\"\"\"\nget_Se(value::ESAC8B) = value.Se\n\"\"\"Get [`ESAC8B`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESAC8B) = value.V_ref\n\"\"\"Get [`ESAC8B`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::ESAC8B) = value.saturation_coeffs\n\"\"\"Get [`ESAC8B`](@ref) `ext`.\"\"\"\nget_ext(value::ESAC8B) = value.ext\n\"\"\"Get [`ESAC8B`](@ref) `states`.\"\"\"\nget_states(value::ESAC8B) = value.states\n\"\"\"Get [`ESAC8B`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESAC8B) = value.n_states\n\"\"\"Get [`ESAC8B`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESAC8B) = value.states_types\n\"\"\"Get [`ESAC8B`](@ref) `internal`.\"\"\"\nget_internal(value::ESAC8B) = value.internal\n\n\"\"\"Set [`ESAC8B`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESAC8B, val) = value.Tr = val\n\"\"\"Set [`ESAC8B`](@ref) `Kp`.\"\"\"\nset_Kp!(value::ESAC8B, val) = value.Kp = val\n\"\"\"Set [`ESAC8B`](@ref) `Ki`.\"\"\"\nset_Ki!(value::ESAC8B, val) = value.Ki = val\n\"\"\"Set [`ESAC8B`](@ref) `Kd`.\"\"\"\nset_Kd!(value::ESAC8B, val) = value.Kd = val\n\"\"\"Set [`ESAC8B`](@ref) `Td`.\"\"\"\nset_Td!(value::ESAC8B, val) = value.Td = val\n\"\"\"Set [`ESAC8B`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESAC8B, val) = value.Ka = val\n\"\"\"Set [`ESAC8B`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESAC8B, val) = value.Ta = val\n\"\"\"Set [`ESAC8B`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESAC8B, val) = value.Vr_lim = val\n\"\"\"Set [`ESAC8B`](@ref) `Te`.\"\"\"\nset_Te!(value::ESAC8B, val) = value.Te = val\n\"\"\"Set [`ESAC8B`](@ref) `Ke`.\"\"\"\nset_Ke!(value::ESAC8B, val) = value.Ke = val\n\"\"\"Set [`ESAC8B`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::ESAC8B, val) = value.E_sat = val\n\"\"\"Set [`ESAC8B`](@ref) `Se`.\"\"\"\nset_Se!(value::ESAC8B, val) = value.Se = val\n\"\"\"Set [`ESAC8B`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESAC8B, val) = value.V_ref = val\n\"\"\"Set [`ESAC8B`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::ESAC8B, val) = value.saturation_coeffs = val\n\"\"\"Set [`ESAC8B`](@ref) `ext`.\"\"\"\nset_ext!(value::ESAC8B, val) = value.ext = val\n\"\"\"Set [`ESAC8B`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESAC8B, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESDC1A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESDC1A <: AVR\n        Tr::Float64\n        Ka::Float64\n        Ta::Float64\n        Tb::Float64\n        Tc::Float64\n        Vr_lim::MinMax\n        Ke::Float64\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        switch::Int\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nSelf-excited shunt fields with the voltage regulator operating in a mode commonly termed buck-boost. \nParameters of IEEE Std 421.5 Type DC1A Excitacion System. This model corresponds to ESDC1A in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, 0.5)`\n- `Ka::Float64`: Amplifier Gain, validation range: `(10, 500)`\n- `Ta::Float64`: Amplifier Time Constant in s, validation range: `(0, 1)`\n- `Tb::Float64`: Regulator input Time Constant in s, validation range: `(0, nothing)`\n- `Tc::Float64`: Regulator input Time Constant in s, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (regulator output) (Vi_min, Vi_max)\n- `Ke::Float64`: Exciter constant related to self-excited field, validation range: `(0, nothing)`\n- `Te::Float64`: Exciter time constant, integration rate associated with exciter control, validation range: `(eps(), 1)`\n- `Kf::Float64`: Excitation control system stabilizer gain, validation range: `(eps(), 0.3)`\n- `Tf::Float64`: Excitation control system stabilizer time constant, validation range: `(eps(), nothing)`\n- `switch::Int`: Switch, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr1: input lead lag,\n\tVr2: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\n- `n_states::Int`: (**Do not modify.**) The ESDC1A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ESDC1A has 5 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESDC1A <: AVR\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Amplifier Gain\"\n    Ka::Float64\n    \"Amplifier Time Constant in s\"\n    Ta::Float64\n    \"Regulator input Time Constant in s\"\n    Tb::Float64\n    \"Regulator input Time Constant in s\"\n    Tc::Float64\n    \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Exciter constant related to self-excited field\"\n    Ke::Float64\n    \"Exciter time constant, integration rate associated with exciter control\"\n    Te::Float64\n    \"Excitation control system stabilizer gain\"\n    Kf::Float64\n    \"Excitation control system stabilizer time constant\"\n    Tf::Float64\n    \"Switch\"\n    switch::Int\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr1: input lead lag,\n\tVr2: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The ESDC1A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ESDC1A has 5 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESDC1A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    ESDC1A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vt, :Vr1, :Vr2, :Vf, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction ESDC1A(; Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vt, :Vr1, :Vr2, :Vf, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    ESDC1A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESDC1A(::Nothing)\n    ESDC1A(;\n        Tr=0,\n        Ka=0,\n        Ta=0,\n        Tb=0,\n        Tc=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Ke=0,\n        Te=0,\n        Kf=0,\n        Tf=0,\n        switch=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESDC1A`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESDC1A) = value.Tr\n\"\"\"Get [`ESDC1A`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESDC1A) = value.Ka\n\"\"\"Get [`ESDC1A`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESDC1A) = value.Ta\n\"\"\"Get [`ESDC1A`](@ref) `Tb`.\"\"\"\nget_Tb(value::ESDC1A) = value.Tb\n\"\"\"Get [`ESDC1A`](@ref) `Tc`.\"\"\"\nget_Tc(value::ESDC1A) = value.Tc\n\"\"\"Get [`ESDC1A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESDC1A) = value.Vr_lim\n\"\"\"Get [`ESDC1A`](@ref) `Ke`.\"\"\"\nget_Ke(value::ESDC1A) = value.Ke\n\"\"\"Get [`ESDC1A`](@ref) `Te`.\"\"\"\nget_Te(value::ESDC1A) = value.Te\n\"\"\"Get [`ESDC1A`](@ref) `Kf`.\"\"\"\nget_Kf(value::ESDC1A) = value.Kf\n\"\"\"Get [`ESDC1A`](@ref) `Tf`.\"\"\"\nget_Tf(value::ESDC1A) = value.Tf\n\"\"\"Get [`ESDC1A`](@ref) `switch`.\"\"\"\nget_switch(value::ESDC1A) = value.switch\n\"\"\"Get [`ESDC1A`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::ESDC1A) = value.E_sat\n\"\"\"Get [`ESDC1A`](@ref) `Se`.\"\"\"\nget_Se(value::ESDC1A) = value.Se\n\"\"\"Get [`ESDC1A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESDC1A) = value.V_ref\n\"\"\"Get [`ESDC1A`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::ESDC1A) = value.saturation_coeffs\n\"\"\"Get [`ESDC1A`](@ref) `ext`.\"\"\"\nget_ext(value::ESDC1A) = value.ext\n\"\"\"Get [`ESDC1A`](@ref) `states`.\"\"\"\nget_states(value::ESDC1A) = value.states\n\"\"\"Get [`ESDC1A`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESDC1A) = value.n_states\n\"\"\"Get [`ESDC1A`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESDC1A) = value.states_types\n\"\"\"Get [`ESDC1A`](@ref) `internal`.\"\"\"\nget_internal(value::ESDC1A) = value.internal\n\n\"\"\"Set [`ESDC1A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESDC1A, val) = value.Tr = val\n\"\"\"Set [`ESDC1A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESDC1A, val) = value.Ka = val\n\"\"\"Set [`ESDC1A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESDC1A, val) = value.Ta = val\n\"\"\"Set [`ESDC1A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::ESDC1A, val) = value.Tb = val\n\"\"\"Set [`ESDC1A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::ESDC1A, val) = value.Tc = val\n\"\"\"Set [`ESDC1A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESDC1A, val) = value.Vr_lim = val\n\"\"\"Set [`ESDC1A`](@ref) `Ke`.\"\"\"\nset_Ke!(value::ESDC1A, val) = value.Ke = val\n\"\"\"Set [`ESDC1A`](@ref) `Te`.\"\"\"\nset_Te!(value::ESDC1A, val) = value.Te = val\n\"\"\"Set [`ESDC1A`](@ref) `Kf`.\"\"\"\nset_Kf!(value::ESDC1A, val) = value.Kf = val\n\"\"\"Set [`ESDC1A`](@ref) `Tf`.\"\"\"\nset_Tf!(value::ESDC1A, val) = value.Tf = val\n\"\"\"Set [`ESDC1A`](@ref) `switch`.\"\"\"\nset_switch!(value::ESDC1A, val) = value.switch = val\n\"\"\"Set [`ESDC1A`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::ESDC1A, val) = value.E_sat = val\n\"\"\"Set [`ESDC1A`](@ref) `Se`.\"\"\"\nset_Se!(value::ESDC1A, val) = value.Se = val\n\"\"\"Set [`ESDC1A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESDC1A, val) = value.V_ref = val\n\"\"\"Set [`ESDC1A`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::ESDC1A, val) = value.saturation_coeffs = val\n\"\"\"Set [`ESDC1A`](@ref) `ext`.\"\"\"\nset_ext!(value::ESDC1A, val) = value.ext = val\n\"\"\"Set [`ESDC1A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESDC1A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESDC2A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESDC2A <: AVR\n        Tr::Float64\n        Ka::Float64\n        Ta::Float64\n        Tb::Float64\n        Tc::Float64\n        Vr_lim::MinMax\n        Ke::Float64\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        switch::Int\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIs used to represent field-controlled dc commutator exciters with continuously acting voltage regulators having power supplies derived from the generator or auxiliaries bus.\nParameters of IEEE Std 421.5 Type DC2A Excitacion System. This model corresponds to ESDC2A in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, 0.5)`\n- `Ka::Float64`: Amplifier Gain, validation range: `(10, 500)`\n- `Ta::Float64`: Amplifier Time Constant in s, validation range: `(0, 1)`\n- `Tb::Float64`: Regulator input Time Constant in s, validation range: `(0, nothing)`\n- `Tc::Float64`: Regulator input Time Constant in s, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (regulator output) (Vi_min, Vi_max)\n- `Ke::Float64`: Exciter constant related to self-excited field, validation range: `(-1, 1)`\n- `Te::Float64`: Exciter time constant, integration rate associated with exciter control, validation range: `(eps(), 2)`\n- `Kf::Float64`: Excitation control system stabilizer gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Excitation control system stabilizer time constant. Appropiate Data: 5.0 <= Tf/Kf <= 15.0, validation range: `(eps(), 1.5)`\n- `switch::Int`: Switch, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr1: input lead lag,\n\tVr2: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\n- `n_states::Int`: (**Do not modify.**) The ESDC2A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ESDC2A has 5 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESDC2A <: AVR\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Amplifier Gain\"\n    Ka::Float64\n    \"Amplifier Time Constant in s\"\n    Ta::Float64\n    \"Regulator input Time Constant in s\"\n    Tb::Float64\n    \"Regulator input Time Constant in s\"\n    Tc::Float64\n    \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Exciter constant related to self-excited field\"\n    Ke::Float64\n    \"Exciter time constant, integration rate associated with exciter control\"\n    Te::Float64\n    \"Excitation control system stabilizer gain\"\n    Kf::Float64\n    \"Excitation control system stabilizer time constant. Appropiate Data: 5.0 <= Tf/Kf <= 15.0\"\n    Tf::Float64\n    \"Switch\"\n    switch::Int\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr1: input lead lag,\n\tVr2: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The ESDC2A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ESDC2A has 5 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESDC2A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    ESDC2A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vt, :Vr1, :Vr2, :Vf, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction ESDC2A(; Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vt, :Vr1, :Vr2, :Vf, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    ESDC2A(Tr, Ka, Ta, Tb, Tc, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESDC2A(::Nothing)\n    ESDC2A(;\n        Tr=0,\n        Ka=0,\n        Ta=0,\n        Tb=0,\n        Tc=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Ke=0,\n        Te=0,\n        Kf=0,\n        Tf=0,\n        switch=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESDC2A`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESDC2A) = value.Tr\n\"\"\"Get [`ESDC2A`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESDC2A) = value.Ka\n\"\"\"Get [`ESDC2A`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESDC2A) = value.Ta\n\"\"\"Get [`ESDC2A`](@ref) `Tb`.\"\"\"\nget_Tb(value::ESDC2A) = value.Tb\n\"\"\"Get [`ESDC2A`](@ref) `Tc`.\"\"\"\nget_Tc(value::ESDC2A) = value.Tc\n\"\"\"Get [`ESDC2A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESDC2A) = value.Vr_lim\n\"\"\"Get [`ESDC2A`](@ref) `Ke`.\"\"\"\nget_Ke(value::ESDC2A) = value.Ke\n\"\"\"Get [`ESDC2A`](@ref) `Te`.\"\"\"\nget_Te(value::ESDC2A) = value.Te\n\"\"\"Get [`ESDC2A`](@ref) `Kf`.\"\"\"\nget_Kf(value::ESDC2A) = value.Kf\n\"\"\"Get [`ESDC2A`](@ref) `Tf`.\"\"\"\nget_Tf(value::ESDC2A) = value.Tf\n\"\"\"Get [`ESDC2A`](@ref) `switch`.\"\"\"\nget_switch(value::ESDC2A) = value.switch\n\"\"\"Get [`ESDC2A`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::ESDC2A) = value.E_sat\n\"\"\"Get [`ESDC2A`](@ref) `Se`.\"\"\"\nget_Se(value::ESDC2A) = value.Se\n\"\"\"Get [`ESDC2A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESDC2A) = value.V_ref\n\"\"\"Get [`ESDC2A`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::ESDC2A) = value.saturation_coeffs\n\"\"\"Get [`ESDC2A`](@ref) `ext`.\"\"\"\nget_ext(value::ESDC2A) = value.ext\n\"\"\"Get [`ESDC2A`](@ref) `states`.\"\"\"\nget_states(value::ESDC2A) = value.states\n\"\"\"Get [`ESDC2A`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESDC2A) = value.n_states\n\"\"\"Get [`ESDC2A`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESDC2A) = value.states_types\n\"\"\"Get [`ESDC2A`](@ref) `internal`.\"\"\"\nget_internal(value::ESDC2A) = value.internal\n\n\"\"\"Set [`ESDC2A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESDC2A, val) = value.Tr = val\n\"\"\"Set [`ESDC2A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESDC2A, val) = value.Ka = val\n\"\"\"Set [`ESDC2A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESDC2A, val) = value.Ta = val\n\"\"\"Set [`ESDC2A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::ESDC2A, val) = value.Tb = val\n\"\"\"Set [`ESDC2A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::ESDC2A, val) = value.Tc = val\n\"\"\"Set [`ESDC2A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESDC2A, val) = value.Vr_lim = val\n\"\"\"Set [`ESDC2A`](@ref) `Ke`.\"\"\"\nset_Ke!(value::ESDC2A, val) = value.Ke = val\n\"\"\"Set [`ESDC2A`](@ref) `Te`.\"\"\"\nset_Te!(value::ESDC2A, val) = value.Te = val\n\"\"\"Set [`ESDC2A`](@ref) `Kf`.\"\"\"\nset_Kf!(value::ESDC2A, val) = value.Kf = val\n\"\"\"Set [`ESDC2A`](@ref) `Tf`.\"\"\"\nset_Tf!(value::ESDC2A, val) = value.Tf = val\n\"\"\"Set [`ESDC2A`](@ref) `switch`.\"\"\"\nset_switch!(value::ESDC2A, val) = value.switch = val\n\"\"\"Set [`ESDC2A`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::ESDC2A, val) = value.E_sat = val\n\"\"\"Set [`ESDC2A`](@ref) `Se`.\"\"\"\nset_Se!(value::ESDC2A, val) = value.Se = val\n\"\"\"Set [`ESDC2A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESDC2A, val) = value.V_ref = val\n\"\"\"Set [`ESDC2A`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::ESDC2A, val) = value.saturation_coeffs = val\n\"\"\"Set [`ESDC2A`](@ref) `ext`.\"\"\"\nset_ext!(value::ESDC2A, val) = value.ext = val\n\"\"\"Set [`ESDC2A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESDC2A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESST1A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESST1A <: AVR\n        UEL_flags::Int\n        PSS_flags::Int\n        Tr::Float64\n        Vi_lim::Tuple{Float64, Float64}\n        Tc::Float64\n        Tb::Float64\n        Tc1::Float64\n        Tb1::Float64\n        Ka::Float64\n        Ta::Float64\n        Va_lim::MinMax\n        Vr_lim::MinMax\n        Kc::Float64\n        Kf::Float64\n        Tf::Float64\n        K_lr::Float64\n        I_lr::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nThis excitation system supplies power through a transformer from the generator terminals and its regulated by a controlled rectifier (via thyristors).\nParameters of IEEE Std 421.5 Type ST1A Excitacion System. ESST1A in PSSE and PSLF\n\n# Arguments\n- `UEL_flags::Int`: Code input for Underexcitization limiter (UEL) entry. Not supported, validation range: `(1, 3)`\n- `PSS_flags::Int`: Code input for Power System Stabilizer (PSS) or (VOS) entry, validation range: `(1, 2)`\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.1)`\n- `Vi_lim::Tuple{Float64, Float64}`: Voltage error limits (regulator input) (Vi_min, Vi_max)\n- `Tc::Float64`: First regulator denominator (lead) time constant in s, validation range: `(0, 10)`\n- `Tb::Float64`: First regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc1::Float64`: Second regulator denominator (lead) time constant in s, validation range: `(0, 10)`\n- `Tb1::Float64`: Second regulator denominator (lead) time constant in s, validation range: `(0, 20)`\n- `Ka::Float64`: Voltage regulator gain, validation range: `(50, 1000)`\n- `Ta::Float64`: Voltage regulator time constant in s, validation range: `(0, 0.5)`\n- `Va_lim::MinMax`: Limits for regulator output `(Va_min, Va_max)`\n- `Vr_lim::MinMax`: Limits for exciter output `(Vr_min, Vr_max)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 0.3)`\n- `Kf::Float64`: Rate feedback gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Rate feedback time constant in s, validation range: `(eps(), 1.5)`\n- `K_lr::Float64`: Exciter output current limiter gain, validation range: `(0, 5)`\n- `I_lr::Float64`: Exciter output current limit reference, validation range: `(0, 5)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: First Lead-lag state,\n\tVr2: Second lead-lag state,\n\tVa: Regulator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) ST1A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ST1A has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESST1A <: AVR\n    \"Code input for Underexcitization limiter (UEL) entry. Not supported\"\n    UEL_flags::Int\n    \"Code input for Power System Stabilizer (PSS) or (VOS) entry\"\n    PSS_flags::Int\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Voltage error limits (regulator input) (Vi_min, Vi_max)\"\n    Vi_lim::Tuple{Float64, Float64}\n    \"First regulator denominator (lead) time constant in s\"\n    Tc::Float64\n    \"First regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Second regulator denominator (lead) time constant in s\"\n    Tc1::Float64\n    \"Second regulator denominator (lead) time constant in s\"\n    Tb1::Float64\n    \"Voltage regulator gain\"\n    Ka::Float64\n    \"Voltage regulator time constant in s\"\n    Ta::Float64\n    \"Limits for regulator output `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"Limits for exciter output `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Rate feedback gain\"\n    Kf::Float64\n    \"Rate feedback time constant in s\"\n    Tf::Float64\n    \"Exciter output current limiter gain\"\n    K_lr::Float64\n    \"Exciter output current limit reference\"\n    I_lr::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: First Lead-lag state,\n\tVr2: Second lead-lag state,\n\tVa: Regulator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ST1A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ST1A has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESST1A(UEL_flags, PSS_flags, Tr, Vi_lim, Tc, Tb, Tc1, Tb1, Ka, Ta, Va_lim, Vr_lim, Kc, Kf, Tf, K_lr, I_lr, V_ref=1.0, ext=Dict{String, Any}(), )\n    ESST1A(UEL_flags, PSS_flags, Tr, Vi_lim, Tc, Tb, Tc1, Tb1, Ka, Ta, Va_lim, Vr_lim, Kc, Kf, Tf, K_lr, I_lr, V_ref, ext, [:Vm, :Vr1, :Vr2, :Va, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction ESST1A(; UEL_flags, PSS_flags, Tr, Vi_lim, Tc, Tb, Tc1, Tb1, Ka, Ta, Va_lim, Vr_lim, Kc, Kf, Tf, K_lr, I_lr, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Va, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    ESST1A(UEL_flags, PSS_flags, Tr, Vi_lim, Tc, Tb, Tc1, Tb1, Ka, Ta, Va_lim, Vr_lim, Kc, Kf, Tf, K_lr, I_lr, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESST1A(::Nothing)\n    ESST1A(;\n        UEL_flags=1,\n        PSS_flags=1,\n        Tr=0,\n        Vi_lim=(0.0, 0.0),\n        Tc=0,\n        Tb=0,\n        Tc1=0,\n        Tb1=0,\n        Ka=0,\n        Ta=0,\n        Va_lim=(min=0.0, max=0.0),\n        Vr_lim=(min=0.0, max=0.0),\n        Kc=0,\n        Kf=0,\n        Tf=0,\n        K_lr=0,\n        I_lr=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESST1A`](@ref) `UEL_flags`.\"\"\"\nget_UEL_flags(value::ESST1A) = value.UEL_flags\n\"\"\"Get [`ESST1A`](@ref) `PSS_flags`.\"\"\"\nget_PSS_flags(value::ESST1A) = value.PSS_flags\n\"\"\"Get [`ESST1A`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESST1A) = value.Tr\n\"\"\"Get [`ESST1A`](@ref) `Vi_lim`.\"\"\"\nget_Vi_lim(value::ESST1A) = value.Vi_lim\n\"\"\"Get [`ESST1A`](@ref) `Tc`.\"\"\"\nget_Tc(value::ESST1A) = value.Tc\n\"\"\"Get [`ESST1A`](@ref) `Tb`.\"\"\"\nget_Tb(value::ESST1A) = value.Tb\n\"\"\"Get [`ESST1A`](@ref) `Tc1`.\"\"\"\nget_Tc1(value::ESST1A) = value.Tc1\n\"\"\"Get [`ESST1A`](@ref) `Tb1`.\"\"\"\nget_Tb1(value::ESST1A) = value.Tb1\n\"\"\"Get [`ESST1A`](@ref) `Ka`.\"\"\"\nget_Ka(value::ESST1A) = value.Ka\n\"\"\"Get [`ESST1A`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESST1A) = value.Ta\n\"\"\"Get [`ESST1A`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::ESST1A) = value.Va_lim\n\"\"\"Get [`ESST1A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESST1A) = value.Vr_lim\n\"\"\"Get [`ESST1A`](@ref) `Kc`.\"\"\"\nget_Kc(value::ESST1A) = value.Kc\n\"\"\"Get [`ESST1A`](@ref) `Kf`.\"\"\"\nget_Kf(value::ESST1A) = value.Kf\n\"\"\"Get [`ESST1A`](@ref) `Tf`.\"\"\"\nget_Tf(value::ESST1A) = value.Tf\n\"\"\"Get [`ESST1A`](@ref) `K_lr`.\"\"\"\nget_K_lr(value::ESST1A) = value.K_lr\n\"\"\"Get [`ESST1A`](@ref) `I_lr`.\"\"\"\nget_I_lr(value::ESST1A) = value.I_lr\n\"\"\"Get [`ESST1A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESST1A) = value.V_ref\n\"\"\"Get [`ESST1A`](@ref) `ext`.\"\"\"\nget_ext(value::ESST1A) = value.ext\n\"\"\"Get [`ESST1A`](@ref) `states`.\"\"\"\nget_states(value::ESST1A) = value.states\n\"\"\"Get [`ESST1A`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESST1A) = value.n_states\n\"\"\"Get [`ESST1A`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESST1A) = value.states_types\n\"\"\"Get [`ESST1A`](@ref) `internal`.\"\"\"\nget_internal(value::ESST1A) = value.internal\n\n\"\"\"Set [`ESST1A`](@ref) `UEL_flags`.\"\"\"\nset_UEL_flags!(value::ESST1A, val) = value.UEL_flags = val\n\"\"\"Set [`ESST1A`](@ref) `PSS_flags`.\"\"\"\nset_PSS_flags!(value::ESST1A, val) = value.PSS_flags = val\n\"\"\"Set [`ESST1A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESST1A, val) = value.Tr = val\n\"\"\"Set [`ESST1A`](@ref) `Vi_lim`.\"\"\"\nset_Vi_lim!(value::ESST1A, val) = value.Vi_lim = val\n\"\"\"Set [`ESST1A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::ESST1A, val) = value.Tc = val\n\"\"\"Set [`ESST1A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::ESST1A, val) = value.Tb = val\n\"\"\"Set [`ESST1A`](@ref) `Tc1`.\"\"\"\nset_Tc1!(value::ESST1A, val) = value.Tc1 = val\n\"\"\"Set [`ESST1A`](@ref) `Tb1`.\"\"\"\nset_Tb1!(value::ESST1A, val) = value.Tb1 = val\n\"\"\"Set [`ESST1A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::ESST1A, val) = value.Ka = val\n\"\"\"Set [`ESST1A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESST1A, val) = value.Ta = val\n\"\"\"Set [`ESST1A`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::ESST1A, val) = value.Va_lim = val\n\"\"\"Set [`ESST1A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESST1A, val) = value.Vr_lim = val\n\"\"\"Set [`ESST1A`](@ref) `Kc`.\"\"\"\nset_Kc!(value::ESST1A, val) = value.Kc = val\n\"\"\"Set [`ESST1A`](@ref) `Kf`.\"\"\"\nset_Kf!(value::ESST1A, val) = value.Kf = val\n\"\"\"Set [`ESST1A`](@ref) `Tf`.\"\"\"\nset_Tf!(value::ESST1A, val) = value.Tf = val\n\"\"\"Set [`ESST1A`](@ref) `K_lr`.\"\"\"\nset_K_lr!(value::ESST1A, val) = value.K_lr = val\n\"\"\"Set [`ESST1A`](@ref) `I_lr`.\"\"\"\nset_I_lr!(value::ESST1A, val) = value.I_lr = val\n\"\"\"Set [`ESST1A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESST1A, val) = value.V_ref = val\n\"\"\"Set [`ESST1A`](@ref) `ext`.\"\"\"\nset_ext!(value::ESST1A, val) = value.ext = val\n\"\"\"Set [`ESST1A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESST1A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ESST4B.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ESST4B <: AVR\n        Tr::Float64\n        K_pr::Float64\n        K_ir::Float64\n        Vr_lim::MinMax\n        Ta::Float64\n        K_pm::Float64\n        K_im::Float64\n        Vm_lim::MinMax\n        Kg::Float64\n        Kp::Float64\n        Ki::Float64\n        VB_max::Float64\n        Kc::Float64\n        Xl::Float64\n        θp::Float64\n        V_ref::Float64\n        θp_rad::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIn these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\nParameters of IEEE Std 421.5 Type ST4B Excitacion System. ESST4B in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `K_pr::Float64`: Regulator propotional gain, validation range: `(0, 75)`\n- `K_ir::Float64`: Regulator integral gain, validation range: `(0, 75)`\n- `Vr_lim::MinMax`: Voltage regulator limits (Vi_min, Vi_max)\n- `Ta::Float64`: Voltage regulator time constant in s, validation range: `(0, 1)`\n- `K_pm::Float64`: Voltage regulator proportional gain output, validation range: `(0, 1.2)`\n- `K_im::Float64`: Voltage regulator integral gain output, validation range: `(0, 18)`\n- `Vm_lim::MinMax`: Limits for inner loop output `(Vm_min, Vm_max)`\n- `Kg::Float64`: Feedback gain constant of the inner loop field regulator, validation range: `(0, 1.1)`\n- `Kp::Float64`: Potential circuit (voltage) gain coefficient, validation range: `(0, 10)`\n- `Ki::Float64`: Compound circuit (current) gain coefficient, validation range: `(0, 1.1)`\n- `VB_max::Float64`: Maximum available exciter voltage, validation range: `(1, 20)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Xl::Float64`: Reactance associated with potential source, validation range: `(0, 0.5)`\n- `θp::Float64`: Potential circuit phase angle (degrees), validation range: `(-90, 90)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `θp_rad::Float64`: (default: `θp*π*inv(180)`) (**Do not modify.**) Potential circuit phase angle (radians)\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVt: Sensed Terminal Voltage,\n\tVr1: Regulator Integrator,\n\tVr2: Regulator Output,\n\tVm: Output integrator\n- `n_states::Int`: (**Do not modify.**) ST4B has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ST4B has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ESST4B <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator propotional gain\"\n    K_pr::Float64\n    \"Regulator integral gain\"\n    K_ir::Float64\n    \"Voltage regulator limits (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Voltage regulator time constant in s\"\n    Ta::Float64\n    \"Voltage regulator proportional gain output\"\n    K_pm::Float64\n    \"Voltage regulator integral gain output\"\n    K_im::Float64\n    \"Limits for inner loop output `(Vm_min, Vm_max)`\"\n    Vm_lim::MinMax\n    \"Feedback gain constant of the inner loop field regulator\"\n    Kg::Float64\n    \"Potential circuit (voltage) gain coefficient\"\n    Kp::Float64\n    \"Compound circuit (current) gain coefficient\"\n    Ki::Float64\n    \"Maximum available exciter voltage\"\n    VB_max::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Reactance associated with potential source\"\n    Xl::Float64\n    \"Potential circuit phase angle (degrees)\"\n    θp::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Potential circuit phase angle (radians)\"\n    θp_rad::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVt: Sensed Terminal Voltage,\n\tVr1: Regulator Integrator,\n\tVr2: Regulator Output,\n\tVm: Output integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ST4B has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) ST4B has 4 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ESST4B(Tr, K_pr, K_ir, Vr_lim, Ta, K_pm, K_im, Vm_lim, Kg, Kp, Ki, VB_max, Kc, Xl, θp, V_ref=1.0, θp_rad=θp*π*inv(180), ext=Dict{String, Any}(), )\n    ESST4B(Tr, K_pr, K_ir, Vr_lim, Ta, K_pm, K_im, Vm_lim, Kg, Kp, Ki, VB_max, Kc, Xl, θp, V_ref, θp_rad, ext, [:Vt, :Vr1, :Vr2, :Vm], 4, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction ESST4B(; Tr, K_pr, K_ir, Vr_lim, Ta, K_pm, K_im, Vm_lim, Kg, Kp, Ki, VB_max, Kc, Xl, θp, V_ref=1.0, θp_rad=θp*π*inv(180), ext=Dict{String, Any}(), states=[:Vt, :Vr1, :Vr2, :Vm], n_states=4, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    ESST4B(Tr, K_pr, K_ir, Vr_lim, Ta, K_pm, K_im, Vm_lim, Kg, Kp, Ki, VB_max, Kc, Xl, θp, V_ref, θp_rad, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ESST4B(::Nothing)\n    ESST4B(;\n        Tr=0,\n        K_pr=0,\n        K_ir=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Ta=0,\n        K_pm=0,\n        K_im=0,\n        Vm_lim=(min=0.0, max=0.0),\n        Kg=0,\n        Kp=0,\n        Ki=0,\n        VB_max=0,\n        Kc=0,\n        Xl=0,\n        θp=0,\n        V_ref=0,\n        θp_rad=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ESST4B`](@ref) `Tr`.\"\"\"\nget_Tr(value::ESST4B) = value.Tr\n\"\"\"Get [`ESST4B`](@ref) `K_pr`.\"\"\"\nget_K_pr(value::ESST4B) = value.K_pr\n\"\"\"Get [`ESST4B`](@ref) `K_ir`.\"\"\"\nget_K_ir(value::ESST4B) = value.K_ir\n\"\"\"Get [`ESST4B`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ESST4B) = value.Vr_lim\n\"\"\"Get [`ESST4B`](@ref) `Ta`.\"\"\"\nget_Ta(value::ESST4B) = value.Ta\n\"\"\"Get [`ESST4B`](@ref) `K_pm`.\"\"\"\nget_K_pm(value::ESST4B) = value.K_pm\n\"\"\"Get [`ESST4B`](@ref) `K_im`.\"\"\"\nget_K_im(value::ESST4B) = value.K_im\n\"\"\"Get [`ESST4B`](@ref) `Vm_lim`.\"\"\"\nget_Vm_lim(value::ESST4B) = value.Vm_lim\n\"\"\"Get [`ESST4B`](@ref) `Kg`.\"\"\"\nget_Kg(value::ESST4B) = value.Kg\n\"\"\"Get [`ESST4B`](@ref) `Kp`.\"\"\"\nget_Kp(value::ESST4B) = value.Kp\n\"\"\"Get [`ESST4B`](@ref) `Ki`.\"\"\"\nget_Ki(value::ESST4B) = value.Ki\n\"\"\"Get [`ESST4B`](@ref) `VB_max`.\"\"\"\nget_VB_max(value::ESST4B) = value.VB_max\n\"\"\"Get [`ESST4B`](@ref) `Kc`.\"\"\"\nget_Kc(value::ESST4B) = value.Kc\n\"\"\"Get [`ESST4B`](@ref) `Xl`.\"\"\"\nget_Xl(value::ESST4B) = value.Xl\n\"\"\"Get [`ESST4B`](@ref) `θp`.\"\"\"\nget_θp(value::ESST4B) = value.θp\n\"\"\"Get [`ESST4B`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ESST4B) = value.V_ref\n\"\"\"Get [`ESST4B`](@ref) `θp_rad`.\"\"\"\nget_θp_rad(value::ESST4B) = value.θp_rad\n\"\"\"Get [`ESST4B`](@ref) `ext`.\"\"\"\nget_ext(value::ESST4B) = value.ext\n\"\"\"Get [`ESST4B`](@ref) `states`.\"\"\"\nget_states(value::ESST4B) = value.states\n\"\"\"Get [`ESST4B`](@ref) `n_states`.\"\"\"\nget_n_states(value::ESST4B) = value.n_states\n\"\"\"Get [`ESST4B`](@ref) `states_types`.\"\"\"\nget_states_types(value::ESST4B) = value.states_types\n\"\"\"Get [`ESST4B`](@ref) `internal`.\"\"\"\nget_internal(value::ESST4B) = value.internal\n\n\"\"\"Set [`ESST4B`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ESST4B, val) = value.Tr = val\n\"\"\"Set [`ESST4B`](@ref) `K_pr`.\"\"\"\nset_K_pr!(value::ESST4B, val) = value.K_pr = val\n\"\"\"Set [`ESST4B`](@ref) `K_ir`.\"\"\"\nset_K_ir!(value::ESST4B, val) = value.K_ir = val\n\"\"\"Set [`ESST4B`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ESST4B, val) = value.Vr_lim = val\n\"\"\"Set [`ESST4B`](@ref) `Ta`.\"\"\"\nset_Ta!(value::ESST4B, val) = value.Ta = val\n\"\"\"Set [`ESST4B`](@ref) `K_pm`.\"\"\"\nset_K_pm!(value::ESST4B, val) = value.K_pm = val\n\"\"\"Set [`ESST4B`](@ref) `K_im`.\"\"\"\nset_K_im!(value::ESST4B, val) = value.K_im = val\n\"\"\"Set [`ESST4B`](@ref) `Vm_lim`.\"\"\"\nset_Vm_lim!(value::ESST4B, val) = value.Vm_lim = val\n\"\"\"Set [`ESST4B`](@ref) `Kg`.\"\"\"\nset_Kg!(value::ESST4B, val) = value.Kg = val\n\"\"\"Set [`ESST4B`](@ref) `Kp`.\"\"\"\nset_Kp!(value::ESST4B, val) = value.Kp = val\n\"\"\"Set [`ESST4B`](@ref) `Ki`.\"\"\"\nset_Ki!(value::ESST4B, val) = value.Ki = val\n\"\"\"Set [`ESST4B`](@ref) `VB_max`.\"\"\"\nset_VB_max!(value::ESST4B, val) = value.VB_max = val\n\"\"\"Set [`ESST4B`](@ref) `Kc`.\"\"\"\nset_Kc!(value::ESST4B, val) = value.Kc = val\n\"\"\"Set [`ESST4B`](@ref) `Xl`.\"\"\"\nset_Xl!(value::ESST4B, val) = value.Xl = val\n\"\"\"Set [`ESST4B`](@ref) `θp`.\"\"\"\nset_θp!(value::ESST4B, val) = value.θp = val\n\"\"\"Set [`ESST4B`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ESST4B, val) = value.V_ref = val\n\"\"\"Set [`ESST4B`](@ref) `θp_rad`.\"\"\"\nset_θp_rad!(value::ESST4B, val) = value.θp_rad = val\n\"\"\"Set [`ESST4B`](@ref) `ext`.\"\"\"\nset_ext!(value::ESST4B, val) = value.ext = val\n\"\"\"Set [`ESST4B`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ESST4B, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/EX4VSA.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EX4VSA <: AVR\n        Iflim::Float64\n        d::Float64\n        f::Float64\n        Spar::Float64\n        K1::Float64\n        K2::Float64\n        Oel_lim::MinMax\n        G::Float64\n        Ta::Float64\n        Tb::Float64\n        Te::Float64\n        E_lim::MinMax\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE Excitation System for Voltage Security Assesment\n\n# Arguments\n- `Iflim::Float64`: OEL Field current limit, validation range: `(0, nothing)`\n- `d::Float64`: OEL parameter d, validation range: `(0, nothing)`\n- `f::Float64`: OEL parameter f, validation range: `(0, nothing)`\n- `Spar::Float64`: OEL parameter Spar, validation range: `(0, nothing)`\n- `K1::Float64`: OEL delay time constant, validation range: `(0, nothing)`\n- `K2::Float64`: OEL parameter K2, validation range: `(0, nothing)`\n- `Oel_lim::MinMax`: Oel integrator limits (Oel_min, Oel_max)\n- `G::Float64`: AVR Exciter Gain, validation range: `(0, nothing)`\n- `Ta::Float64`: Numerator lead-lag (lag) time constant in s, validation range: `(0, nothing)`\n- `Tb::Float64`: Denominator lead-lag (lag) time constant in s, validation range: `(0, nothing)`\n- `Te::Float64`: Exciter Time Constant in s, validation range: `(0, nothing)`\n- `E_lim::MinMax`: Voltage regulator limits (regulator output) (E_min, E_max)\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVll: Lead-lag internal state,\n\tVex: Exciter Output, \n\toel: OEL integrator state\n- `n_states::Int`: (**Do not modify.**) The EX4VSA has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EX4VSA <: AVR\n    \"OEL Field current limit\"\n    Iflim::Float64\n    \"OEL parameter d\"\n    d::Float64\n    \"OEL parameter f\"\n    f::Float64\n    \"OEL parameter Spar\"\n    Spar::Float64\n    \"OEL delay time constant\"\n    K1::Float64\n    \"OEL parameter K2\"\n    K2::Float64\n    \"Oel integrator limits (Oel_min, Oel_max)\"\n    Oel_lim::MinMax\n    \"AVR Exciter Gain\"\n    G::Float64\n    \"Numerator lead-lag (lag) time constant in s\"\n    Ta::Float64\n    \"Denominator lead-lag (lag) time constant in s\"\n    Tb::Float64\n    \"Exciter Time Constant in s\"\n    Te::Float64\n    \"Voltage regulator limits (regulator output) (E_min, E_max)\"\n    E_lim::MinMax\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVll: Lead-lag internal state,\n\tVex: Exciter Output, \n\toel: OEL integrator state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The EX4VSA has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref=1.0, ext=Dict{String, Any}(), )\n    EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref, ext, [:Vll, :Vex, :oel], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction EX4VSA(; Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vll, :Vex, :oel], n_states=3, internal=InfrastructureSystemsInternal(), )\n    EX4VSA(Iflim, d, f, Spar, K1, K2, Oel_lim, G, Ta, Tb, Te, E_lim, V_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EX4VSA(::Nothing)\n    EX4VSA(;\n        Iflim=0,\n        d=0,\n        f=0,\n        Spar=0,\n        K1=0,\n        K2=0,\n        Oel_lim=(min=0.0, max=0.0),\n        G=0,\n        Ta=0,\n        Tb=0,\n        Te=0,\n        E_lim=(min=0.0, max=0.0),\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EX4VSA`](@ref) `Iflim`.\"\"\"\nget_Iflim(value::EX4VSA) = value.Iflim\n\"\"\"Get [`EX4VSA`](@ref) `d`.\"\"\"\nget_d(value::EX4VSA) = value.d\n\"\"\"Get [`EX4VSA`](@ref) `f`.\"\"\"\nget_f(value::EX4VSA) = value.f\n\"\"\"Get [`EX4VSA`](@ref) `Spar`.\"\"\"\nget_Spar(value::EX4VSA) = value.Spar\n\"\"\"Get [`EX4VSA`](@ref) `K1`.\"\"\"\nget_K1(value::EX4VSA) = value.K1\n\"\"\"Get [`EX4VSA`](@ref) `K2`.\"\"\"\nget_K2(value::EX4VSA) = value.K2\n\"\"\"Get [`EX4VSA`](@ref) `Oel_lim`.\"\"\"\nget_Oel_lim(value::EX4VSA) = value.Oel_lim\n\"\"\"Get [`EX4VSA`](@ref) `G`.\"\"\"\nget_G(value::EX4VSA) = value.G\n\"\"\"Get [`EX4VSA`](@ref) `Ta`.\"\"\"\nget_Ta(value::EX4VSA) = value.Ta\n\"\"\"Get [`EX4VSA`](@ref) `Tb`.\"\"\"\nget_Tb(value::EX4VSA) = value.Tb\n\"\"\"Get [`EX4VSA`](@ref) `Te`.\"\"\"\nget_Te(value::EX4VSA) = value.Te\n\"\"\"Get [`EX4VSA`](@ref) `E_lim`.\"\"\"\nget_E_lim(value::EX4VSA) = value.E_lim\n\"\"\"Get [`EX4VSA`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EX4VSA) = value.V_ref\n\"\"\"Get [`EX4VSA`](@ref) `ext`.\"\"\"\nget_ext(value::EX4VSA) = value.ext\n\"\"\"Get [`EX4VSA`](@ref) `states`.\"\"\"\nget_states(value::EX4VSA) = value.states\n\"\"\"Get [`EX4VSA`](@ref) `n_states`.\"\"\"\nget_n_states(value::EX4VSA) = value.n_states\n\"\"\"Get [`EX4VSA`](@ref) `internal`.\"\"\"\nget_internal(value::EX4VSA) = value.internal\n\n\"\"\"Set [`EX4VSA`](@ref) `Iflim`.\"\"\"\nset_Iflim!(value::EX4VSA, val) = value.Iflim = val\n\"\"\"Set [`EX4VSA`](@ref) `d`.\"\"\"\nset_d!(value::EX4VSA, val) = value.d = val\n\"\"\"Set [`EX4VSA`](@ref) `f`.\"\"\"\nset_f!(value::EX4VSA, val) = value.f = val\n\"\"\"Set [`EX4VSA`](@ref) `Spar`.\"\"\"\nset_Spar!(value::EX4VSA, val) = value.Spar = val\n\"\"\"Set [`EX4VSA`](@ref) `K1`.\"\"\"\nset_K1!(value::EX4VSA, val) = value.K1 = val\n\"\"\"Set [`EX4VSA`](@ref) `K2`.\"\"\"\nset_K2!(value::EX4VSA, val) = value.K2 = val\n\"\"\"Set [`EX4VSA`](@ref) `Oel_lim`.\"\"\"\nset_Oel_lim!(value::EX4VSA, val) = value.Oel_lim = val\n\"\"\"Set [`EX4VSA`](@ref) `G`.\"\"\"\nset_G!(value::EX4VSA, val) = value.G = val\n\"\"\"Set [`EX4VSA`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EX4VSA, val) = value.Ta = val\n\"\"\"Set [`EX4VSA`](@ref) `Tb`.\"\"\"\nset_Tb!(value::EX4VSA, val) = value.Tb = val\n\"\"\"Set [`EX4VSA`](@ref) `Te`.\"\"\"\nset_Te!(value::EX4VSA, val) = value.Te = val\n\"\"\"Set [`EX4VSA`](@ref) `E_lim`.\"\"\"\nset_E_lim!(value::EX4VSA, val) = value.E_lim = val\n\"\"\"Set [`EX4VSA`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EX4VSA, val) = value.V_ref = val\n\"\"\"Set [`EX4VSA`](@ref) `ext`.\"\"\"\nset_ext!(value::EX4VSA, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/EXAC1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EXAC1 <: AVR\n        Tr::Float64\n        Tb::Float64\n        Tc::Float64\n        Ka::Float64\n        Ta::Float64\n        Vr_lim::MinMax\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        Kc::Float64\n        Kd::Float64\n        Ke::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nModified ESAC1A. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\nParameters of IEEE Std 421.5 Type AC1A.  EXAC1 in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Tb::Float64`: Regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc::Float64`: Regulator numerator (lead) time constant in s, validation range: `(0, 20)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output time constant in s, validation range: `(0, 10)`\n- `Vr_lim::MinMax`: Limits for regulator output `(Vr_min, Vr_max)`\n- `Te::Float64`: Exciter field time constant in s, validation range: `(eps(), 2)`\n- `Kf::Float64`: Rate feedback excitation system stabilizer gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Rate feedback time constant, validation range: `(eps(), 1.5)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Kd::Float64`: Demagnetizing factor, function of exciter alternator reactances, validation range: `(0, 1)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) EXAC1 has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) EXAC1 has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EXAC1 <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Regulator numerator (lead) time constant in s\"\n    Tc::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output time constant in s\"\n    Ta::Float64\n    \"Limits for regulator output `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Exciter field time constant in s\"\n    Te::Float64\n    \"Rate feedback excitation system stabilizer gain\"\n    Kf::Float64\n    \"Rate feedback time constant\"\n    Tf::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Demagnetizing factor, function of exciter alternator reactances\"\n    Kd::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) EXAC1 has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) EXAC1 has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EXAC1(Tr, Tb, Tc, Ka, Ta, Vr_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    EXAC1(Tr, Tb, Tc, Ka, Ta, Vr_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Ve, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction EXAC1(; Tr, Tb, Tc, Ka, Ta, Vr_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Ve, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    EXAC1(Tr, Tb, Tc, Ka, Ta, Vr_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EXAC1(::Nothing)\n    EXAC1(;\n        Tr=0,\n        Tb=0,\n        Tc=0,\n        Ka=0,\n        Ta=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Te=0,\n        Kf=0,\n        Tf=0,\n        Kc=0,\n        Kd=0,\n        Ke=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EXAC1`](@ref) `Tr`.\"\"\"\nget_Tr(value::EXAC1) = value.Tr\n\"\"\"Get [`EXAC1`](@ref) `Tb`.\"\"\"\nget_Tb(value::EXAC1) = value.Tb\n\"\"\"Get [`EXAC1`](@ref) `Tc`.\"\"\"\nget_Tc(value::EXAC1) = value.Tc\n\"\"\"Get [`EXAC1`](@ref) `Ka`.\"\"\"\nget_Ka(value::EXAC1) = value.Ka\n\"\"\"Get [`EXAC1`](@ref) `Ta`.\"\"\"\nget_Ta(value::EXAC1) = value.Ta\n\"\"\"Get [`EXAC1`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::EXAC1) = value.Vr_lim\n\"\"\"Get [`EXAC1`](@ref) `Te`.\"\"\"\nget_Te(value::EXAC1) = value.Te\n\"\"\"Get [`EXAC1`](@ref) `Kf`.\"\"\"\nget_Kf(value::EXAC1) = value.Kf\n\"\"\"Get [`EXAC1`](@ref) `Tf`.\"\"\"\nget_Tf(value::EXAC1) = value.Tf\n\"\"\"Get [`EXAC1`](@ref) `Kc`.\"\"\"\nget_Kc(value::EXAC1) = value.Kc\n\"\"\"Get [`EXAC1`](@ref) `Kd`.\"\"\"\nget_Kd(value::EXAC1) = value.Kd\n\"\"\"Get [`EXAC1`](@ref) `Ke`.\"\"\"\nget_Ke(value::EXAC1) = value.Ke\n\"\"\"Get [`EXAC1`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::EXAC1) = value.E_sat\n\"\"\"Get [`EXAC1`](@ref) `Se`.\"\"\"\nget_Se(value::EXAC1) = value.Se\n\"\"\"Get [`EXAC1`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EXAC1) = value.V_ref\n\"\"\"Get [`EXAC1`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::EXAC1) = value.saturation_coeffs\n\"\"\"Get [`EXAC1`](@ref) `ext`.\"\"\"\nget_ext(value::EXAC1) = value.ext\n\"\"\"Get [`EXAC1`](@ref) `states`.\"\"\"\nget_states(value::EXAC1) = value.states\n\"\"\"Get [`EXAC1`](@ref) `n_states`.\"\"\"\nget_n_states(value::EXAC1) = value.n_states\n\"\"\"Get [`EXAC1`](@ref) `states_types`.\"\"\"\nget_states_types(value::EXAC1) = value.states_types\n\"\"\"Get [`EXAC1`](@ref) `internal`.\"\"\"\nget_internal(value::EXAC1) = value.internal\n\n\"\"\"Set [`EXAC1`](@ref) `Tr`.\"\"\"\nset_Tr!(value::EXAC1, val) = value.Tr = val\n\"\"\"Set [`EXAC1`](@ref) `Tb`.\"\"\"\nset_Tb!(value::EXAC1, val) = value.Tb = val\n\"\"\"Set [`EXAC1`](@ref) `Tc`.\"\"\"\nset_Tc!(value::EXAC1, val) = value.Tc = val\n\"\"\"Set [`EXAC1`](@ref) `Ka`.\"\"\"\nset_Ka!(value::EXAC1, val) = value.Ka = val\n\"\"\"Set [`EXAC1`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EXAC1, val) = value.Ta = val\n\"\"\"Set [`EXAC1`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::EXAC1, val) = value.Vr_lim = val\n\"\"\"Set [`EXAC1`](@ref) `Te`.\"\"\"\nset_Te!(value::EXAC1, val) = value.Te = val\n\"\"\"Set [`EXAC1`](@ref) `Kf`.\"\"\"\nset_Kf!(value::EXAC1, val) = value.Kf = val\n\"\"\"Set [`EXAC1`](@ref) `Tf`.\"\"\"\nset_Tf!(value::EXAC1, val) = value.Tf = val\n\"\"\"Set [`EXAC1`](@ref) `Kc`.\"\"\"\nset_Kc!(value::EXAC1, val) = value.Kc = val\n\"\"\"Set [`EXAC1`](@ref) `Kd`.\"\"\"\nset_Kd!(value::EXAC1, val) = value.Kd = val\n\"\"\"Set [`EXAC1`](@ref) `Ke`.\"\"\"\nset_Ke!(value::EXAC1, val) = value.Ke = val\n\"\"\"Set [`EXAC1`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::EXAC1, val) = value.E_sat = val\n\"\"\"Set [`EXAC1`](@ref) `Se`.\"\"\"\nset_Se!(value::EXAC1, val) = value.Se = val\n\"\"\"Set [`EXAC1`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EXAC1, val) = value.V_ref = val\n\"\"\"Set [`EXAC1`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::EXAC1, val) = value.saturation_coeffs = val\n\"\"\"Set [`EXAC1`](@ref) `ext`.\"\"\"\nset_ext!(value::EXAC1, val) = value.ext = val\n\"\"\"Set [`EXAC1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::EXAC1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/EXAC1A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EXAC1A <: AVR\n        Tr::Float64\n        Tb::Float64\n        Tc::Float64\n        Ka::Float64\n        Ta::Float64\n        Va_lim::MinMax\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        Kc::Float64\n        Kd::Float64\n        Ke::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        Vr_lim::MinMax\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nModified ESAC1A. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\nParameters of IEEE Std 421.5 Type AC1A Excitacion System. EXAC1A in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Tb::Float64`: Regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc::Float64`: Regulator numerator (lead) time constant in s, validation range: `(0, 20)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output time constant in s, validation range: `(0, 10)`\n- `Va_lim::MinMax`: Limits for regulator output `(Va_min, Va_max)`\n- `Te::Float64`: Exciter field time constant in s, validation range: `(eps(), 2)`\n- `Kf::Float64`: Rate feedback excitation system stabilizer gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Rate feedback time constant, validation range: `(eps(), 1.5)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Kd::Float64`: Demagnetizing factor, function of exciter alternator reactances, validation range: `(0, 1)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `Vr_lim::MinMax`: Limits for exciter field voltage: `(Vr_min, Vr_max)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) EXAC1A has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) EXAC1A has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EXAC1A <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Regulator numerator (lead) time constant in s\"\n    Tc::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output time constant in s\"\n    Ta::Float64\n    \"Limits for regulator output `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"Exciter field time constant in s\"\n    Te::Float64\n    \"Rate feedback excitation system stabilizer gain\"\n    Kf::Float64\n    \"Rate feedback time constant\"\n    Tf::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Demagnetizing factor, function of exciter alternator reactances\"\n    Kd::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Limits for exciter field voltage: `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(x) = B(x - A)^2/x\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) EXAC1A has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) EXAC1A has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EXAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    EXAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Ve, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction EXAC1A(; Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Ve, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    EXAC1A(Tr, Tb, Tc, Ka, Ta, Va_lim, Te, Kf, Tf, Kc, Kd, Ke, E_sat, Se, Vr_lim, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EXAC1A(::Nothing)\n    EXAC1A(;\n        Tr=0,\n        Tb=0,\n        Tc=0,\n        Ka=0,\n        Ta=0,\n        Va_lim=(min=0.0, max=0.0),\n        Te=0,\n        Kf=0,\n        Tf=0,\n        Kc=0,\n        Kd=0,\n        Ke=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        Vr_lim=(min=0.0, max=0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EXAC1A`](@ref) `Tr`.\"\"\"\nget_Tr(value::EXAC1A) = value.Tr\n\"\"\"Get [`EXAC1A`](@ref) `Tb`.\"\"\"\nget_Tb(value::EXAC1A) = value.Tb\n\"\"\"Get [`EXAC1A`](@ref) `Tc`.\"\"\"\nget_Tc(value::EXAC1A) = value.Tc\n\"\"\"Get [`EXAC1A`](@ref) `Ka`.\"\"\"\nget_Ka(value::EXAC1A) = value.Ka\n\"\"\"Get [`EXAC1A`](@ref) `Ta`.\"\"\"\nget_Ta(value::EXAC1A) = value.Ta\n\"\"\"Get [`EXAC1A`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::EXAC1A) = value.Va_lim\n\"\"\"Get [`EXAC1A`](@ref) `Te`.\"\"\"\nget_Te(value::EXAC1A) = value.Te\n\"\"\"Get [`EXAC1A`](@ref) `Kf`.\"\"\"\nget_Kf(value::EXAC1A) = value.Kf\n\"\"\"Get [`EXAC1A`](@ref) `Tf`.\"\"\"\nget_Tf(value::EXAC1A) = value.Tf\n\"\"\"Get [`EXAC1A`](@ref) `Kc`.\"\"\"\nget_Kc(value::EXAC1A) = value.Kc\n\"\"\"Get [`EXAC1A`](@ref) `Kd`.\"\"\"\nget_Kd(value::EXAC1A) = value.Kd\n\"\"\"Get [`EXAC1A`](@ref) `Ke`.\"\"\"\nget_Ke(value::EXAC1A) = value.Ke\n\"\"\"Get [`EXAC1A`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::EXAC1A) = value.E_sat\n\"\"\"Get [`EXAC1A`](@ref) `Se`.\"\"\"\nget_Se(value::EXAC1A) = value.Se\n\"\"\"Get [`EXAC1A`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::EXAC1A) = value.Vr_lim\n\"\"\"Get [`EXAC1A`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EXAC1A) = value.V_ref\n\"\"\"Get [`EXAC1A`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::EXAC1A) = value.saturation_coeffs\n\"\"\"Get [`EXAC1A`](@ref) `ext`.\"\"\"\nget_ext(value::EXAC1A) = value.ext\n\"\"\"Get [`EXAC1A`](@ref) `states`.\"\"\"\nget_states(value::EXAC1A) = value.states\n\"\"\"Get [`EXAC1A`](@ref) `n_states`.\"\"\"\nget_n_states(value::EXAC1A) = value.n_states\n\"\"\"Get [`EXAC1A`](@ref) `states_types`.\"\"\"\nget_states_types(value::EXAC1A) = value.states_types\n\"\"\"Get [`EXAC1A`](@ref) `internal`.\"\"\"\nget_internal(value::EXAC1A) = value.internal\n\n\"\"\"Set [`EXAC1A`](@ref) `Tr`.\"\"\"\nset_Tr!(value::EXAC1A, val) = value.Tr = val\n\"\"\"Set [`EXAC1A`](@ref) `Tb`.\"\"\"\nset_Tb!(value::EXAC1A, val) = value.Tb = val\n\"\"\"Set [`EXAC1A`](@ref) `Tc`.\"\"\"\nset_Tc!(value::EXAC1A, val) = value.Tc = val\n\"\"\"Set [`EXAC1A`](@ref) `Ka`.\"\"\"\nset_Ka!(value::EXAC1A, val) = value.Ka = val\n\"\"\"Set [`EXAC1A`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EXAC1A, val) = value.Ta = val\n\"\"\"Set [`EXAC1A`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::EXAC1A, val) = value.Va_lim = val\n\"\"\"Set [`EXAC1A`](@ref) `Te`.\"\"\"\nset_Te!(value::EXAC1A, val) = value.Te = val\n\"\"\"Set [`EXAC1A`](@ref) `Kf`.\"\"\"\nset_Kf!(value::EXAC1A, val) = value.Kf = val\n\"\"\"Set [`EXAC1A`](@ref) `Tf`.\"\"\"\nset_Tf!(value::EXAC1A, val) = value.Tf = val\n\"\"\"Set [`EXAC1A`](@ref) `Kc`.\"\"\"\nset_Kc!(value::EXAC1A, val) = value.Kc = val\n\"\"\"Set [`EXAC1A`](@ref) `Kd`.\"\"\"\nset_Kd!(value::EXAC1A, val) = value.Kd = val\n\"\"\"Set [`EXAC1A`](@ref) `Ke`.\"\"\"\nset_Ke!(value::EXAC1A, val) = value.Ke = val\n\"\"\"Set [`EXAC1A`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::EXAC1A, val) = value.E_sat = val\n\"\"\"Set [`EXAC1A`](@ref) `Se`.\"\"\"\nset_Se!(value::EXAC1A, val) = value.Se = val\n\"\"\"Set [`EXAC1A`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::EXAC1A, val) = value.Vr_lim = val\n\"\"\"Set [`EXAC1A`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EXAC1A, val) = value.V_ref = val\n\"\"\"Set [`EXAC1A`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::EXAC1A, val) = value.saturation_coeffs = val\n\"\"\"Set [`EXAC1A`](@ref) `ext`.\"\"\"\nset_ext!(value::EXAC1A, val) = value.ext = val\n\"\"\"Set [`EXAC1A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::EXAC1A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/EXAC2.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EXAC2 <: AVR\n        Tr::Float64\n        Tb::Float64\n        Tc::Float64\n        Ka::Float64\n        Ta::Float64\n        Va_lim::MinMax\n        Kb::Float64\n        Vr_lim::MinMax\n        Te::Float64\n        Kl::Float64\n        Kh::Float64\n        Kf::Float64\n        Tf::Float64\n        Kc::Float64\n        Kd::Float64\n        Ke::Float64\n        V_lr::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nModified AC2. This excitation systems consists of an alternator main exciter feeding its output via non-controlled rectifiers.\nThe exciter does not employ self-excitation, and the voltage regulator power is taken from a source that is not affected by external transients.\nParameters of IEEE Std 421.5 Type AC2A Excitacion System. The alternator main exciter is used, feeding its output via non-controlled rectifiers. The Type AC2C model is similar to that of Type AC1C except for the inclusion of exciter time constant compensation and exciter field current limiting elements. EXAC2 in PSSE and PSLF\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Tb::Float64`: Regulator denominator (lag) time constant in s, validation range: `(0, 20)`\n- `Tc::Float64`: Regulator numerator (lead) time constant in s, validation range: `(0, 20)`\n- `Ka::Float64`: Regulator output gain, validation range: `(0, 1000)`\n- `Ta::Float64`: Regulator output time constant in s, validation range: `(0, 10)`\n- `Va_lim::MinMax`: Limits for regulator output `(Va_min, Va_max)`\n- `Kb::Float64`: Second Stage regulator gain, validation range: `(eps(), 500)`\n- `Vr_lim::MinMax`: Limits for exciter field voltage `(Vr_min, Vr_max)`\n- `Te::Float64`: Exciter field time constant, validation range: `(eps(), 2)`\n- `Kl::Float64`: Exciter field current limiter gain, validation range: `(0, 1.1)`\n- `Kh::Float64`: Exciter field current regulator feedback gain, validation range: `(0, 1.1)`\n- `Kf::Float64`: Rate feedback excitation system stabilizer gain, validation range: `(0, 0.3)`\n- `Tf::Float64`: Rate feedback time constant, validation range: `(eps(), nothing)`\n- `Kc::Float64`: Rectifier loading factor proportional to commutating reactance, validation range: `(0, 1)`\n- `Kd::Float64`: Demagnetizing factor, function of exciter alternator reactances, validation range: `(0, 1)`\n- `Ke::Float64`: Exciter field proportional constant, validation range: `(0, 1)`\n- `V_lr::Float64`: Maximum exciter field current, validation range: `(0, nothing)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\n- `n_states::Int`: (**Do not modify.**) EXAC2 has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) EXAC2 has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EXAC2 <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator denominator (lag) time constant in s\"\n    Tb::Float64\n    \"Regulator numerator (lead) time constant in s\"\n    Tc::Float64\n    \"Regulator output gain\"\n    Ka::Float64\n    \"Regulator output time constant in s\"\n    Ta::Float64\n    \"Limits for regulator output `(Va_min, Va_max)`\"\n    Va_lim::MinMax\n    \"Second Stage regulator gain\"\n    Kb::Float64\n    \"Limits for exciter field voltage `(Vr_min, Vr_max)`\"\n    Vr_lim::MinMax\n    \"Exciter field time constant\"\n    Te::Float64\n    \"Exciter field current limiter gain\"\n    Kl::Float64\n    \"Exciter field current regulator feedback gain\"\n    Kh::Float64\n    \"Rate feedback excitation system stabilizer gain\"\n    Kf::Float64\n    \"Rate feedback time constant\"\n    Tf::Float64\n    \"Rectifier loading factor proportional to commutating reactance\"\n    Kc::Float64\n    \"Demagnetizing factor, function of exciter alternator reactances\"\n    Kd::Float64\n    \"Exciter field proportional constant\"\n    Ke::Float64\n    \"Maximum exciter field current\"\n    V_lr::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: Lead-lag state,\n\tVr2: Regulator output state,\n\tVe: Integrator output state,\n\tVr3: Feedback output state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) EXAC2 has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) EXAC2 has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EXAC2(Tr, Tb, Tc, Ka, Ta, Va_lim, Kb, Vr_lim, Te, Kl, Kh, Kf, Tf, Kc, Kd, Ke, V_lr, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    EXAC2(Tr, Tb, Tc, Ka, Ta, Va_lim, Kb, Vr_lim, Te, Kl, Kh, Kf, Tf, Kc, Kd, Ke, V_lr, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Ve, :Vr3], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction EXAC2(; Tr, Tb, Tc, Ka, Ta, Va_lim, Kb, Vr_lim, Te, Kl, Kh, Kf, Tf, Kc, Kd, Ke, V_lr, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Ve, :Vr3], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    EXAC2(Tr, Tb, Tc, Ka, Ta, Va_lim, Kb, Vr_lim, Te, Kl, Kh, Kf, Tf, Kc, Kd, Ke, V_lr, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EXAC2(::Nothing)\n    EXAC2(;\n        Tr=0,\n        Tb=0,\n        Tc=0,\n        Ka=0,\n        Ta=0,\n        Va_lim=(min=0.0, max=0.0),\n        Kb=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Te=0,\n        Kl=0,\n        Kh=0,\n        Kf=0,\n        Tf=0,\n        Kc=0,\n        Kd=0,\n        Ke=0,\n        V_lr=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EXAC2`](@ref) `Tr`.\"\"\"\nget_Tr(value::EXAC2) = value.Tr\n\"\"\"Get [`EXAC2`](@ref) `Tb`.\"\"\"\nget_Tb(value::EXAC2) = value.Tb\n\"\"\"Get [`EXAC2`](@ref) `Tc`.\"\"\"\nget_Tc(value::EXAC2) = value.Tc\n\"\"\"Get [`EXAC2`](@ref) `Ka`.\"\"\"\nget_Ka(value::EXAC2) = value.Ka\n\"\"\"Get [`EXAC2`](@ref) `Ta`.\"\"\"\nget_Ta(value::EXAC2) = value.Ta\n\"\"\"Get [`EXAC2`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::EXAC2) = value.Va_lim\n\"\"\"Get [`EXAC2`](@ref) `Kb`.\"\"\"\nget_Kb(value::EXAC2) = value.Kb\n\"\"\"Get [`EXAC2`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::EXAC2) = value.Vr_lim\n\"\"\"Get [`EXAC2`](@ref) `Te`.\"\"\"\nget_Te(value::EXAC2) = value.Te\n\"\"\"Get [`EXAC2`](@ref) `Kl`.\"\"\"\nget_Kl(value::EXAC2) = value.Kl\n\"\"\"Get [`EXAC2`](@ref) `Kh`.\"\"\"\nget_Kh(value::EXAC2) = value.Kh\n\"\"\"Get [`EXAC2`](@ref) `Kf`.\"\"\"\nget_Kf(value::EXAC2) = value.Kf\n\"\"\"Get [`EXAC2`](@ref) `Tf`.\"\"\"\nget_Tf(value::EXAC2) = value.Tf\n\"\"\"Get [`EXAC2`](@ref) `Kc`.\"\"\"\nget_Kc(value::EXAC2) = value.Kc\n\"\"\"Get [`EXAC2`](@ref) `Kd`.\"\"\"\nget_Kd(value::EXAC2) = value.Kd\n\"\"\"Get [`EXAC2`](@ref) `Ke`.\"\"\"\nget_Ke(value::EXAC2) = value.Ke\n\"\"\"Get [`EXAC2`](@ref) `V_lr`.\"\"\"\nget_V_lr(value::EXAC2) = value.V_lr\n\"\"\"Get [`EXAC2`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::EXAC2) = value.E_sat\n\"\"\"Get [`EXAC2`](@ref) `Se`.\"\"\"\nget_Se(value::EXAC2) = value.Se\n\"\"\"Get [`EXAC2`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EXAC2) = value.V_ref\n\"\"\"Get [`EXAC2`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::EXAC2) = value.saturation_coeffs\n\"\"\"Get [`EXAC2`](@ref) `ext`.\"\"\"\nget_ext(value::EXAC2) = value.ext\n\"\"\"Get [`EXAC2`](@ref) `states`.\"\"\"\nget_states(value::EXAC2) = value.states\n\"\"\"Get [`EXAC2`](@ref) `n_states`.\"\"\"\nget_n_states(value::EXAC2) = value.n_states\n\"\"\"Get [`EXAC2`](@ref) `states_types`.\"\"\"\nget_states_types(value::EXAC2) = value.states_types\n\"\"\"Get [`EXAC2`](@ref) `internal`.\"\"\"\nget_internal(value::EXAC2) = value.internal\n\n\"\"\"Set [`EXAC2`](@ref) `Tr`.\"\"\"\nset_Tr!(value::EXAC2, val) = value.Tr = val\n\"\"\"Set [`EXAC2`](@ref) `Tb`.\"\"\"\nset_Tb!(value::EXAC2, val) = value.Tb = val\n\"\"\"Set [`EXAC2`](@ref) `Tc`.\"\"\"\nset_Tc!(value::EXAC2, val) = value.Tc = val\n\"\"\"Set [`EXAC2`](@ref) `Ka`.\"\"\"\nset_Ka!(value::EXAC2, val) = value.Ka = val\n\"\"\"Set [`EXAC2`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EXAC2, val) = value.Ta = val\n\"\"\"Set [`EXAC2`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::EXAC2, val) = value.Va_lim = val\n\"\"\"Set [`EXAC2`](@ref) `Kb`.\"\"\"\nset_Kb!(value::EXAC2, val) = value.Kb = val\n\"\"\"Set [`EXAC2`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::EXAC2, val) = value.Vr_lim = val\n\"\"\"Set [`EXAC2`](@ref) `Te`.\"\"\"\nset_Te!(value::EXAC2, val) = value.Te = val\n\"\"\"Set [`EXAC2`](@ref) `Kl`.\"\"\"\nset_Kl!(value::EXAC2, val) = value.Kl = val\n\"\"\"Set [`EXAC2`](@ref) `Kh`.\"\"\"\nset_Kh!(value::EXAC2, val) = value.Kh = val\n\"\"\"Set [`EXAC2`](@ref) `Kf`.\"\"\"\nset_Kf!(value::EXAC2, val) = value.Kf = val\n\"\"\"Set [`EXAC2`](@ref) `Tf`.\"\"\"\nset_Tf!(value::EXAC2, val) = value.Tf = val\n\"\"\"Set [`EXAC2`](@ref) `Kc`.\"\"\"\nset_Kc!(value::EXAC2, val) = value.Kc = val\n\"\"\"Set [`EXAC2`](@ref) `Kd`.\"\"\"\nset_Kd!(value::EXAC2, val) = value.Kd = val\n\"\"\"Set [`EXAC2`](@ref) `Ke`.\"\"\"\nset_Ke!(value::EXAC2, val) = value.Ke = val\n\"\"\"Set [`EXAC2`](@ref) `V_lr`.\"\"\"\nset_V_lr!(value::EXAC2, val) = value.V_lr = val\n\"\"\"Set [`EXAC2`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::EXAC2, val) = value.E_sat = val\n\"\"\"Set [`EXAC2`](@ref) `Se`.\"\"\"\nset_Se!(value::EXAC2, val) = value.Se = val\n\"\"\"Set [`EXAC2`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EXAC2, val) = value.V_ref = val\n\"\"\"Set [`EXAC2`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::EXAC2, val) = value.saturation_coeffs = val\n\"\"\"Set [`EXAC2`](@ref) `ext`.\"\"\"\nset_ext!(value::EXAC2, val) = value.ext = val\n\"\"\"Set [`EXAC2`](@ref) `states_types`.\"\"\"\nset_states_types!(value::EXAC2, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/EXPIC1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EXPIC1 <: AVR\n        Tr::Float64\n        Ka::Float64\n        Ta::Float64\n        Va_lim::MinMax\n        Ta_2::Float64\n        Ta_3::Float64\n        Ta_4::Float64\n        Vr_lim::MinMax\n        Kf::Float64\n        Tf_1::Float64\n        Tf_2::Float64\n        Efd_lim::MinMax\n        Ke::Float64\n        Te::Float64\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        Kp::Float64\n        Ki::Float64\n        Kc::Float64\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nGeneric Proportional/Integral Excitation System\n\n# Arguments\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, 0.5)`\n- `Ka::Float64`: Voltage regulator gain, validation range: `(1, 500)`\n- `Ta::Float64`: Voltage regulator time constant in s, validation range: `(0, 10)`\n- `Va_lim::MinMax`: Limits for pi controler `(Vr_min, Vr_max)`\n- `Ta_2::Float64`: Voltage regulator time constant in s, validation range: `(0, nothing)`\n- `Ta_3::Float64`: Voltage regulator time constant in s, validation range: `(0, nothing)`\n- `Ta_4::Float64`: Voltage regulator time constant in s, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (regulator output) (Vi_min, Vi_max)\n- `Kf::Float64`: Rate feedback gain, validation range: `(0, 0.3)`\n- `Tf_1::Float64`: Rate Feedback time constant in s, validation range: `(eps(), 15)`\n- `Tf_2::Float64`: Rate Feedback time constant in s, validation range: `(0, 5)`\n- `Efd_lim::MinMax`: Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\n- `Ke::Float64`: Exciter constant, validation range: `(0, 1)`\n- `Te::Float64`: Exciter time constant, validation range: `(0, 2)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `Kp::Float64`: Potential source gain, validation range: `(0, 5)`\n- `Ki::Float64`: current source gain, validation range: `(0, 1.1)`\n- `Kc::Float64`: Exciter regulation factor, validation range: `(0, 2)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: First Lead-lag state,\n\tVr2: Second regulator lead-lag state,\n\tVr2: Third regulator lead-lag state \n\tVf: Exciter output \n\tVr3: First feedback integrator,\n\tVr4: second feedback integrator\n- `n_states::Int`: (**Do not modify.**) EXPIC1 has 6 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) EXPIC has 6 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EXPIC1 <: AVR\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Voltage regulator gain\"\n    Ka::Float64\n    \"Voltage regulator time constant in s\"\n    Ta::Float64\n    \"Limits for pi controler `(Vr_min, Vr_max)`\"\n    Va_lim::MinMax\n    \"Voltage regulator time constant in s\"\n    Ta_2::Float64\n    \"Voltage regulator time constant in s\"\n    Ta_3::Float64\n    \"Voltage regulator time constant in s\"\n    Ta_4::Float64\n    \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Rate feedback gain\"\n    Kf::Float64\n    \"Rate Feedback time constant in s\"\n    Tf_1::Float64\n    \"Rate Feedback time constant in s\"\n    Tf_2::Float64\n    \"Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\"\n    Efd_lim::MinMax\n    \"Exciter constant\"\n    Ke::Float64\n    \"Exciter time constant\"\n    Te::Float64\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Potential source gain\"\n    Kp::Float64\n    \"current source gain\"\n    Ki::Float64\n    \"Exciter regulation factor\"\n    Kc::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tVr1: First Lead-lag state,\n\tVr2: Second regulator lead-lag state,\n\tVr2: Third regulator lead-lag state \n\tVf: Exciter output \n\tVr3: First feedback integrator,\n\tVr4: second feedback integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) EXPIC1 has 6 states\"\n    n_states::Int\n    \"(**Do not modify.**) EXPIC has 6 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EXPIC1(Tr, Ka, Ta, Va_lim, Ta_2, Ta_3, Ta_4, Vr_lim, Kf, Tf_1, Tf_2, Efd_lim, Ke, Te, E_sat, Se, Kp, Ki, Kc, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    EXPIC1(Tr, Ka, Ta, Va_lim, Ta_2, Ta_3, Ta_4, Vr_lim, Kf, Tf_1, Tf_2, Efd_lim, Ke, Te, E_sat, Se, Kp, Ki, Kc, V_ref, saturation_coeffs, ext, [:Vm, :Vr1, :Vr2, :Vf, :Vr3, :Vr4], 6, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction EXPIC1(; Tr, Ka, Ta, Va_lim, Ta_2, Ta_3, Ta_4, Vr_lim, Kf, Tf_1, Tf_2, Efd_lim, Ke, Te, E_sat, Se, Kp, Ki, Kc, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vm, :Vr1, :Vr2, :Vf, :Vr3, :Vr4], n_states=6, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    EXPIC1(Tr, Ka, Ta, Va_lim, Ta_2, Ta_3, Ta_4, Vr_lim, Kf, Tf_1, Tf_2, Efd_lim, Ke, Te, E_sat, Se, Kp, Ki, Kc, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EXPIC1(::Nothing)\n    EXPIC1(;\n        Tr=0,\n        Ka=0,\n        Ta=0,\n        Va_lim=(min=0.0, max=0.0),\n        Ta_2=0,\n        Ta_3=0,\n        Ta_4=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Kf=0,\n        Tf_1=0,\n        Tf_2=0,\n        Efd_lim=(min=0.0, max=0.0),\n        Ke=0,\n        Te=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        Kp=0,\n        Ki=0,\n        Kc=0,\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EXPIC1`](@ref) `Tr`.\"\"\"\nget_Tr(value::EXPIC1) = value.Tr\n\"\"\"Get [`EXPIC1`](@ref) `Ka`.\"\"\"\nget_Ka(value::EXPIC1) = value.Ka\n\"\"\"Get [`EXPIC1`](@ref) `Ta`.\"\"\"\nget_Ta(value::EXPIC1) = value.Ta\n\"\"\"Get [`EXPIC1`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::EXPIC1) = value.Va_lim\n\"\"\"Get [`EXPIC1`](@ref) `Ta_2`.\"\"\"\nget_Ta_2(value::EXPIC1) = value.Ta_2\n\"\"\"Get [`EXPIC1`](@ref) `Ta_3`.\"\"\"\nget_Ta_3(value::EXPIC1) = value.Ta_3\n\"\"\"Get [`EXPIC1`](@ref) `Ta_4`.\"\"\"\nget_Ta_4(value::EXPIC1) = value.Ta_4\n\"\"\"Get [`EXPIC1`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::EXPIC1) = value.Vr_lim\n\"\"\"Get [`EXPIC1`](@ref) `Kf`.\"\"\"\nget_Kf(value::EXPIC1) = value.Kf\n\"\"\"Get [`EXPIC1`](@ref) `Tf_1`.\"\"\"\nget_Tf_1(value::EXPIC1) = value.Tf_1\n\"\"\"Get [`EXPIC1`](@ref) `Tf_2`.\"\"\"\nget_Tf_2(value::EXPIC1) = value.Tf_2\n\"\"\"Get [`EXPIC1`](@ref) `Efd_lim`.\"\"\"\nget_Efd_lim(value::EXPIC1) = value.Efd_lim\n\"\"\"Get [`EXPIC1`](@ref) `Ke`.\"\"\"\nget_Ke(value::EXPIC1) = value.Ke\n\"\"\"Get [`EXPIC1`](@ref) `Te`.\"\"\"\nget_Te(value::EXPIC1) = value.Te\n\"\"\"Get [`EXPIC1`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::EXPIC1) = value.E_sat\n\"\"\"Get [`EXPIC1`](@ref) `Se`.\"\"\"\nget_Se(value::EXPIC1) = value.Se\n\"\"\"Get [`EXPIC1`](@ref) `Kp`.\"\"\"\nget_Kp(value::EXPIC1) = value.Kp\n\"\"\"Get [`EXPIC1`](@ref) `Ki`.\"\"\"\nget_Ki(value::EXPIC1) = value.Ki\n\"\"\"Get [`EXPIC1`](@ref) `Kc`.\"\"\"\nget_Kc(value::EXPIC1) = value.Kc\n\"\"\"Get [`EXPIC1`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EXPIC1) = value.V_ref\n\"\"\"Get [`EXPIC1`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::EXPIC1) = value.saturation_coeffs\n\"\"\"Get [`EXPIC1`](@ref) `ext`.\"\"\"\nget_ext(value::EXPIC1) = value.ext\n\"\"\"Get [`EXPIC1`](@ref) `states`.\"\"\"\nget_states(value::EXPIC1) = value.states\n\"\"\"Get [`EXPIC1`](@ref) `n_states`.\"\"\"\nget_n_states(value::EXPIC1) = value.n_states\n\"\"\"Get [`EXPIC1`](@ref) `states_types`.\"\"\"\nget_states_types(value::EXPIC1) = value.states_types\n\"\"\"Get [`EXPIC1`](@ref) `internal`.\"\"\"\nget_internal(value::EXPIC1) = value.internal\n\n\"\"\"Set [`EXPIC1`](@ref) `Tr`.\"\"\"\nset_Tr!(value::EXPIC1, val) = value.Tr = val\n\"\"\"Set [`EXPIC1`](@ref) `Ka`.\"\"\"\nset_Ka!(value::EXPIC1, val) = value.Ka = val\n\"\"\"Set [`EXPIC1`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EXPIC1, val) = value.Ta = val\n\"\"\"Set [`EXPIC1`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::EXPIC1, val) = value.Va_lim = val\n\"\"\"Set [`EXPIC1`](@ref) `Ta_2`.\"\"\"\nset_Ta_2!(value::EXPIC1, val) = value.Ta_2 = val\n\"\"\"Set [`EXPIC1`](@ref) `Ta_3`.\"\"\"\nset_Ta_3!(value::EXPIC1, val) = value.Ta_3 = val\n\"\"\"Set [`EXPIC1`](@ref) `Ta_4`.\"\"\"\nset_Ta_4!(value::EXPIC1, val) = value.Ta_4 = val\n\"\"\"Set [`EXPIC1`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::EXPIC1, val) = value.Vr_lim = val\n\"\"\"Set [`EXPIC1`](@ref) `Kf`.\"\"\"\nset_Kf!(value::EXPIC1, val) = value.Kf = val\n\"\"\"Set [`EXPIC1`](@ref) `Tf_1`.\"\"\"\nset_Tf_1!(value::EXPIC1, val) = value.Tf_1 = val\n\"\"\"Set [`EXPIC1`](@ref) `Tf_2`.\"\"\"\nset_Tf_2!(value::EXPIC1, val) = value.Tf_2 = val\n\"\"\"Set [`EXPIC1`](@ref) `Efd_lim`.\"\"\"\nset_Efd_lim!(value::EXPIC1, val) = value.Efd_lim = val\n\"\"\"Set [`EXPIC1`](@ref) `Ke`.\"\"\"\nset_Ke!(value::EXPIC1, val) = value.Ke = val\n\"\"\"Set [`EXPIC1`](@ref) `Te`.\"\"\"\nset_Te!(value::EXPIC1, val) = value.Te = val\n\"\"\"Set [`EXPIC1`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::EXPIC1, val) = value.E_sat = val\n\"\"\"Set [`EXPIC1`](@ref) `Se`.\"\"\"\nset_Se!(value::EXPIC1, val) = value.Se = val\n\"\"\"Set [`EXPIC1`](@ref) `Kp`.\"\"\"\nset_Kp!(value::EXPIC1, val) = value.Kp = val\n\"\"\"Set [`EXPIC1`](@ref) `Ki`.\"\"\"\nset_Ki!(value::EXPIC1, val) = value.Ki = val\n\"\"\"Set [`EXPIC1`](@ref) `Kc`.\"\"\"\nset_Kc!(value::EXPIC1, val) = value.Kc = val\n\"\"\"Set [`EXPIC1`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EXPIC1, val) = value.V_ref = val\n\"\"\"Set [`EXPIC1`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::EXPIC1, val) = value.saturation_coeffs = val\n\"\"\"Set [`EXPIC1`](@ref) `ext`.\"\"\"\nset_ext!(value::EXPIC1, val) = value.ext = val\n\"\"\"Set [`EXPIC1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::EXPIC1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/EXST1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EXST1 <: AVR\n        Tr::Float64\n        Vi_lim::MinMax\n        Tc::Float64\n        Tb::Float64\n        Ka::Float64\n        Ta::Float64\n        Vr_lim::MinMax\n        Kc::Float64\n        Kf::Float64\n        Tf::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE Type ST1 Excitation System (PTI version)\n\n# Arguments\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, nothing)`\n- `Vi_lim::MinMax`: Voltage input limits (Vi_min, Vi_max)\n- `Tc::Float64`: Numerator lead-lag (lead) time constant in s, validation range: `(0, nothing)`\n- `Tb::Float64`: Denominator lead-lag (lag) time constant in s, validation range: `(0, nothing)`\n- `Ka::Float64`: Amplifier Gain, validation range: `(0, nothing)`\n- `Ta::Float64`: Amplifier Time Constant in s, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (regulator output) (Vr_min, Vr_max)\n- `Kc::Float64`: Current field constant limiter multiplier, validation range: `(0, nothing)`\n- `Kf::Float64`: Excitation control system stabilizer gain, validation range: `(eps(), 0.3)`\n- `Tf::Float64`: Excitation control system stabilizer time constant, validation range: `(eps(), nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed Terminal Voltage,\n\tVrll: Lead-Lag state,\n\tVr: Regulator Output, \n\tVfb: Feedback state\n- `n_states::Int`: (**Do not modify.**) The EXST1 has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EXST1 <: AVR\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Voltage input limits (Vi_min, Vi_max)\"\n    Vi_lim::MinMax\n    \"Numerator lead-lag (lead) time constant in s\"\n    Tc::Float64\n    \"Denominator lead-lag (lag) time constant in s\"\n    Tb::Float64\n    \"Amplifier Gain\"\n    Ka::Float64\n    \"Amplifier Time Constant in s\"\n    Ta::Float64\n    \"Voltage regulator limits (regulator output) (Vr_min, Vr_max)\"\n    Vr_lim::MinMax\n    \"Current field constant limiter multiplier\"\n    Kc::Float64\n    \"Excitation control system stabilizer gain\"\n    Kf::Float64\n    \"Excitation control system stabilizer time constant\"\n    Tf::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed Terminal Voltage,\n\tVrll: Lead-Lag state,\n\tVr: Regulator Output, \n\tVfb: Feedback state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The EXST1 has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EXST1(Tr, Vi_lim, Tc, Tb, Ka, Ta, Vr_lim, Kc, Kf, Tf, V_ref=1.0, ext=Dict{String, Any}(), )\n    EXST1(Tr, Vi_lim, Tc, Tb, Ka, Ta, Vr_lim, Kc, Kf, Tf, V_ref, ext, [:Vm, :Vrll, :Vr, :Vfb], 4, InfrastructureSystemsInternal(), )\nend\n\nfunction EXST1(; Tr, Vi_lim, Tc, Tb, Ka, Ta, Vr_lim, Kc, Kf, Tf, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vm, :Vrll, :Vr, :Vfb], n_states=4, internal=InfrastructureSystemsInternal(), )\n    EXST1(Tr, Vi_lim, Tc, Tb, Ka, Ta, Vr_lim, Kc, Kf, Tf, V_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EXST1(::Nothing)\n    EXST1(;\n        Tr=0,\n        Vi_lim=(min=0.0, max=0.0),\n        Tc=0,\n        Tb=0,\n        Ka=0,\n        Ta=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Kc=0,\n        Kf=0,\n        Tf=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EXST1`](@ref) `Tr`.\"\"\"\nget_Tr(value::EXST1) = value.Tr\n\"\"\"Get [`EXST1`](@ref) `Vi_lim`.\"\"\"\nget_Vi_lim(value::EXST1) = value.Vi_lim\n\"\"\"Get [`EXST1`](@ref) `Tc`.\"\"\"\nget_Tc(value::EXST1) = value.Tc\n\"\"\"Get [`EXST1`](@ref) `Tb`.\"\"\"\nget_Tb(value::EXST1) = value.Tb\n\"\"\"Get [`EXST1`](@ref) `Ka`.\"\"\"\nget_Ka(value::EXST1) = value.Ka\n\"\"\"Get [`EXST1`](@ref) `Ta`.\"\"\"\nget_Ta(value::EXST1) = value.Ta\n\"\"\"Get [`EXST1`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::EXST1) = value.Vr_lim\n\"\"\"Get [`EXST1`](@ref) `Kc`.\"\"\"\nget_Kc(value::EXST1) = value.Kc\n\"\"\"Get [`EXST1`](@ref) `Kf`.\"\"\"\nget_Kf(value::EXST1) = value.Kf\n\"\"\"Get [`EXST1`](@ref) `Tf`.\"\"\"\nget_Tf(value::EXST1) = value.Tf\n\"\"\"Get [`EXST1`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::EXST1) = value.V_ref\n\"\"\"Get [`EXST1`](@ref) `ext`.\"\"\"\nget_ext(value::EXST1) = value.ext\n\"\"\"Get [`EXST1`](@ref) `states`.\"\"\"\nget_states(value::EXST1) = value.states\n\"\"\"Get [`EXST1`](@ref) `n_states`.\"\"\"\nget_n_states(value::EXST1) = value.n_states\n\"\"\"Get [`EXST1`](@ref) `internal`.\"\"\"\nget_internal(value::EXST1) = value.internal\n\n\"\"\"Set [`EXST1`](@ref) `Tr`.\"\"\"\nset_Tr!(value::EXST1, val) = value.Tr = val\n\"\"\"Set [`EXST1`](@ref) `Vi_lim`.\"\"\"\nset_Vi_lim!(value::EXST1, val) = value.Vi_lim = val\n\"\"\"Set [`EXST1`](@ref) `Tc`.\"\"\"\nset_Tc!(value::EXST1, val) = value.Tc = val\n\"\"\"Set [`EXST1`](@ref) `Tb`.\"\"\"\nset_Tb!(value::EXST1, val) = value.Tb = val\n\"\"\"Set [`EXST1`](@ref) `Ka`.\"\"\"\nset_Ka!(value::EXST1, val) = value.Ka = val\n\"\"\"Set [`EXST1`](@ref) `Ta`.\"\"\"\nset_Ta!(value::EXST1, val) = value.Ta = val\n\"\"\"Set [`EXST1`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::EXST1, val) = value.Vr_lim = val\n\"\"\"Set [`EXST1`](@ref) `Kc`.\"\"\"\nset_Kc!(value::EXST1, val) = value.Kc = val\n\"\"\"Set [`EXST1`](@ref) `Kf`.\"\"\"\nset_Kf!(value::EXST1, val) = value.Kf = val\n\"\"\"Set [`EXST1`](@ref) `Tf`.\"\"\"\nset_Tf!(value::EXST1, val) = value.Tf = val\n\"\"\"Set [`EXST1`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::EXST1, val) = value.V_ref = val\n\"\"\"Set [`EXST1`](@ref) `ext`.\"\"\"\nset_ext!(value::EXST1, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/EnergyReservoirStorage.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct EnergyReservoirStorage <: Storage\n        name::String\n        available::Bool\n        bus::ACBus\n        prime_mover_type::PrimeMovers\n        storage_technology_type::StorageTech\n        storage_capacity::Float64\n        storage_level_limits::MinMax\n        initial_storage_capacity_level::Float64\n        rating::Float64\n        active_power::Float64\n        input_active_power_limits::MinMax\n        output_active_power_limits::MinMax\n        efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}\n        reactive_power::Float64\n        reactive_power_limits::Union{Nothing, MinMax}\n        base_power::Float64\n        operation_cost::Union{StorageCost, MarketBidCost}\n        conversion_factor::Float64\n        storage_target::Float64\n        cycle_limits::Int\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAn energy storage device, modeled as a generic energy reservoir.\n\nThis is suitable for modeling storage charging and discharging with average efficiency losses, ignoring the physical dynamics of the storage unit. A variety of energy storage types and chemistries can be modeled with this approach. For pumped hydro storage, alternatively see [`HydroPumpTurbine`](@ref) and [`HydroReservoir`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `prime_mover_type::PrimeMovers`: Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `storage_technology_type::StorageTech`: Storage Technology Complementary to EIA 923. Options are listed [here](@ref storagetech_list)\n- `storage_capacity::Float64`: Maximum storage capacity (can be in units of, e.g., MWh for batteries or liters for hydrogen). When in MWh, this value divided by base_power (MVA) gives an approximate duration in hours, assuming unity power factor. For understanding this relationship, see [per unitization](@ref per_unit), validation range: `(0, nothing)`\n- `storage_level_limits::MinMax`: Minimum and maximum allowable storage levels [0, 1], which can be used to model derates or other restrictions, such as state-of-charge restrictions on battery cycling, validation range: `(0, 1)`\n- `initial_storage_capacity_level::Float64`: Initial storage capacity level as a ratio [0, 1.0] of `storage_capacity`, validation range: `(0, 1)`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `input_active_power_limits::MinMax`: Minimum and maximum limits on the input active power (i.e., charging), validation range: `(0, nothing)`\n- `output_active_power_limits::MinMax`: Minimum and maximum limits on the output active power (i.e., discharging), validation range: `(0, nothing)`\n- `efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}`: Average efficiency [0, 1] `in` (charging/filling) and `out` (discharging/consuming) of the storage system, validation range: `(0, 1)`\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `operation_cost::Union{StorageCost, MarketBidCost}`: (default: `StorageCost(nothing)`) [`OperationalCost`](@ref) of storage\n- `conversion_factor::Float64`: (default: `1.0`) Conversion factor of `storage_capacity` to MWh, if different than 1.0. For example, X MWh/liter hydrogen\n- `storage_target::Float64`: (default: `0.0`) Storage target at the end of simulation as ratio of storage capacity\n- `cycle_limits::Int`: (default: `1e4`) Storage Maximum number of cycles per year\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct EnergyReservoirStorage <: Storage\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Storage Technology Complementary to EIA 923. Options are listed [here](@ref storagetech_list)\"\n    storage_technology_type::StorageTech\n    \"Maximum storage capacity (can be in units of, e.g., MWh for batteries or liters for hydrogen). When in MWh, this value divided by base_power (MVA) gives an approximate duration in hours, assuming unity power factor. For understanding this relationship, see [per unitization](@ref per_unit)\"\n    storage_capacity::Float64\n    \"Minimum and maximum allowable storage levels [0, 1], which can be used to model derates or other restrictions, such as state-of-charge restrictions on battery cycling\"\n    storage_level_limits::MinMax\n    \"Initial storage capacity level as a ratio [0, 1.0] of `storage_capacity`\"\n    initial_storage_capacity_level::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Minimum and maximum limits on the input active power (i.e., charging)\"\n    input_active_power_limits::MinMax\n    \"Minimum and maximum limits on the output active power (i.e., discharging)\"\n    output_active_power_limits::MinMax\n    \"Average efficiency [0, 1] `in` (charging/filling) and `out` (discharging/consuming) of the storage system\"\n    efficiency::NamedTuple{(:in, :out), Tuple{Float64, Float64}}\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"[`OperationalCost`](@ref) of storage\"\n    operation_cost::Union{StorageCost, MarketBidCost}\n    \"Conversion factor of `storage_capacity` to MWh, if different than 1.0. For example, X MWh/liter hydrogen\"\n    conversion_factor::Float64\n    \"Storage target at the end of simulation as ratio of storage capacity\"\n    storage_target::Float64\n    \"Storage Maximum number of cycles per year\"\n    cycle_limits::Int\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction EnergyReservoirStorage(name, available, bus, prime_mover_type, storage_technology_type, storage_capacity, storage_level_limits, initial_storage_capacity_level, rating, active_power, input_active_power_limits, output_active_power_limits, efficiency, reactive_power, reactive_power_limits, base_power, operation_cost=StorageCost(nothing), conversion_factor=1.0, storage_target=0.0, cycle_limits=1e4, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    EnergyReservoirStorage(name, available, bus, prime_mover_type, storage_technology_type, storage_capacity, storage_level_limits, initial_storage_capacity_level, rating, active_power, input_active_power_limits, output_active_power_limits, efficiency, reactive_power, reactive_power_limits, base_power, operation_cost, conversion_factor, storage_target, cycle_limits, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction EnergyReservoirStorage(; name, available, bus, prime_mover_type, storage_technology_type, storage_capacity, storage_level_limits, initial_storage_capacity_level, rating, active_power, input_active_power_limits, output_active_power_limits, efficiency, reactive_power, reactive_power_limits, base_power, operation_cost=StorageCost(nothing), conversion_factor=1.0, storage_target=0.0, cycle_limits=1e4, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    EnergyReservoirStorage(name, available, bus, prime_mover_type, storage_technology_type, storage_capacity, storage_level_limits, initial_storage_capacity_level, rating, active_power, input_active_power_limits, output_active_power_limits, efficiency, reactive_power, reactive_power_limits, base_power, operation_cost, conversion_factor, storage_target, cycle_limits, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction EnergyReservoirStorage(::Nothing)\n    EnergyReservoirStorage(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        prime_mover_type=PrimeMovers.BA,\n        storage_technology_type=StorageTech.OTHER_CHEM,\n        storage_capacity=0.0,\n        storage_level_limits=(min=0.0, max=0.0),\n        initial_storage_capacity_level=0.0,\n        rating=0.0,\n        active_power=0.0,\n        input_active_power_limits=(min=0.0, max=0.0),\n        output_active_power_limits=(min=0.0, max=0.0),\n        efficiency=(in=0.0, out=0.0),\n        reactive_power=0.0,\n        reactive_power_limits=(min=0.0, max=0.0),\n        base_power=100.0,\n        operation_cost=StorageCost(nothing),\n        conversion_factor=0.0,\n        storage_target=0.0,\n        cycle_limits=0,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `name`.\"\"\"\nget_name(value::EnergyReservoirStorage) = value.name\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `available`.\"\"\"\nget_available(value::EnergyReservoirStorage) = value.available\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `bus`.\"\"\"\nget_bus(value::EnergyReservoirStorage) = value.bus\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::EnergyReservoirStorage) = value.prime_mover_type\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `storage_technology_type`.\"\"\"\nget_storage_technology_type(value::EnergyReservoirStorage) = value.storage_technology_type\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `storage_capacity`.\"\"\"\nget_storage_capacity(value::EnergyReservoirStorage) = get_value(value, Val(:storage_capacity), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `storage_level_limits`.\"\"\"\nget_storage_level_limits(value::EnergyReservoirStorage) = value.storage_level_limits\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `initial_storage_capacity_level`.\"\"\"\nget_initial_storage_capacity_level(value::EnergyReservoirStorage) = value.initial_storage_capacity_level\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `rating`.\"\"\"\nget_rating(value::EnergyReservoirStorage) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `active_power`.\"\"\"\nget_active_power(value::EnergyReservoirStorage) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `input_active_power_limits`.\"\"\"\nget_input_active_power_limits(value::EnergyReservoirStorage) = get_value(value, Val(:input_active_power_limits), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `output_active_power_limits`.\"\"\"\nget_output_active_power_limits(value::EnergyReservoirStorage) = get_value(value, Val(:output_active_power_limits), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `efficiency`.\"\"\"\nget_efficiency(value::EnergyReservoirStorage) = value.efficiency\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::EnergyReservoirStorage) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::EnergyReservoirStorage) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `base_power`.\"\"\"\nget_base_power(value::EnergyReservoirStorage) = value.base_power\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::EnergyReservoirStorage) = value.operation_cost\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `conversion_factor`.\"\"\"\nget_conversion_factor(value::EnergyReservoirStorage) = value.conversion_factor\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `storage_target`.\"\"\"\nget_storage_target(value::EnergyReservoirStorage) = value.storage_target\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `cycle_limits`.\"\"\"\nget_cycle_limits(value::EnergyReservoirStorage) = value.cycle_limits\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `services`.\"\"\"\nget_services(value::EnergyReservoirStorage) = value.services\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::EnergyReservoirStorage) = value.dynamic_injector\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `ext`.\"\"\"\nget_ext(value::EnergyReservoirStorage) = value.ext\n\"\"\"Get [`EnergyReservoirStorage`](@ref) `internal`.\"\"\"\nget_internal(value::EnergyReservoirStorage) = value.internal\n\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `available`.\"\"\"\nset_available!(value::EnergyReservoirStorage, val) = value.available = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `bus`.\"\"\"\nset_bus!(value::EnergyReservoirStorage, val) = value.bus = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::EnergyReservoirStorage, val) = value.prime_mover_type = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `storage_technology_type`.\"\"\"\nset_storage_technology_type!(value::EnergyReservoirStorage, val) = value.storage_technology_type = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `storage_capacity`.\"\"\"\nset_storage_capacity!(value::EnergyReservoirStorage, val) = value.storage_capacity = set_value(value, Val(:storage_capacity), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `storage_level_limits`.\"\"\"\nset_storage_level_limits!(value::EnergyReservoirStorage, val) = value.storage_level_limits = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `initial_storage_capacity_level`.\"\"\"\nset_initial_storage_capacity_level!(value::EnergyReservoirStorage, val) = value.initial_storage_capacity_level = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `rating`.\"\"\"\nset_rating!(value::EnergyReservoirStorage, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `active_power`.\"\"\"\nset_active_power!(value::EnergyReservoirStorage, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `input_active_power_limits`.\"\"\"\nset_input_active_power_limits!(value::EnergyReservoirStorage, val) = value.input_active_power_limits = set_value(value, Val(:input_active_power_limits), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `output_active_power_limits`.\"\"\"\nset_output_active_power_limits!(value::EnergyReservoirStorage, val) = value.output_active_power_limits = set_value(value, Val(:output_active_power_limits), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `efficiency`.\"\"\"\nset_efficiency!(value::EnergyReservoirStorage, val) = value.efficiency = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::EnergyReservoirStorage, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::EnergyReservoirStorage, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `base_power`.\"\"\"\nset_base_power!(value::EnergyReservoirStorage, val) = value.base_power = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::EnergyReservoirStorage, val) = value.operation_cost = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `conversion_factor`.\"\"\"\nset_conversion_factor!(value::EnergyReservoirStorage, val) = value.conversion_factor = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `storage_target`.\"\"\"\nset_storage_target!(value::EnergyReservoirStorage, val) = value.storage_target = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `cycle_limits`.\"\"\"\nset_cycle_limits!(value::EnergyReservoirStorage, val) = value.cycle_limits = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `services`.\"\"\"\nset_services!(value::EnergyReservoirStorage, val) = value.services = val\n\"\"\"Set [`EnergyReservoirStorage`](@ref) `ext`.\"\"\"\nset_ext!(value::EnergyReservoirStorage, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ExponentialLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ExponentialLoad <: StaticLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        α::Float64\n        β::Float64\n        base_power::Float64\n        max_active_power::Float64\n        max_reactive_power::Float64\n        conformity::LoadConformity\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\n\nAn `ExponentialLoad` models active power as P = P0 * V^α and reactive power as Q = Q0 * V^β, where the exponents α and β select govern the voltage dependency. For an alternative three-part formulation of the ZIP model, see [`StandardLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Active power coefficient, P0 (MW)\n- `reactive_power::Float64`: Reactive power coefficient, Q0 (MVAR)\n- `α::Float64`: Exponent relating voltage dependency for active power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only, validation range: `(0, nothing)`\n- `β::Float64`: Exponent relating voltage dependency for reactive power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `max_active_power::Float64`: Maximum active power (MW) that this load can demand\n- `max_reactive_power::Float64`: Maximum reactive power (MVAR) that this load can demand\n- `conformity::LoadConformity`: (default: `LoadConformity.UNDEFINED`) Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ExponentialLoad <: StaticLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Active power coefficient, P0 (MW)\"\n    active_power::Float64\n    \"Reactive power coefficient, Q0 (MVAR)\"\n    reactive_power::Float64\n    \"Exponent relating voltage dependency for active power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only\"\n    α::Float64\n    \"Exponent relating voltage dependency for reactive power. 0 = constant power only, 1 = constant current only, and 2 = constant impedance only\"\n    β::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Maximum active power (MW) that this load can demand\"\n    max_active_power::Float64\n    \"Maximum reactive power (MVAR) that this load can demand\"\n    max_reactive_power::Float64\n    \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\"\n    conformity::LoadConformity\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ExponentialLoad(name, available, bus, active_power, reactive_power, α, β, base_power, max_active_power, max_reactive_power, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    ExponentialLoad(name, available, bus, active_power, reactive_power, α, β, base_power, max_active_power, max_reactive_power, conformity, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ExponentialLoad(; name, available, bus, active_power, reactive_power, α, β, base_power, max_active_power, max_reactive_power, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ExponentialLoad(name, available, bus, active_power, reactive_power, α, β, base_power, max_active_power, max_reactive_power, conformity, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ExponentialLoad(::Nothing)\n    ExponentialLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        α=0.0,\n        β=0.0,\n        base_power=100.0,\n        max_active_power=0.0,\n        max_reactive_power=0.0,\n        conformity=LoadConformity.UNDEFINED,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ExponentialLoad`](@ref) `name`.\"\"\"\nget_name(value::ExponentialLoad) = value.name\n\"\"\"Get [`ExponentialLoad`](@ref) `available`.\"\"\"\nget_available(value::ExponentialLoad) = value.available\n\"\"\"Get [`ExponentialLoad`](@ref) `bus`.\"\"\"\nget_bus(value::ExponentialLoad) = value.bus\n\"\"\"Get [`ExponentialLoad`](@ref) `active_power`.\"\"\"\nget_active_power(value::ExponentialLoad) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`ExponentialLoad`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::ExponentialLoad) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`ExponentialLoad`](@ref) `α`.\"\"\"\nget_α(value::ExponentialLoad) = value.α\n\"\"\"Get [`ExponentialLoad`](@ref) `β`.\"\"\"\nget_β(value::ExponentialLoad) = value.β\n\"\"\"Get [`ExponentialLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::ExponentialLoad) = value.base_power\n\"\"\"Get [`ExponentialLoad`](@ref) `max_active_power`.\"\"\"\nget_max_active_power(value::ExponentialLoad) = get_value(value, Val(:max_active_power), Val(:mva))\n\"\"\"Get [`ExponentialLoad`](@ref) `max_reactive_power`.\"\"\"\nget_max_reactive_power(value::ExponentialLoad) = get_value(value, Val(:max_reactive_power), Val(:mva))\n\"\"\"Get [`ExponentialLoad`](@ref) `conformity`.\"\"\"\nget_conformity(value::ExponentialLoad) = value.conformity\n\"\"\"Get [`ExponentialLoad`](@ref) `services`.\"\"\"\nget_services(value::ExponentialLoad) = value.services\n\"\"\"Get [`ExponentialLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::ExponentialLoad) = value.dynamic_injector\n\"\"\"Get [`ExponentialLoad`](@ref) `ext`.\"\"\"\nget_ext(value::ExponentialLoad) = value.ext\n\"\"\"Get [`ExponentialLoad`](@ref) `internal`.\"\"\"\nget_internal(value::ExponentialLoad) = value.internal\n\n\"\"\"Set [`ExponentialLoad`](@ref) `available`.\"\"\"\nset_available!(value::ExponentialLoad, val) = value.available = val\n\"\"\"Set [`ExponentialLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::ExponentialLoad, val) = value.bus = val\n\"\"\"Set [`ExponentialLoad`](@ref) `active_power`.\"\"\"\nset_active_power!(value::ExponentialLoad, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`ExponentialLoad`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::ExponentialLoad, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`ExponentialLoad`](@ref) `α`.\"\"\"\nset_α!(value::ExponentialLoad, val) = value.α = val\n\"\"\"Set [`ExponentialLoad`](@ref) `β`.\"\"\"\nset_β!(value::ExponentialLoad, val) = value.β = val\n\"\"\"Set [`ExponentialLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::ExponentialLoad, val) = value.base_power = val\n\"\"\"Set [`ExponentialLoad`](@ref) `max_active_power`.\"\"\"\nset_max_active_power!(value::ExponentialLoad, val) = value.max_active_power = set_value(value, Val(:max_active_power), val, Val(:mva))\n\"\"\"Set [`ExponentialLoad`](@ref) `max_reactive_power`.\"\"\"\nset_max_reactive_power!(value::ExponentialLoad, val) = value.max_reactive_power = set_value(value, Val(:max_reactive_power), val, Val(:mva))\n\"\"\"Set [`ExponentialLoad`](@ref) `conformity`.\"\"\"\nset_conformity!(value::ExponentialLoad, val) = value.conformity = val\n\"\"\"Set [`ExponentialLoad`](@ref) `services`.\"\"\"\nset_services!(value::ExponentialLoad, val) = value.services = val\n\"\"\"Set [`ExponentialLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::ExponentialLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FACTSControlDevice.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FACTSControlDevice <: StaticInjection\n        name::String\n        available::Bool\n        bus::ACBus\n        control_mode::Union{Nothing, FACTSOperationModes}\n        voltage_setpoint::Float64\n        max_shunt_current::Float64\n        reactive_power_required::Float64\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nFacts control devices.\n\nMost often used in AC power flow studies as a control of voltage and, active and reactive power.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Sending end bus number\n- `control_mode::Union{Nothing, FACTSOperationModes}`: Control mode. Used to describe the behavior of the control device. [Options are listed here.](@ref factsmodes_list)\n- `voltage_setpoint::Float64`: Voltage setpoint at the sending end bus, it has to be a [`PV`](@ref acbustypes_list) bus, in p.u. ([`SYSTEM_BASE`](@ref per_unit)).\n- `max_shunt_current::Float64`: Maximum shunt current at the sending end bus; entered in MVA at unity voltage.\n- `reactive_power_required::Float64`: Total MVAr required to hold voltage at sending bus, in %.\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) Corresponding dynamic injection model for FACTS control device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct FACTSControlDevice <: StaticInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Sending end bus number\"\n    bus::ACBus\n    \"Control mode. Used to describe the behavior of the control device. [Options are listed here.](@ref factsmodes_list)\"\n    control_mode::Union{Nothing, FACTSOperationModes}\n    \"Voltage setpoint at the sending end bus, it has to be a [`PV`](@ref acbustypes_list) bus, in p.u. ([`SYSTEM_BASE`](@ref per_unit)).\"\n    voltage_setpoint::Float64\n    \"Maximum shunt current at the sending end bus; entered in MVA at unity voltage.\"\n    max_shunt_current::Float64\n    \"Total MVAr required to hold voltage at sending bus, in %.\"\n    reactive_power_required::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"Corresponding dynamic injection model for FACTS control device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction FACTSControlDevice(name, available, bus, control_mode, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    FACTSControlDevice(name, available, bus, control_mode, services, dynamic_injector, ext, 1.0, 9999.0, 100.0, InfrastructureSystemsInternal(), )\nend\n\nfunction FACTSControlDevice(; name, available, bus, control_mode, voltage_setpoint=1.0, max_shunt_current=9999.0, reactive_power_required=100.0, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    FACTSControlDevice(name, available, bus, control_mode, voltage_setpoint, max_shunt_current, reactive_power_required, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FACTSControlDevice(::Nothing)\n    FACTSControlDevice(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        control_mode=nothing,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FACTSControlDevice`](@ref) `name`.\"\"\"\nget_name(value::FACTSControlDevice) = value.name\n\"\"\"Get [`FACTSControlDevice`](@ref) `available`.\"\"\"\nget_available(value::FACTSControlDevice) = value.available\n\"\"\"Get [`FACTSControlDevice`](@ref) `bus`.\"\"\"\nget_bus(value::FACTSControlDevice) = value.bus\n\"\"\"Get [`FACTSControlDevice`](@ref) `control_mode`.\"\"\"\nget_control_mode(value::FACTSControlDevice) = value.control_mode\n\"\"\"Get [`FACTSControlDevice`](@ref) `voltage_setpoint`.\"\"\"\nget_voltage_setpoint(value::FACTSControlDevice) = value.voltage_setpoint\n\"\"\"Get [`FACTSControlDevice`](@ref) `max_shunt_current`.\"\"\"\nget_max_shunt_current(value::FACTSControlDevice) = value.max_shunt_current\n\"\"\"Get [`FACTSControlDevice`](@ref) `reactive_power_required`.\"\"\"\nget_reactive_power_required(value::FACTSControlDevice) = value.reactive_power_required\n\"\"\"Get [`FACTSControlDevice`](@ref) `services`.\"\"\"\nget_services(value::FACTSControlDevice) = value.services\n\"\"\"Get [`FACTSControlDevice`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::FACTSControlDevice) = value.dynamic_injector\n\"\"\"Get [`FACTSControlDevice`](@ref) `ext`.\"\"\"\nget_ext(value::FACTSControlDevice) = value.ext\n\"\"\"Get [`FACTSControlDevice`](@ref) `internal`.\"\"\"\nget_internal(value::FACTSControlDevice) = value.internal\n\n\"\"\"Set [`FACTSControlDevice`](@ref) `available`.\"\"\"\nset_available!(value::FACTSControlDevice, val) = value.available = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `bus`.\"\"\"\nset_bus!(value::FACTSControlDevice, val) = value.bus = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `control_mode`.\"\"\"\nset_control_mode!(value::FACTSControlDevice, val) = value.control_mode = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `voltage_setpoint`.\"\"\"\nset_voltage_setpoint!(value::FACTSControlDevice, val) = value.voltage_setpoint = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `max_shunt_current`.\"\"\"\nset_max_shunt_current!(value::FACTSControlDevice, val) = value.max_shunt_current = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `reactive_power_required`.\"\"\"\nset_reactive_power_required!(value::FACTSControlDevice, val) = value.reactive_power_required = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `services`.\"\"\"\nset_services!(value::FACTSControlDevice, val) = value.services = val\n\"\"\"Set [`FACTSControlDevice`](@ref) `ext`.\"\"\"\nset_ext!(value::FACTSControlDevice, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FiveMassShaft.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FiveMassShaft <: Shaft\n        H::Float64\n        H_hp::Float64\n        H_ip::Float64\n        H_lp::Float64\n        H_ex::Float64\n        D::Float64\n        D_hp::Float64\n        D_ip::Float64\n        D_lp::Float64\n        D_ex::Float64\n        D_12::Float64\n        D_23::Float64\n        D_34::Float64\n        D_45::Float64\n        K_hp::Float64\n        K_ip::Float64\n        K_lp::Float64\n        K_ex::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 5 mass-spring shaft model.\n It contains a High-Pressure (HP) steam turbine, Intermediate-Pressure (IP)\n steam turbine, Low-Pressure (LP) steam turbine, the Rotor and an Exciter (EX) mover\n\n# Arguments\n- `H::Float64`: Rotor inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `H_hp::Float64`: High pressure turbine inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `H_ip::Float64`: Intermediate pressure turbine inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `H_lp::Float64`: Low pressure turbine inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `H_ex::Float64`:  Exciter inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `D::Float64`: Rotor natural damping in pu, validation range: `(0, nothing)`\n- `D_hp::Float64`: High pressure turbine natural damping in pu, validation range: `(0, nothing)`\n- `D_ip::Float64`: Intermediate pressure turbine natural damping in pu, validation range: `(0, nothing)`\n- `D_lp::Float64`: Low pressure turbine natural damping in pu, validation range: `(0, nothing)`\n- `D_ex::Float64`: Exciter natural damping in pu, validation range: `(0, nothing)`\n- `D_12::Float64`: High-Intermediate pressure turbine damping, validation range: `(0, nothing)`\n- `D_23::Float64`: Intermediate-Low pressure turbine damping, validation range: `(0, nothing)`\n- `D_34::Float64`: Low pressure turbine-Rotor damping, validation range: `(0, nothing)`\n- `D_45::Float64`: Rotor-Exciter damping, validation range: `(0, nothing)`\n- `K_hp::Float64`: High pressure turbine angle coefficient, validation range: `(0, nothing)`\n- `K_ip::Float64`: Intermediate pressure turbine angle coefficient, validation range: `(0, nothing)`\n- `K_lp::Float64`: Low pressure turbine angle coefficient, validation range: `(0, nothing)`\n- `K_ex::Float64`: Exciter angle coefficient, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tδ: rotor angle,\n\tω: rotor speed,\n\tδ_hp: rotor angle of high pressure turbine,\n\tω_hp: rotor speed of high pressure turbine,\n\tδ_ip: rotor angle of intermediate pressure turbine,\n\tω_ip: rotor speed of intermediate pressure turbine,\n\tδ_lp: rotor angle of low pressure turbine,\n\tω_lp: rotor speed of low pressure turbine,\n\tδ_ex: rotor angle of exciter,\n\tω_lp: rotor speed of exciter\n- `n_states::Int`: (**Do not modify.**) FiveMassShaft has 10 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct FiveMassShaft <: Shaft\n    \"Rotor inertia constant in MWs/MVA\"\n    H::Float64\n    \"High pressure turbine inertia constant in MWs/MVA\"\n    H_hp::Float64\n    \"Intermediate pressure turbine inertia constant in MWs/MVA\"\n    H_ip::Float64\n    \"Low pressure turbine inertia constant in MWs/MVA\"\n    H_lp::Float64\n    \" Exciter inertia constant in MWs/MVA\"\n    H_ex::Float64\n    \"Rotor natural damping in pu\"\n    D::Float64\n    \"High pressure turbine natural damping in pu\"\n    D_hp::Float64\n    \"Intermediate pressure turbine natural damping in pu\"\n    D_ip::Float64\n    \"Low pressure turbine natural damping in pu\"\n    D_lp::Float64\n    \"Exciter natural damping in pu\"\n    D_ex::Float64\n    \"High-Intermediate pressure turbine damping\"\n    D_12::Float64\n    \"Intermediate-Low pressure turbine damping\"\n    D_23::Float64\n    \"Low pressure turbine-Rotor damping\"\n    D_34::Float64\n    \"Rotor-Exciter damping\"\n    D_45::Float64\n    \"High pressure turbine angle coefficient\"\n    K_hp::Float64\n    \"Intermediate pressure turbine angle coefficient\"\n    K_ip::Float64\n    \"Low pressure turbine angle coefficient\"\n    K_lp::Float64\n    \"Exciter angle coefficient\"\n    K_ex::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tδ: rotor angle,\n\tω: rotor speed,\n\tδ_hp: rotor angle of high pressure turbine,\n\tω_hp: rotor speed of high pressure turbine,\n\tδ_ip: rotor angle of intermediate pressure turbine,\n\tω_ip: rotor speed of intermediate pressure turbine,\n\tδ_lp: rotor angle of low pressure turbine,\n\tω_lp: rotor speed of low pressure turbine,\n\tδ_ex: rotor angle of exciter,\n\tω_lp: rotor speed of exciter\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) FiveMassShaft has 10 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction FiveMassShaft(H, H_hp, H_ip, H_lp, H_ex, D, D_hp, D_ip, D_lp, D_ex, D_12, D_23, D_34, D_45, K_hp, K_ip, K_lp, K_ex, ext=Dict{String, Any}(), )\n    FiveMassShaft(H, H_hp, H_ip, H_lp, H_ex, D, D_hp, D_ip, D_lp, D_ex, D_12, D_23, D_34, D_45, K_hp, K_ip, K_lp, K_ex, ext, [:δ, :ω, :δ_hp, :ω_hp, :δ_ip, :ω_ip, :δ_lp, :ω_lp, :δ_ex, :ω_ex], 10, InfrastructureSystemsInternal(), )\nend\n\nfunction FiveMassShaft(; H, H_hp, H_ip, H_lp, H_ex, D, D_hp, D_ip, D_lp, D_ex, D_12, D_23, D_34, D_45, K_hp, K_ip, K_lp, K_ex, ext=Dict{String, Any}(), states=[:δ, :ω, :δ_hp, :ω_hp, :δ_ip, :ω_ip, :δ_lp, :ω_lp, :δ_ex, :ω_ex], n_states=10, internal=InfrastructureSystemsInternal(), )\n    FiveMassShaft(H, H_hp, H_ip, H_lp, H_ex, D, D_hp, D_ip, D_lp, D_ex, D_12, D_23, D_34, D_45, K_hp, K_ip, K_lp, K_ex, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FiveMassShaft(::Nothing)\n    FiveMassShaft(;\n        H=0,\n        H_hp=0,\n        H_ip=0,\n        H_lp=0,\n        H_ex=0,\n        D=0,\n        D_hp=0,\n        D_ip=0,\n        D_lp=0,\n        D_ex=0,\n        D_12=0,\n        D_23=0,\n        D_34=0,\n        D_45=0,\n        K_hp=0,\n        K_ip=0,\n        K_lp=0,\n        K_ex=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FiveMassShaft`](@ref) `H`.\"\"\"\nget_H(value::FiveMassShaft) = value.H\n\"\"\"Get [`FiveMassShaft`](@ref) `H_hp`.\"\"\"\nget_H_hp(value::FiveMassShaft) = value.H_hp\n\"\"\"Get [`FiveMassShaft`](@ref) `H_ip`.\"\"\"\nget_H_ip(value::FiveMassShaft) = value.H_ip\n\"\"\"Get [`FiveMassShaft`](@ref) `H_lp`.\"\"\"\nget_H_lp(value::FiveMassShaft) = value.H_lp\n\"\"\"Get [`FiveMassShaft`](@ref) `H_ex`.\"\"\"\nget_H_ex(value::FiveMassShaft) = value.H_ex\n\"\"\"Get [`FiveMassShaft`](@ref) `D`.\"\"\"\nget_D(value::FiveMassShaft) = value.D\n\"\"\"Get [`FiveMassShaft`](@ref) `D_hp`.\"\"\"\nget_D_hp(value::FiveMassShaft) = value.D_hp\n\"\"\"Get [`FiveMassShaft`](@ref) `D_ip`.\"\"\"\nget_D_ip(value::FiveMassShaft) = value.D_ip\n\"\"\"Get [`FiveMassShaft`](@ref) `D_lp`.\"\"\"\nget_D_lp(value::FiveMassShaft) = value.D_lp\n\"\"\"Get [`FiveMassShaft`](@ref) `D_ex`.\"\"\"\nget_D_ex(value::FiveMassShaft) = value.D_ex\n\"\"\"Get [`FiveMassShaft`](@ref) `D_12`.\"\"\"\nget_D_12(value::FiveMassShaft) = value.D_12\n\"\"\"Get [`FiveMassShaft`](@ref) `D_23`.\"\"\"\nget_D_23(value::FiveMassShaft) = value.D_23\n\"\"\"Get [`FiveMassShaft`](@ref) `D_34`.\"\"\"\nget_D_34(value::FiveMassShaft) = value.D_34\n\"\"\"Get [`FiveMassShaft`](@ref) `D_45`.\"\"\"\nget_D_45(value::FiveMassShaft) = value.D_45\n\"\"\"Get [`FiveMassShaft`](@ref) `K_hp`.\"\"\"\nget_K_hp(value::FiveMassShaft) = value.K_hp\n\"\"\"Get [`FiveMassShaft`](@ref) `K_ip`.\"\"\"\nget_K_ip(value::FiveMassShaft) = value.K_ip\n\"\"\"Get [`FiveMassShaft`](@ref) `K_lp`.\"\"\"\nget_K_lp(value::FiveMassShaft) = value.K_lp\n\"\"\"Get [`FiveMassShaft`](@ref) `K_ex`.\"\"\"\nget_K_ex(value::FiveMassShaft) = value.K_ex\n\"\"\"Get [`FiveMassShaft`](@ref) `ext`.\"\"\"\nget_ext(value::FiveMassShaft) = value.ext\n\"\"\"Get [`FiveMassShaft`](@ref) `states`.\"\"\"\nget_states(value::FiveMassShaft) = value.states\n\"\"\"Get [`FiveMassShaft`](@ref) `n_states`.\"\"\"\nget_n_states(value::FiveMassShaft) = value.n_states\n\"\"\"Get [`FiveMassShaft`](@ref) `internal`.\"\"\"\nget_internal(value::FiveMassShaft) = value.internal\n\n\"\"\"Set [`FiveMassShaft`](@ref) `H`.\"\"\"\nset_H!(value::FiveMassShaft, val) = value.H = val\n\"\"\"Set [`FiveMassShaft`](@ref) `H_hp`.\"\"\"\nset_H_hp!(value::FiveMassShaft, val) = value.H_hp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `H_ip`.\"\"\"\nset_H_ip!(value::FiveMassShaft, val) = value.H_ip = val\n\"\"\"Set [`FiveMassShaft`](@ref) `H_lp`.\"\"\"\nset_H_lp!(value::FiveMassShaft, val) = value.H_lp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `H_ex`.\"\"\"\nset_H_ex!(value::FiveMassShaft, val) = value.H_ex = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D`.\"\"\"\nset_D!(value::FiveMassShaft, val) = value.D = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_hp`.\"\"\"\nset_D_hp!(value::FiveMassShaft, val) = value.D_hp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_ip`.\"\"\"\nset_D_ip!(value::FiveMassShaft, val) = value.D_ip = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_lp`.\"\"\"\nset_D_lp!(value::FiveMassShaft, val) = value.D_lp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_ex`.\"\"\"\nset_D_ex!(value::FiveMassShaft, val) = value.D_ex = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_12`.\"\"\"\nset_D_12!(value::FiveMassShaft, val) = value.D_12 = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_23`.\"\"\"\nset_D_23!(value::FiveMassShaft, val) = value.D_23 = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_34`.\"\"\"\nset_D_34!(value::FiveMassShaft, val) = value.D_34 = val\n\"\"\"Set [`FiveMassShaft`](@ref) `D_45`.\"\"\"\nset_D_45!(value::FiveMassShaft, val) = value.D_45 = val\n\"\"\"Set [`FiveMassShaft`](@ref) `K_hp`.\"\"\"\nset_K_hp!(value::FiveMassShaft, val) = value.K_hp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `K_ip`.\"\"\"\nset_K_ip!(value::FiveMassShaft, val) = value.K_ip = val\n\"\"\"Set [`FiveMassShaft`](@ref) `K_lp`.\"\"\"\nset_K_lp!(value::FiveMassShaft, val) = value.K_lp = val\n\"\"\"Set [`FiveMassShaft`](@ref) `K_ex`.\"\"\"\nset_K_ex!(value::FiveMassShaft, val) = value.K_ex = val\n\"\"\"Set [`FiveMassShaft`](@ref) `ext`.\"\"\"\nset_ext!(value::FiveMassShaft, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FixedAdmittance.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FixedAdmittance <: ElectricLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        Y::Complex{Float64}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA fixed admittance.\n\nMost often used in dynamics or AC power flow studies as a source of reactive power\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `Y::Complex{Float64}`: Fixed admittance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection model for admittance\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct FixedAdmittance <: ElectricLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Fixed admittance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    Y::Complex{Float64}\n    \"corresponding dynamic injection model for admittance\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction FixedAdmittance(name, available, bus, Y, dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), )\n    FixedAdmittance(name, available, bus, Y, dynamic_injector, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction FixedAdmittance(; name, available, bus, Y, dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    FixedAdmittance(name, available, bus, Y, dynamic_injector, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FixedAdmittance(::Nothing)\n    FixedAdmittance(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        Y=0.0,\n        dynamic_injector=nothing,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FixedAdmittance`](@ref) `name`.\"\"\"\nget_name(value::FixedAdmittance) = value.name\n\"\"\"Get [`FixedAdmittance`](@ref) `available`.\"\"\"\nget_available(value::FixedAdmittance) = value.available\n\"\"\"Get [`FixedAdmittance`](@ref) `bus`.\"\"\"\nget_bus(value::FixedAdmittance) = value.bus\n\"\"\"Get [`FixedAdmittance`](@ref) `Y`.\"\"\"\nget_Y(value::FixedAdmittance) = value.Y\n\"\"\"Get [`FixedAdmittance`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::FixedAdmittance) = value.dynamic_injector\n\"\"\"Get [`FixedAdmittance`](@ref) `services`.\"\"\"\nget_services(value::FixedAdmittance) = value.services\n\"\"\"Get [`FixedAdmittance`](@ref) `ext`.\"\"\"\nget_ext(value::FixedAdmittance) = value.ext\n\"\"\"Get [`FixedAdmittance`](@ref) `internal`.\"\"\"\nget_internal(value::FixedAdmittance) = value.internal\n\n\"\"\"Set [`FixedAdmittance`](@ref) `available`.\"\"\"\nset_available!(value::FixedAdmittance, val) = value.available = val\n\"\"\"Set [`FixedAdmittance`](@ref) `bus`.\"\"\"\nset_bus!(value::FixedAdmittance, val) = value.bus = val\n\"\"\"Set [`FixedAdmittance`](@ref) `Y`.\"\"\"\nset_Y!(value::FixedAdmittance, val) = value.Y = val\n\"\"\"Set [`FixedAdmittance`](@ref) `services`.\"\"\"\nset_services!(value::FixedAdmittance, val) = value.services = val\n\"\"\"Set [`FixedAdmittance`](@ref) `ext`.\"\"\"\nset_ext!(value::FixedAdmittance, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FixedDCSource.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FixedDCSource <: DCSource\n        voltage::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Fixed DC Source that returns a fixed DC voltage\n\n# Arguments\n- `voltage::Float64`: Voltage (V), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) FixedDCSource has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) FixedDCSource has no states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct FixedDCSource <: DCSource\n    \"Voltage (V)\"\n    voltage::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) FixedDCSource has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) FixedDCSource has no states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction FixedDCSource(voltage, ext=Dict{String, Any}(), )\n    FixedDCSource(voltage, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )\nend\n\nfunction FixedDCSource(; voltage, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )\n    FixedDCSource(voltage, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FixedDCSource(::Nothing)\n    FixedDCSource(;\n        voltage=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FixedDCSource`](@ref) `voltage`.\"\"\"\nget_voltage(value::FixedDCSource) = value.voltage\n\"\"\"Get [`FixedDCSource`](@ref) `ext`.\"\"\"\nget_ext(value::FixedDCSource) = value.ext\n\"\"\"Get [`FixedDCSource`](@ref) `states`.\"\"\"\nget_states(value::FixedDCSource) = value.states\n\"\"\"Get [`FixedDCSource`](@ref) `n_states`.\"\"\"\nget_n_states(value::FixedDCSource) = value.n_states\n\"\"\"Get [`FixedDCSource`](@ref) `internal`.\"\"\"\nget_internal(value::FixedDCSource) = value.internal\n\n\"\"\"Set [`FixedDCSource`](@ref) `voltage`.\"\"\"\nset_voltage!(value::FixedDCSource, val) = value.voltage = val\n\"\"\"Set [`FixedDCSource`](@ref) `ext`.\"\"\"\nset_ext!(value::FixedDCSource, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FixedFrequency.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FixedFrequency <: FrequencyEstimator\n        frequency::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Fixed Frequency Estimator (i.e. no PLL)\n\n# Arguments\n- `frequency::Float64`: (default: `1.0`) Reference Frequency (pu)\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) FixedFrequency has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) FixedFrequency has no states\n\"\"\"\nmutable struct FixedFrequency <: FrequencyEstimator\n    \"Reference Frequency (pu)\"\n    frequency::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) FixedFrequency has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) FixedFrequency has no states\"\n    n_states::Int\nend\n\n\nfunction FixedFrequency(; frequency=1.0, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, )\n    FixedFrequency(frequency, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FixedFrequency(::Nothing)\n    FixedFrequency(;\n        frequency=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FixedFrequency`](@ref) `frequency`.\"\"\"\nget_frequency(value::FixedFrequency) = value.frequency\n\"\"\"Get [`FixedFrequency`](@ref) `ext`.\"\"\"\nget_ext(value::FixedFrequency) = value.ext\n\"\"\"Get [`FixedFrequency`](@ref) `states`.\"\"\"\nget_states(value::FixedFrequency) = value.states\n\"\"\"Get [`FixedFrequency`](@ref) `n_states`.\"\"\"\nget_n_states(value::FixedFrequency) = value.n_states\n\n\"\"\"Set [`FixedFrequency`](@ref) `frequency`.\"\"\"\nset_frequency!(value::FixedFrequency, val) = value.frequency = val\n\"\"\"Set [`FixedFrequency`](@ref) `ext`.\"\"\"\nset_ext!(value::FixedFrequency, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/FullMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct FullMachine <: Machine\n        R::Float64\n        R_f::Float64\n        R_1d::Float64\n        R_1q::Float64\n        L_d::Float64\n        L_q::Float64\n        L_ad::Float64\n        L_aq::Float64\n        L_f1d::Float64\n        L_ff::Float64\n        L_1d::Float64\n        L_1q::Float64\n        ext::Dict{String, Any}\n        inv_d_fluxlink::Array{Float64,2}\n        inv_q_fluxlink::Array{Float64,2}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameter of a full order flux stator-rotor model without zero sequence flux in the stator.\n The derivative of stator fluxes (ψd and ψq) is NOT neglected. Only one q-axis damping circuit is considered. All parameters are in machine per unit.\n Refer to Chapter 3 of [Power System Stability and Control by P. Kundur](https://www.accessengineeringlibrary.com/content/book/9781260473544) or Chapter 11 of [Power System Dynamics: Stability and Control, by J. Machowski, J. Bialek and J. Bumby](https://www.wiley.com/en-us/Power+System+Dynamics%3A+Stability+and+Control%2C+3rd+Edition-p-9781119526360), for more details.\n Note that the models are somewhat different (but equivalent) due to the different Park Transformation used in both books\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `R_f::Float64`: Field rotor winding resistance in per unit, validation range: `(0, nothing)`\n- `R_1d::Float64`:  Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski, validation range: `(0, nothing)`\n- `R_1q::Float64`: Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski, validation range: `(0, nothing)`\n- `L_d::Float64`: Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski), validation range: `(0, nothing)`\n- `L_q::Float64`: Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur, validation range: `(0, nothing)`\n- `L_ad::Float64`: Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit, validation range: `(0, nothing)`\n- `L_aq::Float64`: Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit, validation range: `(0, nothing)`\n- `L_f1d::Float64`: Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit, validation range: `(0, nothing)`\n- `L_ff::Float64`: Field rotor winding inductance, in per unit, validation range: `(0, nothing)`\n- `L_1d::Float64`: Inductance of the d-axis rotor damping circuit, in per unit, validation range: `(0, nothing)`\n- `L_1q::Float64`: Inductance of the q-axis rotor damping circuit, in per unit, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `inv_d_fluxlink::Array{Float64,2}`: (**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\n- `inv_q_fluxlink::Array{Float64,2}`: (**Do not modify.**) Equations 3.128, 3.132 From Kundur\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψd: d-axis stator flux,\n\tψq: q-axis stator flux,\n\tψf: field rotor flux,\n\tψ1d: d-axis rotor damping flux,\n\tψ1q: q-axis rotor damping flux\n- `n_states::Int`: (**Do not modify.**) FullMachine has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct FullMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Field rotor winding resistance in per unit\"\n    R_f::Float64\n    \" Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski\"\n    R_1d::Float64\n    \"Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski\"\n    R_1q::Float64\n    \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski)\"\n    L_d::Float64\n    \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur\"\n    L_q::Float64\n    \"Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit\"\n    L_ad::Float64\n    \"Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit\"\n    L_aq::Float64\n    \"Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit\"\n    L_f1d::Float64\n    \"Field rotor winding inductance, in per unit\"\n    L_ff::Float64\n    \"Inductance of the d-axis rotor damping circuit, in per unit\"\n    L_1d::Float64\n    \"Inductance of the q-axis rotor damping circuit, in per unit\"\n    L_1q::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\"\n    inv_d_fluxlink::Array{Float64,2}\n    \"(**Do not modify.**) Equations 3.128, 3.132 From Kundur\"\n    inv_q_fluxlink::Array{Float64,2}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψd: d-axis stator flux,\n\tψq: q-axis stator flux,\n\tψf: field rotor flux,\n\tψ1d: d-axis rotor damping flux,\n\tψ1q: q-axis rotor damping flux\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) FullMachine has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction FullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext=Dict{String, Any}(), )\n    FullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext, inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]]), inv([[-L_q L_aq]; [-L_aq L_1q]]), [:ψd, :ψq, :ψf, :ψ1d, :ψ1q], 5, InfrastructureSystemsInternal(), )\nend\n\nfunction FullMachine(; R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext=Dict{String, Any}(), inv_d_fluxlink=inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]]), inv_q_fluxlink=inv([[-L_q L_aq]; [-L_aq L_1q]]), states=[:ψd, :ψq, :ψf, :ψ1d, :ψ1q], n_states=5, internal=InfrastructureSystemsInternal(), )\n    FullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext, inv_d_fluxlink, inv_q_fluxlink, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction FullMachine(::Nothing)\n    FullMachine(;\n        R=0,\n        R_f=0,\n        R_1d=0,\n        R_1q=0,\n        L_d=1,\n        L_q=1,\n        L_ad=2,\n        L_aq=2,\n        L_f1d=1,\n        L_ff=2,\n        L_1d=1,\n        L_1q=1,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`FullMachine`](@ref) `R`.\"\"\"\nget_R(value::FullMachine) = value.R\n\"\"\"Get [`FullMachine`](@ref) `R_f`.\"\"\"\nget_R_f(value::FullMachine) = value.R_f\n\"\"\"Get [`FullMachine`](@ref) `R_1d`.\"\"\"\nget_R_1d(value::FullMachine) = value.R_1d\n\"\"\"Get [`FullMachine`](@ref) `R_1q`.\"\"\"\nget_R_1q(value::FullMachine) = value.R_1q\n\"\"\"Get [`FullMachine`](@ref) `L_d`.\"\"\"\nget_L_d(value::FullMachine) = value.L_d\n\"\"\"Get [`FullMachine`](@ref) `L_q`.\"\"\"\nget_L_q(value::FullMachine) = value.L_q\n\"\"\"Get [`FullMachine`](@ref) `L_ad`.\"\"\"\nget_L_ad(value::FullMachine) = value.L_ad\n\"\"\"Get [`FullMachine`](@ref) `L_aq`.\"\"\"\nget_L_aq(value::FullMachine) = value.L_aq\n\"\"\"Get [`FullMachine`](@ref) `L_f1d`.\"\"\"\nget_L_f1d(value::FullMachine) = value.L_f1d\n\"\"\"Get [`FullMachine`](@ref) `L_ff`.\"\"\"\nget_L_ff(value::FullMachine) = value.L_ff\n\"\"\"Get [`FullMachine`](@ref) `L_1d`.\"\"\"\nget_L_1d(value::FullMachine) = value.L_1d\n\"\"\"Get [`FullMachine`](@ref) `L_1q`.\"\"\"\nget_L_1q(value::FullMachine) = value.L_1q\n\"\"\"Get [`FullMachine`](@ref) `ext`.\"\"\"\nget_ext(value::FullMachine) = value.ext\n\"\"\"Get [`FullMachine`](@ref) `inv_d_fluxlink`.\"\"\"\nget_inv_d_fluxlink(value::FullMachine) = value.inv_d_fluxlink\n\"\"\"Get [`FullMachine`](@ref) `inv_q_fluxlink`.\"\"\"\nget_inv_q_fluxlink(value::FullMachine) = value.inv_q_fluxlink\n\"\"\"Get [`FullMachine`](@ref) `states`.\"\"\"\nget_states(value::FullMachine) = value.states\n\"\"\"Get [`FullMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::FullMachine) = value.n_states\n\"\"\"Get [`FullMachine`](@ref) `internal`.\"\"\"\nget_internal(value::FullMachine) = value.internal\n\n\"\"\"Set [`FullMachine`](@ref) `R`.\"\"\"\nset_R!(value::FullMachine, val) = value.R = val\n\"\"\"Set [`FullMachine`](@ref) `R_f`.\"\"\"\nset_R_f!(value::FullMachine, val) = value.R_f = val\n\"\"\"Set [`FullMachine`](@ref) `R_1d`.\"\"\"\nset_R_1d!(value::FullMachine, val) = value.R_1d = val\n\"\"\"Set [`FullMachine`](@ref) `R_1q`.\"\"\"\nset_R_1q!(value::FullMachine, val) = value.R_1q = val\n\"\"\"Set [`FullMachine`](@ref) `L_d`.\"\"\"\nset_L_d!(value::FullMachine, val) = value.L_d = val\n\"\"\"Set [`FullMachine`](@ref) `L_q`.\"\"\"\nset_L_q!(value::FullMachine, val) = value.L_q = val\n\"\"\"Set [`FullMachine`](@ref) `L_ad`.\"\"\"\nset_L_ad!(value::FullMachine, val) = value.L_ad = val\n\"\"\"Set [`FullMachine`](@ref) `L_aq`.\"\"\"\nset_L_aq!(value::FullMachine, val) = value.L_aq = val\n\"\"\"Set [`FullMachine`](@ref) `L_f1d`.\"\"\"\nset_L_f1d!(value::FullMachine, val) = value.L_f1d = val\n\"\"\"Set [`FullMachine`](@ref) `L_ff`.\"\"\"\nset_L_ff!(value::FullMachine, val) = value.L_ff = val\n\"\"\"Set [`FullMachine`](@ref) `L_1d`.\"\"\"\nset_L_1d!(value::FullMachine, val) = value.L_1d = val\n\"\"\"Set [`FullMachine`](@ref) `L_1q`.\"\"\"\nset_L_1q!(value::FullMachine, val) = value.L_1q = val\n\"\"\"Set [`FullMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::FullMachine, val) = value.ext = val\n\"\"\"Set [`FullMachine`](@ref) `inv_d_fluxlink`.\"\"\"\nset_inv_d_fluxlink!(value::FullMachine, val) = value.inv_d_fluxlink = val\n\"\"\"Set [`FullMachine`](@ref) `inv_q_fluxlink`.\"\"\"\nset_inv_q_fluxlink!(value::FullMachine, val) = value.inv_q_fluxlink = val\n"
  },
  {
    "path": "src/models/generated/GasTG.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct GasTG <: TurbineGov\n        R::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        AT::Float64\n        Kt::Float64\n        V_lim::Tuple{Float64, Float64}\n        D_turb::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of Gas Turbine-Governor. GAST in PSSE and GAST_PTI in PowerWorld\n\n# Arguments\n- `R::Float64`: Speed droop parameter, validation range: `(eps(), 0.1)`\n- `T1::Float64`: Governor time constant in s, validation range: `(eps(), 0.5)`\n- `T2::Float64`: Combustion chamber time constant, validation range: `(eps(), 0.5)`\n- `T3::Float64`: Load limit time constant (exhaust gas measurement time), validation range: `(eps(), 5)`\n- `AT::Float64`: Ambient temperature load limit, validation range: `(0, 1)`\n- `Kt::Float64`: Load limit feedback gain, validation range: `(0, 5)`\n- `V_lim::Tuple{Float64, Float64}`: Operational control limits on fuel valve opening (V_min, V_max)\n- `D_turb::Float64`: Speed damping coefficient of gas turbine rotor, validation range: `(0, 0.5)`\n- `P_ref::Float64`: (default: `1.0`) Reference Load Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the GAST model are:\n\tx_g1: Fuel valve opening,\n\tx_g2: Fuel flow,\n\tx_g3: Exhaust temperature load\n- `n_states::Int`: (**Do not modify.**) GasTG has 3 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) GAST has 3 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct GasTG <: TurbineGov\n    \"Speed droop parameter\"\n    R::Float64\n    \"Governor time constant in s\"\n    T1::Float64\n    \"Combustion chamber time constant\"\n    T2::Float64\n    \"Load limit time constant (exhaust gas measurement time)\"\n    T3::Float64\n    \"Ambient temperature load limit\"\n    AT::Float64\n    \"Load limit feedback gain\"\n    Kt::Float64\n    \"Operational control limits on fuel valve opening (V_min, V_max)\"\n    V_lim::Tuple{Float64, Float64}\n    \"Speed damping coefficient of gas turbine rotor\"\n    D_turb::Float64\n    \"Reference Load Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the GAST model are:\n\tx_g1: Fuel valve opening,\n\tx_g2: Fuel flow,\n\tx_g3: Exhaust temperature load\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) GasTG has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) GAST has 3 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction GasTG(R, T1, T2, T3, AT, Kt, V_lim, D_turb, P_ref=1.0, ext=Dict{String, Any}(), )\n    GasTG(R, T1, T2, T3, AT, Kt, V_lim, D_turb, P_ref, ext, [:x_g1, :x_g2, :x_g3], 3, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction GasTG(; R, T1, T2, T3, AT, Kt, V_lim, D_turb, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3], n_states=3, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    GasTG(R, T1, T2, T3, AT, Kt, V_lim, D_turb, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction GasTG(::Nothing)\n    GasTG(;\n        R=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        AT=0,\n        Kt=0,\n        V_lim=(0.0, 0.0),\n        D_turb=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`GasTG`](@ref) `R`.\"\"\"\nget_R(value::GasTG) = value.R\n\"\"\"Get [`GasTG`](@ref) `T1`.\"\"\"\nget_T1(value::GasTG) = value.T1\n\"\"\"Get [`GasTG`](@ref) `T2`.\"\"\"\nget_T2(value::GasTG) = value.T2\n\"\"\"Get [`GasTG`](@ref) `T3`.\"\"\"\nget_T3(value::GasTG) = value.T3\n\"\"\"Get [`GasTG`](@ref) `AT`.\"\"\"\nget_AT(value::GasTG) = value.AT\n\"\"\"Get [`GasTG`](@ref) `Kt`.\"\"\"\nget_Kt(value::GasTG) = value.Kt\n\"\"\"Get [`GasTG`](@ref) `V_lim`.\"\"\"\nget_V_lim(value::GasTG) = value.V_lim\n\"\"\"Get [`GasTG`](@ref) `D_turb`.\"\"\"\nget_D_turb(value::GasTG) = value.D_turb\n\"\"\"Get [`GasTG`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::GasTG) = value.P_ref\n\"\"\"Get [`GasTG`](@ref) `ext`.\"\"\"\nget_ext(value::GasTG) = value.ext\n\"\"\"Get [`GasTG`](@ref) `states`.\"\"\"\nget_states(value::GasTG) = value.states\n\"\"\"Get [`GasTG`](@ref) `n_states`.\"\"\"\nget_n_states(value::GasTG) = value.n_states\n\"\"\"Get [`GasTG`](@ref) `states_types`.\"\"\"\nget_states_types(value::GasTG) = value.states_types\n\"\"\"Get [`GasTG`](@ref) `internal`.\"\"\"\nget_internal(value::GasTG) = value.internal\n\n\"\"\"Set [`GasTG`](@ref) `R`.\"\"\"\nset_R!(value::GasTG, val) = value.R = val\n\"\"\"Set [`GasTG`](@ref) `T1`.\"\"\"\nset_T1!(value::GasTG, val) = value.T1 = val\n\"\"\"Set [`GasTG`](@ref) `T2`.\"\"\"\nset_T2!(value::GasTG, val) = value.T2 = val\n\"\"\"Set [`GasTG`](@ref) `T3`.\"\"\"\nset_T3!(value::GasTG, val) = value.T3 = val\n\"\"\"Set [`GasTG`](@ref) `AT`.\"\"\"\nset_AT!(value::GasTG, val) = value.AT = val\n\"\"\"Set [`GasTG`](@ref) `Kt`.\"\"\"\nset_Kt!(value::GasTG, val) = value.Kt = val\n\"\"\"Set [`GasTG`](@ref) `V_lim`.\"\"\"\nset_V_lim!(value::GasTG, val) = value.V_lim = val\n\"\"\"Set [`GasTG`](@ref) `D_turb`.\"\"\"\nset_D_turb!(value::GasTG, val) = value.D_turb = val\n\"\"\"Set [`GasTG`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::GasTG, val) = value.P_ref = val\n\"\"\"Set [`GasTG`](@ref) `ext`.\"\"\"\nset_ext!(value::GasTG, val) = value.ext = val\n\"\"\"Set [`GasTG`](@ref) `states_types`.\"\"\"\nset_states_types!(value::GasTG, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/GeneralGovModel.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct GeneralGovModel <: TurbineGov\n        Rselect::Int\n        fuel_flag::Int\n        R::Float64\n        Tpelec::Float64\n        speed_error_signal::MinMax\n        Kp_gov::Float64\n        Ki_gov::Float64\n        Kd_gov::Float64\n        Td_gov::Float64\n        valve_position_limits::MinMax\n        T_act::Float64\n        K_turb::Float64\n        Wf_nl::Float64\n        Tb::Float64\n        Tc::Float64\n        T_eng::Float64\n        Tf_load::Float64\n        Kp_load::Float64\n        Ki_load::Float64\n        Ld_ref::Float64\n        Dm::Float64\n        R_open::Float64\n        R_close::Float64\n        Ki_mw::Float64\n        A_set::Float64\n        Ka::Float64\n        Ta::Float64\n        T_rate::Float64\n        db::Float64\n        Tsa::Float64\n        Tsb::Float64\n        R_lim::UpDown\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nGE General Governor/Turbine Model. The GeneralGovModel (GGOV1) model is a general purpose governor model used for a variety of prime movers controlled by proportional-integral-derivative (PID) governors including gas turbines\n\n# Arguments\n- `Rselect::Int`: Feedback signal for governor droop, validation range: `(-2, 1)`\n- `fuel_flag::Int`: Flag Switch for fuel source characteristic, validation range: `(0, 1)`\n- `R::Float64`: Speed droop parameter, validation range: `(eps(), nothing)`\n- `Tpelec::Float64`: Electrical power transducer time constant, seconds, validation range: `(eps(), nothing)`\n- `speed_error_signal::MinMax`: Speed error signal limits\n- `Kp_gov::Float64`: Governor proportional gain, validation range: `(0, nothing)`\n- `Ki_gov::Float64`: Governor integral gain, validation range: `(0, nothing)`\n- `Kd_gov::Float64`: Governor derivative gain, validation range: `(0, nothing)`\n- `Td_gov::Float64`: Governor derivative time constant, validation range: `(0, nothing)`\n- `valve_position_limits::MinMax`: Valve position limits\n- `T_act::Float64`: Actuator time constant, validation range: `(0, nothing)`\n- `K_turb::Float64`: Turbine gain, validation range: `(0, nothing)`\n- `Wf_nl::Float64`: No load fuel flow, pu, validation range: `(0, nothing)`\n- `Tb::Float64`: Turbine lag time constant, sec, validation range: `(0, nothing)`\n- `Tc::Float64`: Turbine lead time constant, sec, validation range: `(0, nothing)`\n- `T_eng::Float64`: Transport lag time constant for diesel engine, sec, validation range: `(0, nothing)`\n- `Tf_load::Float64`: Load limiter time constant, validation range: `(0, nothing)`\n- `Kp_load::Float64`: Load limiter proportional gain for PI controller, validation range: `(0, nothing)`\n- `Ki_load::Float64`: Load integral gain for PI controller, validation range: `(0, nothing)`\n- `Ld_ref::Float64`: Load limiter integral gain for PI controller, validation range: `(0, nothing)`\n- `Dm::Float64`: Mechanical damping coefficient, pu, validation range: `(0, nothing)`\n- `R_open::Float64`: Maximum valve opening rate, pu/sec, validation range: `(0, nothing)`\n- `R_close::Float64`: Maximum valve closing rate, pu/sec, validation range: `(0, nothing)`\n- `Ki_mw::Float64`: Power controller (reset) gain, validation range: `(0, nothing)`\n- `A_set::Float64`: Acceleration limiter setpoint, pu/sec, validation range: `(0, nothing)`\n- `Ka::Float64`: Acceleration limiter gain, validation range: `(0, nothing)`\n- `Ta::Float64`: Acceleration limiter time constant , validation range: `(eps(), nothing)`\n- `T_rate::Float64`: Turbine rating, validation range: `(0, nothing)`\n- `db::Float64`: Speed governor deadband, validation range: `(0, nothing)`\n- `Tsa::Float64`: Temperature detection lead time constant, validation range: `(0, nothing)`\n- `Tsb::Float64`: Temperature detection lag time constant, validation range: `(0, nothing)`\n- `R_lim::UpDown`: Maximum rate of load increase\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the GGOV1 model are:\n\tPe: Machine Electrical Power Measurement,\n\tx_g1: Governor differential control,\n\tx_g2: Governor integral control, \n\tx_g3: Turbine actuator, \n\tx_g4: Turbine Lead-Lag, \n\tx_g5: Turbine load limiter measurement, \n\tx_g6: Turbine Load Limiter Integral Control, \n\tx_g7: Supervisory Load Control, \n\tx_g8: Acceleration Control, \n\tx_g9 Temperature Detection Lead - Lag:\n- `n_states::Int`: (**Do not modify.**) GeneralGovModel has 10 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) GGOV1 has 10 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct GeneralGovModel <: TurbineGov\n    \"Feedback signal for governor droop\"\n    Rselect::Int\n    \"Flag Switch for fuel source characteristic\"\n    fuel_flag::Int\n    \"Speed droop parameter\"\n    R::Float64\n    \"Electrical power transducer time constant, seconds\"\n    Tpelec::Float64\n    \"Speed error signal limits\"\n    speed_error_signal::MinMax\n    \"Governor proportional gain\"\n    Kp_gov::Float64\n    \"Governor integral gain\"\n    Ki_gov::Float64\n    \"Governor derivative gain\"\n    Kd_gov::Float64\n    \"Governor derivative time constant\"\n    Td_gov::Float64\n    \"Valve position limits\"\n    valve_position_limits::MinMax\n    \"Actuator time constant\"\n    T_act::Float64\n    \"Turbine gain\"\n    K_turb::Float64\n    \"No load fuel flow, pu\"\n    Wf_nl::Float64\n    \"Turbine lag time constant, sec\"\n    Tb::Float64\n    \"Turbine lead time constant, sec\"\n    Tc::Float64\n    \"Transport lag time constant for diesel engine, sec\"\n    T_eng::Float64\n    \"Load limiter time constant\"\n    Tf_load::Float64\n    \"Load limiter proportional gain for PI controller\"\n    Kp_load::Float64\n    \"Load integral gain for PI controller\"\n    Ki_load::Float64\n    \"Load limiter integral gain for PI controller\"\n    Ld_ref::Float64\n    \"Mechanical damping coefficient, pu\"\n    Dm::Float64\n    \"Maximum valve opening rate, pu/sec\"\n    R_open::Float64\n    \"Maximum valve closing rate, pu/sec\"\n    R_close::Float64\n    \"Power controller (reset) gain\"\n    Ki_mw::Float64\n    \"Acceleration limiter setpoint, pu/sec\"\n    A_set::Float64\n    \"Acceleration limiter gain\"\n    Ka::Float64\n    \"Acceleration limiter time constant \"\n    Ta::Float64\n    \"Turbine rating\"\n    T_rate::Float64\n    \"Speed governor deadband\"\n    db::Float64\n    \"Temperature detection lead time constant\"\n    Tsa::Float64\n    \"Temperature detection lag time constant\"\n    Tsb::Float64\n    \"Maximum rate of load increase\"\n    R_lim::UpDown\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the GGOV1 model are:\n\tPe: Machine Electrical Power Measurement,\n\tx_g1: Governor differential control,\n\tx_g2: Governor integral control, \n\tx_g3: Turbine actuator, \n\tx_g4: Turbine Lead-Lag, \n\tx_g5: Turbine load limiter measurement, \n\tx_g6: Turbine Load Limiter Integral Control, \n\tx_g7: Supervisory Load Control, \n\tx_g8: Acceleration Control, \n\tx_g9 Temperature Detection Lead - Lag:\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) GeneralGovModel has 10 states\"\n    n_states::Int\n    \"(**Do not modify.**) GGOV1 has 10 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction GeneralGovModel(Rselect, fuel_flag, R, Tpelec, speed_error_signal, Kp_gov, Ki_gov, Kd_gov, Td_gov, valve_position_limits, T_act, K_turb, Wf_nl, Tb, Tc, T_eng, Tf_load, Kp_load, Ki_load, Ld_ref, Dm, R_open, R_close, Ki_mw, A_set, Ka, Ta, T_rate, db, Tsa, Tsb, R_lim, P_ref=1.0, ext=Dict{String, Any}(), )\n    GeneralGovModel(Rselect, fuel_flag, R, Tpelec, speed_error_signal, Kp_gov, Ki_gov, Kd_gov, Td_gov, valve_position_limits, T_act, K_turb, Wf_nl, Tb, Tc, T_eng, Tf_load, Kp_load, Ki_load, Ld_ref, Dm, R_open, R_close, Ki_mw, A_set, Ka, Ta, T_rate, db, Tsa, Tsb, R_lim, P_ref, ext, [:Pe, :x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7, :x_g8, :x_g9], 10, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction GeneralGovModel(; Rselect, fuel_flag, R, Tpelec, speed_error_signal, Kp_gov, Ki_gov, Kd_gov, Td_gov, valve_position_limits, T_act, K_turb, Wf_nl, Tb, Tc, T_eng, Tf_load, Kp_load, Ki_load, Ld_ref, Dm, R_open, R_close, Ki_mw, A_set, Ka, Ta, T_rate, db, Tsa, Tsb, R_lim, P_ref=1.0, ext=Dict{String, Any}(), states=[:Pe, :x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7, :x_g8, :x_g9], n_states=10, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    GeneralGovModel(Rselect, fuel_flag, R, Tpelec, speed_error_signal, Kp_gov, Ki_gov, Kd_gov, Td_gov, valve_position_limits, T_act, K_turb, Wf_nl, Tb, Tc, T_eng, Tf_load, Kp_load, Ki_load, Ld_ref, Dm, R_open, R_close, Ki_mw, A_set, Ka, Ta, T_rate, db, Tsa, Tsb, R_lim, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction GeneralGovModel(::Nothing)\n    GeneralGovModel(;\n        Rselect=1,\n        fuel_flag=0,\n        R=0,\n        Tpelec=0,\n        speed_error_signal=(min=0.0, max=0.0),\n        Kp_gov=0,\n        Ki_gov=0,\n        Kd_gov=0,\n        Td_gov=0,\n        valve_position_limits=(min=0.0, max=0.0),\n        T_act=0,\n        K_turb=0,\n        Wf_nl=0,\n        Tb=0,\n        Tc=0,\n        T_eng=0,\n        Tf_load=0,\n        Kp_load=0,\n        Ki_load=0,\n        Ld_ref=0,\n        Dm=0,\n        R_open=0,\n        R_close=0,\n        Ki_mw=0,\n        A_set=0,\n        Ka=0,\n        Ta=0,\n        T_rate=0,\n        db=0,\n        Tsa=0,\n        Tsb=0,\n        R_lim=(up = 0.0, down = 0.0),\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`GeneralGovModel`](@ref) `Rselect`.\"\"\"\nget_Rselect(value::GeneralGovModel) = value.Rselect\n\"\"\"Get [`GeneralGovModel`](@ref) `fuel_flag`.\"\"\"\nget_fuel_flag(value::GeneralGovModel) = value.fuel_flag\n\"\"\"Get [`GeneralGovModel`](@ref) `R`.\"\"\"\nget_R(value::GeneralGovModel) = value.R\n\"\"\"Get [`GeneralGovModel`](@ref) `Tpelec`.\"\"\"\nget_Tpelec(value::GeneralGovModel) = value.Tpelec\n\"\"\"Get [`GeneralGovModel`](@ref) `speed_error_signal`.\"\"\"\nget_speed_error_signal(value::GeneralGovModel) = value.speed_error_signal\n\"\"\"Get [`GeneralGovModel`](@ref) `Kp_gov`.\"\"\"\nget_Kp_gov(value::GeneralGovModel) = value.Kp_gov\n\"\"\"Get [`GeneralGovModel`](@ref) `Ki_gov`.\"\"\"\nget_Ki_gov(value::GeneralGovModel) = value.Ki_gov\n\"\"\"Get [`GeneralGovModel`](@ref) `Kd_gov`.\"\"\"\nget_Kd_gov(value::GeneralGovModel) = value.Kd_gov\n\"\"\"Get [`GeneralGovModel`](@ref) `Td_gov`.\"\"\"\nget_Td_gov(value::GeneralGovModel) = value.Td_gov\n\"\"\"Get [`GeneralGovModel`](@ref) `valve_position_limits`.\"\"\"\nget_valve_position_limits(value::GeneralGovModel) = value.valve_position_limits\n\"\"\"Get [`GeneralGovModel`](@ref) `T_act`.\"\"\"\nget_T_act(value::GeneralGovModel) = value.T_act\n\"\"\"Get [`GeneralGovModel`](@ref) `K_turb`.\"\"\"\nget_K_turb(value::GeneralGovModel) = value.K_turb\n\"\"\"Get [`GeneralGovModel`](@ref) `Wf_nl`.\"\"\"\nget_Wf_nl(value::GeneralGovModel) = value.Wf_nl\n\"\"\"Get [`GeneralGovModel`](@ref) `Tb`.\"\"\"\nget_Tb(value::GeneralGovModel) = value.Tb\n\"\"\"Get [`GeneralGovModel`](@ref) `Tc`.\"\"\"\nget_Tc(value::GeneralGovModel) = value.Tc\n\"\"\"Get [`GeneralGovModel`](@ref) `T_eng`.\"\"\"\nget_T_eng(value::GeneralGovModel) = value.T_eng\n\"\"\"Get [`GeneralGovModel`](@ref) `Tf_load`.\"\"\"\nget_Tf_load(value::GeneralGovModel) = value.Tf_load\n\"\"\"Get [`GeneralGovModel`](@ref) `Kp_load`.\"\"\"\nget_Kp_load(value::GeneralGovModel) = value.Kp_load\n\"\"\"Get [`GeneralGovModel`](@ref) `Ki_load`.\"\"\"\nget_Ki_load(value::GeneralGovModel) = value.Ki_load\n\"\"\"Get [`GeneralGovModel`](@ref) `Ld_ref`.\"\"\"\nget_Ld_ref(value::GeneralGovModel) = value.Ld_ref\n\"\"\"Get [`GeneralGovModel`](@ref) `Dm`.\"\"\"\nget_Dm(value::GeneralGovModel) = value.Dm\n\"\"\"Get [`GeneralGovModel`](@ref) `R_open`.\"\"\"\nget_R_open(value::GeneralGovModel) = value.R_open\n\"\"\"Get [`GeneralGovModel`](@ref) `R_close`.\"\"\"\nget_R_close(value::GeneralGovModel) = value.R_close\n\"\"\"Get [`GeneralGovModel`](@ref) `Ki_mw`.\"\"\"\nget_Ki_mw(value::GeneralGovModel) = value.Ki_mw\n\"\"\"Get [`GeneralGovModel`](@ref) `A_set`.\"\"\"\nget_A_set(value::GeneralGovModel) = value.A_set\n\"\"\"Get [`GeneralGovModel`](@ref) `Ka`.\"\"\"\nget_Ka(value::GeneralGovModel) = value.Ka\n\"\"\"Get [`GeneralGovModel`](@ref) `Ta`.\"\"\"\nget_Ta(value::GeneralGovModel) = value.Ta\n\"\"\"Get [`GeneralGovModel`](@ref) `T_rate`.\"\"\"\nget_T_rate(value::GeneralGovModel) = value.T_rate\n\"\"\"Get [`GeneralGovModel`](@ref) `db`.\"\"\"\nget_db(value::GeneralGovModel) = value.db\n\"\"\"Get [`GeneralGovModel`](@ref) `Tsa`.\"\"\"\nget_Tsa(value::GeneralGovModel) = value.Tsa\n\"\"\"Get [`GeneralGovModel`](@ref) `Tsb`.\"\"\"\nget_Tsb(value::GeneralGovModel) = value.Tsb\n\"\"\"Get [`GeneralGovModel`](@ref) `R_lim`.\"\"\"\nget_R_lim(value::GeneralGovModel) = value.R_lim\n\"\"\"Get [`GeneralGovModel`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::GeneralGovModel) = value.P_ref\n\"\"\"Get [`GeneralGovModel`](@ref) `ext`.\"\"\"\nget_ext(value::GeneralGovModel) = value.ext\n\"\"\"Get [`GeneralGovModel`](@ref) `states`.\"\"\"\nget_states(value::GeneralGovModel) = value.states\n\"\"\"Get [`GeneralGovModel`](@ref) `n_states`.\"\"\"\nget_n_states(value::GeneralGovModel) = value.n_states\n\"\"\"Get [`GeneralGovModel`](@ref) `states_types`.\"\"\"\nget_states_types(value::GeneralGovModel) = value.states_types\n\"\"\"Get [`GeneralGovModel`](@ref) `internal`.\"\"\"\nget_internal(value::GeneralGovModel) = value.internal\n\n\"\"\"Set [`GeneralGovModel`](@ref) `Rselect`.\"\"\"\nset_Rselect!(value::GeneralGovModel, val) = value.Rselect = val\n\"\"\"Set [`GeneralGovModel`](@ref) `fuel_flag`.\"\"\"\nset_fuel_flag!(value::GeneralGovModel, val) = value.fuel_flag = val\n\"\"\"Set [`GeneralGovModel`](@ref) `R`.\"\"\"\nset_R!(value::GeneralGovModel, val) = value.R = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tpelec`.\"\"\"\nset_Tpelec!(value::GeneralGovModel, val) = value.Tpelec = val\n\"\"\"Set [`GeneralGovModel`](@ref) `speed_error_signal`.\"\"\"\nset_speed_error_signal!(value::GeneralGovModel, val) = value.speed_error_signal = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Kp_gov`.\"\"\"\nset_Kp_gov!(value::GeneralGovModel, val) = value.Kp_gov = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ki_gov`.\"\"\"\nset_Ki_gov!(value::GeneralGovModel, val) = value.Ki_gov = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Kd_gov`.\"\"\"\nset_Kd_gov!(value::GeneralGovModel, val) = value.Kd_gov = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Td_gov`.\"\"\"\nset_Td_gov!(value::GeneralGovModel, val) = value.Td_gov = val\n\"\"\"Set [`GeneralGovModel`](@ref) `valve_position_limits`.\"\"\"\nset_valve_position_limits!(value::GeneralGovModel, val) = value.valve_position_limits = val\n\"\"\"Set [`GeneralGovModel`](@ref) `T_act`.\"\"\"\nset_T_act!(value::GeneralGovModel, val) = value.T_act = val\n\"\"\"Set [`GeneralGovModel`](@ref) `K_turb`.\"\"\"\nset_K_turb!(value::GeneralGovModel, val) = value.K_turb = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Wf_nl`.\"\"\"\nset_Wf_nl!(value::GeneralGovModel, val) = value.Wf_nl = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tb`.\"\"\"\nset_Tb!(value::GeneralGovModel, val) = value.Tb = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tc`.\"\"\"\nset_Tc!(value::GeneralGovModel, val) = value.Tc = val\n\"\"\"Set [`GeneralGovModel`](@ref) `T_eng`.\"\"\"\nset_T_eng!(value::GeneralGovModel, val) = value.T_eng = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tf_load`.\"\"\"\nset_Tf_load!(value::GeneralGovModel, val) = value.Tf_load = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Kp_load`.\"\"\"\nset_Kp_load!(value::GeneralGovModel, val) = value.Kp_load = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ki_load`.\"\"\"\nset_Ki_load!(value::GeneralGovModel, val) = value.Ki_load = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ld_ref`.\"\"\"\nset_Ld_ref!(value::GeneralGovModel, val) = value.Ld_ref = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Dm`.\"\"\"\nset_Dm!(value::GeneralGovModel, val) = value.Dm = val\n\"\"\"Set [`GeneralGovModel`](@ref) `R_open`.\"\"\"\nset_R_open!(value::GeneralGovModel, val) = value.R_open = val\n\"\"\"Set [`GeneralGovModel`](@ref) `R_close`.\"\"\"\nset_R_close!(value::GeneralGovModel, val) = value.R_close = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ki_mw`.\"\"\"\nset_Ki_mw!(value::GeneralGovModel, val) = value.Ki_mw = val\n\"\"\"Set [`GeneralGovModel`](@ref) `A_set`.\"\"\"\nset_A_set!(value::GeneralGovModel, val) = value.A_set = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ka`.\"\"\"\nset_Ka!(value::GeneralGovModel, val) = value.Ka = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Ta`.\"\"\"\nset_Ta!(value::GeneralGovModel, val) = value.Ta = val\n\"\"\"Set [`GeneralGovModel`](@ref) `T_rate`.\"\"\"\nset_T_rate!(value::GeneralGovModel, val) = value.T_rate = val\n\"\"\"Set [`GeneralGovModel`](@ref) `db`.\"\"\"\nset_db!(value::GeneralGovModel, val) = value.db = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tsa`.\"\"\"\nset_Tsa!(value::GeneralGovModel, val) = value.Tsa = val\n\"\"\"Set [`GeneralGovModel`](@ref) `Tsb`.\"\"\"\nset_Tsb!(value::GeneralGovModel, val) = value.Tsb = val\n\"\"\"Set [`GeneralGovModel`](@ref) `R_lim`.\"\"\"\nset_R_lim!(value::GeneralGovModel, val) = value.R_lim = val\n\"\"\"Set [`GeneralGovModel`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::GeneralGovModel, val) = value.P_ref = val\n\"\"\"Set [`GeneralGovModel`](@ref) `ext`.\"\"\"\nset_ext!(value::GeneralGovModel, val) = value.ext = val\n\"\"\"Set [`GeneralGovModel`](@ref) `states_types`.\"\"\"\nset_states_types!(value::GeneralGovModel, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/GenericArcImpedance.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct GenericArcImpedance <: ACTransmission\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        max_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA virtual impedance between two buses that does not correspond to a physical component. This can be used to model the effects of network reductions (e.g. Ward reduction).\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow on the line (MVAR)\n- `max_flow::Float64`: Maximum allowable flow on the generic impedance. When defining a GenericArcImpedance before it is attached to a `System`, `max_flow` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct GenericArcImpedance <: ACTransmission\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow on the line (MVAR)\"\n    reactive_power_flow::Float64\n    \"Maximum allowable flow on the generic impedance. When defining a GenericArcImpedance before it is attached to a `System`, `max_flow` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    max_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction GenericArcImpedance(name, available, active_power_flow, reactive_power_flow, max_flow, arc, r, x, ext=Dict{String, Any}(), )\n    GenericArcImpedance(name, available, active_power_flow, reactive_power_flow, max_flow, arc, r, x, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction GenericArcImpedance(; name, available, active_power_flow, reactive_power_flow, max_flow, arc, r, x, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    GenericArcImpedance(name, available, active_power_flow, reactive_power_flow, max_flow, arc, r, x, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction GenericArcImpedance(::Nothing)\n    GenericArcImpedance(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        max_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`GenericArcImpedance`](@ref) `name`.\"\"\"\nget_name(value::GenericArcImpedance) = value.name\n\"\"\"Get [`GenericArcImpedance`](@ref) `available`.\"\"\"\nget_available(value::GenericArcImpedance) = value.available\n\"\"\"Get [`GenericArcImpedance`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::GenericArcImpedance) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`GenericArcImpedance`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::GenericArcImpedance) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`GenericArcImpedance`](@ref) `max_flow`.\"\"\"\nget_max_flow(value::GenericArcImpedance) = get_value(value, Val(:max_flow), Val(:mva))\n\"\"\"Get [`GenericArcImpedance`](@ref) `arc`.\"\"\"\nget_arc(value::GenericArcImpedance) = value.arc\n\"\"\"Get [`GenericArcImpedance`](@ref) `r`.\"\"\"\nget_r(value::GenericArcImpedance) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`GenericArcImpedance`](@ref) `x`.\"\"\"\nget_x(value::GenericArcImpedance) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`GenericArcImpedance`](@ref) `ext`.\"\"\"\nget_ext(value::GenericArcImpedance) = value.ext\n\"\"\"Get [`GenericArcImpedance`](@ref) `internal`.\"\"\"\nget_internal(value::GenericArcImpedance) = value.internal\n\n\"\"\"Set [`GenericArcImpedance`](@ref) `available`.\"\"\"\nset_available!(value::GenericArcImpedance, val) = value.available = val\n\"\"\"Set [`GenericArcImpedance`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::GenericArcImpedance, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`GenericArcImpedance`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::GenericArcImpedance, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`GenericArcImpedance`](@ref) `max_flow`.\"\"\"\nset_max_flow!(value::GenericArcImpedance, val) = value.max_flow = set_value(value, Val(:max_flow), val, Val(:mva))\n\"\"\"Set [`GenericArcImpedance`](@ref) `arc`.\"\"\"\nset_arc!(value::GenericArcImpedance, val) = value.arc = val\n\"\"\"Set [`GenericArcImpedance`](@ref) `r`.\"\"\"\nset_r!(value::GenericArcImpedance, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`GenericArcImpedance`](@ref) `x`.\"\"\"\nset_x!(value::GenericArcImpedance, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`GenericArcImpedance`](@ref) `ext`.\"\"\"\nset_ext!(value::GenericArcImpedance, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/GenericDER.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct GenericDER <: DynamicInjection\n        name::String\n        Qref_Flag::Int\n        PQ_Flag::Int\n        Gen_Flag::Int\n        PerOp_Flag::Int\n        Recon_Flag::Int\n        Trv::Float64\n        VV_pnts::NamedTuple{(:V1, :V2, :V3, :V4), Tuple{Float64, Float64, Float64, Float64}}\n        Q_lim::MinMax\n        Tp::Float64\n        e_lim::MinMax\n        Kpq::Float64\n        Kiq::Float64\n        Iqr_lim::MinMax\n        I_max::Float64\n        Tg::Float64\n        kWh_Cap::Float64\n        SOC_ini::Float64\n        SOC_lim::MinMax\n        Trf::Float64\n        fdbd_pnts::NamedTuple{(:fdbd1, :fdbd2), Tuple{Float64, Float64}}\n        D_dn::Float64\n        D_up::Float64\n        fe_lim::MinMax\n        Kpp::Float64\n        Kip::Float64\n        P_lim::MinMax\n        dP_lim::MinMax\n        T_pord::Float64\n        rrpwr::Float64\n        VRT_pnts::NamedTuple{(:vrt1, :vrt2, :vrt3, :vrt4, :vrt5), Tuple{Float64, Float64, Float64, Float64, Float64}}\n        TVRT_pnts::NamedTuple{(:tvrt1, :tvrt2, :tvrt3), Tuple{Float64, Float64, Float64}}\n        tV_delay::Float64\n        VES_lim::MinMax\n        FRT_pnts::NamedTuple{(:frt1, :frt2, :frt3, :frt4), Tuple{Float64, Float64, Float64, Float64}}\n        TFRT_pnts::NamedTuple{(:tfrt1, :tfrt2), Tuple{Float64, Float64}}\n        tF_delay::Float64\n        FES_lim::MinMax\n        Pfa_ref::Float64\n        Q_ref::Float64\n        P_ref::Float64\n        base_power::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Generic Distributed Energy Resource Model. Based on [\"Modeling Framework and Coordination of DER and Flexible Loads for Ancillary Service Provision.\"](http://hdl.handle.net/10125/70994)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `Qref_Flag::Int`: Reactive Power Control Mode. 1 VoltVar Control, 2 Constant Q Control, 3 Constant PF Control, validation range: `(1, 3)`\n- `PQ_Flag::Int`: Active and reactive power priority mode. 0 for Q priority, 1 for P priority, validation range: `(0, 1)`\n- `Gen_Flag::Int`: Define generator or storage system. 0 unit is a storage device, 1 unit is a generator, validation range: `(0, 1)`\n- `PerOp_Flag::Int`: Defines operation of permisible region in VRT characteristic. 0 for cease, 1 for continuous operation, validation range: `(0, 1)`\n- `Recon_Flag::Int`: Defines if DER can reconnect after voltage ride-through disconnection, validation range: `(0, 1)`\n- `Trv::Float64`: Voltage measurement transducer's time constant, in s, validation range: `(0, nothing)`\n- `VV_pnts::NamedTuple{(:V1, :V2, :V3, :V4), Tuple{Float64, Float64, Float64, Float64}}`: Y-axis Volt-var curve points (V1,V2,V3,V4)\n- `Q_lim::MinMax`: Reactive power limits in pu (Q_min, Q_max)\n- `Tp::Float64`: Power measurement transducer's time constant, in s, validation range: `(0, nothing)`\n- `e_lim::MinMax`: Error limit in PI controller for q control (e_min, e_max)\n- `Kpq::Float64`: PI controller proportional gain for q control, validation range: `(0, nothing)`\n- `Kiq::Float64`: PI controller integral gain for q control, validation range: `(0, nothing)`\n- `Iqr_lim::MinMax`: Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\n- `I_max::Float64`: Max. inverter's current, validation range: `(0, nothing)`\n- `Tg::Float64`: Current control's time constant, in s, validation range: `(0, nothing)`\n- `kWh_Cap::Float64`: BESS capacity in kWh, validation range: `(0, nothing)`\n- `SOC_ini::Float64`: Initial state of charge (SOC) in pu, validation range: `(0, 1)`\n- `SOC_lim::MinMax`: Battery's SOC limits (SOC_min, SOC_max)\n- `Trf::Float64`: Time constant to estimate system frequency, in s, validation range: `(0, nothing)`\n- `fdbd_pnts::NamedTuple{(:fdbd1, :fdbd2), Tuple{Float64, Float64}}`: Frequency error dead band thresholds `(fdbd1, fdbd2)`\n- `D_dn::Float64`: reciprocal of droop for over-frequency conditions, in pu, validation range: `(0, nothing)`\n- `D_up::Float64`: reciprocal of droop for under-frequency conditions, in pu, validation range: `(0, nothing)`\n- `fe_lim::MinMax`: Frequency error limits in pu (fe_min, fe_max)\n- `Kpp::Float64`: PI controller proportional gain for p control, validation range: `(0, nothing)`\n- `Kip::Float64`: PI controller integral gain for p control, validation range: `(0, nothing)`\n- `P_lim::MinMax`: Active power limits in pu (P_min, P_max)\n- `dP_lim::MinMax`: Ramp rate limits for active power in pu/s (dP_min, dP_max)\n- `T_pord::Float64`: Power filter time constant in s, validation range: `(0, nothing)`\n- `rrpwr::Float64`: Ramp rate for real power increase following a fault, in pu/s, validation range: `(0, nothing)`\n- `VRT_pnts::NamedTuple{(:vrt1, :vrt2, :vrt3, :vrt4, :vrt5), Tuple{Float64, Float64, Float64, Float64, Float64}}`: Voltage ride through v points (vrt1,vrt2,vrt3,vrt4,vrt5)\n- `TVRT_pnts::NamedTuple{(:tvrt1, :tvrt2, :tvrt3), Tuple{Float64, Float64, Float64}}`: Voltage ride through time points (tvrt1,tvrt2,tvrt3)\n- `tV_delay::Float64`: Time delay for reconnection after voltage ride-through disconnection, validation range: `(0, nothing)`\n- `VES_lim::MinMax`: Min and max voltage for entering service (VES_min,VES_max)\n- `FRT_pnts::NamedTuple{(:frt1, :frt2, :frt3, :frt4), Tuple{Float64, Float64, Float64, Float64}}`: Frequency ride through v points (frt1,frt2,frt3,frt4)\n- `TFRT_pnts::NamedTuple{(:tfrt1, :tfrt2), Tuple{Float64, Float64}}`: Frequency ride through time points (tfrt1,tfrt2)\n- `tF_delay::Float64`: Time delay for reconnection after frequency ride-through disconnection, validation range: `(0, nothing)`\n- `FES_lim::MinMax`: Min and max frequency for entering service (FES_min,FES_max)\n- `Pfa_ref::Float64`: (default: `0.0`) Reference power factor, validation range: `(0, nothing)`\n- `Q_ref::Float64`: (default: `0.0`) Reference reactive power, in pu, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference active power, in pu, validation range: `(0, nothing)`\n- `base_power::Float64`: (default: `100.0`) Base power of the unit (MVA) for [per unitization](@ref per_unit)\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\n- `n_states::Int`: (**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct GenericDER <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Reactive Power Control Mode. 1 VoltVar Control, 2 Constant Q Control, 3 Constant PF Control\"\n    Qref_Flag::Int\n    \"Active and reactive power priority mode. 0 for Q priority, 1 for P priority\"\n    PQ_Flag::Int\n    \"Define generator or storage system. 0 unit is a storage device, 1 unit is a generator\"\n    Gen_Flag::Int\n    \"Defines operation of permisible region in VRT characteristic. 0 for cease, 1 for continuous operation\"\n    PerOp_Flag::Int\n    \"Defines if DER can reconnect after voltage ride-through disconnection\"\n    Recon_Flag::Int\n    \"Voltage measurement transducer's time constant, in s\"\n    Trv::Float64\n    \"Y-axis Volt-var curve points (V1,V2,V3,V4)\"\n    VV_pnts::NamedTuple{(:V1, :V2, :V3, :V4), Tuple{Float64, Float64, Float64, Float64}}\n    \"Reactive power limits in pu (Q_min, Q_max)\"\n    Q_lim::MinMax\n    \"Power measurement transducer's time constant, in s\"\n    Tp::Float64\n    \"Error limit in PI controller for q control (e_min, e_max)\"\n    e_lim::MinMax\n    \"PI controller proportional gain for q control\"\n    Kpq::Float64\n    \"PI controller integral gain for q control\"\n    Kiq::Float64\n    \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\"\n    Iqr_lim::MinMax\n    \"Max. inverter's current\"\n    I_max::Float64\n    \"Current control's time constant, in s\"\n    Tg::Float64\n    \"BESS capacity in kWh\"\n    kWh_Cap::Float64\n    \"Initial state of charge (SOC) in pu\"\n    SOC_ini::Float64\n    \"Battery's SOC limits (SOC_min, SOC_max)\"\n    SOC_lim::MinMax\n    \"Time constant to estimate system frequency, in s\"\n    Trf::Float64\n    \"Frequency error dead band thresholds `(fdbd1, fdbd2)`\"\n    fdbd_pnts::NamedTuple{(:fdbd1, :fdbd2), Tuple{Float64, Float64}}\n    \"reciprocal of droop for over-frequency conditions, in pu\"\n    D_dn::Float64\n    \"reciprocal of droop for under-frequency conditions, in pu\"\n    D_up::Float64\n    \"Frequency error limits in pu (fe_min, fe_max)\"\n    fe_lim::MinMax\n    \"PI controller proportional gain for p control\"\n    Kpp::Float64\n    \"PI controller integral gain for p control\"\n    Kip::Float64\n    \"Active power limits in pu (P_min, P_max)\"\n    P_lim::MinMax\n    \"Ramp rate limits for active power in pu/s (dP_min, dP_max)\"\n    dP_lim::MinMax\n    \"Power filter time constant in s\"\n    T_pord::Float64\n    \"Ramp rate for real power increase following a fault, in pu/s\"\n    rrpwr::Float64\n    \"Voltage ride through v points (vrt1,vrt2,vrt3,vrt4,vrt5)\"\n    VRT_pnts::NamedTuple{(:vrt1, :vrt2, :vrt3, :vrt4, :vrt5), Tuple{Float64, Float64, Float64, Float64, Float64}}\n    \"Voltage ride through time points (tvrt1,tvrt2,tvrt3)\"\n    TVRT_pnts::NamedTuple{(:tvrt1, :tvrt2, :tvrt3), Tuple{Float64, Float64, Float64}}\n    \"Time delay for reconnection after voltage ride-through disconnection\"\n    tV_delay::Float64\n    \"Min and max voltage for entering service (VES_min,VES_max)\"\n    VES_lim::MinMax\n    \"Frequency ride through v points (frt1,frt2,frt3,frt4)\"\n    FRT_pnts::NamedTuple{(:frt1, :frt2, :frt3, :frt4), Tuple{Float64, Float64, Float64, Float64}}\n    \"Frequency ride through time points (tfrt1,tfrt2)\"\n    TFRT_pnts::NamedTuple{(:tfrt1, :tfrt2), Tuple{Float64, Float64}}\n    \"Time delay for reconnection after frequency ride-through disconnection\"\n    tF_delay::Float64\n    \"Min and max frequency for entering service (FES_min,FES_max)\"\n    FES_lim::MinMax\n    \"Reference power factor\"\n    Pfa_ref::Float64\n    \"Reference reactive power, in pu\"\n    Q_ref::Float64\n    \"Reference active power, in pu\"\n    P_ref::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"(**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The [states](@ref S) of GenericDER depend on the Flags\"\n    n_states::Int\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction GenericDER(name, Qref_Flag, PQ_Flag, Gen_Flag, PerOp_Flag, Recon_Flag, Trv, VV_pnts, Q_lim, Tp, e_lim, Kpq, Kiq, Iqr_lim, I_max, Tg, kWh_Cap, SOC_ini, SOC_lim, Trf, fdbd_pnts, D_dn, D_up, fe_lim, Kpp, Kip, P_lim, dP_lim, T_pord, rrpwr, VRT_pnts, TVRT_pnts, tV_delay, VES_lim, FRT_pnts, TFRT_pnts, tF_delay, FES_lim, Pfa_ref=0.0, Q_ref=0.0, P_ref=1.0, base_power=100.0, ext=Dict{String, Any}(), )\n    GenericDER(name, Qref_Flag, PQ_Flag, Gen_Flag, PerOp_Flag, Recon_Flag, Trv, VV_pnts, Q_lim, Tp, e_lim, Kpq, Kiq, Iqr_lim, I_max, Tg, kWh_Cap, SOC_ini, SOC_lim, Trf, fdbd_pnts, D_dn, D_up, fe_lim, Kpp, Kip, P_lim, dP_lim, T_pord, rrpwr, VRT_pnts, TVRT_pnts, tV_delay, VES_lim, FRT_pnts, TFRT_pnts, tF_delay, FES_lim, Pfa_ref, Q_ref, P_ref, base_power, ext, PowerSystems.get_GenericDER_states(Qref_Flag)[1], PowerSystems.get_GenericDER_states(Qref_Flag)[2], InfrastructureSystemsInternal(), )\nend\n\nfunction GenericDER(; name, Qref_Flag, PQ_Flag, Gen_Flag, PerOp_Flag, Recon_Flag, Trv, VV_pnts, Q_lim, Tp, e_lim, Kpq, Kiq, Iqr_lim, I_max, Tg, kWh_Cap, SOC_ini, SOC_lim, Trf, fdbd_pnts, D_dn, D_up, fe_lim, Kpp, Kip, P_lim, dP_lim, T_pord, rrpwr, VRT_pnts, TVRT_pnts, tV_delay, VES_lim, FRT_pnts, TFRT_pnts, tF_delay, FES_lim, Pfa_ref=0.0, Q_ref=0.0, P_ref=1.0, base_power=100.0, states=PowerSystems.get_GenericDER_states(Qref_Flag)[1], n_states=PowerSystems.get_GenericDER_states(Qref_Flag)[2], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    GenericDER(name, Qref_Flag, PQ_Flag, Gen_Flag, PerOp_Flag, Recon_Flag, Trv, VV_pnts, Q_lim, Tp, e_lim, Kpq, Kiq, Iqr_lim, I_max, Tg, kWh_Cap, SOC_ini, SOC_lim, Trf, fdbd_pnts, D_dn, D_up, fe_lim, Kpp, Kip, P_lim, dP_lim, T_pord, rrpwr, VRT_pnts, TVRT_pnts, tV_delay, VES_lim, FRT_pnts, TFRT_pnts, tF_delay, FES_lim, Pfa_ref, Q_ref, P_ref, base_power, states, n_states, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction GenericDER(::Nothing)\n    GenericDER(;\n        name=\"init\",\n        Qref_Flag=1,\n        PQ_Flag=0,\n        Gen_Flag=0,\n        PerOp_Flag=0,\n        Recon_Flag=0,\n        Trv=0,\n        VV_pnts=(V1=0.0, V2=0.0, V3=0.0, V4=0.0),\n        Q_lim=(min=0.0, max=0.0),\n        Tp=0,\n        e_lim=(min=0.0, max=0.0),\n        Kpq=0,\n        Kiq=0,\n        Iqr_lim=(min=0.0, max=0.0),\n        I_max=0,\n        Tg=0,\n        kWh_Cap=0,\n        SOC_ini=0,\n        SOC_lim=(min=0.0, max=0.0),\n        Trf=0,\n        fdbd_pnts=(fdbd1=0.0, fdbd2=0.0),\n        D_dn=0,\n        D_up=0,\n        fe_lim=(min=0.0, max=0.0),\n        Kpp=0,\n        Kip=0,\n        P_lim=(min=0.0, max=0.0),\n        dP_lim=(min=0.0, max=0.0),\n        T_pord=0,\n        rrpwr=0,\n        VRT_pnts=(vrt1=0.0, vrt2=0.0, vrt3=0.0, vrt4=0.0, vrt5=0.0),\n        TVRT_pnts=(tvrt1=0.0, tvrt2=0.0, tvrt3=0.0),\n        tV_delay=0,\n        VES_lim=(min=0.0, max=0.0),\n        FRT_pnts=(frt1=0.0, frt2=0.0, frt3=0.0, frt4=0.0),\n        TFRT_pnts=(tfrt1=0.0, tfrt2=0.0),\n        tF_delay=0,\n        FES_lim=(min=0.0, max=0.0),\n        Pfa_ref=0,\n        Q_ref=0,\n        P_ref=0,\n        base_power=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`GenericDER`](@ref) `name`.\"\"\"\nget_name(value::GenericDER) = value.name\n\"\"\"Get [`GenericDER`](@ref) `Qref_Flag`.\"\"\"\nget_Qref_Flag(value::GenericDER) = value.Qref_Flag\n\"\"\"Get [`GenericDER`](@ref) `PQ_Flag`.\"\"\"\nget_PQ_Flag(value::GenericDER) = value.PQ_Flag\n\"\"\"Get [`GenericDER`](@ref) `Gen_Flag`.\"\"\"\nget_Gen_Flag(value::GenericDER) = value.Gen_Flag\n\"\"\"Get [`GenericDER`](@ref) `PerOp_Flag`.\"\"\"\nget_PerOp_Flag(value::GenericDER) = value.PerOp_Flag\n\"\"\"Get [`GenericDER`](@ref) `Recon_Flag`.\"\"\"\nget_Recon_Flag(value::GenericDER) = value.Recon_Flag\n\"\"\"Get [`GenericDER`](@ref) `Trv`.\"\"\"\nget_Trv(value::GenericDER) = value.Trv\n\"\"\"Get [`GenericDER`](@ref) `VV_pnts`.\"\"\"\nget_VV_pnts(value::GenericDER) = value.VV_pnts\n\"\"\"Get [`GenericDER`](@ref) `Q_lim`.\"\"\"\nget_Q_lim(value::GenericDER) = value.Q_lim\n\"\"\"Get [`GenericDER`](@ref) `Tp`.\"\"\"\nget_Tp(value::GenericDER) = value.Tp\n\"\"\"Get [`GenericDER`](@ref) `e_lim`.\"\"\"\nget_e_lim(value::GenericDER) = value.e_lim\n\"\"\"Get [`GenericDER`](@ref) `Kpq`.\"\"\"\nget_Kpq(value::GenericDER) = value.Kpq\n\"\"\"Get [`GenericDER`](@ref) `Kiq`.\"\"\"\nget_Kiq(value::GenericDER) = value.Kiq\n\"\"\"Get [`GenericDER`](@ref) `Iqr_lim`.\"\"\"\nget_Iqr_lim(value::GenericDER) = value.Iqr_lim\n\"\"\"Get [`GenericDER`](@ref) `I_max`.\"\"\"\nget_I_max(value::GenericDER) = value.I_max\n\"\"\"Get [`GenericDER`](@ref) `Tg`.\"\"\"\nget_Tg(value::GenericDER) = value.Tg\n\"\"\"Get [`GenericDER`](@ref) `kWh_Cap`.\"\"\"\nget_kWh_Cap(value::GenericDER) = value.kWh_Cap\n\"\"\"Get [`GenericDER`](@ref) `SOC_ini`.\"\"\"\nget_SOC_ini(value::GenericDER) = value.SOC_ini\n\"\"\"Get [`GenericDER`](@ref) `SOC_lim`.\"\"\"\nget_SOC_lim(value::GenericDER) = value.SOC_lim\n\"\"\"Get [`GenericDER`](@ref) `Trf`.\"\"\"\nget_Trf(value::GenericDER) = value.Trf\n\"\"\"Get [`GenericDER`](@ref) `fdbd_pnts`.\"\"\"\nget_fdbd_pnts(value::GenericDER) = value.fdbd_pnts\n\"\"\"Get [`GenericDER`](@ref) `D_dn`.\"\"\"\nget_D_dn(value::GenericDER) = value.D_dn\n\"\"\"Get [`GenericDER`](@ref) `D_up`.\"\"\"\nget_D_up(value::GenericDER) = value.D_up\n\"\"\"Get [`GenericDER`](@ref) `fe_lim`.\"\"\"\nget_fe_lim(value::GenericDER) = value.fe_lim\n\"\"\"Get [`GenericDER`](@ref) `Kpp`.\"\"\"\nget_Kpp(value::GenericDER) = value.Kpp\n\"\"\"Get [`GenericDER`](@ref) `Kip`.\"\"\"\nget_Kip(value::GenericDER) = value.Kip\n\"\"\"Get [`GenericDER`](@ref) `P_lim`.\"\"\"\nget_P_lim(value::GenericDER) = value.P_lim\n\"\"\"Get [`GenericDER`](@ref) `dP_lim`.\"\"\"\nget_dP_lim(value::GenericDER) = value.dP_lim\n\"\"\"Get [`GenericDER`](@ref) `T_pord`.\"\"\"\nget_T_pord(value::GenericDER) = value.T_pord\n\"\"\"Get [`GenericDER`](@ref) `rrpwr`.\"\"\"\nget_rrpwr(value::GenericDER) = value.rrpwr\n\"\"\"Get [`GenericDER`](@ref) `VRT_pnts`.\"\"\"\nget_VRT_pnts(value::GenericDER) = value.VRT_pnts\n\"\"\"Get [`GenericDER`](@ref) `TVRT_pnts`.\"\"\"\nget_TVRT_pnts(value::GenericDER) = value.TVRT_pnts\n\"\"\"Get [`GenericDER`](@ref) `tV_delay`.\"\"\"\nget_tV_delay(value::GenericDER) = value.tV_delay\n\"\"\"Get [`GenericDER`](@ref) `VES_lim`.\"\"\"\nget_VES_lim(value::GenericDER) = value.VES_lim\n\"\"\"Get [`GenericDER`](@ref) `FRT_pnts`.\"\"\"\nget_FRT_pnts(value::GenericDER) = value.FRT_pnts\n\"\"\"Get [`GenericDER`](@ref) `TFRT_pnts`.\"\"\"\nget_TFRT_pnts(value::GenericDER) = value.TFRT_pnts\n\"\"\"Get [`GenericDER`](@ref) `tF_delay`.\"\"\"\nget_tF_delay(value::GenericDER) = value.tF_delay\n\"\"\"Get [`GenericDER`](@ref) `FES_lim`.\"\"\"\nget_FES_lim(value::GenericDER) = value.FES_lim\n\"\"\"Get [`GenericDER`](@ref) `Pfa_ref`.\"\"\"\nget_Pfa_ref(value::GenericDER) = value.Pfa_ref\n\"\"\"Get [`GenericDER`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::GenericDER) = value.Q_ref\n\"\"\"Get [`GenericDER`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::GenericDER) = value.P_ref\n\"\"\"Get [`GenericDER`](@ref) `base_power`.\"\"\"\nget_base_power(value::GenericDER) = value.base_power\n\"\"\"Get [`GenericDER`](@ref) `states`.\"\"\"\nget_states(value::GenericDER) = value.states\n\"\"\"Get [`GenericDER`](@ref) `n_states`.\"\"\"\nget_n_states(value::GenericDER) = value.n_states\n\"\"\"Get [`GenericDER`](@ref) `ext`.\"\"\"\nget_ext(value::GenericDER) = value.ext\n\"\"\"Get [`GenericDER`](@ref) `internal`.\"\"\"\nget_internal(value::GenericDER) = value.internal\n\n\"\"\"Set [`GenericDER`](@ref) `Qref_Flag`.\"\"\"\nset_Qref_Flag!(value::GenericDER, val) = value.Qref_Flag = val\n\"\"\"Set [`GenericDER`](@ref) `PQ_Flag`.\"\"\"\nset_PQ_Flag!(value::GenericDER, val) = value.PQ_Flag = val\n\"\"\"Set [`GenericDER`](@ref) `Gen_Flag`.\"\"\"\nset_Gen_Flag!(value::GenericDER, val) = value.Gen_Flag = val\n\"\"\"Set [`GenericDER`](@ref) `PerOp_Flag`.\"\"\"\nset_PerOp_Flag!(value::GenericDER, val) = value.PerOp_Flag = val\n\"\"\"Set [`GenericDER`](@ref) `Recon_Flag`.\"\"\"\nset_Recon_Flag!(value::GenericDER, val) = value.Recon_Flag = val\n\"\"\"Set [`GenericDER`](@ref) `Trv`.\"\"\"\nset_Trv!(value::GenericDER, val) = value.Trv = val\n\"\"\"Set [`GenericDER`](@ref) `VV_pnts`.\"\"\"\nset_VV_pnts!(value::GenericDER, val) = value.VV_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `Q_lim`.\"\"\"\nset_Q_lim!(value::GenericDER, val) = value.Q_lim = val\n\"\"\"Set [`GenericDER`](@ref) `Tp`.\"\"\"\nset_Tp!(value::GenericDER, val) = value.Tp = val\n\"\"\"Set [`GenericDER`](@ref) `e_lim`.\"\"\"\nset_e_lim!(value::GenericDER, val) = value.e_lim = val\n\"\"\"Set [`GenericDER`](@ref) `Kpq`.\"\"\"\nset_Kpq!(value::GenericDER, val) = value.Kpq = val\n\"\"\"Set [`GenericDER`](@ref) `Kiq`.\"\"\"\nset_Kiq!(value::GenericDER, val) = value.Kiq = val\n\"\"\"Set [`GenericDER`](@ref) `Iqr_lim`.\"\"\"\nset_Iqr_lim!(value::GenericDER, val) = value.Iqr_lim = val\n\"\"\"Set [`GenericDER`](@ref) `I_max`.\"\"\"\nset_I_max!(value::GenericDER, val) = value.I_max = val\n\"\"\"Set [`GenericDER`](@ref) `Tg`.\"\"\"\nset_Tg!(value::GenericDER, val) = value.Tg = val\n\"\"\"Set [`GenericDER`](@ref) `kWh_Cap`.\"\"\"\nset_kWh_Cap!(value::GenericDER, val) = value.kWh_Cap = val\n\"\"\"Set [`GenericDER`](@ref) `SOC_ini`.\"\"\"\nset_SOC_ini!(value::GenericDER, val) = value.SOC_ini = val\n\"\"\"Set [`GenericDER`](@ref) `SOC_lim`.\"\"\"\nset_SOC_lim!(value::GenericDER, val) = value.SOC_lim = val\n\"\"\"Set [`GenericDER`](@ref) `Trf`.\"\"\"\nset_Trf!(value::GenericDER, val) = value.Trf = val\n\"\"\"Set [`GenericDER`](@ref) `fdbd_pnts`.\"\"\"\nset_fdbd_pnts!(value::GenericDER, val) = value.fdbd_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `D_dn`.\"\"\"\nset_D_dn!(value::GenericDER, val) = value.D_dn = val\n\"\"\"Set [`GenericDER`](@ref) `D_up`.\"\"\"\nset_D_up!(value::GenericDER, val) = value.D_up = val\n\"\"\"Set [`GenericDER`](@ref) `fe_lim`.\"\"\"\nset_fe_lim!(value::GenericDER, val) = value.fe_lim = val\n\"\"\"Set [`GenericDER`](@ref) `Kpp`.\"\"\"\nset_Kpp!(value::GenericDER, val) = value.Kpp = val\n\"\"\"Set [`GenericDER`](@ref) `Kip`.\"\"\"\nset_Kip!(value::GenericDER, val) = value.Kip = val\n\"\"\"Set [`GenericDER`](@ref) `P_lim`.\"\"\"\nset_P_lim!(value::GenericDER, val) = value.P_lim = val\n\"\"\"Set [`GenericDER`](@ref) `dP_lim`.\"\"\"\nset_dP_lim!(value::GenericDER, val) = value.dP_lim = val\n\"\"\"Set [`GenericDER`](@ref) `T_pord`.\"\"\"\nset_T_pord!(value::GenericDER, val) = value.T_pord = val\n\"\"\"Set [`GenericDER`](@ref) `rrpwr`.\"\"\"\nset_rrpwr!(value::GenericDER, val) = value.rrpwr = val\n\"\"\"Set [`GenericDER`](@ref) `VRT_pnts`.\"\"\"\nset_VRT_pnts!(value::GenericDER, val) = value.VRT_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `TVRT_pnts`.\"\"\"\nset_TVRT_pnts!(value::GenericDER, val) = value.TVRT_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `tV_delay`.\"\"\"\nset_tV_delay!(value::GenericDER, val) = value.tV_delay = val\n\"\"\"Set [`GenericDER`](@ref) `VES_lim`.\"\"\"\nset_VES_lim!(value::GenericDER, val) = value.VES_lim = val\n\"\"\"Set [`GenericDER`](@ref) `FRT_pnts`.\"\"\"\nset_FRT_pnts!(value::GenericDER, val) = value.FRT_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `TFRT_pnts`.\"\"\"\nset_TFRT_pnts!(value::GenericDER, val) = value.TFRT_pnts = val\n\"\"\"Set [`GenericDER`](@ref) `tF_delay`.\"\"\"\nset_tF_delay!(value::GenericDER, val) = value.tF_delay = val\n\"\"\"Set [`GenericDER`](@ref) `FES_lim`.\"\"\"\nset_FES_lim!(value::GenericDER, val) = value.FES_lim = val\n\"\"\"Set [`GenericDER`](@ref) `Pfa_ref`.\"\"\"\nset_Pfa_ref!(value::GenericDER, val) = value.Pfa_ref = val\n\"\"\"Set [`GenericDER`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::GenericDER, val) = value.Q_ref = val\n\"\"\"Set [`GenericDER`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::GenericDER, val) = value.P_ref = val\n\"\"\"Set [`GenericDER`](@ref) `base_power`.\"\"\"\nset_base_power!(value::GenericDER, val) = value.base_power = val\n\"\"\"Set [`GenericDER`](@ref) `ext`.\"\"\"\nset_ext!(value::GenericDER, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HybridOutputCurrentLimiter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HybridOutputCurrentLimiter <: OutputCurrentLimiter\n        I_max::Float64\n        rv::Float64\n        lv::Float64\n        ext::Dict{String, Any}\n    end\n\nParameters of Hybrid Current Controller Limiter. Regulates the magnitude of the inverter output current, but with a closed loop feedback regulated by a virtual impedance which provides ant-windup. Described in: Novel Hybrid Current Limiter for Grid-Forming Inverter Control During Unbalanced Faults by Baeckland and Seo, 2023 \n\n# Arguments\n- `I_max::Float64`: Maximum limit on current controller input current (device base), validation range: `(0, nothing)`\n- `rv::Float64`: Real part of the virtual impedance, validation range: `(0, nothing)`\n- `lv::Float64`: Imaginary part of the virtual impedance, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`)\n\"\"\"\nmutable struct HybridOutputCurrentLimiter <: OutputCurrentLimiter\n    \"Maximum limit on current controller input current (device base)\"\n    I_max::Float64\n    \"Real part of the virtual impedance\"\n    rv::Float64\n    \"Imaginary part of the virtual impedance\"\n    lv::Float64\n    ext::Dict{String, Any}\nend\n\n\nfunction HybridOutputCurrentLimiter(; I_max, rv, lv, ext=Dict{String, Any}(), )\n    HybridOutputCurrentLimiter(I_max, rv, lv, ext, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HybridOutputCurrentLimiter(::Nothing)\n    HybridOutputCurrentLimiter(;\n        I_max=0,\n        rv=0,\n        lv=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HybridOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nget_I_max(value::HybridOutputCurrentLimiter) = value.I_max\n\"\"\"Get [`HybridOutputCurrentLimiter`](@ref) `rv`.\"\"\"\nget_rv(value::HybridOutputCurrentLimiter) = value.rv\n\"\"\"Get [`HybridOutputCurrentLimiter`](@ref) `lv`.\"\"\"\nget_lv(value::HybridOutputCurrentLimiter) = value.lv\n\"\"\"Get [`HybridOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nget_ext(value::HybridOutputCurrentLimiter) = value.ext\n\n\"\"\"Set [`HybridOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nset_I_max!(value::HybridOutputCurrentLimiter, val) = value.I_max = val\n\"\"\"Set [`HybridOutputCurrentLimiter`](@ref) `rv`.\"\"\"\nset_rv!(value::HybridOutputCurrentLimiter, val) = value.rv = val\n\"\"\"Set [`HybridOutputCurrentLimiter`](@ref) `lv`.\"\"\"\nset_lv!(value::HybridOutputCurrentLimiter, val) = value.lv = val\n\"\"\"Set [`HybridOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nset_ext!(value::HybridOutputCurrentLimiter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HydroDispatch.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HydroDispatch <: HydroGen\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        prime_mover_type::PrimeMovers\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        ramp_limits::Union{Nothing, UpDown}\n        time_limits::Union{Nothing, UpDown}\n        base_power::Float64\n        status::Bool\n        time_at_status::Float64\n        operation_cost::Union{HydroGenerationCost, MarketBidCost}\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA hydropower generator without a reservoir, suitable for modeling run-of-river hydropower.\n\nFor hydro generators with an upper reservoir, see [`HydroReservoir`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `prime_mover_type::PrimeMovers`: Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW), validation range: `(0, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `ramp_limits::Union{Nothing, UpDown}`: ramp up and ramp down limits in MW/min, validation range: `(0, nothing)`\n- `time_limits::Union{Nothing, UpDown}`: Minimum up and Minimum down time limits in hours, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `status::Bool`: (default: `false`) Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\n- `time_at_status::Float64`: (default: `INFINITE_TIME`) Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\n- `operation_cost::Union{HydroGenerationCost, MarketBidCost}`: (default: `HydroGenerationCost(nothing)`) [`OperationalCost`](@ref) of generation\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct HydroDispatch <: HydroGen\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"ramp up and ramp down limits in MW/min\"\n    ramp_limits::Union{Nothing, UpDown}\n    \"Minimum up and Minimum down time limits in hours\"\n    time_limits::Union{Nothing, UpDown}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\"\n    status::Bool\n    \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\"\n    time_at_status::Float64\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{HydroGenerationCost, MarketBidCost}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HydroDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, active_power_limits, reactive_power_limits, ramp_limits, time_limits, base_power, status=false, time_at_status=INFINITE_TIME, operation_cost=HydroGenerationCost(nothing), services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    HydroDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, active_power_limits, reactive_power_limits, ramp_limits, time_limits, base_power, status, time_at_status, operation_cost, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction HydroDispatch(; name, available, bus, active_power, reactive_power, rating, prime_mover_type, active_power_limits, reactive_power_limits, ramp_limits, time_limits, base_power, status=false, time_at_status=INFINITE_TIME, operation_cost=HydroGenerationCost(nothing), services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    HydroDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, active_power_limits, reactive_power_limits, ramp_limits, time_limits, base_power, status, time_at_status, operation_cost, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroDispatch(::Nothing)\n    HydroDispatch(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        prime_mover_type=PrimeMovers.HY,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        ramp_limits=nothing,\n        time_limits=nothing,\n        base_power=100.0,\n        status=false,\n        time_at_status=INFINITE_TIME,\n        operation_cost=HydroGenerationCost(nothing),\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HydroDispatch`](@ref) `name`.\"\"\"\nget_name(value::HydroDispatch) = value.name\n\"\"\"Get [`HydroDispatch`](@ref) `available`.\"\"\"\nget_available(value::HydroDispatch) = value.available\n\"\"\"Get [`HydroDispatch`](@ref) `bus`.\"\"\"\nget_bus(value::HydroDispatch) = value.bus\n\"\"\"Get [`HydroDispatch`](@ref) `active_power`.\"\"\"\nget_active_power(value::HydroDispatch) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::HydroDispatch) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `rating`.\"\"\"\nget_rating(value::HydroDispatch) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::HydroDispatch) = value.prime_mover_type\n\"\"\"Get [`HydroDispatch`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::HydroDispatch) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::HydroDispatch) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `ramp_limits`.\"\"\"\nget_ramp_limits(value::HydroDispatch) = get_value(value, Val(:ramp_limits), Val(:mva))\n\"\"\"Get [`HydroDispatch`](@ref) `time_limits`.\"\"\"\nget_time_limits(value::HydroDispatch) = value.time_limits\n\"\"\"Get [`HydroDispatch`](@ref) `base_power`.\"\"\"\nget_base_power(value::HydroDispatch) = value.base_power\n\"\"\"Get [`HydroDispatch`](@ref) `status`.\"\"\"\nget_status(value::HydroDispatch) = value.status\n\"\"\"Get [`HydroDispatch`](@ref) `time_at_status`.\"\"\"\nget_time_at_status(value::HydroDispatch) = value.time_at_status\n\"\"\"Get [`HydroDispatch`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::HydroDispatch) = value.operation_cost\n\"\"\"Get [`HydroDispatch`](@ref) `services`.\"\"\"\nget_services(value::HydroDispatch) = value.services\n\"\"\"Get [`HydroDispatch`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::HydroDispatch) = value.dynamic_injector\n\"\"\"Get [`HydroDispatch`](@ref) `ext`.\"\"\"\nget_ext(value::HydroDispatch) = value.ext\n\"\"\"Get [`HydroDispatch`](@ref) `internal`.\"\"\"\nget_internal(value::HydroDispatch) = value.internal\n\n\"\"\"Set [`HydroDispatch`](@ref) `available`.\"\"\"\nset_available!(value::HydroDispatch, val) = value.available = val\n\"\"\"Set [`HydroDispatch`](@ref) `bus`.\"\"\"\nset_bus!(value::HydroDispatch, val) = value.bus = val\n\"\"\"Set [`HydroDispatch`](@ref) `active_power`.\"\"\"\nset_active_power!(value::HydroDispatch, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::HydroDispatch, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `rating`.\"\"\"\nset_rating!(value::HydroDispatch, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::HydroDispatch, val) = value.prime_mover_type = val\n\"\"\"Set [`HydroDispatch`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::HydroDispatch, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::HydroDispatch, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `ramp_limits`.\"\"\"\nset_ramp_limits!(value::HydroDispatch, val) = value.ramp_limits = set_value(value, Val(:ramp_limits), val, Val(:mva))\n\"\"\"Set [`HydroDispatch`](@ref) `time_limits`.\"\"\"\nset_time_limits!(value::HydroDispatch, val) = value.time_limits = val\n\"\"\"Set [`HydroDispatch`](@ref) `base_power`.\"\"\"\nset_base_power!(value::HydroDispatch, val) = value.base_power = val\n\"\"\"Set [`HydroDispatch`](@ref) `status`.\"\"\"\nset_status!(value::HydroDispatch, val) = value.status = val\n\"\"\"Set [`HydroDispatch`](@ref) `time_at_status`.\"\"\"\nset_time_at_status!(value::HydroDispatch, val) = value.time_at_status = val\n\"\"\"Set [`HydroDispatch`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::HydroDispatch, val) = value.operation_cost = val\n\"\"\"Set [`HydroDispatch`](@ref) `services`.\"\"\"\nset_services!(value::HydroDispatch, val) = value.services = val\n\"\"\"Set [`HydroDispatch`](@ref) `ext`.\"\"\"\nset_ext!(value::HydroDispatch, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HydroPumpTurbine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HydroPumpTurbine <: HydroUnit\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        active_power_limits_pump::MinMax\n        outflow_limits::Union{Nothing, MinMax}\n        powerhouse_elevation::Float64\n        ramp_limits::Union{Nothing, UpDown}\n        time_limits::Union{Nothing, UpDown}\n        base_power::Float64\n        status::PumpHydroStatus\n        time_at_status::Float64\n        operation_cost::Union{HydroGenerationCost, MarketBidCost}\n        active_power_pump::Float64\n        efficiency::TurbinePump\n        transition_time::TurbinePump\n        minimum_time::TurbinePump\n        travel_time::Union{Nothing, Float64}\n        conversion_factor::Float64\n        must_run::Bool\n        prime_mover_type::PrimeMovers\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA hydropower pumped turbine that needs to have two [`HydroReservoir`](@ref)s attached, suitable for modeling independent pumped hydro with reservoirs.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the turbine unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW) for the turbine, validation range: `(0, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `active_power_limits_pump::MinMax`: Minimum and maximum stable active power levels (MW) for the pump, validation range: `(0, nothing)`\n- `outflow_limits::Union{Nothing, MinMax}`: Turbine/Pump outflow limits in m3/s. Set to `Nothing` if not applicable\n- `powerhouse_elevation::Float64`: Height level in meters above the sea level of the powerhouse on which the turbine is installed., validation range: `(0, nothing)`\n- `ramp_limits::Union{Nothing, UpDown}`: ramp up and ramp down limits in MW/min, validation range: `(0, nothing)`\n- `time_limits::Union{Nothing, UpDown}`: Minimum up and Minimum down time limits in hours, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `status::PumpHydroStatus`: (default: `PumpHydroStatus.OFF`) Initial Operating status of a pumped‑storage hydro unit. See [PumpHydroStatus](@ref) for reference\n- `time_at_status::Float64`: (default: `INFINITE_TIME`) Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\n- `operation_cost::Union{HydroGenerationCost, MarketBidCost}`: (default: `HydroGenerationCost(nothing)`) [`OperationalCost`](@ref) of generation\n- `active_power_pump::Float64`: (default: `0.0`) Initial active power set point of the pump unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `efficiency::TurbinePump`: (default: `(turbine = 1.0, pump = 1.0)`) Turbine/Pump efficiency [0, 1.0]\n- `transition_time::TurbinePump`: (default: `(turbine = 0.0, pump = 0.0)`) Transition time in hours to switch into the specific mode.\n- `minimum_time::TurbinePump`: (default: `(turbine = 0.0, pump = 0.0)`) Minimum operating time in hours for the specific mode.\n- `travel_time::Union{Nothing, Float64}`: (default: `nothing`) Downstream (from reservoir into turbine) travel time in hours.\n- `conversion_factor::Float64`: (default: `1.0`) Conversion factor from flow/volume to energy: m^3 -> p.u-hr\n- `must_run::Bool`: (default: `false`) Whether the unit must run (i.e., cannot be curtailed)\n- `prime_mover_type::PrimeMovers`: (default: `PrimeMovers.PS`) Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct HydroPumpTurbine <: HydroUnit\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the turbine unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Minimum and maximum stable active power levels (MW) for the turbine\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Minimum and maximum stable active power levels (MW) for the pump\"\n    active_power_limits_pump::MinMax\n    \"Turbine/Pump outflow limits in m3/s. Set to `Nothing` if not applicable\"\n    outflow_limits::Union{Nothing, MinMax}\n    \"Height level in meters above the sea level of the powerhouse on which the turbine is installed.\"\n    powerhouse_elevation::Float64\n    \"ramp up and ramp down limits in MW/min\"\n    ramp_limits::Union{Nothing, UpDown}\n    \"Minimum up and Minimum down time limits in hours\"\n    time_limits::Union{Nothing, UpDown}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Initial Operating status of a pumped‑storage hydro unit. See [PumpHydroStatus](@ref) for reference\"\n    status::PumpHydroStatus\n    \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\"\n    time_at_status::Float64\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{HydroGenerationCost, MarketBidCost}\n    \"Initial active power set point of the pump unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power_pump::Float64\n    \"Turbine/Pump efficiency [0, 1.0]\"\n    efficiency::TurbinePump\n    \"Transition time in hours to switch into the specific mode.\"\n    transition_time::TurbinePump\n    \"Minimum operating time in hours for the specific mode.\"\n    minimum_time::TurbinePump\n    \"Downstream (from reservoir into turbine) travel time in hours.\"\n    travel_time::Union{Nothing, Float64}\n    \"Conversion factor from flow/volume to energy: m^3 -> p.u-hr\"\n    conversion_factor::Float64\n    \"Whether the unit must run (i.e., cannot be curtailed)\"\n    must_run::Bool\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HydroPumpTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, active_power_limits_pump, outflow_limits, powerhouse_elevation, ramp_limits, time_limits, base_power, status=PumpHydroStatus.OFF, time_at_status=INFINITE_TIME, operation_cost=HydroGenerationCost(nothing), active_power_pump=0.0, efficiency=(turbine = 1.0, pump = 1.0), transition_time=(turbine = 0.0, pump = 0.0), minimum_time=(turbine = 0.0, pump = 0.0), travel_time=nothing, conversion_factor=1.0, must_run=false, prime_mover_type=PrimeMovers.PS, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    HydroPumpTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, active_power_limits_pump, outflow_limits, powerhouse_elevation, ramp_limits, time_limits, base_power, status, time_at_status, operation_cost, active_power_pump, efficiency, transition_time, minimum_time, travel_time, conversion_factor, must_run, prime_mover_type, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction HydroPumpTurbine(; name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, active_power_limits_pump, outflow_limits, powerhouse_elevation, ramp_limits, time_limits, base_power, status=PumpHydroStatus.OFF, time_at_status=INFINITE_TIME, operation_cost=HydroGenerationCost(nothing), active_power_pump=0.0, efficiency=(turbine = 1.0, pump = 1.0), transition_time=(turbine = 0.0, pump = 0.0), minimum_time=(turbine = 0.0, pump = 0.0), travel_time=nothing, conversion_factor=1.0, must_run=false, prime_mover_type=PrimeMovers.PS, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    HydroPumpTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, active_power_limits_pump, outflow_limits, powerhouse_elevation, ramp_limits, time_limits, base_power, status, time_at_status, operation_cost, active_power_pump, efficiency, transition_time, minimum_time, travel_time, conversion_factor, must_run, prime_mover_type, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroPumpTurbine(::Nothing)\n    HydroPumpTurbine(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        active_power_limits_pump=(min=0.0, max=0.0),\n        outflow_limits=nothing,\n        powerhouse_elevation=0.0,\n        ramp_limits=nothing,\n        time_limits=nothing,\n        base_power=100.0,\n        status=PumpHydroStatus.OFF,\n        time_at_status=INFINITE_TIME,\n        operation_cost=HydroGenerationCost(nothing),\n        active_power_pump=0.0,\n        efficiency=(turbine = 1.0, pump = 1.0),\n        transition_time=(turbine = 0.0, pump = 0.0),\n        minimum_time=(turbine = 0.0, pump = 0.0),\n        travel_time=nothing,\n        conversion_factor=1.0,\n        must_run=false,\n        prime_mover_type=PrimeMovers.OT,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HydroPumpTurbine`](@ref) `name`.\"\"\"\nget_name(value::HydroPumpTurbine) = value.name\n\"\"\"Get [`HydroPumpTurbine`](@ref) `available`.\"\"\"\nget_available(value::HydroPumpTurbine) = value.available\n\"\"\"Get [`HydroPumpTurbine`](@ref) `bus`.\"\"\"\nget_bus(value::HydroPumpTurbine) = value.bus\n\"\"\"Get [`HydroPumpTurbine`](@ref) `active_power`.\"\"\"\nget_active_power(value::HydroPumpTurbine) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::HydroPumpTurbine) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `rating`.\"\"\"\nget_rating(value::HydroPumpTurbine) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::HydroPumpTurbine) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::HydroPumpTurbine) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `active_power_limits_pump`.\"\"\"\nget_active_power_limits_pump(value::HydroPumpTurbine) = get_value(value, Val(:active_power_limits_pump), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `outflow_limits`.\"\"\"\nget_outflow_limits(value::HydroPumpTurbine) = value.outflow_limits\n\"\"\"Get [`HydroPumpTurbine`](@ref) `powerhouse_elevation`.\"\"\"\nget_powerhouse_elevation(value::HydroPumpTurbine) = value.powerhouse_elevation\n\"\"\"Get [`HydroPumpTurbine`](@ref) `ramp_limits`.\"\"\"\nget_ramp_limits(value::HydroPumpTurbine) = get_value(value, Val(:ramp_limits), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `time_limits`.\"\"\"\nget_time_limits(value::HydroPumpTurbine) = value.time_limits\n\"\"\"Get [`HydroPumpTurbine`](@ref) `base_power`.\"\"\"\nget_base_power(value::HydroPumpTurbine) = value.base_power\n\"\"\"Get [`HydroPumpTurbine`](@ref) `status`.\"\"\"\nget_status(value::HydroPumpTurbine) = value.status\n\"\"\"Get [`HydroPumpTurbine`](@ref) `time_at_status`.\"\"\"\nget_time_at_status(value::HydroPumpTurbine) = value.time_at_status\n\"\"\"Get [`HydroPumpTurbine`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::HydroPumpTurbine) = value.operation_cost\n\"\"\"Get [`HydroPumpTurbine`](@ref) `active_power_pump`.\"\"\"\nget_active_power_pump(value::HydroPumpTurbine) = get_value(value, Val(:active_power_pump), Val(:mva))\n\"\"\"Get [`HydroPumpTurbine`](@ref) `efficiency`.\"\"\"\nget_efficiency(value::HydroPumpTurbine) = value.efficiency\n\"\"\"Get [`HydroPumpTurbine`](@ref) `transition_time`.\"\"\"\nget_transition_time(value::HydroPumpTurbine) = value.transition_time\n\"\"\"Get [`HydroPumpTurbine`](@ref) `minimum_time`.\"\"\"\nget_minimum_time(value::HydroPumpTurbine) = value.minimum_time\n\"\"\"Get [`HydroPumpTurbine`](@ref) `travel_time`.\"\"\"\nget_travel_time(value::HydroPumpTurbine) = value.travel_time\n\"\"\"Get [`HydroPumpTurbine`](@ref) `conversion_factor`.\"\"\"\nget_conversion_factor(value::HydroPumpTurbine) = value.conversion_factor\n\"\"\"Get [`HydroPumpTurbine`](@ref) `must_run`.\"\"\"\nget_must_run(value::HydroPumpTurbine) = value.must_run\n\"\"\"Get [`HydroPumpTurbine`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::HydroPumpTurbine) = value.prime_mover_type\n\"\"\"Get [`HydroPumpTurbine`](@ref) `services`.\"\"\"\nget_services(value::HydroPumpTurbine) = value.services\n\"\"\"Get [`HydroPumpTurbine`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::HydroPumpTurbine) = value.dynamic_injector\n\"\"\"Get [`HydroPumpTurbine`](@ref) `ext`.\"\"\"\nget_ext(value::HydroPumpTurbine) = value.ext\n\"\"\"Get [`HydroPumpTurbine`](@ref) `internal`.\"\"\"\nget_internal(value::HydroPumpTurbine) = value.internal\n\n\"\"\"Set [`HydroPumpTurbine`](@ref) `available`.\"\"\"\nset_available!(value::HydroPumpTurbine, val) = value.available = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `bus`.\"\"\"\nset_bus!(value::HydroPumpTurbine, val) = value.bus = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `active_power`.\"\"\"\nset_active_power!(value::HydroPumpTurbine, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::HydroPumpTurbine, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `rating`.\"\"\"\nset_rating!(value::HydroPumpTurbine, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::HydroPumpTurbine, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::HydroPumpTurbine, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `active_power_limits_pump`.\"\"\"\nset_active_power_limits_pump!(value::HydroPumpTurbine, val) = value.active_power_limits_pump = set_value(value, Val(:active_power_limits_pump), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `outflow_limits`.\"\"\"\nset_outflow_limits!(value::HydroPumpTurbine, val) = value.outflow_limits = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `powerhouse_elevation`.\"\"\"\nset_powerhouse_elevation!(value::HydroPumpTurbine, val) = value.powerhouse_elevation = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `ramp_limits`.\"\"\"\nset_ramp_limits!(value::HydroPumpTurbine, val) = value.ramp_limits = set_value(value, Val(:ramp_limits), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `time_limits`.\"\"\"\nset_time_limits!(value::HydroPumpTurbine, val) = value.time_limits = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `base_power`.\"\"\"\nset_base_power!(value::HydroPumpTurbine, val) = value.base_power = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `status`.\"\"\"\nset_status!(value::HydroPumpTurbine, val) = value.status = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `time_at_status`.\"\"\"\nset_time_at_status!(value::HydroPumpTurbine, val) = value.time_at_status = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::HydroPumpTurbine, val) = value.operation_cost = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `active_power_pump`.\"\"\"\nset_active_power_pump!(value::HydroPumpTurbine, val) = value.active_power_pump = set_value(value, Val(:active_power_pump), val, Val(:mva))\n\"\"\"Set [`HydroPumpTurbine`](@ref) `efficiency`.\"\"\"\nset_efficiency!(value::HydroPumpTurbine, val) = value.efficiency = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `transition_time`.\"\"\"\nset_transition_time!(value::HydroPumpTurbine, val) = value.transition_time = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `minimum_time`.\"\"\"\nset_minimum_time!(value::HydroPumpTurbine, val) = value.minimum_time = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `travel_time`.\"\"\"\nset_travel_time!(value::HydroPumpTurbine, val) = value.travel_time = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `conversion_factor`.\"\"\"\nset_conversion_factor!(value::HydroPumpTurbine, val) = value.conversion_factor = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `must_run`.\"\"\"\nset_must_run!(value::HydroPumpTurbine, val) = value.must_run = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::HydroPumpTurbine, val) = value.prime_mover_type = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `services`.\"\"\"\nset_services!(value::HydroPumpTurbine, val) = value.services = val\n\"\"\"Set [`HydroPumpTurbine`](@ref) `ext`.\"\"\"\nset_ext!(value::HydroPumpTurbine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HydroReservoir.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HydroReservoir <: Device\n        name::String\n        available::Bool\n        storage_level_limits::MinMax\n        initial_level::Float64\n        spillage_limits::Union{Nothing, MinMax}\n        inflow::Float64\n        outflow::Float64\n        level_targets::Union{Nothing, Float64}\n        intake_elevation::Float64\n        head_to_volume_factor::ValueCurve\n        upstream_turbines::Vector{HydroUnit}\n        downstream_turbines::Vector{HydroUnit}\n        upstream_reservoirs::Vector{Device}\n        operation_cost::HydroReservoirCost\n        level_data_type::ReservoirDataType\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA hydropower reservoir that have attached [`HydroTurbine`](@ref)(s) or [`HydroPumpTurbine`](@ref)(s) used to generate power.\nSee [How to Define Hydro Generators with Reservoirs](@ref hydro_resv) for supported configurations.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `storage_level_limits::MinMax`: Storage level limits for the reservoir in m^3, m, or MWh, based on the [`ReservoirDataType`](@ref  hydroreservoir_list) selected for `level_data_type`\n- `initial_level::Float64`: Initial level of the reservoir relative to the `storage_level_limits.max`.\n- `spillage_limits::Union{Nothing, MinMax}`: Amount of water allowed to be spilled from the reservoir. If nothing, infinite spillage is allowed.\n- `inflow::Float64`: Amount of water refilling the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\n- `outflow::Float64`: Amount of water naturally going out of the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\n- `level_targets::Union{Nothing, Float64}`: Reservoir level targets at the end of a simulation as a fraction of the `storage_level_limits.max`.\n- `intake_elevation::Float64`: Height of the intake of the reservoir, towards the downstream turbines, in meters above the sea level.\n- `head_to_volume_factor::ValueCurve`: Head to volume relationship for the reservoir.\n- `upstream_turbines::Vector{HydroUnit}`: (default: `Device[]`) Vector of [HydroUnit](@ref)(s) that are immediately upstream of this reservoir. This reservoir is the tail reservoir for these units, and their flow goes into this reservoir.\n- `downstream_turbines::Vector{HydroUnit}`: (default: `Device[]`) Vector of [HydroUnit](@ref)(s) that are immediately downstream of this reservoir. This reservoir is the head reservoir for these units, and its feed flow into these units.\n- `upstream_reservoirs::Vector{Device}`: (default: `Device[]`) Vector of [Device](@ref)(s) reservoirs that are immediately upstream of this reservoir. This reservoir receives the spillage flow from upstream_reservoirs.\n- `operation_cost::HydroReservoirCost`: (default: `HydroReservoirCost(nothing)`) [`OperationalCost`](@ref) of reservoir.\n- `level_data_type::ReservoirDataType`: (default: `ReservoirDataType.USABLE_VOLUME`) Reservoir level data type. See [ReservoirDataType](@ref) for reference.\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct HydroReservoir <: Device\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Storage level limits for the reservoir in m^3, m, or MWh, based on the [`ReservoirDataType`](@ref  hydroreservoir_list) selected for `level_data_type`\"\n    storage_level_limits::MinMax\n    \"Initial level of the reservoir relative to the `storage_level_limits.max`.\"\n    initial_level::Float64\n    \"Amount of water allowed to be spilled from the reservoir. If nothing, infinite spillage is allowed.\"\n    spillage_limits::Union{Nothing, MinMax}\n    \"Amount of water refilling the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\"\n    inflow::Float64\n    \"Amount of water naturally going out of the reservoir in m^3/h or MW (if `level_data_type` is [`ReservoirDataType`](@ref hydroreservoir_list)`.ENERGY`).\"\n    outflow::Float64\n    \"Reservoir level targets at the end of a simulation as a fraction of the `storage_level_limits.max`.\"\n    level_targets::Union{Nothing, Float64}\n    \"Height of the intake of the reservoir, towards the downstream turbines, in meters above the sea level.\"\n    intake_elevation::Float64\n    \"Head to volume relationship for the reservoir.\"\n    head_to_volume_factor::ValueCurve\n    \"Vector of [HydroUnit](@ref)(s) that are immediately upstream of this reservoir. This reservoir is the tail reservoir for these units, and their flow goes into this reservoir.\"\n    upstream_turbines::Vector{HydroUnit}\n    \"Vector of [HydroUnit](@ref)(s) that are immediately downstream of this reservoir. This reservoir is the head reservoir for these units, and its feed flow into these units.\"\n    downstream_turbines::Vector{HydroUnit}\n    \"Vector of [Device](@ref)(s) reservoirs that are immediately upstream of this reservoir. This reservoir receives the spillage flow from upstream_reservoirs.\"\n    upstream_reservoirs::Vector{Device}\n    \"[`OperationalCost`](@ref) of reservoir.\"\n    operation_cost::HydroReservoirCost\n    \"Reservoir level data type. See [ReservoirDataType](@ref) for reference.\"\n    level_data_type::ReservoirDataType\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HydroReservoir(name, available, storage_level_limits, initial_level, spillage_limits, inflow, outflow, level_targets, intake_elevation, head_to_volume_factor, upstream_turbines=Device[], downstream_turbines=Device[], upstream_reservoirs=Device[], operation_cost=HydroReservoirCost(nothing), level_data_type=ReservoirDataType.USABLE_VOLUME, ext=Dict{String, Any}(), )\n    HydroReservoir(name, available, storage_level_limits, initial_level, spillage_limits, inflow, outflow, level_targets, intake_elevation, head_to_volume_factor, upstream_turbines, downstream_turbines, upstream_reservoirs, operation_cost, level_data_type, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction HydroReservoir(; name, available, storage_level_limits, initial_level, spillage_limits, inflow, outflow, level_targets, intake_elevation, head_to_volume_factor, upstream_turbines=Device[], downstream_turbines=Device[], upstream_reservoirs=Device[], operation_cost=HydroReservoirCost(nothing), level_data_type=ReservoirDataType.USABLE_VOLUME, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    HydroReservoir(name, available, storage_level_limits, initial_level, spillage_limits, inflow, outflow, level_targets, intake_elevation, head_to_volume_factor, upstream_turbines, downstream_turbines, upstream_reservoirs, operation_cost, level_data_type, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroReservoir(::Nothing)\n    HydroReservoir(;\n        name=\"init\",\n        available=false,\n        storage_level_limits=(min=0.0, max=0.0),\n        initial_level=0.0,\n        spillage_limits=nothing,\n        inflow=0.0,\n        outflow=0.0,\n        level_targets=nothing,\n        intake_elevation=0.0,\n        head_to_volume_factor=LinearCurve(0.0),\n        upstream_turbines=Device[],\n        downstream_turbines=Device[],\n        upstream_reservoirs=Device[],\n        operation_cost=HydroReservoirCost(nothing),\n        level_data_type=ReservoirDataType.USABLE_VOLUME,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HydroReservoir`](@ref) `name`.\"\"\"\nget_name(value::HydroReservoir) = value.name\n\"\"\"Get [`HydroReservoir`](@ref) `available`.\"\"\"\nget_available(value::HydroReservoir) = value.available\n\"\"\"Get [`HydroReservoir`](@ref) `storage_level_limits`.\"\"\"\nget_storage_level_limits(value::HydroReservoir) = value.storage_level_limits\n\"\"\"Get [`HydroReservoir`](@ref) `initial_level`.\"\"\"\nget_initial_level(value::HydroReservoir) = value.initial_level\n\"\"\"Get [`HydroReservoir`](@ref) `spillage_limits`.\"\"\"\nget_spillage_limits(value::HydroReservoir) = value.spillage_limits\n\"\"\"Get [`HydroReservoir`](@ref) `inflow`.\"\"\"\nget_inflow(value::HydroReservoir) = value.inflow\n\"\"\"Get [`HydroReservoir`](@ref) `outflow`.\"\"\"\nget_outflow(value::HydroReservoir) = value.outflow\n\"\"\"Get [`HydroReservoir`](@ref) `level_targets`.\"\"\"\nget_level_targets(value::HydroReservoir) = value.level_targets\n\"\"\"Get [`HydroReservoir`](@ref) `intake_elevation`.\"\"\"\nget_intake_elevation(value::HydroReservoir) = value.intake_elevation\n\"\"\"Get [`HydroReservoir`](@ref) `head_to_volume_factor`.\"\"\"\nget_head_to_volume_factor(value::HydroReservoir) = value.head_to_volume_factor\n\"\"\"Get [`HydroReservoir`](@ref) `upstream_turbines`.\"\"\"\nget_upstream_turbines(value::HydroReservoir) = value.upstream_turbines\n\"\"\"Get [`HydroReservoir`](@ref) `downstream_turbines`.\"\"\"\nget_downstream_turbines(value::HydroReservoir) = value.downstream_turbines\n\"\"\"Get [`HydroReservoir`](@ref) `upstream_reservoirs`.\"\"\"\nget_upstream_reservoirs(value::HydroReservoir) = value.upstream_reservoirs\n\"\"\"Get [`HydroReservoir`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::HydroReservoir) = value.operation_cost\n\"\"\"Get [`HydroReservoir`](@ref) `level_data_type`.\"\"\"\nget_level_data_type(value::HydroReservoir) = value.level_data_type\n\"\"\"Get [`HydroReservoir`](@ref) `ext`.\"\"\"\nget_ext(value::HydroReservoir) = value.ext\n\"\"\"Get [`HydroReservoir`](@ref) `internal`.\"\"\"\nget_internal(value::HydroReservoir) = value.internal\n\n\"\"\"Set [`HydroReservoir`](@ref) `available`.\"\"\"\nset_available!(value::HydroReservoir, val) = value.available = val\n\"\"\"Set [`HydroReservoir`](@ref) `storage_level_limits`.\"\"\"\nset_storage_level_limits!(value::HydroReservoir, val) = value.storage_level_limits = val\n\"\"\"Set [`HydroReservoir`](@ref) `initial_level`.\"\"\"\nset_initial_level!(value::HydroReservoir, val) = value.initial_level = val\n\"\"\"Set [`HydroReservoir`](@ref) `spillage_limits`.\"\"\"\nset_spillage_limits!(value::HydroReservoir, val) = value.spillage_limits = val\n\"\"\"Set [`HydroReservoir`](@ref) `inflow`.\"\"\"\nset_inflow!(value::HydroReservoir, val) = value.inflow = val\n\"\"\"Set [`HydroReservoir`](@ref) `outflow`.\"\"\"\nset_outflow!(value::HydroReservoir, val) = value.outflow = val\n\"\"\"Set [`HydroReservoir`](@ref) `level_targets`.\"\"\"\nset_level_targets!(value::HydroReservoir, val) = value.level_targets = val\n\"\"\"Set [`HydroReservoir`](@ref) `intake_elevation`.\"\"\"\nset_intake_elevation!(value::HydroReservoir, val) = value.intake_elevation = val\n\"\"\"Set [`HydroReservoir`](@ref) `head_to_volume_factor`.\"\"\"\nset_head_to_volume_factor!(value::HydroReservoir, val) = value.head_to_volume_factor = val\n\"\"\"Set [`HydroReservoir`](@ref) `upstream_turbines`.\"\"\"\nset_upstream_turbines!(value::HydroReservoir, val) = value.upstream_turbines = val\n\"\"\"Set [`HydroReservoir`](@ref) `downstream_turbines`.\"\"\"\nset_downstream_turbines!(value::HydroReservoir, val) = value.downstream_turbines = val\n\"\"\"Set [`HydroReservoir`](@ref) `upstream_reservoirs`.\"\"\"\nset_upstream_reservoirs!(value::HydroReservoir, val) = value.upstream_reservoirs = val\n\"\"\"Set [`HydroReservoir`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::HydroReservoir, val) = value.operation_cost = val\n\"\"\"Set [`HydroReservoir`](@ref) `level_data_type`.\"\"\"\nset_level_data_type!(value::HydroReservoir, val) = value.level_data_type = val\n\"\"\"Set [`HydroReservoir`](@ref) `ext`.\"\"\"\nset_ext!(value::HydroReservoir, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HydroTurbine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HydroTurbine <: HydroUnit\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        base_power::Float64\n        operation_cost::Union{HydroGenerationCost, MarketBidCost}\n        powerhouse_elevation::Float64\n        ramp_limits::Union{Nothing, UpDown}\n        time_limits::Union{Nothing, UpDown}\n        outflow_limits::Union{Nothing, MinMax}\n        efficiency::Float64\n        turbine_type::HydroTurbineType\n        conversion_factor::Float64\n        prime_mover_type::PrimeMovers\n        travel_time::Union{Nothing, Float64}\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA hydropower generator that must have a [`HydroReservoir`](@ref) attached, suitable for modeling independent turbines and reservoirs.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW), validation range: `(0, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `operation_cost::Union{HydroGenerationCost, MarketBidCost}`: (default: `HydroGenerationCost(nothing)`) [`OperationalCost`](@ref) of generation\n- `powerhouse_elevation::Float64`: (default: `0.0`) Height level in meters above the sea level of the powerhouse on which the turbine is installed., validation range: `(0, nothing)`\n- `ramp_limits::Union{Nothing, UpDown}`: (default: `nothing`) ramp up and ramp down limits in MW/min, validation range: `(0, nothing)`\n- `time_limits::Union{Nothing, UpDown}`: (default: `nothing`) Minimum up and Minimum down time limits in hours, validation range: `(0, nothing)`\n- `outflow_limits::Union{Nothing, MinMax}`: (default: `nothing`) Turbine outflow limits in m3/s. Set to `Nothing` if not applicable\n- `efficiency::Float64`: (default: `1.0`) Turbine efficiency [0, 1.0], validation range: `(0, 1)`\n- `turbine_type::HydroTurbineType`: (default: `HydroTurbineType.UNKNOWN`) Type of the turbine\n- `conversion_factor::Float64`: (default: `1.0`) Conversion factor from flow/volume to energy: m^3 -> p.u-hr\n- `prime_mover_type::PrimeMovers`: (default: `PrimeMovers.HY`) Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `travel_time::Union{Nothing, Float64}`: (default: `nothing`) Downstream (from reservoir into turbine) travel time in hours.\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct HydroTurbine <: HydroUnit\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{HydroGenerationCost, MarketBidCost}\n    \"Height level in meters above the sea level of the powerhouse on which the turbine is installed.\"\n    powerhouse_elevation::Float64\n    \"ramp up and ramp down limits in MW/min\"\n    ramp_limits::Union{Nothing, UpDown}\n    \"Minimum up and Minimum down time limits in hours\"\n    time_limits::Union{Nothing, UpDown}\n    \"Turbine outflow limits in m3/s. Set to `Nothing` if not applicable\"\n    outflow_limits::Union{Nothing, MinMax}\n    \"Turbine efficiency [0, 1.0]\"\n    efficiency::Float64\n    \"Type of the turbine\"\n    turbine_type::HydroTurbineType\n    \"Conversion factor from flow/volume to energy: m^3 -> p.u-hr\"\n    conversion_factor::Float64\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Downstream (from reservoir into turbine) travel time in hours.\"\n    travel_time::Union{Nothing, Float64}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HydroTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, base_power, operation_cost=HydroGenerationCost(nothing), powerhouse_elevation=0.0, ramp_limits=nothing, time_limits=nothing, outflow_limits=nothing, efficiency=1.0, turbine_type=HydroTurbineType.UNKNOWN, conversion_factor=1.0, prime_mover_type=PrimeMovers.HY, travel_time=nothing, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    HydroTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, base_power, operation_cost, powerhouse_elevation, ramp_limits, time_limits, outflow_limits, efficiency, turbine_type, conversion_factor, prime_mover_type, travel_time, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction HydroTurbine(; name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, base_power, operation_cost=HydroGenerationCost(nothing), powerhouse_elevation=0.0, ramp_limits=nothing, time_limits=nothing, outflow_limits=nothing, efficiency=1.0, turbine_type=HydroTurbineType.UNKNOWN, conversion_factor=1.0, prime_mover_type=PrimeMovers.HY, travel_time=nothing, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    HydroTurbine(name, available, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, base_power, operation_cost, powerhouse_elevation, ramp_limits, time_limits, outflow_limits, efficiency, turbine_type, conversion_factor, prime_mover_type, travel_time, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroTurbine(::Nothing)\n    HydroTurbine(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        base_power=100.0,\n        operation_cost=HydroGenerationCost(nothing),\n        powerhouse_elevation=0.0,\n        ramp_limits=nothing,\n        time_limits=nothing,\n        outflow_limits=nothing,\n        efficiency=1.0,\n        turbine_type=HydroTurbineType.UNKNOWN,\n        conversion_factor=1.0,\n        prime_mover_type=PrimeMovers.OT,\n        travel_time=nothing,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HydroTurbine`](@ref) `name`.\"\"\"\nget_name(value::HydroTurbine) = value.name\n\"\"\"Get [`HydroTurbine`](@ref) `available`.\"\"\"\nget_available(value::HydroTurbine) = value.available\n\"\"\"Get [`HydroTurbine`](@ref) `bus`.\"\"\"\nget_bus(value::HydroTurbine) = value.bus\n\"\"\"Get [`HydroTurbine`](@ref) `active_power`.\"\"\"\nget_active_power(value::HydroTurbine) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::HydroTurbine) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `rating`.\"\"\"\nget_rating(value::HydroTurbine) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::HydroTurbine) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::HydroTurbine) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `base_power`.\"\"\"\nget_base_power(value::HydroTurbine) = value.base_power\n\"\"\"Get [`HydroTurbine`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::HydroTurbine) = value.operation_cost\n\"\"\"Get [`HydroTurbine`](@ref) `powerhouse_elevation`.\"\"\"\nget_powerhouse_elevation(value::HydroTurbine) = value.powerhouse_elevation\n\"\"\"Get [`HydroTurbine`](@ref) `ramp_limits`.\"\"\"\nget_ramp_limits(value::HydroTurbine) = get_value(value, Val(:ramp_limits), Val(:mva))\n\"\"\"Get [`HydroTurbine`](@ref) `time_limits`.\"\"\"\nget_time_limits(value::HydroTurbine) = value.time_limits\n\"\"\"Get [`HydroTurbine`](@ref) `outflow_limits`.\"\"\"\nget_outflow_limits(value::HydroTurbine) = value.outflow_limits\n\"\"\"Get [`HydroTurbine`](@ref) `efficiency`.\"\"\"\nget_efficiency(value::HydroTurbine) = value.efficiency\n\"\"\"Get [`HydroTurbine`](@ref) `turbine_type`.\"\"\"\nget_turbine_type(value::HydroTurbine) = value.turbine_type\n\"\"\"Get [`HydroTurbine`](@ref) `conversion_factor`.\"\"\"\nget_conversion_factor(value::HydroTurbine) = value.conversion_factor\n\"\"\"Get [`HydroTurbine`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::HydroTurbine) = value.prime_mover_type\n\"\"\"Get [`HydroTurbine`](@ref) `travel_time`.\"\"\"\nget_travel_time(value::HydroTurbine) = value.travel_time\n\"\"\"Get [`HydroTurbine`](@ref) `services`.\"\"\"\nget_services(value::HydroTurbine) = value.services\n\"\"\"Get [`HydroTurbine`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::HydroTurbine) = value.dynamic_injector\n\"\"\"Get [`HydroTurbine`](@ref) `ext`.\"\"\"\nget_ext(value::HydroTurbine) = value.ext\n\"\"\"Get [`HydroTurbine`](@ref) `internal`.\"\"\"\nget_internal(value::HydroTurbine) = value.internal\n\n\"\"\"Set [`HydroTurbine`](@ref) `available`.\"\"\"\nset_available!(value::HydroTurbine, val) = value.available = val\n\"\"\"Set [`HydroTurbine`](@ref) `bus`.\"\"\"\nset_bus!(value::HydroTurbine, val) = value.bus = val\n\"\"\"Set [`HydroTurbine`](@ref) `active_power`.\"\"\"\nset_active_power!(value::HydroTurbine, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::HydroTurbine, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `rating`.\"\"\"\nset_rating!(value::HydroTurbine, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::HydroTurbine, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::HydroTurbine, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `base_power`.\"\"\"\nset_base_power!(value::HydroTurbine, val) = value.base_power = val\n\"\"\"Set [`HydroTurbine`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::HydroTurbine, val) = value.operation_cost = val\n\"\"\"Set [`HydroTurbine`](@ref) `powerhouse_elevation`.\"\"\"\nset_powerhouse_elevation!(value::HydroTurbine, val) = value.powerhouse_elevation = val\n\"\"\"Set [`HydroTurbine`](@ref) `ramp_limits`.\"\"\"\nset_ramp_limits!(value::HydroTurbine, val) = value.ramp_limits = set_value(value, Val(:ramp_limits), val, Val(:mva))\n\"\"\"Set [`HydroTurbine`](@ref) `time_limits`.\"\"\"\nset_time_limits!(value::HydroTurbine, val) = value.time_limits = val\n\"\"\"Set [`HydroTurbine`](@ref) `outflow_limits`.\"\"\"\nset_outflow_limits!(value::HydroTurbine, val) = value.outflow_limits = val\n\"\"\"Set [`HydroTurbine`](@ref) `efficiency`.\"\"\"\nset_efficiency!(value::HydroTurbine, val) = value.efficiency = val\n\"\"\"Set [`HydroTurbine`](@ref) `turbine_type`.\"\"\"\nset_turbine_type!(value::HydroTurbine, val) = value.turbine_type = val\n\"\"\"Set [`HydroTurbine`](@ref) `conversion_factor`.\"\"\"\nset_conversion_factor!(value::HydroTurbine, val) = value.conversion_factor = val\n\"\"\"Set [`HydroTurbine`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::HydroTurbine, val) = value.prime_mover_type = val\n\"\"\"Set [`HydroTurbine`](@ref) `travel_time`.\"\"\"\nset_travel_time!(value::HydroTurbine, val) = value.travel_time = val\n\"\"\"Set [`HydroTurbine`](@ref) `services`.\"\"\"\nset_services!(value::HydroTurbine, val) = value.services = val\n\"\"\"Set [`HydroTurbine`](@ref) `ext`.\"\"\"\nset_ext!(value::HydroTurbine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/HydroTurbineGov.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct HydroTurbineGov <: TurbineGov\n        R::Float64\n        r::Float64\n        Tr::Float64\n        Tf::Float64\n        Tg::Float64\n        VELM::Float64\n        gate_position_limits::MinMax\n        Tw::Float64\n        At::Float64\n        D_T::Float64\n        q_nl::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nHydro Turbine-Governor\n\n# Arguments\n- `R::Float64`: Permanent droop parameter, validation range: `(0, 0.1)`\n- `r::Float64`: Temporary Droop, validation range: `(0, 2)`\n- `Tr::Float64`: Governor time constant, validation range: `(eps(), 30)`\n- `Tf::Float64`: Filter Time constant, validation range: `(eps(), 0.1)`\n- `Tg::Float64`: Servo time constant, validation range: `(eps(), 1)`\n- `VELM::Float64`: gate velocity limit, validation range: `(eps(), 0.3)`\n- `gate_position_limits::MinMax`: Gate position limits\n- `Tw::Float64`: water time constant, validation range: `(eps(), 3)`\n- `At::Float64`: Turbine gain, validation range: `(0.8, 1.5)`\n- `D_T::Float64`: Turbine Damping, validation range: `(0, 0.5)`\n- `q_nl::Float64`: No-power flow, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the HydroTurbineGov model are:\n\tx_g1: filter_output,\n\tx_g2: desired gate, \n\tx_g3: gate opening, \n\tx_g4: turbine flow\n- `n_states::Int`: (**Do not modify.**) HYGOV has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) HYGOV has 4 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct HydroTurbineGov <: TurbineGov\n    \"Permanent droop parameter\"\n    R::Float64\n    \"Temporary Droop\"\n    r::Float64\n    \"Governor time constant\"\n    Tr::Float64\n    \"Filter Time constant\"\n    Tf::Float64\n    \"Servo time constant\"\n    Tg::Float64\n    \"gate velocity limit\"\n    VELM::Float64\n    \"Gate position limits\"\n    gate_position_limits::MinMax\n    \"water time constant\"\n    Tw::Float64\n    \"Turbine gain\"\n    At::Float64\n    \"Turbine Damping\"\n    D_T::Float64\n    \"No-power flow\"\n    q_nl::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the HydroTurbineGov model are:\n\tx_g1: filter_output,\n\tx_g2: desired gate, \n\tx_g3: gate opening, \n\tx_g4: turbine flow\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) HYGOV has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) HYGOV has 4 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction HydroTurbineGov(R, r, Tr, Tf, Tg, VELM, gate_position_limits, Tw, At, D_T, q_nl, P_ref=1.0, ext=Dict{String, Any}(), )\n    HydroTurbineGov(R, r, Tr, Tf, Tg, VELM, gate_position_limits, Tw, At, D_T, q_nl, P_ref, ext, [:x_g1, :x_g2, :x_g3, :x_g4], 4, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction HydroTurbineGov(; R, r, Tr, Tf, Tg, VELM, gate_position_limits, Tw, At, D_T, q_nl, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3, :x_g4], n_states=4, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    HydroTurbineGov(R, r, Tr, Tf, Tg, VELM, gate_position_limits, Tw, At, D_T, q_nl, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction HydroTurbineGov(::Nothing)\n    HydroTurbineGov(;\n        R=0,\n        r=0,\n        Tr=0,\n        Tf=0,\n        Tg=0,\n        VELM=0,\n        gate_position_limits=(min=0.0, max=0.0),\n        Tw=0,\n        At=0,\n        D_T=0,\n        q_nl=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`HydroTurbineGov`](@ref) `R`.\"\"\"\nget_R(value::HydroTurbineGov) = value.R\n\"\"\"Get [`HydroTurbineGov`](@ref) `r`.\"\"\"\nget_r(value::HydroTurbineGov) = value.r\n\"\"\"Get [`HydroTurbineGov`](@ref) `Tr`.\"\"\"\nget_Tr(value::HydroTurbineGov) = value.Tr\n\"\"\"Get [`HydroTurbineGov`](@ref) `Tf`.\"\"\"\nget_Tf(value::HydroTurbineGov) = value.Tf\n\"\"\"Get [`HydroTurbineGov`](@ref) `Tg`.\"\"\"\nget_Tg(value::HydroTurbineGov) = value.Tg\n\"\"\"Get [`HydroTurbineGov`](@ref) `VELM`.\"\"\"\nget_VELM(value::HydroTurbineGov) = value.VELM\n\"\"\"Get [`HydroTurbineGov`](@ref) `gate_position_limits`.\"\"\"\nget_gate_position_limits(value::HydroTurbineGov) = value.gate_position_limits\n\"\"\"Get [`HydroTurbineGov`](@ref) `Tw`.\"\"\"\nget_Tw(value::HydroTurbineGov) = value.Tw\n\"\"\"Get [`HydroTurbineGov`](@ref) `At`.\"\"\"\nget_At(value::HydroTurbineGov) = value.At\n\"\"\"Get [`HydroTurbineGov`](@ref) `D_T`.\"\"\"\nget_D_T(value::HydroTurbineGov) = value.D_T\n\"\"\"Get [`HydroTurbineGov`](@ref) `q_nl`.\"\"\"\nget_q_nl(value::HydroTurbineGov) = value.q_nl\n\"\"\"Get [`HydroTurbineGov`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::HydroTurbineGov) = value.P_ref\n\"\"\"Get [`HydroTurbineGov`](@ref) `ext`.\"\"\"\nget_ext(value::HydroTurbineGov) = value.ext\n\"\"\"Get [`HydroTurbineGov`](@ref) `states`.\"\"\"\nget_states(value::HydroTurbineGov) = value.states\n\"\"\"Get [`HydroTurbineGov`](@ref) `n_states`.\"\"\"\nget_n_states(value::HydroTurbineGov) = value.n_states\n\"\"\"Get [`HydroTurbineGov`](@ref) `states_types`.\"\"\"\nget_states_types(value::HydroTurbineGov) = value.states_types\n\"\"\"Get [`HydroTurbineGov`](@ref) `internal`.\"\"\"\nget_internal(value::HydroTurbineGov) = value.internal\n\n\"\"\"Set [`HydroTurbineGov`](@ref) `R`.\"\"\"\nset_R!(value::HydroTurbineGov, val) = value.R = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `r`.\"\"\"\nset_r!(value::HydroTurbineGov, val) = value.r = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `Tr`.\"\"\"\nset_Tr!(value::HydroTurbineGov, val) = value.Tr = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `Tf`.\"\"\"\nset_Tf!(value::HydroTurbineGov, val) = value.Tf = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `Tg`.\"\"\"\nset_Tg!(value::HydroTurbineGov, val) = value.Tg = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `VELM`.\"\"\"\nset_VELM!(value::HydroTurbineGov, val) = value.VELM = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `gate_position_limits`.\"\"\"\nset_gate_position_limits!(value::HydroTurbineGov, val) = value.gate_position_limits = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `Tw`.\"\"\"\nset_Tw!(value::HydroTurbineGov, val) = value.Tw = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `At`.\"\"\"\nset_At!(value::HydroTurbineGov, val) = value.At = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `D_T`.\"\"\"\nset_D_T!(value::HydroTurbineGov, val) = value.D_T = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `q_nl`.\"\"\"\nset_q_nl!(value::HydroTurbineGov, val) = value.q_nl = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::HydroTurbineGov, val) = value.P_ref = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `ext`.\"\"\"\nset_ext!(value::HydroTurbineGov, val) = value.ext = val\n\"\"\"Set [`HydroTurbineGov`](@ref) `states_types`.\"\"\"\nset_states_types!(value::HydroTurbineGov, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/IEEEST.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct IEEEST <: PSS\n        input_code::Int\n        remote_bus_control::Int\n        A1::Float64\n        A2::Float64\n        A3::Float64\n        A4::Float64\n        A5::Float64\n        A6::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        T5::Float64\n        T6::Float64\n        Ks::Float64\n        Ls_lim::Tuple{Float64, Float64}\n        Vcu::Float64\n        Vcl::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE Stabilizing Model PSS. \n\n# Arguments\n- `input_code::Int`: Code input for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control::Int`: ACBus identification [`number`](@ref ACBus) for control. `0` identifies the bus connected to this component\n- `A1::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `A2::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `A3::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `A4::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `A5::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `A6::Float64`: Filter coefficient, validation range: `(0, nothing)`\n- `T1::Float64`: Time constant, validation range: `(0, 10)`\n- `T2::Float64`: Time constant, validation range: `(0, 10)`\n- `T3::Float64`: Time constant, validation range: `(0, 10)`\n- `T4::Float64`: Time constant, validation range: `(0, 10)`\n- `T5::Float64`: Time constant, validation range: `(0, 10)`\n- `T6::Float64`: Time constant, validation range: `(eps(), 2.0)`\n- `Ks::Float64`: Proportional gain, validation range: `(0, nothing)`\n- `Ls_lim::Tuple{Float64, Float64}`: PSS output limits for regulator output `(Ls_min, Ls_max)`\n- `Vcu::Float64`: Cutoff limiter upper bound, validation range: `(0, 1.25)`\n- `Vcl::Float64`: Cutoff limiter lower bound, validation range: `(0, 1.0)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st filter integration,\n\tx_p2: 2nd filter integration, \n\tx_p3: 3rd filter integration, \n\tx_p4: 4rd filter integration, \n\tx_p5: T1/T2 lead-lag integrator, \n\tx_p6: T3/T4 lead-lag integrator, \n\t:x_p7 last integer,\n- `n_states::Int`: (**Do not modify.**) IEEEST has 7 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEEST has 7 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct IEEEST <: PSS\n    \"Code input for stabilizer\"\n    input_code::Int\n    \"ACBus identification [`number`](@ref ACBus) for control. `0` identifies the bus connected to this component\"\n    remote_bus_control::Int\n    \"Filter coefficient\"\n    A1::Float64\n    \"Filter coefficient\"\n    A2::Float64\n    \"Filter coefficient\"\n    A3::Float64\n    \"Filter coefficient\"\n    A4::Float64\n    \"Filter coefficient\"\n    A5::Float64\n    \"Filter coefficient\"\n    A6::Float64\n    \"Time constant\"\n    T1::Float64\n    \"Time constant\"\n    T2::Float64\n    \"Time constant\"\n    T3::Float64\n    \"Time constant\"\n    T4::Float64\n    \"Time constant\"\n    T5::Float64\n    \"Time constant\"\n    T6::Float64\n    \"Proportional gain\"\n    Ks::Float64\n    \"PSS output limits for regulator output `(Ls_min, Ls_max)`\"\n    Ls_lim::Tuple{Float64, Float64}\n    \"Cutoff limiter upper bound\"\n    Vcu::Float64\n    \"Cutoff limiter lower bound\"\n    Vcl::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st filter integration,\n\tx_p2: 2nd filter integration, \n\tx_p3: 3rd filter integration, \n\tx_p4: 4rd filter integration, \n\tx_p5: T1/T2 lead-lag integrator, \n\tx_p6: T3/T4 lead-lag integrator, \n\t:x_p7 last integer,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) IEEEST has 7 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEEST has 7 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction IEEEST(input_code, remote_bus_control, A1, A2, A3, A4, A5, A6, T1, T2, T3, T4, T5, T6, Ks, Ls_lim, Vcu, Vcl, ext=Dict{String, Any}(), )\n    IEEEST(input_code, remote_bus_control, A1, A2, A3, A4, A5, A6, T1, T2, T3, T4, T5, T6, Ks, Ls_lim, Vcu, Vcl, ext, [:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7], 7, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction IEEEST(; input_code, remote_bus_control, A1, A2, A3, A4, A5, A6, T1, T2, T3, T4, T5, T6, Ks, Ls_lim, Vcu, Vcl, ext=Dict{String, Any}(), states=[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7], n_states=7, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    IEEEST(input_code, remote_bus_control, A1, A2, A3, A4, A5, A6, T1, T2, T3, T4, T5, T6, Ks, Ls_lim, Vcu, Vcl, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction IEEEST(::Nothing)\n    IEEEST(;\n        input_code=1,\n        remote_bus_control=0,\n        A1=0,\n        A2=0,\n        A3=0,\n        A4=0,\n        A5=0,\n        A6=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        T5=0,\n        T6=0,\n        Ks=0,\n        Ls_lim=(0.0, 0.0),\n        Vcu=0,\n        Vcl=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`IEEEST`](@ref) `input_code`.\"\"\"\nget_input_code(value::IEEEST) = value.input_code\n\"\"\"Get [`IEEEST`](@ref) `remote_bus_control`.\"\"\"\nget_remote_bus_control(value::IEEEST) = value.remote_bus_control\n\"\"\"Get [`IEEEST`](@ref) `A1`.\"\"\"\nget_A1(value::IEEEST) = value.A1\n\"\"\"Get [`IEEEST`](@ref) `A2`.\"\"\"\nget_A2(value::IEEEST) = value.A2\n\"\"\"Get [`IEEEST`](@ref) `A3`.\"\"\"\nget_A3(value::IEEEST) = value.A3\n\"\"\"Get [`IEEEST`](@ref) `A4`.\"\"\"\nget_A4(value::IEEEST) = value.A4\n\"\"\"Get [`IEEEST`](@ref) `A5`.\"\"\"\nget_A5(value::IEEEST) = value.A5\n\"\"\"Get [`IEEEST`](@ref) `A6`.\"\"\"\nget_A6(value::IEEEST) = value.A6\n\"\"\"Get [`IEEEST`](@ref) `T1`.\"\"\"\nget_T1(value::IEEEST) = value.T1\n\"\"\"Get [`IEEEST`](@ref) `T2`.\"\"\"\nget_T2(value::IEEEST) = value.T2\n\"\"\"Get [`IEEEST`](@ref) `T3`.\"\"\"\nget_T3(value::IEEEST) = value.T3\n\"\"\"Get [`IEEEST`](@ref) `T4`.\"\"\"\nget_T4(value::IEEEST) = value.T4\n\"\"\"Get [`IEEEST`](@ref) `T5`.\"\"\"\nget_T5(value::IEEEST) = value.T5\n\"\"\"Get [`IEEEST`](@ref) `T6`.\"\"\"\nget_T6(value::IEEEST) = value.T6\n\"\"\"Get [`IEEEST`](@ref) `Ks`.\"\"\"\nget_Ks(value::IEEEST) = value.Ks\n\"\"\"Get [`IEEEST`](@ref) `Ls_lim`.\"\"\"\nget_Ls_lim(value::IEEEST) = value.Ls_lim\n\"\"\"Get [`IEEEST`](@ref) `Vcu`.\"\"\"\nget_Vcu(value::IEEEST) = value.Vcu\n\"\"\"Get [`IEEEST`](@ref) `Vcl`.\"\"\"\nget_Vcl(value::IEEEST) = value.Vcl\n\"\"\"Get [`IEEEST`](@ref) `ext`.\"\"\"\nget_ext(value::IEEEST) = value.ext\n\"\"\"Get [`IEEEST`](@ref) `states`.\"\"\"\nget_states(value::IEEEST) = value.states\n\"\"\"Get [`IEEEST`](@ref) `n_states`.\"\"\"\nget_n_states(value::IEEEST) = value.n_states\n\"\"\"Get [`IEEEST`](@ref) `states_types`.\"\"\"\nget_states_types(value::IEEEST) = value.states_types\n\"\"\"Get [`IEEEST`](@ref) `internal`.\"\"\"\nget_internal(value::IEEEST) = value.internal\n\n\"\"\"Set [`IEEEST`](@ref) `input_code`.\"\"\"\nset_input_code!(value::IEEEST, val) = value.input_code = val\n\"\"\"Set [`IEEEST`](@ref) `remote_bus_control`.\"\"\"\nset_remote_bus_control!(value::IEEEST, val) = value.remote_bus_control = val\n\"\"\"Set [`IEEEST`](@ref) `A1`.\"\"\"\nset_A1!(value::IEEEST, val) = value.A1 = val\n\"\"\"Set [`IEEEST`](@ref) `A2`.\"\"\"\nset_A2!(value::IEEEST, val) = value.A2 = val\n\"\"\"Set [`IEEEST`](@ref) `A3`.\"\"\"\nset_A3!(value::IEEEST, val) = value.A3 = val\n\"\"\"Set [`IEEEST`](@ref) `A4`.\"\"\"\nset_A4!(value::IEEEST, val) = value.A4 = val\n\"\"\"Set [`IEEEST`](@ref) `A5`.\"\"\"\nset_A5!(value::IEEEST, val) = value.A5 = val\n\"\"\"Set [`IEEEST`](@ref) `A6`.\"\"\"\nset_A6!(value::IEEEST, val) = value.A6 = val\n\"\"\"Set [`IEEEST`](@ref) `T1`.\"\"\"\nset_T1!(value::IEEEST, val) = value.T1 = val\n\"\"\"Set [`IEEEST`](@ref) `T2`.\"\"\"\nset_T2!(value::IEEEST, val) = value.T2 = val\n\"\"\"Set [`IEEEST`](@ref) `T3`.\"\"\"\nset_T3!(value::IEEEST, val) = value.T3 = val\n\"\"\"Set [`IEEEST`](@ref) `T4`.\"\"\"\nset_T4!(value::IEEEST, val) = value.T4 = val\n\"\"\"Set [`IEEEST`](@ref) `T5`.\"\"\"\nset_T5!(value::IEEEST, val) = value.T5 = val\n\"\"\"Set [`IEEEST`](@ref) `T6`.\"\"\"\nset_T6!(value::IEEEST, val) = value.T6 = val\n\"\"\"Set [`IEEEST`](@ref) `Ks`.\"\"\"\nset_Ks!(value::IEEEST, val) = value.Ks = val\n\"\"\"Set [`IEEEST`](@ref) `Ls_lim`.\"\"\"\nset_Ls_lim!(value::IEEEST, val) = value.Ls_lim = val\n\"\"\"Set [`IEEEST`](@ref) `Vcu`.\"\"\"\nset_Vcu!(value::IEEEST, val) = value.Vcu = val\n\"\"\"Set [`IEEEST`](@ref) `Vcl`.\"\"\"\nset_Vcl!(value::IEEEST, val) = value.Vcl = val\n\"\"\"Set [`IEEEST`](@ref) `ext`.\"\"\"\nset_ext!(value::IEEEST, val) = value.ext = val\n\"\"\"Set [`IEEEST`](@ref) `states_types`.\"\"\"\nset_states_types!(value::IEEEST, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/IEEET1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct IEEET1 <: AVR\n        Tr::Float64\n        Ka::Float64\n        Ta::Float64\n        Vr_lim::MinMax\n        Ke::Float64\n        Te::Float64\n        Kf::Float64\n        Tf::Float64\n        switch::Int\n        E_sat::Tuple{Float64, Float64}\n        Se::Tuple{Float64, Float64}\n        V_ref::Float64\n        saturation_coeffs::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\n1968 IEEE type 1 excitation system model\n\n# Arguments\n- `Tr::Float64`: Voltage Measurement Time Constant in s, validation range: `(0, 0.5)`\n- `Ka::Float64`: Amplifier Gain, validation range: `(10, 500)`\n- `Ta::Float64`: Amplifier Time Constant in s, validation range: `(0, 1)`\n- `Vr_lim::MinMax`: Voltage regulator limits (regulator output) (Vi_min, Vi_max)\n- `Ke::Float64`: Exciter constant related to self-excited field, validation range: `(-1, 1)`\n- `Te::Float64`: Exciter time constant, integration rate associated with exciter control, validation range: `(eps(), 1)`\n- `Kf::Float64`: Excitation control system stabilizer gain, validation range: `(eps(), 0.3)`\n- `Tf::Float64`: Excitation control system stabilizer time constant. Appropiate Data: 5 <= Tf/Kf <= 15, validation range: `(eps(), nothing)`\n- `switch::Int`: Switch, validation range: `(0, 1)`\n- `E_sat::Tuple{Float64, Float64}`: Exciter output voltage for saturation factor: (E1, E2)\n- `Se::Tuple{Float64, Float64}`: Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `saturation_coeffs::Tuple{Float64, Float64}`: (default: `PowerSystems.get_avr_saturation(E_sat, Se)`) (**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\n- `n_states::Int`: (**Do not modify.**) The IEEET1 has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEET1 I has 4 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct IEEET1 <: AVR\n    \"Voltage Measurement Time Constant in s\"\n    Tr::Float64\n    \"Amplifier Gain\"\n    Ka::Float64\n    \"Amplifier Time Constant in s\"\n    Ta::Float64\n    \"Voltage regulator limits (regulator output) (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Exciter constant related to self-excited field\"\n    Ke::Float64\n    \"Exciter time constant, integration rate associated with exciter control\"\n    Te::Float64\n    \"Excitation control system stabilizer gain\"\n    Kf::Float64\n    \"Excitation control system stabilizer time constant. Appropiate Data: 5 <= Tf/Kf <= 15\"\n    Tf::Float64\n    \"Switch\"\n    switch::Int\n    \"Exciter output voltage for saturation factor: (E1, E2)\"\n    E_sat::Tuple{Float64, Float64}\n    \"Exciter saturation factor at exciter output voltage: (Se(E1), Se(E2))\"\n    Se::Tuple{Float64, Float64}\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"(**Do not modify.**) Coefficients (A,B) of the function: Se(V) = B(V - A)^2/V\"\n    saturation_coeffs::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVt: Terminal Voltage,\n\tVr: Regulator Output,\n\tVf: Exciter Output, \n\tVr3: Rate feedback integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The IEEET1 has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEET1 I has 4 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction IEEET1(Tr, Ka, Ta, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), )\n    IEEET1(Tr, Ka, Ta, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, [:Vt, :Vr1, :Vf, :Vr2], 4, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction IEEET1(; Tr, Ka, Ta, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref=1.0, saturation_coeffs=PowerSystems.get_avr_saturation(E_sat, Se), ext=Dict{String, Any}(), states=[:Vt, :Vr1, :Vf, :Vr2], n_states=4, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    IEEET1(Tr, Ka, Ta, Vr_lim, Ke, Te, Kf, Tf, switch, E_sat, Se, V_ref, saturation_coeffs, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction IEEET1(::Nothing)\n    IEEET1(;\n        Tr=0,\n        Ka=0,\n        Ta=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Ke=0,\n        Te=0,\n        Kf=0,\n        Tf=0,\n        switch=0,\n        E_sat=(0.0, 0.0),\n        Se=(0.0, 0.0),\n        V_ref=0,\n        saturation_coeffs=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`IEEET1`](@ref) `Tr`.\"\"\"\nget_Tr(value::IEEET1) = value.Tr\n\"\"\"Get [`IEEET1`](@ref) `Ka`.\"\"\"\nget_Ka(value::IEEET1) = value.Ka\n\"\"\"Get [`IEEET1`](@ref) `Ta`.\"\"\"\nget_Ta(value::IEEET1) = value.Ta\n\"\"\"Get [`IEEET1`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::IEEET1) = value.Vr_lim\n\"\"\"Get [`IEEET1`](@ref) `Ke`.\"\"\"\nget_Ke(value::IEEET1) = value.Ke\n\"\"\"Get [`IEEET1`](@ref) `Te`.\"\"\"\nget_Te(value::IEEET1) = value.Te\n\"\"\"Get [`IEEET1`](@ref) `Kf`.\"\"\"\nget_Kf(value::IEEET1) = value.Kf\n\"\"\"Get [`IEEET1`](@ref) `Tf`.\"\"\"\nget_Tf(value::IEEET1) = value.Tf\n\"\"\"Get [`IEEET1`](@ref) `switch`.\"\"\"\nget_switch(value::IEEET1) = value.switch\n\"\"\"Get [`IEEET1`](@ref) `E_sat`.\"\"\"\nget_E_sat(value::IEEET1) = value.E_sat\n\"\"\"Get [`IEEET1`](@ref) `Se`.\"\"\"\nget_Se(value::IEEET1) = value.Se\n\"\"\"Get [`IEEET1`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::IEEET1) = value.V_ref\n\"\"\"Get [`IEEET1`](@ref) `saturation_coeffs`.\"\"\"\nget_saturation_coeffs(value::IEEET1) = value.saturation_coeffs\n\"\"\"Get [`IEEET1`](@ref) `ext`.\"\"\"\nget_ext(value::IEEET1) = value.ext\n\"\"\"Get [`IEEET1`](@ref) `states`.\"\"\"\nget_states(value::IEEET1) = value.states\n\"\"\"Get [`IEEET1`](@ref) `n_states`.\"\"\"\nget_n_states(value::IEEET1) = value.n_states\n\"\"\"Get [`IEEET1`](@ref) `states_types`.\"\"\"\nget_states_types(value::IEEET1) = value.states_types\n\"\"\"Get [`IEEET1`](@ref) `internal`.\"\"\"\nget_internal(value::IEEET1) = value.internal\n\n\"\"\"Set [`IEEET1`](@ref) `Tr`.\"\"\"\nset_Tr!(value::IEEET1, val) = value.Tr = val\n\"\"\"Set [`IEEET1`](@ref) `Ka`.\"\"\"\nset_Ka!(value::IEEET1, val) = value.Ka = val\n\"\"\"Set [`IEEET1`](@ref) `Ta`.\"\"\"\nset_Ta!(value::IEEET1, val) = value.Ta = val\n\"\"\"Set [`IEEET1`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::IEEET1, val) = value.Vr_lim = val\n\"\"\"Set [`IEEET1`](@ref) `Ke`.\"\"\"\nset_Ke!(value::IEEET1, val) = value.Ke = val\n\"\"\"Set [`IEEET1`](@ref) `Te`.\"\"\"\nset_Te!(value::IEEET1, val) = value.Te = val\n\"\"\"Set [`IEEET1`](@ref) `Kf`.\"\"\"\nset_Kf!(value::IEEET1, val) = value.Kf = val\n\"\"\"Set [`IEEET1`](@ref) `Tf`.\"\"\"\nset_Tf!(value::IEEET1, val) = value.Tf = val\n\"\"\"Set [`IEEET1`](@ref) `switch`.\"\"\"\nset_switch!(value::IEEET1, val) = value.switch = val\n\"\"\"Set [`IEEET1`](@ref) `E_sat`.\"\"\"\nset_E_sat!(value::IEEET1, val) = value.E_sat = val\n\"\"\"Set [`IEEET1`](@ref) `Se`.\"\"\"\nset_Se!(value::IEEET1, val) = value.Se = val\n\"\"\"Set [`IEEET1`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::IEEET1, val) = value.V_ref = val\n\"\"\"Set [`IEEET1`](@ref) `saturation_coeffs`.\"\"\"\nset_saturation_coeffs!(value::IEEET1, val) = value.saturation_coeffs = val\n\"\"\"Set [`IEEET1`](@ref) `ext`.\"\"\"\nset_ext!(value::IEEET1, val) = value.ext = val\n\"\"\"Set [`IEEET1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::IEEET1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/IEEETurbineGov1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct IEEETurbineGov1 <: TurbineGov\n        K::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        U0::Float64\n        U_c::Float64\n        valve_position_limits::MinMax\n        T4::Float64\n        K1::Float64\n        K2::Float64\n        T5::Float64\n        K3::Float64\n        K4::Float64\n        T6::Float64\n        K5::Float64\n        K6::Float64\n        T7::Float64\n        K7::Float64\n        K8::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE Type 1 Speed-Governing Model\n\n# Arguments\n- `K::Float64`: Governor Gain, validation range: `(5, 30)`\n- `T1::Float64`: Input Filter Lag, validation range: `(0, 5)`\n- `T2::Float64`: Input Filter Lead, validation range: `(0, 10)`\n- `T3::Float64`: Valve position Time Constant, validation range: `(eps(), 1)`\n- `U0::Float64`: Maximum Valve Opening Rate, validation range: `(0.01, 0.03)`\n- `U_c::Float64`: Maximum Valve closing rate, validation range: `(-0.3, 0)`\n- `valve_position_limits::MinMax`: Valve position limits in MW\n- `T4::Float64`: Time Constant inlet steam, validation range: `(0, 1)`\n- `K1::Float64`: Fraction of high presure shaft power, validation range: `(-2, 1)`\n- `K2::Float64`: Fraction of low presure shaft power, validation range: `(0, nothing)`\n- `T5::Float64`: Time constant for second boiler pass, validation range: `(0, 10)`\n- `K3::Float64`: Fraction of high presure shaft power second boiler pass, validation range: `(0, 0.5)`\n- `K4::Float64`: Fraction of low presure shaft power second boiler pass, validation range: `(0, 0.5)`\n- `T6::Float64`: Time constant for third boiler pass, validation range: `(0, 10)`\n- `K5::Float64`: Fraction of high presure shaft power third boiler pass, validation range: `(0, 0.35)`\n- `K6::Float64`: Fraction of low presure shaft power third boiler pass, validation range: `(0, 0.55)`\n- `T7::Float64`: Time constant for fourth boiler pass, validation range: `(0, 10)`\n- `K7::Float64`: Fraction of high presure shaft power fourth boiler pass, validation range: `(0, 0.3)`\n- `K8::Float64`: Fraction of low presure shaft power fourth boiler pass, validation range: `(0, 0.3)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the IEEETurbineGov model are:\n\tx_g1: First Governor integrator,\n\tx_g2: Governor output,\n\tx_g3: First Turbine integrator, \n\tx_g4: Second Turbine Integrator, \n\tx_g5: Third Turbine Integrator, \n\tx_g6: Fourth Turbine Integrator, \n- `n_states::Int`: (**Do not modify.**) IEEEG1 has 6 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEEG1 has 6 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct IEEETurbineGov1 <: TurbineGov\n    \"Governor Gain\"\n    K::Float64\n    \"Input Filter Lag\"\n    T1::Float64\n    \"Input Filter Lead\"\n    T2::Float64\n    \"Valve position Time Constant\"\n    T3::Float64\n    \"Maximum Valve Opening Rate\"\n    U0::Float64\n    \"Maximum Valve closing rate\"\n    U_c::Float64\n    \"Valve position limits in MW\"\n    valve_position_limits::MinMax\n    \"Time Constant inlet steam\"\n    T4::Float64\n    \"Fraction of high presure shaft power\"\n    K1::Float64\n    \"Fraction of low presure shaft power\"\n    K2::Float64\n    \"Time constant for second boiler pass\"\n    T5::Float64\n    \"Fraction of high presure shaft power second boiler pass\"\n    K3::Float64\n    \"Fraction of low presure shaft power second boiler pass\"\n    K4::Float64\n    \"Time constant for third boiler pass\"\n    T6::Float64\n    \"Fraction of high presure shaft power third boiler pass\"\n    K5::Float64\n    \"Fraction of low presure shaft power third boiler pass\"\n    K6::Float64\n    \"Time constant for fourth boiler pass\"\n    T7::Float64\n    \"Fraction of high presure shaft power fourth boiler pass\"\n    K7::Float64\n    \"Fraction of low presure shaft power fourth boiler pass\"\n    K8::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the IEEETurbineGov model are:\n\tx_g1: First Governor integrator,\n\tx_g2: Governor output,\n\tx_g3: First Turbine integrator, \n\tx_g4: Second Turbine Integrator, \n\tx_g5: Third Turbine Integrator, \n\tx_g6: Fourth Turbine Integrator, \"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) IEEEG1 has 6 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEEG1 has 6 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction IEEETurbineGov1(K, T1, T2, T3, U0, U_c, valve_position_limits, T4, K1, K2, T5, K3, K4, T6, K5, K6, T7, K7, K8, P_ref=1.0, ext=Dict{String, Any}(), )\n    IEEETurbineGov1(K, T1, T2, T3, U0, U_c, valve_position_limits, T4, K1, K2, T5, K3, K4, T6, K5, K6, T7, K7, K8, P_ref, ext, [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6], 6, [StateTypes.Differential, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction IEEETurbineGov1(; K, T1, T2, T3, U0, U_c, valve_position_limits, T4, K1, K2, T5, K3, K4, T6, K5, K6, T7, K7, K8, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6], n_states=6, states_types=[StateTypes.Differential, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    IEEETurbineGov1(K, T1, T2, T3, U0, U_c, valve_position_limits, T4, K1, K2, T5, K3, K4, T6, K5, K6, T7, K7, K8, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction IEEETurbineGov1(::Nothing)\n    IEEETurbineGov1(;\n        K=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        U0=0,\n        U_c=0,\n        valve_position_limits=(min=0.0, max=0.0),\n        T4=0,\n        K1=0,\n        K2=0,\n        T5=0,\n        K3=0,\n        K4=0,\n        T6=0,\n        K5=0,\n        K6=0,\n        T7=0,\n        K7=0,\n        K8=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K`.\"\"\"\nget_K(value::IEEETurbineGov1) = value.K\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T1`.\"\"\"\nget_T1(value::IEEETurbineGov1) = value.T1\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T2`.\"\"\"\nget_T2(value::IEEETurbineGov1) = value.T2\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T3`.\"\"\"\nget_T3(value::IEEETurbineGov1) = value.T3\n\"\"\"Get [`IEEETurbineGov1`](@ref) `U0`.\"\"\"\nget_U0(value::IEEETurbineGov1) = value.U0\n\"\"\"Get [`IEEETurbineGov1`](@ref) `U_c`.\"\"\"\nget_U_c(value::IEEETurbineGov1) = value.U_c\n\"\"\"Get [`IEEETurbineGov1`](@ref) `valve_position_limits`.\"\"\"\nget_valve_position_limits(value::IEEETurbineGov1) = value.valve_position_limits\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T4`.\"\"\"\nget_T4(value::IEEETurbineGov1) = value.T4\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K1`.\"\"\"\nget_K1(value::IEEETurbineGov1) = value.K1\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K2`.\"\"\"\nget_K2(value::IEEETurbineGov1) = value.K2\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T5`.\"\"\"\nget_T5(value::IEEETurbineGov1) = value.T5\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K3`.\"\"\"\nget_K3(value::IEEETurbineGov1) = value.K3\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K4`.\"\"\"\nget_K4(value::IEEETurbineGov1) = value.K4\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T6`.\"\"\"\nget_T6(value::IEEETurbineGov1) = value.T6\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K5`.\"\"\"\nget_K5(value::IEEETurbineGov1) = value.K5\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K6`.\"\"\"\nget_K6(value::IEEETurbineGov1) = value.K6\n\"\"\"Get [`IEEETurbineGov1`](@ref) `T7`.\"\"\"\nget_T7(value::IEEETurbineGov1) = value.T7\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K7`.\"\"\"\nget_K7(value::IEEETurbineGov1) = value.K7\n\"\"\"Get [`IEEETurbineGov1`](@ref) `K8`.\"\"\"\nget_K8(value::IEEETurbineGov1) = value.K8\n\"\"\"Get [`IEEETurbineGov1`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::IEEETurbineGov1) = value.P_ref\n\"\"\"Get [`IEEETurbineGov1`](@ref) `ext`.\"\"\"\nget_ext(value::IEEETurbineGov1) = value.ext\n\"\"\"Get [`IEEETurbineGov1`](@ref) `states`.\"\"\"\nget_states(value::IEEETurbineGov1) = value.states\n\"\"\"Get [`IEEETurbineGov1`](@ref) `n_states`.\"\"\"\nget_n_states(value::IEEETurbineGov1) = value.n_states\n\"\"\"Get [`IEEETurbineGov1`](@ref) `states_types`.\"\"\"\nget_states_types(value::IEEETurbineGov1) = value.states_types\n\"\"\"Get [`IEEETurbineGov1`](@ref) `internal`.\"\"\"\nget_internal(value::IEEETurbineGov1) = value.internal\n\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K`.\"\"\"\nset_K!(value::IEEETurbineGov1, val) = value.K = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T1`.\"\"\"\nset_T1!(value::IEEETurbineGov1, val) = value.T1 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T2`.\"\"\"\nset_T2!(value::IEEETurbineGov1, val) = value.T2 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T3`.\"\"\"\nset_T3!(value::IEEETurbineGov1, val) = value.T3 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `U0`.\"\"\"\nset_U0!(value::IEEETurbineGov1, val) = value.U0 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `U_c`.\"\"\"\nset_U_c!(value::IEEETurbineGov1, val) = value.U_c = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `valve_position_limits`.\"\"\"\nset_valve_position_limits!(value::IEEETurbineGov1, val) = value.valve_position_limits = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T4`.\"\"\"\nset_T4!(value::IEEETurbineGov1, val) = value.T4 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K1`.\"\"\"\nset_K1!(value::IEEETurbineGov1, val) = value.K1 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K2`.\"\"\"\nset_K2!(value::IEEETurbineGov1, val) = value.K2 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T5`.\"\"\"\nset_T5!(value::IEEETurbineGov1, val) = value.T5 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K3`.\"\"\"\nset_K3!(value::IEEETurbineGov1, val) = value.K3 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K4`.\"\"\"\nset_K4!(value::IEEETurbineGov1, val) = value.K4 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T6`.\"\"\"\nset_T6!(value::IEEETurbineGov1, val) = value.T6 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K5`.\"\"\"\nset_K5!(value::IEEETurbineGov1, val) = value.K5 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K6`.\"\"\"\nset_K6!(value::IEEETurbineGov1, val) = value.K6 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `T7`.\"\"\"\nset_T7!(value::IEEETurbineGov1, val) = value.T7 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K7`.\"\"\"\nset_K7!(value::IEEETurbineGov1, val) = value.K7 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `K8`.\"\"\"\nset_K8!(value::IEEETurbineGov1, val) = value.K8 = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::IEEETurbineGov1, val) = value.P_ref = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `ext`.\"\"\"\nset_ext!(value::IEEETurbineGov1, val) = value.ext = val\n\"\"\"Set [`IEEETurbineGov1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::IEEETurbineGov1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/InstantaneousOutputCurrentLimiter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct InstantaneousOutputCurrentLimiter <: OutputCurrentLimiter\n        Id_max::Float64\n        Iq_max::Float64\n        ext::Dict{String, Any}\n    end\n\nParameters of Instantaneous (Square) Current Controller Limiter. Regulates inverter output current on the d and q axis separately\n\n# Arguments\n- `Id_max::Float64`: Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `Iq_max::Float64`: Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n\"\"\"\nmutable struct InstantaneousOutputCurrentLimiter <: OutputCurrentLimiter\n    \"Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    Id_max::Float64\n    \"Maximum limit on d-axis current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    Iq_max::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\nend\n\n\nfunction InstantaneousOutputCurrentLimiter(; Id_max, Iq_max, ext=Dict{String, Any}(), )\n    InstantaneousOutputCurrentLimiter(Id_max, Iq_max, ext, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction InstantaneousOutputCurrentLimiter(::Nothing)\n    InstantaneousOutputCurrentLimiter(;\n        Id_max=0,\n        Iq_max=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`InstantaneousOutputCurrentLimiter`](@ref) `Id_max`.\"\"\"\nget_Id_max(value::InstantaneousOutputCurrentLimiter) = value.Id_max\n\"\"\"Get [`InstantaneousOutputCurrentLimiter`](@ref) `Iq_max`.\"\"\"\nget_Iq_max(value::InstantaneousOutputCurrentLimiter) = value.Iq_max\n\"\"\"Get [`InstantaneousOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nget_ext(value::InstantaneousOutputCurrentLimiter) = value.ext\n\n\"\"\"Set [`InstantaneousOutputCurrentLimiter`](@ref) `Id_max`.\"\"\"\nset_Id_max!(value::InstantaneousOutputCurrentLimiter, val) = value.Id_max = val\n\"\"\"Set [`InstantaneousOutputCurrentLimiter`](@ref) `Iq_max`.\"\"\"\nset_Iq_max!(value::InstantaneousOutputCurrentLimiter, val) = value.Iq_max = val\n\"\"\"Set [`InstantaneousOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nset_ext!(value::InstantaneousOutputCurrentLimiter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/InterconnectingConverter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct InterconnectingConverter <: StaticInjection\n        name::String\n        available::Bool\n        bus::ACBus\n        dc_bus::DCBus\n        active_power::Float64\n        rating::Float64\n        active_power_limits::MinMax\n        base_power::Float64\n        reactive_power_limits::Union{Nothing, MinMax}\n        dc_current::Float64\n        max_dc_current::Float64\n        loss_function::Union{LinearCurve, QuadraticCurve}\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nInterconnecting Power Converter (IPC) for transforming power from an ACBus to a DCBus\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus on the AC side of this converter\n- `dc_bus::DCBus`: Bus on the DC side of this converter\n- `active_power::Float64`: Active power (MW) on the DC side, validation range: `active_power_limits`\n- `rating::Float64`: Maximum output power rating of the converter (MVA), validation range: `(0, nothing)`\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW)\n- `base_power::Float64`: Base power of the converter in MVA, validation range: `(0.0001, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: (default: `nothing`) Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `dc_current::Float64`: (default: `0.0`) DC current (A) on the converter\n- `max_dc_current::Float64`: (default: `1e8`) Maximum stable dc current limits (A)\n- `loss_function::Union{LinearCurve, QuadraticCurve}`: (default: `LinearCurve(0.0)`) Linear or quadratic loss function with respect to the converter current\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct InterconnectingConverter <: StaticInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus on the AC side of this converter\"\n    bus::ACBus\n    \"Bus on the DC side of this converter\"\n    dc_bus::DCBus\n    \"Active power (MW) on the DC side\"\n    active_power::Float64\n    \"Maximum output power rating of the converter (MVA)\"\n    rating::Float64\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Base power of the converter in MVA\"\n    base_power::Float64\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"DC current (A) on the converter\"\n    dc_current::Float64\n    \"Maximum stable dc current limits (A)\"\n    max_dc_current::Float64\n    \"Linear or quadratic loss function with respect to the converter current\"\n    loss_function::Union{LinearCurve, QuadraticCurve}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction InterconnectingConverter(name, available, bus, dc_bus, active_power, rating, active_power_limits, base_power, reactive_power_limits=nothing, dc_current=0.0, max_dc_current=1e8, loss_function=LinearCurve(0.0), services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    InterconnectingConverter(name, available, bus, dc_bus, active_power, rating, active_power_limits, base_power, reactive_power_limits, dc_current, max_dc_current, loss_function, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction InterconnectingConverter(; name, available, bus, dc_bus, active_power, rating, active_power_limits, base_power, reactive_power_limits=nothing, dc_current=0.0, max_dc_current=1e8, loss_function=LinearCurve(0.0), services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    InterconnectingConverter(name, available, bus, dc_bus, active_power, rating, active_power_limits, base_power, reactive_power_limits, dc_current, max_dc_current, loss_function, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction InterconnectingConverter(::Nothing)\n    InterconnectingConverter(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        dc_bus=DCBus(nothing),\n        active_power=0.0,\n        rating=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        base_power=100,\n        reactive_power_limits=nothing,\n        dc_current=0.0,\n        max_dc_current=0.0,\n        loss_function=LinearCurve(0.0),\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`InterconnectingConverter`](@ref) `name`.\"\"\"\nget_name(value::InterconnectingConverter) = value.name\n\"\"\"Get [`InterconnectingConverter`](@ref) `available`.\"\"\"\nget_available(value::InterconnectingConverter) = value.available\n\"\"\"Get [`InterconnectingConverter`](@ref) `bus`.\"\"\"\nget_bus(value::InterconnectingConverter) = value.bus\n\"\"\"Get [`InterconnectingConverter`](@ref) `dc_bus`.\"\"\"\nget_dc_bus(value::InterconnectingConverter) = value.dc_bus\n\"\"\"Get [`InterconnectingConverter`](@ref) `active_power`.\"\"\"\nget_active_power(value::InterconnectingConverter) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`InterconnectingConverter`](@ref) `rating`.\"\"\"\nget_rating(value::InterconnectingConverter) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`InterconnectingConverter`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::InterconnectingConverter) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`InterconnectingConverter`](@ref) `base_power`.\"\"\"\nget_base_power(value::InterconnectingConverter) = value.base_power\n\"\"\"Get [`InterconnectingConverter`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::InterconnectingConverter) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`InterconnectingConverter`](@ref) `dc_current`.\"\"\"\nget_dc_current(value::InterconnectingConverter) = value.dc_current\n\"\"\"Get [`InterconnectingConverter`](@ref) `max_dc_current`.\"\"\"\nget_max_dc_current(value::InterconnectingConverter) = value.max_dc_current\n\"\"\"Get [`InterconnectingConverter`](@ref) `loss_function`.\"\"\"\nget_loss_function(value::InterconnectingConverter) = value.loss_function\n\"\"\"Get [`InterconnectingConverter`](@ref) `services`.\"\"\"\nget_services(value::InterconnectingConverter) = value.services\n\"\"\"Get [`InterconnectingConverter`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::InterconnectingConverter) = value.dynamic_injector\n\"\"\"Get [`InterconnectingConverter`](@ref) `ext`.\"\"\"\nget_ext(value::InterconnectingConverter) = value.ext\n\"\"\"Get [`InterconnectingConverter`](@ref) `internal`.\"\"\"\nget_internal(value::InterconnectingConverter) = value.internal\n\n\"\"\"Set [`InterconnectingConverter`](@ref) `available`.\"\"\"\nset_available!(value::InterconnectingConverter, val) = value.available = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `bus`.\"\"\"\nset_bus!(value::InterconnectingConverter, val) = value.bus = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `dc_bus`.\"\"\"\nset_dc_bus!(value::InterconnectingConverter, val) = value.dc_bus = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `active_power`.\"\"\"\nset_active_power!(value::InterconnectingConverter, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`InterconnectingConverter`](@ref) `rating`.\"\"\"\nset_rating!(value::InterconnectingConverter, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`InterconnectingConverter`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::InterconnectingConverter, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`InterconnectingConverter`](@ref) `base_power`.\"\"\"\nset_base_power!(value::InterconnectingConverter, val) = value.base_power = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::InterconnectingConverter, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`InterconnectingConverter`](@ref) `dc_current`.\"\"\"\nset_dc_current!(value::InterconnectingConverter, val) = value.dc_current = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `max_dc_current`.\"\"\"\nset_max_dc_current!(value::InterconnectingConverter, val) = value.max_dc_current = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `loss_function`.\"\"\"\nset_loss_function!(value::InterconnectingConverter, val) = value.loss_function = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `services`.\"\"\"\nset_services!(value::InterconnectingConverter, val) = value.services = val\n\"\"\"Set [`InterconnectingConverter`](@ref) `ext`.\"\"\"\nset_ext!(value::InterconnectingConverter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/InterruptiblePowerLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct InterruptiblePowerLoad <: ControllableLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        max_active_power::Float64\n        max_reactive_power::Float64\n        base_power::Float64\n        operation_cost::Union{LoadCost, MarketBidCost}\n        conformity::LoadConformity\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA [static](@ref S) power load that can be compensated for temporary or continuous interruptions to its requested demand.\n\n These loads are most commonly used for operational optimizations and can be used to model, for example, large commercial and industrial customers enrolled in demand response programs. This load has a target demand profile (set by a [`max_active_power` time series](@ref ts_data) for an operational simulation) that can be reduced to satisfy other system needs. For simpler loads without an operating cost for demand response, see [`PowerLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial steady state active power demand (MW)\n- `reactive_power::Float64`: Initial steady state reactive power demand (MVAR)\n- `max_active_power::Float64`: Maximum active power (MW) that this load can demand\n- `max_reactive_power::Float64`: Maximum reactive power (MVAR) that this load can demand\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `operation_cost::Union{LoadCost, MarketBidCost}`: [`OperationalCost`](@ref) of interrupting load\n- `conformity::LoadConformity`: (default: `LoadConformity.UNDEFINED`) Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct InterruptiblePowerLoad <: ControllableLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial steady state active power demand (MW)\"\n    active_power::Float64\n    \"Initial steady state reactive power demand (MVAR)\"\n    reactive_power::Float64\n    \"Maximum active power (MW) that this load can demand\"\n    max_active_power::Float64\n    \"Maximum reactive power (MVAR) that this load can demand\"\n    max_reactive_power::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"[`OperationalCost`](@ref) of interrupting load\"\n    operation_cost::Union{LoadCost, MarketBidCost}\n    \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\"\n    conformity::LoadConformity\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction InterruptiblePowerLoad(name, available, bus, active_power, reactive_power, max_active_power, max_reactive_power, base_power, operation_cost, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    InterruptiblePowerLoad(name, available, bus, active_power, reactive_power, max_active_power, max_reactive_power, base_power, operation_cost, conformity, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction InterruptiblePowerLoad(; name, available, bus, active_power, reactive_power, max_active_power, max_reactive_power, base_power, operation_cost, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    InterruptiblePowerLoad(name, available, bus, active_power, reactive_power, max_active_power, max_reactive_power, base_power, operation_cost, conformity, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction InterruptiblePowerLoad(::Nothing)\n    InterruptiblePowerLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        max_active_power=0.0,\n        max_reactive_power=0.0,\n        base_power=100.0,\n        operation_cost=LoadCost(nothing),\n        conformity=LoadConformity.UNDEFINED,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `name`.\"\"\"\nget_name(value::InterruptiblePowerLoad) = value.name\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `available`.\"\"\"\nget_available(value::InterruptiblePowerLoad) = value.available\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `bus`.\"\"\"\nget_bus(value::InterruptiblePowerLoad) = value.bus\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `active_power`.\"\"\"\nget_active_power(value::InterruptiblePowerLoad) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::InterruptiblePowerLoad) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `max_active_power`.\"\"\"\nget_max_active_power(value::InterruptiblePowerLoad) = get_value(value, Val(:max_active_power), Val(:mva))\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `max_reactive_power`.\"\"\"\nget_max_reactive_power(value::InterruptiblePowerLoad) = get_value(value, Val(:max_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::InterruptiblePowerLoad) = value.base_power\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::InterruptiblePowerLoad) = value.operation_cost\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `conformity`.\"\"\"\nget_conformity(value::InterruptiblePowerLoad) = value.conformity\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `services`.\"\"\"\nget_services(value::InterruptiblePowerLoad) = value.services\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::InterruptiblePowerLoad) = value.dynamic_injector\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `ext`.\"\"\"\nget_ext(value::InterruptiblePowerLoad) = value.ext\n\"\"\"Get [`InterruptiblePowerLoad`](@ref) `internal`.\"\"\"\nget_internal(value::InterruptiblePowerLoad) = value.internal\n\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `available`.\"\"\"\nset_available!(value::InterruptiblePowerLoad, val) = value.available = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::InterruptiblePowerLoad, val) = value.bus = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `active_power`.\"\"\"\nset_active_power!(value::InterruptiblePowerLoad, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::InterruptiblePowerLoad, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `max_active_power`.\"\"\"\nset_max_active_power!(value::InterruptiblePowerLoad, val) = value.max_active_power = set_value(value, Val(:max_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `max_reactive_power`.\"\"\"\nset_max_reactive_power!(value::InterruptiblePowerLoad, val) = value.max_reactive_power = set_value(value, Val(:max_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::InterruptiblePowerLoad, val) = value.base_power = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::InterruptiblePowerLoad, val) = value.operation_cost = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `conformity`.\"\"\"\nset_conformity!(value::InterruptiblePowerLoad, val) = value.conformity = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `services`.\"\"\"\nset_services!(value::InterruptiblePowerLoad, val) = value.services = val\n\"\"\"Set [`InterruptiblePowerLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::InterruptiblePowerLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/InterruptibleStandardLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct InterruptibleStandardLoad <: ControllableLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        base_power::Float64\n        operation_cost::Union{LoadCost, MarketBidCost}\n        conformity::LoadConformity\n        constant_active_power::Float64\n        constant_reactive_power::Float64\n        impedance_active_power::Float64\n        impedance_reactive_power::Float64\n        current_active_power::Float64\n        current_reactive_power::Float64\n        max_constant_active_power::Float64\n        max_constant_reactive_power::Float64\n        max_impedance_active_power::Float64\n        max_impedance_reactive_power::Float64\n        max_current_active_power::Float64\n        max_current_reactive_power::Float64\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\n\nA `StandardLoad` breaks the ZIP into three pieces: Z (constant impedance), I (constant current), and P (constant power), according to `P = P_P * V^0 + P_I * V^1 + P_Z * V^2` for active power and `Q = Q_P * V^0 + Q_I * V^1 + Q_Z * V^2` for reactive power. (Voltage V is in per unit.)\n\nFor an alternative exponential formulation of the ZIP model, see [`ExponentialLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `base_power::Float64`: Base power of the load (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `operation_cost::Union{LoadCost, MarketBidCost}`: [`OperationalCost`](@ref) of interrupting load\n- `conformity::LoadConformity`: (default: `LoadConformity.UNDEFINED`) Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\n- `constant_active_power::Float64`: (default: `0.0`) Constant active power demand in MW (P_P)\n- `constant_reactive_power::Float64`: (default: `0.0`) Constant reactive power demand in MVAR (Q_P)\n- `impedance_active_power::Float64`: (default: `0.0`) Active power coefficient in MW for constant impedance load (P_Z)\n- `impedance_reactive_power::Float64`: (default: `0.0`) Reactive power coefficient in MVAR for constant impedance load (Q_Z)\n- `current_active_power::Float64`: (default: `0.0`) Active power coefficient in MW for constant current load (P_I)\n- `current_reactive_power::Float64`: (default: `0.0`) Reactive power coefficient in MVAR for constant current load (Q_I)\n- `max_constant_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant power load\n- `max_constant_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant power load\n- `max_impedance_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant impedance load\n- `max_impedance_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant impedance load\n- `max_current_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant current load\n- `max_current_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant current load\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct InterruptibleStandardLoad <: ControllableLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Base power of the load (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"[`OperationalCost`](@ref) of interrupting load\"\n    operation_cost::Union{LoadCost, MarketBidCost}\n    \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\"\n    conformity::LoadConformity\n    \"Constant active power demand in MW (P_P)\"\n    constant_active_power::Float64\n    \"Constant reactive power demand in MVAR (Q_P)\"\n    constant_reactive_power::Float64\n    \"Active power coefficient in MW for constant impedance load (P_Z)\"\n    impedance_active_power::Float64\n    \"Reactive power coefficient in MVAR for constant impedance load (Q_Z)\"\n    impedance_reactive_power::Float64\n    \"Active power coefficient in MW for constant current load (P_I)\"\n    current_active_power::Float64\n    \"Reactive power coefficient in MVAR for constant current load (Q_I)\"\n    current_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant power load\"\n    max_constant_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant power load\"\n    max_constant_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant impedance load\"\n    max_impedance_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant impedance load\"\n    max_impedance_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant current load\"\n    max_current_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant current load\"\n    max_current_reactive_power::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction InterruptibleStandardLoad(name, available, bus, base_power, operation_cost, conformity=LoadConformity.UNDEFINED, constant_active_power=0.0, constant_reactive_power=0.0, impedance_active_power=0.0, impedance_reactive_power=0.0, current_active_power=0.0, current_reactive_power=0.0, max_constant_active_power=0.0, max_constant_reactive_power=0.0, max_impedance_active_power=0.0, max_impedance_reactive_power=0.0, max_current_active_power=0.0, max_current_reactive_power=0.0, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    InterruptibleStandardLoad(name, available, bus, base_power, operation_cost, conformity, constant_active_power, constant_reactive_power, impedance_active_power, impedance_reactive_power, current_active_power, current_reactive_power, max_constant_active_power, max_constant_reactive_power, max_impedance_active_power, max_impedance_reactive_power, max_current_active_power, max_current_reactive_power, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction InterruptibleStandardLoad(; name, available, bus, base_power, operation_cost, conformity=LoadConformity.UNDEFINED, constant_active_power=0.0, constant_reactive_power=0.0, impedance_active_power=0.0, impedance_reactive_power=0.0, current_active_power=0.0, current_reactive_power=0.0, max_constant_active_power=0.0, max_constant_reactive_power=0.0, max_impedance_active_power=0.0, max_impedance_reactive_power=0.0, max_current_active_power=0.0, max_current_reactive_power=0.0, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    InterruptibleStandardLoad(name, available, bus, base_power, operation_cost, conformity, constant_active_power, constant_reactive_power, impedance_active_power, impedance_reactive_power, current_active_power, current_reactive_power, max_constant_active_power, max_constant_reactive_power, max_impedance_active_power, max_impedance_reactive_power, max_current_active_power, max_current_reactive_power, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction InterruptibleStandardLoad(::Nothing)\n    InterruptibleStandardLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        base_power=100.0,\n        operation_cost=LoadCost(nothing),\n        conformity=LoadConformity.UNDEFINED,\n        constant_active_power=0.0,\n        constant_reactive_power=0.0,\n        impedance_active_power=0.0,\n        impedance_reactive_power=0.0,\n        current_active_power=0.0,\n        current_reactive_power=0.0,\n        max_constant_active_power=0.0,\n        max_constant_reactive_power=0.0,\n        max_impedance_active_power=0.0,\n        max_impedance_reactive_power=0.0,\n        max_current_active_power=0.0,\n        max_current_reactive_power=0.0,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `name`.\"\"\"\nget_name(value::InterruptibleStandardLoad) = value.name\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `available`.\"\"\"\nget_available(value::InterruptibleStandardLoad) = value.available\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `bus`.\"\"\"\nget_bus(value::InterruptibleStandardLoad) = value.bus\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::InterruptibleStandardLoad) = value.base_power\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::InterruptibleStandardLoad) = value.operation_cost\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `conformity`.\"\"\"\nget_conformity(value::InterruptibleStandardLoad) = value.conformity\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `constant_active_power`.\"\"\"\nget_constant_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:constant_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `constant_reactive_power`.\"\"\"\nget_constant_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:constant_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `impedance_active_power`.\"\"\"\nget_impedance_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:impedance_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `impedance_reactive_power`.\"\"\"\nget_impedance_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:impedance_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `current_active_power`.\"\"\"\nget_current_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:current_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `current_reactive_power`.\"\"\"\nget_current_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:current_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_constant_active_power`.\"\"\"\nget_max_constant_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_constant_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_constant_reactive_power`.\"\"\"\nget_max_constant_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_constant_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_impedance_active_power`.\"\"\"\nget_max_impedance_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_impedance_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_impedance_reactive_power`.\"\"\"\nget_max_impedance_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_impedance_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_current_active_power`.\"\"\"\nget_max_current_active_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_current_active_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `max_current_reactive_power`.\"\"\"\nget_max_current_reactive_power(value::InterruptibleStandardLoad) = get_value(value, Val(:max_current_reactive_power), Val(:mva))\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `services`.\"\"\"\nget_services(value::InterruptibleStandardLoad) = value.services\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::InterruptibleStandardLoad) = value.dynamic_injector\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `ext`.\"\"\"\nget_ext(value::InterruptibleStandardLoad) = value.ext\n\"\"\"Get [`InterruptibleStandardLoad`](@ref) `internal`.\"\"\"\nget_internal(value::InterruptibleStandardLoad) = value.internal\n\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `available`.\"\"\"\nset_available!(value::InterruptibleStandardLoad, val) = value.available = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::InterruptibleStandardLoad, val) = value.bus = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::InterruptibleStandardLoad, val) = value.base_power = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::InterruptibleStandardLoad, val) = value.operation_cost = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `conformity`.\"\"\"\nset_conformity!(value::InterruptibleStandardLoad, val) = value.conformity = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `constant_active_power`.\"\"\"\nset_constant_active_power!(value::InterruptibleStandardLoad, val) = value.constant_active_power = set_value(value, Val(:constant_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `constant_reactive_power`.\"\"\"\nset_constant_reactive_power!(value::InterruptibleStandardLoad, val) = value.constant_reactive_power = set_value(value, Val(:constant_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `impedance_active_power`.\"\"\"\nset_impedance_active_power!(value::InterruptibleStandardLoad, val) = value.impedance_active_power = set_value(value, Val(:impedance_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `impedance_reactive_power`.\"\"\"\nset_impedance_reactive_power!(value::InterruptibleStandardLoad, val) = value.impedance_reactive_power = set_value(value, Val(:impedance_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `current_active_power`.\"\"\"\nset_current_active_power!(value::InterruptibleStandardLoad, val) = value.current_active_power = set_value(value, Val(:current_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `current_reactive_power`.\"\"\"\nset_current_reactive_power!(value::InterruptibleStandardLoad, val) = value.current_reactive_power = set_value(value, Val(:current_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_constant_active_power`.\"\"\"\nset_max_constant_active_power!(value::InterruptibleStandardLoad, val) = value.max_constant_active_power = set_value(value, Val(:max_constant_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_constant_reactive_power`.\"\"\"\nset_max_constant_reactive_power!(value::InterruptibleStandardLoad, val) = value.max_constant_reactive_power = set_value(value, Val(:max_constant_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_impedance_active_power`.\"\"\"\nset_max_impedance_active_power!(value::InterruptibleStandardLoad, val) = value.max_impedance_active_power = set_value(value, Val(:max_impedance_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_impedance_reactive_power`.\"\"\"\nset_max_impedance_reactive_power!(value::InterruptibleStandardLoad, val) = value.max_impedance_reactive_power = set_value(value, Val(:max_impedance_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_current_active_power`.\"\"\"\nset_max_current_active_power!(value::InterruptibleStandardLoad, val) = value.max_current_active_power = set_value(value, Val(:max_current_active_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `max_current_reactive_power`.\"\"\"\nset_max_current_reactive_power!(value::InterruptibleStandardLoad, val) = value.max_current_reactive_power = set_value(value, Val(:max_current_reactive_power), val, Val(:mva))\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `services`.\"\"\"\nset_services!(value::InterruptibleStandardLoad, val) = value.services = val\n\"\"\"Set [`InterruptibleStandardLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::InterruptibleStandardLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/KauraPLL.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct KauraPLL <: FrequencyEstimator\n        ω_lp::Float64\n        kp_pll::Float64\n        ki_pll::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Phase-Locked Loop (PLL) based on [\"Operation of a phase locked loop system under distorted utility conditions\"](https://doi.org/10.1109/28.567077) by Vikram Kaura, and Vladimir Blasko\n\n# Arguments\n- `ω_lp::Float64`: PLL low-pass filter frequency (rad/sec), validation range: `(0, nothing)`\n- `kp_pll::Float64`: PLL proportional gain, validation range: `(0, nothing)`\n- `ki_pll::Float64`: PLL integral gain, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the KauraPLL model are:\n\tvd_pll: d-axis of the measured voltage in the PLL synchronous reference frame (SRF),\n\tvq_pll: q-axis of the measured voltage in the PLL SRF,\n\tε_pll: Integrator state of the PI controller,\n\tθ_pll: Phase angle displacement in the PLL SRF\n- `n_states::Int`: (**Do not modify.**) KauraPLL has 4 states\n\"\"\"\nmutable struct KauraPLL <: FrequencyEstimator\n    \"PLL low-pass filter frequency (rad/sec)\"\n    ω_lp::Float64\n    \"PLL proportional gain\"\n    kp_pll::Float64\n    \"PLL integral gain\"\n    ki_pll::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the KauraPLL model are:\n\tvd_pll: d-axis of the measured voltage in the PLL synchronous reference frame (SRF),\n\tvq_pll: q-axis of the measured voltage in the PLL SRF,\n\tε_pll: Integrator state of the PI controller,\n\tθ_pll: Phase angle displacement in the PLL SRF\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) KauraPLL has 4 states\"\n    n_states::Int\nend\n\nfunction KauraPLL(ω_lp, kp_pll, ki_pll, ext=Dict{String, Any}(), )\n    KauraPLL(ω_lp, kp_pll, ki_pll, ext, [:vd_pll, :vq_pll, :ε_pll, :θ_pll], 4, )\nend\n\nfunction KauraPLL(; ω_lp, kp_pll, ki_pll, ext=Dict{String, Any}(), states=[:vd_pll, :vq_pll, :ε_pll, :θ_pll], n_states=4, )\n    KauraPLL(ω_lp, kp_pll, ki_pll, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction KauraPLL(::Nothing)\n    KauraPLL(;\n        ω_lp=0,\n        kp_pll=0,\n        ki_pll=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`KauraPLL`](@ref) `ω_lp`.\"\"\"\nget_ω_lp(value::KauraPLL) = value.ω_lp\n\"\"\"Get [`KauraPLL`](@ref) `kp_pll`.\"\"\"\nget_kp_pll(value::KauraPLL) = value.kp_pll\n\"\"\"Get [`KauraPLL`](@ref) `ki_pll`.\"\"\"\nget_ki_pll(value::KauraPLL) = value.ki_pll\n\"\"\"Get [`KauraPLL`](@ref) `ext`.\"\"\"\nget_ext(value::KauraPLL) = value.ext\n\"\"\"Get [`KauraPLL`](@ref) `states`.\"\"\"\nget_states(value::KauraPLL) = value.states\n\"\"\"Get [`KauraPLL`](@ref) `n_states`.\"\"\"\nget_n_states(value::KauraPLL) = value.n_states\n\n\"\"\"Set [`KauraPLL`](@ref) `ω_lp`.\"\"\"\nset_ω_lp!(value::KauraPLL, val) = value.ω_lp = val\n\"\"\"Set [`KauraPLL`](@ref) `kp_pll`.\"\"\"\nset_kp_pll!(value::KauraPLL, val) = value.kp_pll = val\n\"\"\"Set [`KauraPLL`](@ref) `ki_pll`.\"\"\"\nset_ki_pll!(value::KauraPLL, val) = value.ki_pll = val\n\"\"\"Set [`KauraPLL`](@ref) `ext`.\"\"\"\nset_ext!(value::KauraPLL, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/LCFilter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct LCFilter <: Filter\n        lf::Float64\n        rf::Float64\n        cf::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a LCL filter outside the converter\n\n# Arguments\n- `lf::Float64`: filter inductance, validation range: `(0, nothing)`\n- `rf::Float64`: filter resistance, validation range: `(0, nothing)`\n- `cf::Float64`: filter capacitance, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the LCFilter model are:\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\n- `n_states::Int`: (**Do not modify.**) LCFilter has two states\n\"\"\"\nmutable struct LCFilter <: Filter\n    \"filter inductance\"\n    lf::Float64\n    \"filter resistance\"\n    rf::Float64\n    \"filter capacitance\"\n    cf::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the LCFilter model are:\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) LCFilter has two states\"\n    n_states::Int\nend\n\nfunction LCFilter(lf, rf, cf, ext=Dict{String, Any}(), )\n    LCFilter(lf, rf, cf, ext, [:ir_filter, :ii_filter], 2, )\nend\n\nfunction LCFilter(; lf, rf, cf, ext=Dict{String, Any}(), states=[:ir_filter, :ii_filter], n_states=2, )\n    LCFilter(lf, rf, cf, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction LCFilter(::Nothing)\n    LCFilter(;\n        lf=0,\n        rf=0,\n        cf=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`LCFilter`](@ref) `lf`.\"\"\"\nget_lf(value::LCFilter) = value.lf\n\"\"\"Get [`LCFilter`](@ref) `rf`.\"\"\"\nget_rf(value::LCFilter) = value.rf\n\"\"\"Get [`LCFilter`](@ref) `cf`.\"\"\"\nget_cf(value::LCFilter) = value.cf\n\"\"\"Get [`LCFilter`](@ref) `ext`.\"\"\"\nget_ext(value::LCFilter) = value.ext\n\"\"\"Get [`LCFilter`](@ref) `states`.\"\"\"\nget_states(value::LCFilter) = value.states\n\"\"\"Get [`LCFilter`](@ref) `n_states`.\"\"\"\nget_n_states(value::LCFilter) = value.n_states\n\n\"\"\"Set [`LCFilter`](@ref) `lf`.\"\"\"\nset_lf!(value::LCFilter, val) = value.lf = val\n\"\"\"Set [`LCFilter`](@ref) `rf`.\"\"\"\nset_rf!(value::LCFilter, val) = value.rf = val\n\"\"\"Set [`LCFilter`](@ref) `cf`.\"\"\"\nset_cf!(value::LCFilter, val) = value.cf = val\n\"\"\"Set [`LCFilter`](@ref) `ext`.\"\"\"\nset_ext!(value::LCFilter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/LCLFilter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct LCLFilter <: Filter\n        lf::Float64\n        rf::Float64\n        cf::Float64\n        lg::Float64\n        rg::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a LCL filter outside the converter, the [states](@ref S) are in the grid's reference frame\n\n# Arguments\n- `lf::Float64`: Series inductance in p.u. of converter filter, validation range: `(0, nothing)`\n- `rf::Float64`: Series resistance in p.u. of converter filter, validation range: `(0, nothing)`\n- `cf::Float64`: Shunt capacitance in p.u. of converter filter, validation range: `(0, nothing)`\n- `lg::Float64`: Series inductance in p.u. of converter filter to the grid, validation range: `(0, nothing)`\n- `rg::Float64`: Series resistance in p.u. of converter filter to the grid, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the LCLFilter model are:\n\tir_cnv: Real current out of the converter,\n\tii_cnv: Imaginary current out of the converter,\n\tvr_filter: Real voltage at the filter's capacitor,\n\tvi_filter: Imaginary voltage at the filter's capacitor,\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\n- `n_states::Int`: (**Do not modify.**) LCLFilter has 6 states\n\"\"\"\nmutable struct LCLFilter <: Filter\n    \"Series inductance in p.u. of converter filter\"\n    lf::Float64\n    \"Series resistance in p.u. of converter filter\"\n    rf::Float64\n    \"Shunt capacitance in p.u. of converter filter\"\n    cf::Float64\n    \"Series inductance in p.u. of converter filter to the grid\"\n    lg::Float64\n    \"Series resistance in p.u. of converter filter to the grid\"\n    rg::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the LCLFilter model are:\n\tir_cnv: Real current out of the converter,\n\tii_cnv: Imaginary current out of the converter,\n\tvr_filter: Real voltage at the filter's capacitor,\n\tvi_filter: Imaginary voltage at the filter's capacitor,\n\tir_filter: Real current out of the filter,\n\tii_filter: Imaginary current out of the filter\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) LCLFilter has 6 states\"\n    n_states::Int\nend\n\nfunction LCLFilter(lf, rf, cf, lg, rg, ext=Dict{String, Any}(), )\n    LCLFilter(lf, rf, cf, lg, rg, ext, [:ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter], 6, )\nend\n\nfunction LCLFilter(; lf, rf, cf, lg, rg, ext=Dict{String, Any}(), states=[:ir_cnv, :ii_cnv, :vr_filter, :vi_filter, :ir_filter, :ii_filter], n_states=6, )\n    LCLFilter(lf, rf, cf, lg, rg, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction LCLFilter(::Nothing)\n    LCLFilter(;\n        lf=0,\n        rf=0,\n        cf=0,\n        lg=0,\n        rg=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`LCLFilter`](@ref) `lf`.\"\"\"\nget_lf(value::LCLFilter) = value.lf\n\"\"\"Get [`LCLFilter`](@ref) `rf`.\"\"\"\nget_rf(value::LCLFilter) = value.rf\n\"\"\"Get [`LCLFilter`](@ref) `cf`.\"\"\"\nget_cf(value::LCLFilter) = value.cf\n\"\"\"Get [`LCLFilter`](@ref) `lg`.\"\"\"\nget_lg(value::LCLFilter) = value.lg\n\"\"\"Get [`LCLFilter`](@ref) `rg`.\"\"\"\nget_rg(value::LCLFilter) = value.rg\n\"\"\"Get [`LCLFilter`](@ref) `ext`.\"\"\"\nget_ext(value::LCLFilter) = value.ext\n\"\"\"Get [`LCLFilter`](@ref) `states`.\"\"\"\nget_states(value::LCLFilter) = value.states\n\"\"\"Get [`LCLFilter`](@ref) `n_states`.\"\"\"\nget_n_states(value::LCLFilter) = value.n_states\n\n\"\"\"Set [`LCLFilter`](@ref) `lf`.\"\"\"\nset_lf!(value::LCLFilter, val) = value.lf = val\n\"\"\"Set [`LCLFilter`](@ref) `rf`.\"\"\"\nset_rf!(value::LCLFilter, val) = value.rf = val\n\"\"\"Set [`LCLFilter`](@ref) `cf`.\"\"\"\nset_cf!(value::LCLFilter, val) = value.cf = val\n\"\"\"Set [`LCLFilter`](@ref) `lg`.\"\"\"\nset_lg!(value::LCLFilter, val) = value.lg = val\n\"\"\"Set [`LCLFilter`](@ref) `rg`.\"\"\"\nset_rg!(value::LCLFilter, val) = value.rg = val\n\"\"\"Set [`LCLFilter`](@ref) `ext`.\"\"\"\nset_ext!(value::LCLFilter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/Line.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Line <: ACTransmission\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        b::FromTo\n        rating::Float64\n        angle_limits::MinMax\n        rating_b::Union{Nothing, Float64}\n        rating_c::Union{Nothing, Float64}\n        g::FromTo\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAn AC transmission line\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow on the line (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `b::FromTo`: Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value, validation range: `(0, 100)`\n- `rating::Float64`: Thermal rating (MVA). Flow on the line must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\n- `angle_limits::MinMax`: Minimum and maximum angle limits (radians)\n- `rating_b::Union{Nothing, Float64}`: (default: `nothing`) Second current rating; entered in MVA.\n- `rating_c::Union{Nothing, Float64}`: (default: `nothing`) Third current rating; entered in MVA.\n- `g::FromTo`: (default: `(from=0.0, to=0.0)`) Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value, validation range: `(0, 100)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Line <: ACTransmission\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow on the line (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\"\n    b::FromTo\n    \"Thermal rating (MVA). Flow on the line must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Float64\n    \"Minimum and maximum angle limits (radians)\"\n    angle_limits::MinMax\n    \"Second current rating; entered in MVA.\"\n    rating_b::Union{Nothing, Float64}\n    \"Third current rating; entered in MVA.\"\n    rating_c::Union{Nothing, Float64}\n    \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\"\n    g::FromTo\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Line(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, rating, angle_limits, rating_b=nothing, rating_c=nothing, g=(from=0.0, to=0.0), services=Device[], ext=Dict{String, Any}(), )\n    Line(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, rating, angle_limits, rating_b, rating_c, g, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction Line(; name, available, active_power_flow, reactive_power_flow, arc, r, x, b, rating, angle_limits, rating_b=nothing, rating_c=nothing, g=(from=0.0, to=0.0), services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    Line(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, rating, angle_limits, rating_b, rating_c, g, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Line(::Nothing)\n    Line(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        b=(from=0.0, to=0.0),\n        rating=0.0,\n        angle_limits=(min=-3.1416, max=3.1416),\n        rating_b=0.0,\n        rating_c=0.0,\n        g=(from=0.0, to=0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`Line`](@ref) `name`.\"\"\"\nget_name(value::Line) = value.name\n\"\"\"Get [`Line`](@ref) `available`.\"\"\"\nget_available(value::Line) = value.available\n\"\"\"Get [`Line`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::Line) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`Line`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::Line) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`Line`](@ref) `arc`.\"\"\"\nget_arc(value::Line) = value.arc\n\"\"\"Get [`Line`](@ref) `r`.\"\"\"\nget_r(value::Line) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`Line`](@ref) `x`.\"\"\"\nget_x(value::Line) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`Line`](@ref) `b`.\"\"\"\nget_b(value::Line) = get_value(value, Val(:b), Val(:siemens))\n\"\"\"Get [`Line`](@ref) `rating`.\"\"\"\nget_rating(value::Line) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`Line`](@ref) `angle_limits`.\"\"\"\nget_angle_limits(value::Line) = value.angle_limits\n\"\"\"Get [`Line`](@ref) `rating_b`.\"\"\"\nget_rating_b(value::Line) = get_value(value, Val(:rating_b), Val(:mva))\n\"\"\"Get [`Line`](@ref) `rating_c`.\"\"\"\nget_rating_c(value::Line) = get_value(value, Val(:rating_c), Val(:mva))\n\"\"\"Get [`Line`](@ref) `g`.\"\"\"\nget_g(value::Line) = get_value(value, Val(:g), Val(:siemens))\n\"\"\"Get [`Line`](@ref) `services`.\"\"\"\nget_services(value::Line) = value.services\n\"\"\"Get [`Line`](@ref) `ext`.\"\"\"\nget_ext(value::Line) = value.ext\n\"\"\"Get [`Line`](@ref) `internal`.\"\"\"\nget_internal(value::Line) = value.internal\n\n\"\"\"Set [`Line`](@ref) `available`.\"\"\"\nset_available!(value::Line, val) = value.available = val\n\"\"\"Set [`Line`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::Line, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`Line`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::Line, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`Line`](@ref) `arc`.\"\"\"\nset_arc!(value::Line, val) = value.arc = val\n\"\"\"Set [`Line`](@ref) `r`.\"\"\"\nset_r!(value::Line, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`Line`](@ref) `x`.\"\"\"\nset_x!(value::Line, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`Line`](@ref) `b`.\"\"\"\nset_b!(value::Line, val) = value.b = set_value(value, Val(:b), val, Val(:siemens))\n\"\"\"Set [`Line`](@ref) `rating`.\"\"\"\nset_rating!(value::Line, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`Line`](@ref) `angle_limits`.\"\"\"\nset_angle_limits!(value::Line, val) = value.angle_limits = val\n\"\"\"Set [`Line`](@ref) `rating_b`.\"\"\"\nset_rating_b!(value::Line, val) = value.rating_b = set_value(value, Val(:rating_b), val, Val(:mva))\n\"\"\"Set [`Line`](@ref) `rating_c`.\"\"\"\nset_rating_c!(value::Line, val) = value.rating_c = set_value(value, Val(:rating_c), val, Val(:mva))\n\"\"\"Set [`Line`](@ref) `g`.\"\"\"\nset_g!(value::Line, val) = value.g = set_value(value, Val(:g), val, Val(:siemens))\n\"\"\"Set [`Line`](@ref) `services`.\"\"\"\nset_services!(value::Line, val) = value.services = val\n\"\"\"Set [`Line`](@ref) `ext`.\"\"\"\nset_ext!(value::Line, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/LoadZone.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct LoadZone <: AggregationTopology\n        name::String\n        peak_active_power::Float64\n        peak_reactive_power::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA load zone for electricity price analysis.\n\nThe load zone can be specified when defining each [`ACBus`](@ref) or [`DCBus`](@ref) in the zone\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `peak_active_power::Float64`: Peak active power in the zone (MW)\n- `peak_reactive_power::Float64`: Peak reactive power in the zone (MVAR)\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct LoadZone <: AggregationTopology\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Peak active power in the zone (MW)\"\n    peak_active_power::Float64\n    \"Peak reactive power in the zone (MVAR)\"\n    peak_reactive_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction LoadZone(name, peak_active_power, peak_reactive_power, ext=Dict{String, Any}(), )\n    LoadZone(name, peak_active_power, peak_reactive_power, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction LoadZone(; name, peak_active_power, peak_reactive_power, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    LoadZone(name, peak_active_power, peak_reactive_power, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction LoadZone(::Nothing)\n    LoadZone(;\n        name=\"init\",\n        peak_active_power=0.0,\n        peak_reactive_power=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`LoadZone`](@ref) `name`.\"\"\"\nget_name(value::LoadZone) = value.name\n\"\"\"Get [`LoadZone`](@ref) `peak_active_power`.\"\"\"\nget_peak_active_power(value::LoadZone) = get_value(value, Val(:peak_active_power), Val(:mva))\n\"\"\"Get [`LoadZone`](@ref) `peak_reactive_power`.\"\"\"\nget_peak_reactive_power(value::LoadZone) = get_value(value, Val(:peak_reactive_power), Val(:mva))\n\"\"\"Get [`LoadZone`](@ref) `ext`.\"\"\"\nget_ext(value::LoadZone) = value.ext\n\"\"\"Get [`LoadZone`](@ref) `internal`.\"\"\"\nget_internal(value::LoadZone) = value.internal\n\n\"\"\"Set [`LoadZone`](@ref) `peak_active_power`.\"\"\"\nset_peak_active_power!(value::LoadZone, val) = value.peak_active_power = set_value(value, Val(:peak_active_power), val, Val(:mva))\n\"\"\"Set [`LoadZone`](@ref) `peak_reactive_power`.\"\"\"\nset_peak_reactive_power!(value::LoadZone, val) = value.peak_reactive_power = set_value(value, Val(:peak_reactive_power), val, Val(:mva))\n\"\"\"Set [`LoadZone`](@ref) `ext`.\"\"\"\nset_ext!(value::LoadZone, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/MagnitudeOutputCurrentLimiter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct MagnitudeOutputCurrentLimiter <: OutputCurrentLimiter\n        I_max::Float64\n        ext::Dict{String, Any}\n    end\n\nParameters of Magnitude (Circular) Current Controller Limiter. Regulates only the magnitude of the inverter output current\n\n# Arguments\n- `I_max::Float64`: Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n\"\"\"\nmutable struct MagnitudeOutputCurrentLimiter <: OutputCurrentLimiter\n    \"Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    I_max::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\nend\n\n\nfunction MagnitudeOutputCurrentLimiter(; I_max, ext=Dict{String, Any}(), )\n    MagnitudeOutputCurrentLimiter(I_max, ext, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction MagnitudeOutputCurrentLimiter(::Nothing)\n    MagnitudeOutputCurrentLimiter(;\n        I_max=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`MagnitudeOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nget_I_max(value::MagnitudeOutputCurrentLimiter) = value.I_max\n\"\"\"Get [`MagnitudeOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nget_ext(value::MagnitudeOutputCurrentLimiter) = value.ext\n\n\"\"\"Set [`MagnitudeOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nset_I_max!(value::MagnitudeOutputCurrentLimiter, val) = value.I_max = val\n\"\"\"Set [`MagnitudeOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nset_ext!(value::MagnitudeOutputCurrentLimiter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/MarconatoMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct MarconatoMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xq_pp::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        T_AA::Float64\n        ext::Dict{String, Any}\n        γd::Float64\n        γq::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 6-[states](@ref S) synchronous machine: Marconato model\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `T_AA::Float64`: Time constant of d-axis additional leakage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `γd::Float64`: (**Do not modify.**) Internal equation\n- `γq::Float64`: (**Do not modify.**) Internal equation\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\n- `n_states::Int`: (**Do not modify.**) MarconatoMachine has 6 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct MarconatoMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit\"\n    Xd_pp::Float64\n    \"Sub-Transient reactance after EMF in q-axis per unit\"\n    Xq_pp::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"Time constant of d-axis additional leakage\"\n    T_AA::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Internal equation\"\n    γd::Float64\n    \"(**Do not modify.**) Internal equation\"\n    γq::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) MarconatoMachine has 6 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction MarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext=Dict{String, Any}(), )\n    MarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext, ((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p), ((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p), [:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp], 6, InfrastructureSystemsInternal(), )\nend\n\nfunction MarconatoMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext=Dict{String, Any}(), γd=((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p), γq=((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p), states=[:ψq, :ψd, :eq_p, :ed_p, :eq_pp, :ed_pp], n_states=6, internal=InfrastructureSystemsInternal(), )\n    MarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext, γd, γq, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction MarconatoMachine(::Nothing)\n    MarconatoMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xq_pp=0,\n        Td0_p=0,\n        Tq0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        T_AA=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`MarconatoMachine`](@ref) `R`.\"\"\"\nget_R(value::MarconatoMachine) = value.R\n\"\"\"Get [`MarconatoMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::MarconatoMachine) = value.Xd\n\"\"\"Get [`MarconatoMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::MarconatoMachine) = value.Xq\n\"\"\"Get [`MarconatoMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::MarconatoMachine) = value.Xd_p\n\"\"\"Get [`MarconatoMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::MarconatoMachine) = value.Xq_p\n\"\"\"Get [`MarconatoMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::MarconatoMachine) = value.Xd_pp\n\"\"\"Get [`MarconatoMachine`](@ref) `Xq_pp`.\"\"\"\nget_Xq_pp(value::MarconatoMachine) = value.Xq_pp\n\"\"\"Get [`MarconatoMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::MarconatoMachine) = value.Td0_p\n\"\"\"Get [`MarconatoMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::MarconatoMachine) = value.Tq0_p\n\"\"\"Get [`MarconatoMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::MarconatoMachine) = value.Td0_pp\n\"\"\"Get [`MarconatoMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::MarconatoMachine) = value.Tq0_pp\n\"\"\"Get [`MarconatoMachine`](@ref) `T_AA`.\"\"\"\nget_T_AA(value::MarconatoMachine) = value.T_AA\n\"\"\"Get [`MarconatoMachine`](@ref) `ext`.\"\"\"\nget_ext(value::MarconatoMachine) = value.ext\n\"\"\"Get [`MarconatoMachine`](@ref) `γd`.\"\"\"\nget_γd(value::MarconatoMachine) = value.γd\n\"\"\"Get [`MarconatoMachine`](@ref) `γq`.\"\"\"\nget_γq(value::MarconatoMachine) = value.γq\n\"\"\"Get [`MarconatoMachine`](@ref) `states`.\"\"\"\nget_states(value::MarconatoMachine) = value.states\n\"\"\"Get [`MarconatoMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::MarconatoMachine) = value.n_states\n\"\"\"Get [`MarconatoMachine`](@ref) `internal`.\"\"\"\nget_internal(value::MarconatoMachine) = value.internal\n\n\"\"\"Set [`MarconatoMachine`](@ref) `R`.\"\"\"\nset_R!(value::MarconatoMachine, val) = value.R = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::MarconatoMachine, val) = value.Xd = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::MarconatoMachine, val) = value.Xq = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::MarconatoMachine, val) = value.Xd_p = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::MarconatoMachine, val) = value.Xq_p = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::MarconatoMachine, val) = value.Xd_pp = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Xq_pp`.\"\"\"\nset_Xq_pp!(value::MarconatoMachine, val) = value.Xq_pp = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::MarconatoMachine, val) = value.Td0_p = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::MarconatoMachine, val) = value.Tq0_p = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::MarconatoMachine, val) = value.Td0_pp = val\n\"\"\"Set [`MarconatoMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::MarconatoMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`MarconatoMachine`](@ref) `T_AA`.\"\"\"\nset_T_AA!(value::MarconatoMachine, val) = value.T_AA = val\n\"\"\"Set [`MarconatoMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::MarconatoMachine, val) = value.ext = val\n\"\"\"Set [`MarconatoMachine`](@ref) `γd`.\"\"\"\nset_γd!(value::MarconatoMachine, val) = value.γd = val\n\"\"\"Set [`MarconatoMachine`](@ref) `γq`.\"\"\"\nset_γq!(value::MarconatoMachine, val) = value.γq = val\n"
  },
  {
    "path": "src/models/generated/MonitoredLine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct MonitoredLine <: ACTransmission\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        b::FromTo\n        flow_limits::FromTo_ToFrom\n        rating::Float64\n        angle_limits::MinMax\n        rating_b::Union{Nothing, Float64}\n        rating_c::Union{Nothing, Float64}\n        g::FromTo\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAn AC transmission line with additional power flow constraints specified by the system operator, more restrictive than the line's thermal limits.\n\nFor example, monitored lines can be used to restrict line flow following a contingency elsewhere in the network. See the `flow_limits` parameter. If monitoring is not needed, see [`Line`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow on the line (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `b::FromTo`: Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value, validation range: `(0, 2)`\n- `flow_limits::FromTo_ToFrom`: Minimum and maximum permissable flow on the line (MVA), if different from the thermal rating defined in `rating`\n- `rating::Float64`: Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\n- `angle_limits::MinMax`: Minimum and maximum angle limits (radians)\n- `rating_b::Union{Nothing, Float64}`: (default: `nothing`) Second current rating; entered in MVA.\n- `rating_c::Union{Nothing, Float64}`: (default: `nothing`) Third current rating; entered in MVA.\n- `g::FromTo`: (default: `(from=0.0, to=0.0)`) Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value, validation range: `(0, 100)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct MonitoredLine <: ACTransmission\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow on the line (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\"\n    b::FromTo\n    \"Minimum and maximum permissable flow on the line (MVA), if different from the thermal rating defined in `rating`\"\n    flow_limits::FromTo_ToFrom\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a line before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Float64\n    \"Minimum and maximum angle limits (radians)\"\n    angle_limits::MinMax\n    \"Second current rating; entered in MVA.\"\n    rating_b::Union{Nothing, Float64}\n    \"Third current rating; entered in MVA.\"\n    rating_c::Union{Nothing, Float64}\n    \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)), specified both on the `from` and `to` ends of the line. These are commonly modeled with the same value\"\n    g::FromTo\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction MonitoredLine(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, flow_limits, rating, angle_limits, rating_b=nothing, rating_c=nothing, g=(from=0.0, to=0.0), services=Device[], ext=Dict{String, Any}(), )\n    MonitoredLine(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, flow_limits, rating, angle_limits, rating_b, rating_c, g, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction MonitoredLine(; name, available, active_power_flow, reactive_power_flow, arc, r, x, b, flow_limits, rating, angle_limits, rating_b=nothing, rating_c=nothing, g=(from=0.0, to=0.0), services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    MonitoredLine(name, available, active_power_flow, reactive_power_flow, arc, r, x, b, flow_limits, rating, angle_limits, rating_b, rating_c, g, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction MonitoredLine(::Nothing)\n    MonitoredLine(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        b=(from=0.0, to=0.0),\n        flow_limits=(from_to=0.0, to_from=0.0),\n        rating=0.0,\n        angle_limits=(min=-3.1416, max=3.1416),\n        rating_b=0.0,\n        rating_c=0.0,\n        g=(from=0.0, to=0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`MonitoredLine`](@ref) `name`.\"\"\"\nget_name(value::MonitoredLine) = value.name\n\"\"\"Get [`MonitoredLine`](@ref) `available`.\"\"\"\nget_available(value::MonitoredLine) = value.available\n\"\"\"Get [`MonitoredLine`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::MonitoredLine) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::MonitoredLine) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `arc`.\"\"\"\nget_arc(value::MonitoredLine) = value.arc\n\"\"\"Get [`MonitoredLine`](@ref) `r`.\"\"\"\nget_r(value::MonitoredLine) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`MonitoredLine`](@ref) `x`.\"\"\"\nget_x(value::MonitoredLine) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`MonitoredLine`](@ref) `b`.\"\"\"\nget_b(value::MonitoredLine) = get_value(value, Val(:b), Val(:siemens))\n\"\"\"Get [`MonitoredLine`](@ref) `flow_limits`.\"\"\"\nget_flow_limits(value::MonitoredLine) = get_value(value, Val(:flow_limits), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `rating`.\"\"\"\nget_rating(value::MonitoredLine) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `angle_limits`.\"\"\"\nget_angle_limits(value::MonitoredLine) = value.angle_limits\n\"\"\"Get [`MonitoredLine`](@ref) `rating_b`.\"\"\"\nget_rating_b(value::MonitoredLine) = get_value(value, Val(:rating_b), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `rating_c`.\"\"\"\nget_rating_c(value::MonitoredLine) = get_value(value, Val(:rating_c), Val(:mva))\n\"\"\"Get [`MonitoredLine`](@ref) `g`.\"\"\"\nget_g(value::MonitoredLine) = get_value(value, Val(:g), Val(:siemens))\n\"\"\"Get [`MonitoredLine`](@ref) `services`.\"\"\"\nget_services(value::MonitoredLine) = value.services\n\"\"\"Get [`MonitoredLine`](@ref) `ext`.\"\"\"\nget_ext(value::MonitoredLine) = value.ext\n\"\"\"Get [`MonitoredLine`](@ref) `internal`.\"\"\"\nget_internal(value::MonitoredLine) = value.internal\n\n\"\"\"Set [`MonitoredLine`](@ref) `available`.\"\"\"\nset_available!(value::MonitoredLine, val) = value.available = val\n\"\"\"Set [`MonitoredLine`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::MonitoredLine, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::MonitoredLine, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `arc`.\"\"\"\nset_arc!(value::MonitoredLine, val) = value.arc = val\n\"\"\"Set [`MonitoredLine`](@ref) `r`.\"\"\"\nset_r!(value::MonitoredLine, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`MonitoredLine`](@ref) `x`.\"\"\"\nset_x!(value::MonitoredLine, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`MonitoredLine`](@ref) `b`.\"\"\"\nset_b!(value::MonitoredLine, val) = value.b = set_value(value, Val(:b), val, Val(:siemens))\n\"\"\"Set [`MonitoredLine`](@ref) `flow_limits`.\"\"\"\nset_flow_limits!(value::MonitoredLine, val) = value.flow_limits = set_value(value, Val(:flow_limits), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `rating`.\"\"\"\nset_rating!(value::MonitoredLine, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `angle_limits`.\"\"\"\nset_angle_limits!(value::MonitoredLine, val) = value.angle_limits = val\n\"\"\"Set [`MonitoredLine`](@ref) `rating_b`.\"\"\"\nset_rating_b!(value::MonitoredLine, val) = value.rating_b = set_value(value, Val(:rating_b), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `rating_c`.\"\"\"\nset_rating_c!(value::MonitoredLine, val) = value.rating_c = set_value(value, Val(:rating_c), val, Val(:mva))\n\"\"\"Set [`MonitoredLine`](@ref) `g`.\"\"\"\nset_g!(value::MonitoredLine, val) = value.g = set_value(value, Val(:g), val, Val(:siemens))\n\"\"\"Set [`MonitoredLine`](@ref) `services`.\"\"\"\nset_services!(value::MonitoredLine, val) = value.services = val\n\"\"\"Set [`MonitoredLine`](@ref) `ext`.\"\"\"\nset_ext!(value::MonitoredLine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/MotorLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct MotorLoad <: StaticLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        base_power::Float64\n        rating::Float64\n        max_active_power::Float64\n        reactive_power_limits::Union{Nothing, MinMax}\n        motor_technology::MotorLoadTechnology\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA [static](@ref S) power load, most commonly used for operational models such as power flow and operational optimizations.\n\nThis load consumes a set amount of power (set by `active_power` for a power flow simulation or a `max_active_power` time series for an operational simulation). For loads that can be compensated for load interruptions through demand response programs, see [`InterruptiblePowerLoad`](@ref). For voltage-dependent loads used in [dynamics](@ref D) modeling, see [`StandardLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `MotorLoad`) must have unique names, but components of different types (e.g., `MotorLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial steady-state active power demand (MW). A positive value indicates power consumption.\n- `reactive_power::Float64`: Initial steady-state reactive power demand (MVAR). A positive value indicates reactive power consumption.\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `max_active_power::Float64`: Maximum active power (MW) that this load can demand\n- `reactive_power_limits::Union{Nothing, MinMax}`: (default: `nothing`) Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `motor_technology::MotorLoadTechnology`: (default: `MotorLoadTechnology.UNDETERMINED`) AC Motor type. Options are listed [here](@ref motor_list)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct MotorLoad <: StaticLoad\n    \"Name of the component. Components of the same type (e.g., `MotorLoad`) must have unique names, but components of different types (e.g., `MotorLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial steady-state active power demand (MW). A positive value indicates power consumption.\"\n    active_power::Float64\n    \"Initial steady-state reactive power demand (MVAR). A positive value indicates reactive power consumption.\"\n    reactive_power::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Maximum active power (MW) that this load can demand\"\n    max_active_power::Float64\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"AC Motor type. Options are listed [here](@ref motor_list)\"\n    motor_technology::MotorLoadTechnology\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction MotorLoad(name, available, bus, active_power, reactive_power, base_power, rating, max_active_power, reactive_power_limits=nothing, motor_technology=MotorLoadTechnology.UNDETERMINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    MotorLoad(name, available, bus, active_power, reactive_power, base_power, rating, max_active_power, reactive_power_limits, motor_technology, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction MotorLoad(; name, available, bus, active_power, reactive_power, base_power, rating, max_active_power, reactive_power_limits=nothing, motor_technology=MotorLoadTechnology.UNDETERMINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    MotorLoad(name, available, bus, active_power, reactive_power, base_power, rating, max_active_power, reactive_power_limits, motor_technology, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction MotorLoad(::Nothing)\n    MotorLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        base_power=100.0,\n        rating=0.0,\n        max_active_power=0.0,\n        reactive_power_limits=nothing,\n        motor_technology=MotorLoadTechnology.UNDETERMINED,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`MotorLoad`](@ref) `name`.\"\"\"\nget_name(value::MotorLoad) = value.name\n\"\"\"Get [`MotorLoad`](@ref) `available`.\"\"\"\nget_available(value::MotorLoad) = value.available\n\"\"\"Get [`MotorLoad`](@ref) `bus`.\"\"\"\nget_bus(value::MotorLoad) = value.bus\n\"\"\"Get [`MotorLoad`](@ref) `active_power`.\"\"\"\nget_active_power(value::MotorLoad) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`MotorLoad`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::MotorLoad) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`MotorLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::MotorLoad) = value.base_power\n\"\"\"Get [`MotorLoad`](@ref) `rating`.\"\"\"\nget_rating(value::MotorLoad) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`MotorLoad`](@ref) `max_active_power`.\"\"\"\nget_max_active_power(value::MotorLoad) = get_value(value, Val(:max_active_power), Val(:mva))\n\"\"\"Get [`MotorLoad`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::MotorLoad) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`MotorLoad`](@ref) `motor_technology`.\"\"\"\nget_motor_technology(value::MotorLoad) = value.motor_technology\n\"\"\"Get [`MotorLoad`](@ref) `services`.\"\"\"\nget_services(value::MotorLoad) = value.services\n\"\"\"Get [`MotorLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::MotorLoad) = value.dynamic_injector\n\"\"\"Get [`MotorLoad`](@ref) `ext`.\"\"\"\nget_ext(value::MotorLoad) = value.ext\n\"\"\"Get [`MotorLoad`](@ref) `internal`.\"\"\"\nget_internal(value::MotorLoad) = value.internal\n\n\"\"\"Set [`MotorLoad`](@ref) `available`.\"\"\"\nset_available!(value::MotorLoad, val) = value.available = val\n\"\"\"Set [`MotorLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::MotorLoad, val) = value.bus = val\n\"\"\"Set [`MotorLoad`](@ref) `active_power`.\"\"\"\nset_active_power!(value::MotorLoad, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`MotorLoad`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::MotorLoad, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`MotorLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::MotorLoad, val) = value.base_power = val\n\"\"\"Set [`MotorLoad`](@ref) `rating`.\"\"\"\nset_rating!(value::MotorLoad, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`MotorLoad`](@ref) `max_active_power`.\"\"\"\nset_max_active_power!(value::MotorLoad, val) = value.max_active_power = set_value(value, Val(:max_active_power), val, Val(:mva))\n\"\"\"Set [`MotorLoad`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::MotorLoad, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`MotorLoad`](@ref) `motor_technology`.\"\"\"\nset_motor_technology!(value::MotorLoad, val) = value.motor_technology = val\n\"\"\"Set [`MotorLoad`](@ref) `services`.\"\"\"\nset_services!(value::MotorLoad, val) = value.services = val\n\"\"\"Set [`MotorLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::MotorLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/OneDOneQMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct OneDOneQMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 4-[states](@ref S) synchronous machine: Simplified Marconato model\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when\n transmission network dynamics is neglected\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage\n- `n_states::Int`: (**Do not modify.**) OneDOneQMachine has 2 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct OneDOneQMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) OneDOneQMachine has 2 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction OneDOneQMachine(R, Xd, Xq, Xd_p, Xq_p, Td0_p, Tq0_p, ext=Dict{String, Any}(), )\n    OneDOneQMachine(R, Xd, Xq, Xd_p, Xq_p, Td0_p, Tq0_p, ext, [:eq_p, :ed_p], 2, InfrastructureSystemsInternal(), )\nend\n\nfunction OneDOneQMachine(; R, Xd, Xq, Xd_p, Xq_p, Td0_p, Tq0_p, ext=Dict{String, Any}(), states=[:eq_p, :ed_p], n_states=2, internal=InfrastructureSystemsInternal(), )\n    OneDOneQMachine(R, Xd, Xq, Xd_p, Xq_p, Td0_p, Tq0_p, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction OneDOneQMachine(::Nothing)\n    OneDOneQMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Td0_p=0,\n        Tq0_p=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`OneDOneQMachine`](@ref) `R`.\"\"\"\nget_R(value::OneDOneQMachine) = value.R\n\"\"\"Get [`OneDOneQMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::OneDOneQMachine) = value.Xd\n\"\"\"Get [`OneDOneQMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::OneDOneQMachine) = value.Xq\n\"\"\"Get [`OneDOneQMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::OneDOneQMachine) = value.Xd_p\n\"\"\"Get [`OneDOneQMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::OneDOneQMachine) = value.Xq_p\n\"\"\"Get [`OneDOneQMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::OneDOneQMachine) = value.Td0_p\n\"\"\"Get [`OneDOneQMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::OneDOneQMachine) = value.Tq0_p\n\"\"\"Get [`OneDOneQMachine`](@ref) `ext`.\"\"\"\nget_ext(value::OneDOneQMachine) = value.ext\n\"\"\"Get [`OneDOneQMachine`](@ref) `states`.\"\"\"\nget_states(value::OneDOneQMachine) = value.states\n\"\"\"Get [`OneDOneQMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::OneDOneQMachine) = value.n_states\n\"\"\"Get [`OneDOneQMachine`](@ref) `internal`.\"\"\"\nget_internal(value::OneDOneQMachine) = value.internal\n\n\"\"\"Set [`OneDOneQMachine`](@ref) `R`.\"\"\"\nset_R!(value::OneDOneQMachine, val) = value.R = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::OneDOneQMachine, val) = value.Xd = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::OneDOneQMachine, val) = value.Xq = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::OneDOneQMachine, val) = value.Xd_p = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::OneDOneQMachine, val) = value.Xq_p = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::OneDOneQMachine, val) = value.Td0_p = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::OneDOneQMachine, val) = value.Tq0_p = val\n\"\"\"Set [`OneDOneQMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::OneDOneQMachine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PIDGOV.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PIDGOV <: TurbineGov\n        feedback_flag::Int\n        Rperm::Float64\n        T_reg::Float64\n        Kp::Float64\n        Ki::Float64\n        Kd::Float64\n        Ta::Float64\n        Tb::Float64\n        D_turb::Float64\n        gate_openings::Tuple{Float64, Float64, Float64}\n        power_gate_openings::Tuple{Float64, Float64, Float64}\n        G_lim::MinMax\n        A_tw::Float64\n        Tw::Float64\n        V_lim::MinMax\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nHydro Turbine-Governor with PID controller.\n\n# Arguments\n- `feedback_flag::Int`: Feedback signal for governor droop: 0 for electrical power, and 1 for gate position., validation range: `(0, 1)`\n- `Rperm::Float64`: Speed permanent droop parameter, validation range: `(0, nothing)`\n- `T_reg::Float64`: Speed detector time constant, validation range: `(0, nothing)`\n- `Kp::Float64`: Governor proportional gain, validation range: `(0, nothing)`\n- `Ki::Float64`: Governor integral gain, validation range: `(0, nothing)`\n- `Kd::Float64`: Governor derivative gain, validation range: `(0, nothing)`\n- `Ta::Float64`: Governor derivative time constant, validation range: `(0, nothing)`\n- `Tb::Float64`: Gate-servo time constant, validation range: `(0, nothing)`\n- `D_turb::Float64`: Turbine damping factor, validation range: `(0, nothing)`\n- `gate_openings::Tuple{Float64, Float64, Float64}`: Gate-opening speed at different loads\n- `power_gate_openings::Tuple{Float64, Float64, Float64}`: Power at gate_openings\n- `G_lim::MinMax`: Minimum/Maximum Gate openings `(G_min, G_max)`.\n- `A_tw::Float64`: Factor multiplying Tw, validation range: `(eps(), nothing)`\n- `Tw::Float64`: Water inertia time constant, sec, validation range: `(eps(), nothing)`\n- `V_lim::MinMax`: Gate opening velocity limits `(G_min, G_max)`.\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\n\tx_g1: Filtered input measurement,\n\tx_g2: PI block internal state,\n\tx_g3: First regulator state, \n\tx_g4: Derivative block internal state, \n\tx_g5: Second regulator state, \n\tx_g6: Gate position state, \n\tx_g7: Water inertia state\n- `n_states::Int`: (**Do not modify.**) PIDGOV has 7 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PIDGOV <: TurbineGov\n    \"Feedback signal for governor droop: 0 for electrical power, and 1 for gate position.\"\n    feedback_flag::Int\n    \"Speed permanent droop parameter\"\n    Rperm::Float64\n    \"Speed detector time constant\"\n    T_reg::Float64\n    \"Governor proportional gain\"\n    Kp::Float64\n    \"Governor integral gain\"\n    Ki::Float64\n    \"Governor derivative gain\"\n    Kd::Float64\n    \"Governor derivative time constant\"\n    Ta::Float64\n    \"Gate-servo time constant\"\n    Tb::Float64\n    \"Turbine damping factor\"\n    D_turb::Float64\n    \"Gate-opening speed at different loads\"\n    gate_openings::Tuple{Float64, Float64, Float64}\n    \"Power at gate_openings\"\n    power_gate_openings::Tuple{Float64, Float64, Float64}\n    \"Minimum/Maximum Gate openings `(G_min, G_max)`.\"\n    G_lim::MinMax\n    \"Factor multiplying Tw\"\n    A_tw::Float64\n    \"Water inertia time constant, sec\"\n    Tw::Float64\n    \"Gate opening velocity limits `(G_min, G_max)`.\"\n    V_lim::MinMax\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\n\tx_g1: Filtered input measurement,\n\tx_g2: PI block internal state,\n\tx_g3: First regulator state, \n\tx_g4: Derivative block internal state, \n\tx_g5: Second regulator state, \n\tx_g6: Gate position state, \n\tx_g7: Water inertia state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) PIDGOV has 7 states\"\n    n_states::Int\n    \"(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref=1.0, ext=Dict{String, Any}(), )\n    PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref, ext, [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], 7, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction PIDGOV(; feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], n_states=7, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    PIDGOV(feedback_flag, Rperm, T_reg, Kp, Ki, Kd, Ta, Tb, D_turb, gate_openings, power_gate_openings, G_lim, A_tw, Tw, V_lim, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PIDGOV(::Nothing)\n    PIDGOV(;\n        feedback_flag=1,\n        Rperm=0,\n        T_reg=0,\n        Kp=0,\n        Ki=0,\n        Kd=0,\n        Ta=0,\n        Tb=0,\n        D_turb=0,\n        gate_openings=(0.0, 0.0, 0.0),\n        power_gate_openings=(0.0, 0.0, 0.0),\n        G_lim=(min=0.0, max=0.0),\n        A_tw=0,\n        Tw=0,\n        V_lim=(min=0.0, max=0.0),\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PIDGOV`](@ref) `feedback_flag`.\"\"\"\nget_feedback_flag(value::PIDGOV) = value.feedback_flag\n\"\"\"Get [`PIDGOV`](@ref) `Rperm`.\"\"\"\nget_Rperm(value::PIDGOV) = value.Rperm\n\"\"\"Get [`PIDGOV`](@ref) `T_reg`.\"\"\"\nget_T_reg(value::PIDGOV) = value.T_reg\n\"\"\"Get [`PIDGOV`](@ref) `Kp`.\"\"\"\nget_Kp(value::PIDGOV) = value.Kp\n\"\"\"Get [`PIDGOV`](@ref) `Ki`.\"\"\"\nget_Ki(value::PIDGOV) = value.Ki\n\"\"\"Get [`PIDGOV`](@ref) `Kd`.\"\"\"\nget_Kd(value::PIDGOV) = value.Kd\n\"\"\"Get [`PIDGOV`](@ref) `Ta`.\"\"\"\nget_Ta(value::PIDGOV) = value.Ta\n\"\"\"Get [`PIDGOV`](@ref) `Tb`.\"\"\"\nget_Tb(value::PIDGOV) = value.Tb\n\"\"\"Get [`PIDGOV`](@ref) `D_turb`.\"\"\"\nget_D_turb(value::PIDGOV) = value.D_turb\n\"\"\"Get [`PIDGOV`](@ref) `gate_openings`.\"\"\"\nget_gate_openings(value::PIDGOV) = value.gate_openings\n\"\"\"Get [`PIDGOV`](@ref) `power_gate_openings`.\"\"\"\nget_power_gate_openings(value::PIDGOV) = value.power_gate_openings\n\"\"\"Get [`PIDGOV`](@ref) `G_lim`.\"\"\"\nget_G_lim(value::PIDGOV) = value.G_lim\n\"\"\"Get [`PIDGOV`](@ref) `A_tw`.\"\"\"\nget_A_tw(value::PIDGOV) = value.A_tw\n\"\"\"Get [`PIDGOV`](@ref) `Tw`.\"\"\"\nget_Tw(value::PIDGOV) = value.Tw\n\"\"\"Get [`PIDGOV`](@ref) `V_lim`.\"\"\"\nget_V_lim(value::PIDGOV) = value.V_lim\n\"\"\"Get [`PIDGOV`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::PIDGOV) = value.P_ref\n\"\"\"Get [`PIDGOV`](@ref) `ext`.\"\"\"\nget_ext(value::PIDGOV) = value.ext\n\"\"\"Get [`PIDGOV`](@ref) `states`.\"\"\"\nget_states(value::PIDGOV) = value.states\n\"\"\"Get [`PIDGOV`](@ref) `n_states`.\"\"\"\nget_n_states(value::PIDGOV) = value.n_states\n\"\"\"Get [`PIDGOV`](@ref) `states_types`.\"\"\"\nget_states_types(value::PIDGOV) = value.states_types\n\"\"\"Get [`PIDGOV`](@ref) `internal`.\"\"\"\nget_internal(value::PIDGOV) = value.internal\n\n\"\"\"Set [`PIDGOV`](@ref) `feedback_flag`.\"\"\"\nset_feedback_flag!(value::PIDGOV, val) = value.feedback_flag = val\n\"\"\"Set [`PIDGOV`](@ref) `Rperm`.\"\"\"\nset_Rperm!(value::PIDGOV, val) = value.Rperm = val\n\"\"\"Set [`PIDGOV`](@ref) `T_reg`.\"\"\"\nset_T_reg!(value::PIDGOV, val) = value.T_reg = val\n\"\"\"Set [`PIDGOV`](@ref) `Kp`.\"\"\"\nset_Kp!(value::PIDGOV, val) = value.Kp = val\n\"\"\"Set [`PIDGOV`](@ref) `Ki`.\"\"\"\nset_Ki!(value::PIDGOV, val) = value.Ki = val\n\"\"\"Set [`PIDGOV`](@ref) `Kd`.\"\"\"\nset_Kd!(value::PIDGOV, val) = value.Kd = val\n\"\"\"Set [`PIDGOV`](@ref) `Ta`.\"\"\"\nset_Ta!(value::PIDGOV, val) = value.Ta = val\n\"\"\"Set [`PIDGOV`](@ref) `Tb`.\"\"\"\nset_Tb!(value::PIDGOV, val) = value.Tb = val\n\"\"\"Set [`PIDGOV`](@ref) `D_turb`.\"\"\"\nset_D_turb!(value::PIDGOV, val) = value.D_turb = val\n\"\"\"Set [`PIDGOV`](@ref) `gate_openings`.\"\"\"\nset_gate_openings!(value::PIDGOV, val) = value.gate_openings = val\n\"\"\"Set [`PIDGOV`](@ref) `power_gate_openings`.\"\"\"\nset_power_gate_openings!(value::PIDGOV, val) = value.power_gate_openings = val\n\"\"\"Set [`PIDGOV`](@ref) `G_lim`.\"\"\"\nset_G_lim!(value::PIDGOV, val) = value.G_lim = val\n\"\"\"Set [`PIDGOV`](@ref) `A_tw`.\"\"\"\nset_A_tw!(value::PIDGOV, val) = value.A_tw = val\n\"\"\"Set [`PIDGOV`](@ref) `Tw`.\"\"\"\nset_Tw!(value::PIDGOV, val) = value.Tw = val\n\"\"\"Set [`PIDGOV`](@ref) `V_lim`.\"\"\"\nset_V_lim!(value::PIDGOV, val) = value.V_lim = val\n\"\"\"Set [`PIDGOV`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::PIDGOV, val) = value.P_ref = val\n\"\"\"Set [`PIDGOV`](@ref) `ext`.\"\"\"\nset_ext!(value::PIDGOV, val) = value.ext = val\n\"\"\"Set [`PIDGOV`](@ref) `states_types`.\"\"\"\nset_states_types!(value::PIDGOV, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/PSS2A.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PSS2A <: PSS\n        input_code_1::Int\n        remote_bus_control_1::Int\n        input_code_2::Int\n        remote_bus_control_2::Int\n        M_rtf::Int\n        N_rtf::Int\n        Tw1::Float64\n        Tw2::Float64\n        T6::Float64\n        Tw3::Float64\n        Tw4::Float64\n        T7::Float64\n        Ks2::Float64\n        Ks3::Float64\n        T8::Float64\n        T9::Float64\n        Ks1::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        Vst_lim::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE Dual-Input Stabilizer Model\n\n# Arguments\n- `input_code_1::Int`: First Input Code for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control_1::Int`: First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `input_code_2::Int`: Second Input Code for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control_2::Int`: Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `M_rtf::Int`: M parameter for ramp tracking filter, validation range: `(0, 8)`\n- `N_rtf::Int`: N parameter for ramp tracking filter, validation range: `(0, 8)`\n- `Tw1::Float64`: Time constant for first washout filter for first input, validation range: `(eps(), nothing)`\n- `Tw2::Float64`: Time constant for second washout filter for first input, validation range: `(0, nothing)`\n- `T6::Float64`: Time constant for low-pass filter for first input, validation range: `(0, nothing)`\n- `Tw3::Float64`: Time constant for first washout filter for second input, validation range: `(eps(), nothing)`\n- `Tw4::Float64`: Time constant for second washout filter for second input, validation range: `(0, nothing)`\n- `T7::Float64`: Time constant for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks2::Float64`: Gain for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks3::Float64`: Gain for second input, validation range: `(0, nothing)`\n- `T8::Float64`: Time constant for ramp tracking filter, validation range: `(0, nothing)`\n- `T9::Float64`: Time constant for ramp tracking filter, validation range: `(eps(), nothing)`\n- `Ks1::Float64`: Gain before lead-lag blocks, validation range: `(0, nothing)`\n- `T1::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T2::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T3::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `T4::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `Vst_lim::Tuple{Float64, Float64}`: PSS output limits `(Vst_min, Vst_max)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag,\n- `n_states::Int`: (**Do not modify.**) IEEEST has 16 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEEST has 16 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PSS2A <: PSS\n    \"First Input Code for stabilizer\"\n    input_code_1::Int\n    \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_1::Int\n    \"Second Input Code for stabilizer\"\n    input_code_2::Int\n    \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_2::Int\n    \"M parameter for ramp tracking filter\"\n    M_rtf::Int\n    \"N parameter for ramp tracking filter\"\n    N_rtf::Int\n    \"Time constant for first washout filter for first input\"\n    Tw1::Float64\n    \"Time constant for second washout filter for first input\"\n    Tw2::Float64\n    \"Time constant for low-pass filter for first input\"\n    T6::Float64\n    \"Time constant for first washout filter for second input\"\n    Tw3::Float64\n    \"Time constant for second washout filter for second input\"\n    Tw4::Float64\n    \"Time constant for low-pass filter for second input\"\n    T7::Float64\n    \"Gain for low-pass filter for second input\"\n    Ks2::Float64\n    \"Gain for second input\"\n    Ks3::Float64\n    \"Time constant for ramp tracking filter\"\n    T8::Float64\n    \"Time constant for ramp tracking filter\"\n    T9::Float64\n    \"Gain before lead-lag blocks\"\n    Ks1::Float64\n    \"Time constant for first lead-lag block\"\n    T1::Float64\n    \"Time constant for first lead-lag block\"\n    T2::Float64\n    \"Time constant for second lead-lag block\"\n    T3::Float64\n    \"Time constant for second lead-lag block\"\n    T4::Float64\n    \"PSS output limits `(Vst_min, Vst_max)`\"\n    Vst_lim::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) IEEEST has 16 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEEST has 16 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PSS2A(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, Vst_lim, ext=Dict{String, Any}(), )\n    PSS2A(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, Vst_lim, ext, [:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16], 16, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction PSS2A(; input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, Vst_lim, ext=Dict{String, Any}(), states=[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16], n_states=16, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    PSS2A(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, Vst_lim, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PSS2A(::Nothing)\n    PSS2A(;\n        input_code_1=1,\n        remote_bus_control_1=0,\n        input_code_2=1,\n        remote_bus_control_2=0,\n        M_rtf=0,\n        N_rtf=0,\n        Tw1=0,\n        Tw2=0,\n        T6=0,\n        Tw3=0,\n        Tw4=0,\n        T7=0,\n        Ks2=0,\n        Ks3=0,\n        T8=0,\n        T9=0,\n        Ks1=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        Vst_lim=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PSS2A`](@ref) `input_code_1`.\"\"\"\nget_input_code_1(value::PSS2A) = value.input_code_1\n\"\"\"Get [`PSS2A`](@ref) `remote_bus_control_1`.\"\"\"\nget_remote_bus_control_1(value::PSS2A) = value.remote_bus_control_1\n\"\"\"Get [`PSS2A`](@ref) `input_code_2`.\"\"\"\nget_input_code_2(value::PSS2A) = value.input_code_2\n\"\"\"Get [`PSS2A`](@ref) `remote_bus_control_2`.\"\"\"\nget_remote_bus_control_2(value::PSS2A) = value.remote_bus_control_2\n\"\"\"Get [`PSS2A`](@ref) `M_rtf`.\"\"\"\nget_M_rtf(value::PSS2A) = value.M_rtf\n\"\"\"Get [`PSS2A`](@ref) `N_rtf`.\"\"\"\nget_N_rtf(value::PSS2A) = value.N_rtf\n\"\"\"Get [`PSS2A`](@ref) `Tw1`.\"\"\"\nget_Tw1(value::PSS2A) = value.Tw1\n\"\"\"Get [`PSS2A`](@ref) `Tw2`.\"\"\"\nget_Tw2(value::PSS2A) = value.Tw2\n\"\"\"Get [`PSS2A`](@ref) `T6`.\"\"\"\nget_T6(value::PSS2A) = value.T6\n\"\"\"Get [`PSS2A`](@ref) `Tw3`.\"\"\"\nget_Tw3(value::PSS2A) = value.Tw3\n\"\"\"Get [`PSS2A`](@ref) `Tw4`.\"\"\"\nget_Tw4(value::PSS2A) = value.Tw4\n\"\"\"Get [`PSS2A`](@ref) `T7`.\"\"\"\nget_T7(value::PSS2A) = value.T7\n\"\"\"Get [`PSS2A`](@ref) `Ks2`.\"\"\"\nget_Ks2(value::PSS2A) = value.Ks2\n\"\"\"Get [`PSS2A`](@ref) `Ks3`.\"\"\"\nget_Ks3(value::PSS2A) = value.Ks3\n\"\"\"Get [`PSS2A`](@ref) `T8`.\"\"\"\nget_T8(value::PSS2A) = value.T8\n\"\"\"Get [`PSS2A`](@ref) `T9`.\"\"\"\nget_T9(value::PSS2A) = value.T9\n\"\"\"Get [`PSS2A`](@ref) `Ks1`.\"\"\"\nget_Ks1(value::PSS2A) = value.Ks1\n\"\"\"Get [`PSS2A`](@ref) `T1`.\"\"\"\nget_T1(value::PSS2A) = value.T1\n\"\"\"Get [`PSS2A`](@ref) `T2`.\"\"\"\nget_T2(value::PSS2A) = value.T2\n\"\"\"Get [`PSS2A`](@ref) `T3`.\"\"\"\nget_T3(value::PSS2A) = value.T3\n\"\"\"Get [`PSS2A`](@ref) `T4`.\"\"\"\nget_T4(value::PSS2A) = value.T4\n\"\"\"Get [`PSS2A`](@ref) `Vst_lim`.\"\"\"\nget_Vst_lim(value::PSS2A) = value.Vst_lim\n\"\"\"Get [`PSS2A`](@ref) `ext`.\"\"\"\nget_ext(value::PSS2A) = value.ext\n\"\"\"Get [`PSS2A`](@ref) `states`.\"\"\"\nget_states(value::PSS2A) = value.states\n\"\"\"Get [`PSS2A`](@ref) `n_states`.\"\"\"\nget_n_states(value::PSS2A) = value.n_states\n\"\"\"Get [`PSS2A`](@ref) `states_types`.\"\"\"\nget_states_types(value::PSS2A) = value.states_types\n\"\"\"Get [`PSS2A`](@ref) `internal`.\"\"\"\nget_internal(value::PSS2A) = value.internal\n\n\"\"\"Set [`PSS2A`](@ref) `input_code_1`.\"\"\"\nset_input_code_1!(value::PSS2A, val) = value.input_code_1 = val\n\"\"\"Set [`PSS2A`](@ref) `remote_bus_control_1`.\"\"\"\nset_remote_bus_control_1!(value::PSS2A, val) = value.remote_bus_control_1 = val\n\"\"\"Set [`PSS2A`](@ref) `input_code_2`.\"\"\"\nset_input_code_2!(value::PSS2A, val) = value.input_code_2 = val\n\"\"\"Set [`PSS2A`](@ref) `remote_bus_control_2`.\"\"\"\nset_remote_bus_control_2!(value::PSS2A, val) = value.remote_bus_control_2 = val\n\"\"\"Set [`PSS2A`](@ref) `M_rtf`.\"\"\"\nset_M_rtf!(value::PSS2A, val) = value.M_rtf = val\n\"\"\"Set [`PSS2A`](@ref) `N_rtf`.\"\"\"\nset_N_rtf!(value::PSS2A, val) = value.N_rtf = val\n\"\"\"Set [`PSS2A`](@ref) `Tw1`.\"\"\"\nset_Tw1!(value::PSS2A, val) = value.Tw1 = val\n\"\"\"Set [`PSS2A`](@ref) `Tw2`.\"\"\"\nset_Tw2!(value::PSS2A, val) = value.Tw2 = val\n\"\"\"Set [`PSS2A`](@ref) `T6`.\"\"\"\nset_T6!(value::PSS2A, val) = value.T6 = val\n\"\"\"Set [`PSS2A`](@ref) `Tw3`.\"\"\"\nset_Tw3!(value::PSS2A, val) = value.Tw3 = val\n\"\"\"Set [`PSS2A`](@ref) `Tw4`.\"\"\"\nset_Tw4!(value::PSS2A, val) = value.Tw4 = val\n\"\"\"Set [`PSS2A`](@ref) `T7`.\"\"\"\nset_T7!(value::PSS2A, val) = value.T7 = val\n\"\"\"Set [`PSS2A`](@ref) `Ks2`.\"\"\"\nset_Ks2!(value::PSS2A, val) = value.Ks2 = val\n\"\"\"Set [`PSS2A`](@ref) `Ks3`.\"\"\"\nset_Ks3!(value::PSS2A, val) = value.Ks3 = val\n\"\"\"Set [`PSS2A`](@ref) `T8`.\"\"\"\nset_T8!(value::PSS2A, val) = value.T8 = val\n\"\"\"Set [`PSS2A`](@ref) `T9`.\"\"\"\nset_T9!(value::PSS2A, val) = value.T9 = val\n\"\"\"Set [`PSS2A`](@ref) `Ks1`.\"\"\"\nset_Ks1!(value::PSS2A, val) = value.Ks1 = val\n\"\"\"Set [`PSS2A`](@ref) `T1`.\"\"\"\nset_T1!(value::PSS2A, val) = value.T1 = val\n\"\"\"Set [`PSS2A`](@ref) `T2`.\"\"\"\nset_T2!(value::PSS2A, val) = value.T2 = val\n\"\"\"Set [`PSS2A`](@ref) `T3`.\"\"\"\nset_T3!(value::PSS2A, val) = value.T3 = val\n\"\"\"Set [`PSS2A`](@ref) `T4`.\"\"\"\nset_T4!(value::PSS2A, val) = value.T4 = val\n\"\"\"Set [`PSS2A`](@ref) `Vst_lim`.\"\"\"\nset_Vst_lim!(value::PSS2A, val) = value.Vst_lim = val\n\"\"\"Set [`PSS2A`](@ref) `ext`.\"\"\"\nset_ext!(value::PSS2A, val) = value.ext = val\n\"\"\"Set [`PSS2A`](@ref) `states_types`.\"\"\"\nset_states_types!(value::PSS2A, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/PSS2B.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PSS2B <: PSS\n        input_code_1::Int\n        remote_bus_control_1::Int\n        input_code_2::Int\n        remote_bus_control_2::Int\n        M_rtf::Int\n        N_rtf::Int\n        Tw1::Float64\n        Tw2::Float64\n        T6::Float64\n        Tw3::Float64\n        Tw4::Float64\n        T7::Float64\n        Ks2::Float64\n        Ks3::Float64\n        T8::Float64\n        T9::Float64\n        Ks1::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        T10::Float64\n        T11::Float64\n        Vs1_lim::Tuple{Float64, Float64}\n        Vs2_lim::Tuple{Float64, Float64}\n        Vst_lim::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE 421.5 2005 PSS2B IEEE Dual-Input Stabilizer Model\n\n# Arguments\n- `input_code_1::Int`: First Input Code for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control_1::Int`: First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `input_code_2::Int`: Second Input Code for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control_2::Int`: Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `M_rtf::Int`: M parameter for ramp tracking filter, validation range: `(0, 8)`\n- `N_rtf::Int`: N parameter for ramp tracking filter, validation range: `(0, 8)`\n- `Tw1::Float64`: Time constant for first washout filter for first input, validation range: `(eps(), nothing)`\n- `Tw2::Float64`: Time constant for second washout filter for first input, validation range: `(0, nothing)`\n- `T6::Float64`: Time constant for low-pass filter for first input, validation range: `(0, nothing)`\n- `Tw3::Float64`: Time constant for first washout filter for second input, validation range: `(eps(), nothing)`\n- `Tw4::Float64`: Time constant for second washout filter for second input, validation range: `(0, nothing)`\n- `T7::Float64`: Time constant for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks2::Float64`: Gain for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks3::Float64`: Gain for second input, validation range: `(0, nothing)`\n- `T8::Float64`: Time constant for ramp tracking filter, validation range: `(0, nothing)`\n- `T9::Float64`: Time constant for ramp tracking filter, validation range: `(eps(), nothing)`\n- `Ks1::Float64`: Gain before lead-lag blocks, validation range: `(0, nothing)`\n- `T1::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T2::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T3::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `T4::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `T10::Float64`: Time constant for third lead-lag block, validation range: `(0, nothing)`\n- `T11::Float64`: Time constant for third lead-lag block, validation range: `(0, nothing)`\n- `Vs1_lim::Tuple{Float64, Float64}`: First input limits `(Vs1_min, Vs1_max)`\n- `Vs2_lim::Tuple{Float64, Float64}`: Second input limits `(Vs2_min, Vs2_max)`\n- `Vst_lim::Tuple{Float64, Float64}`: PSS output limits `(Vst_min, Vst_max)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag, \n\tx_p17: 3rd lead-lag,\n- `n_states::Int`: (**Do not modify.**) IEEEST has 17 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEEST has 17 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PSS2B <: PSS\n    \"First Input Code for stabilizer\"\n    input_code_1::Int\n    \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_1::Int\n    \"Second Input Code for stabilizer\"\n    input_code_2::Int\n    \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_2::Int\n    \"M parameter for ramp tracking filter\"\n    M_rtf::Int\n    \"N parameter for ramp tracking filter\"\n    N_rtf::Int\n    \"Time constant for first washout filter for first input\"\n    Tw1::Float64\n    \"Time constant for second washout filter for first input\"\n    Tw2::Float64\n    \"Time constant for low-pass filter for first input\"\n    T6::Float64\n    \"Time constant for first washout filter for second input\"\n    Tw3::Float64\n    \"Time constant for second washout filter for second input\"\n    Tw4::Float64\n    \"Time constant for low-pass filter for second input\"\n    T7::Float64\n    \"Gain for low-pass filter for second input\"\n    Ks2::Float64\n    \"Gain for second input\"\n    Ks3::Float64\n    \"Time constant for ramp tracking filter\"\n    T8::Float64\n    \"Time constant for ramp tracking filter\"\n    T9::Float64\n    \"Gain before lead-lag blocks\"\n    Ks1::Float64\n    \"Time constant for first lead-lag block\"\n    T1::Float64\n    \"Time constant for first lead-lag block\"\n    T2::Float64\n    \"Time constant for second lead-lag block\"\n    T3::Float64\n    \"Time constant for second lead-lag block\"\n    T4::Float64\n    \"Time constant for third lead-lag block\"\n    T10::Float64\n    \"Time constant for third lead-lag block\"\n    T11::Float64\n    \"First input limits `(Vs1_min, Vs1_max)`\"\n    Vs1_lim::Tuple{Float64, Float64}\n    \"Second input limits `(Vs2_min, Vs2_max)`\"\n    Vs2_lim::Tuple{Float64, Float64}\n    \"PSS output limits `(Vst_min, Vst_max)`\"\n    Vst_lim::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag, \n\tx_p17: 3rd lead-lag,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) IEEEST has 17 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEEST has 17 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PSS2B(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, ext=Dict{String, Any}(), )\n    PSS2B(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, ext, [:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17], 17, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction PSS2B(; input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, ext=Dict{String, Any}(), states=[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17], n_states=17, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    PSS2B(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PSS2B(::Nothing)\n    PSS2B(;\n        input_code_1=1,\n        remote_bus_control_1=0,\n        input_code_2=1,\n        remote_bus_control_2=0,\n        M_rtf=0,\n        N_rtf=0,\n        Tw1=0,\n        Tw2=0,\n        T6=0,\n        Tw3=0,\n        Tw4=0,\n        T7=0,\n        Ks2=0,\n        Ks3=0,\n        T8=0,\n        T9=0,\n        Ks1=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        T10=0,\n        T11=0,\n        Vs1_lim=(0.0, 0.0),\n        Vs2_lim=(0.0, 0.0),\n        Vst_lim=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PSS2B`](@ref) `input_code_1`.\"\"\"\nget_input_code_1(value::PSS2B) = value.input_code_1\n\"\"\"Get [`PSS2B`](@ref) `remote_bus_control_1`.\"\"\"\nget_remote_bus_control_1(value::PSS2B) = value.remote_bus_control_1\n\"\"\"Get [`PSS2B`](@ref) `input_code_2`.\"\"\"\nget_input_code_2(value::PSS2B) = value.input_code_2\n\"\"\"Get [`PSS2B`](@ref) `remote_bus_control_2`.\"\"\"\nget_remote_bus_control_2(value::PSS2B) = value.remote_bus_control_2\n\"\"\"Get [`PSS2B`](@ref) `M_rtf`.\"\"\"\nget_M_rtf(value::PSS2B) = value.M_rtf\n\"\"\"Get [`PSS2B`](@ref) `N_rtf`.\"\"\"\nget_N_rtf(value::PSS2B) = value.N_rtf\n\"\"\"Get [`PSS2B`](@ref) `Tw1`.\"\"\"\nget_Tw1(value::PSS2B) = value.Tw1\n\"\"\"Get [`PSS2B`](@ref) `Tw2`.\"\"\"\nget_Tw2(value::PSS2B) = value.Tw2\n\"\"\"Get [`PSS2B`](@ref) `T6`.\"\"\"\nget_T6(value::PSS2B) = value.T6\n\"\"\"Get [`PSS2B`](@ref) `Tw3`.\"\"\"\nget_Tw3(value::PSS2B) = value.Tw3\n\"\"\"Get [`PSS2B`](@ref) `Tw4`.\"\"\"\nget_Tw4(value::PSS2B) = value.Tw4\n\"\"\"Get [`PSS2B`](@ref) `T7`.\"\"\"\nget_T7(value::PSS2B) = value.T7\n\"\"\"Get [`PSS2B`](@ref) `Ks2`.\"\"\"\nget_Ks2(value::PSS2B) = value.Ks2\n\"\"\"Get [`PSS2B`](@ref) `Ks3`.\"\"\"\nget_Ks3(value::PSS2B) = value.Ks3\n\"\"\"Get [`PSS2B`](@ref) `T8`.\"\"\"\nget_T8(value::PSS2B) = value.T8\n\"\"\"Get [`PSS2B`](@ref) `T9`.\"\"\"\nget_T9(value::PSS2B) = value.T9\n\"\"\"Get [`PSS2B`](@ref) `Ks1`.\"\"\"\nget_Ks1(value::PSS2B) = value.Ks1\n\"\"\"Get [`PSS2B`](@ref) `T1`.\"\"\"\nget_T1(value::PSS2B) = value.T1\n\"\"\"Get [`PSS2B`](@ref) `T2`.\"\"\"\nget_T2(value::PSS2B) = value.T2\n\"\"\"Get [`PSS2B`](@ref) `T3`.\"\"\"\nget_T3(value::PSS2B) = value.T3\n\"\"\"Get [`PSS2B`](@ref) `T4`.\"\"\"\nget_T4(value::PSS2B) = value.T4\n\"\"\"Get [`PSS2B`](@ref) `T10`.\"\"\"\nget_T10(value::PSS2B) = value.T10\n\"\"\"Get [`PSS2B`](@ref) `T11`.\"\"\"\nget_T11(value::PSS2B) = value.T11\n\"\"\"Get [`PSS2B`](@ref) `Vs1_lim`.\"\"\"\nget_Vs1_lim(value::PSS2B) = value.Vs1_lim\n\"\"\"Get [`PSS2B`](@ref) `Vs2_lim`.\"\"\"\nget_Vs2_lim(value::PSS2B) = value.Vs2_lim\n\"\"\"Get [`PSS2B`](@ref) `Vst_lim`.\"\"\"\nget_Vst_lim(value::PSS2B) = value.Vst_lim\n\"\"\"Get [`PSS2B`](@ref) `ext`.\"\"\"\nget_ext(value::PSS2B) = value.ext\n\"\"\"Get [`PSS2B`](@ref) `states`.\"\"\"\nget_states(value::PSS2B) = value.states\n\"\"\"Get [`PSS2B`](@ref) `n_states`.\"\"\"\nget_n_states(value::PSS2B) = value.n_states\n\"\"\"Get [`PSS2B`](@ref) `states_types`.\"\"\"\nget_states_types(value::PSS2B) = value.states_types\n\"\"\"Get [`PSS2B`](@ref) `internal`.\"\"\"\nget_internal(value::PSS2B) = value.internal\n\n\"\"\"Set [`PSS2B`](@ref) `input_code_1`.\"\"\"\nset_input_code_1!(value::PSS2B, val) = value.input_code_1 = val\n\"\"\"Set [`PSS2B`](@ref) `remote_bus_control_1`.\"\"\"\nset_remote_bus_control_1!(value::PSS2B, val) = value.remote_bus_control_1 = val\n\"\"\"Set [`PSS2B`](@ref) `input_code_2`.\"\"\"\nset_input_code_2!(value::PSS2B, val) = value.input_code_2 = val\n\"\"\"Set [`PSS2B`](@ref) `remote_bus_control_2`.\"\"\"\nset_remote_bus_control_2!(value::PSS2B, val) = value.remote_bus_control_2 = val\n\"\"\"Set [`PSS2B`](@ref) `M_rtf`.\"\"\"\nset_M_rtf!(value::PSS2B, val) = value.M_rtf = val\n\"\"\"Set [`PSS2B`](@ref) `N_rtf`.\"\"\"\nset_N_rtf!(value::PSS2B, val) = value.N_rtf = val\n\"\"\"Set [`PSS2B`](@ref) `Tw1`.\"\"\"\nset_Tw1!(value::PSS2B, val) = value.Tw1 = val\n\"\"\"Set [`PSS2B`](@ref) `Tw2`.\"\"\"\nset_Tw2!(value::PSS2B, val) = value.Tw2 = val\n\"\"\"Set [`PSS2B`](@ref) `T6`.\"\"\"\nset_T6!(value::PSS2B, val) = value.T6 = val\n\"\"\"Set [`PSS2B`](@ref) `Tw3`.\"\"\"\nset_Tw3!(value::PSS2B, val) = value.Tw3 = val\n\"\"\"Set [`PSS2B`](@ref) `Tw4`.\"\"\"\nset_Tw4!(value::PSS2B, val) = value.Tw4 = val\n\"\"\"Set [`PSS2B`](@ref) `T7`.\"\"\"\nset_T7!(value::PSS2B, val) = value.T7 = val\n\"\"\"Set [`PSS2B`](@ref) `Ks2`.\"\"\"\nset_Ks2!(value::PSS2B, val) = value.Ks2 = val\n\"\"\"Set [`PSS2B`](@ref) `Ks3`.\"\"\"\nset_Ks3!(value::PSS2B, val) = value.Ks3 = val\n\"\"\"Set [`PSS2B`](@ref) `T8`.\"\"\"\nset_T8!(value::PSS2B, val) = value.T8 = val\n\"\"\"Set [`PSS2B`](@ref) `T9`.\"\"\"\nset_T9!(value::PSS2B, val) = value.T9 = val\n\"\"\"Set [`PSS2B`](@ref) `Ks1`.\"\"\"\nset_Ks1!(value::PSS2B, val) = value.Ks1 = val\n\"\"\"Set [`PSS2B`](@ref) `T1`.\"\"\"\nset_T1!(value::PSS2B, val) = value.T1 = val\n\"\"\"Set [`PSS2B`](@ref) `T2`.\"\"\"\nset_T2!(value::PSS2B, val) = value.T2 = val\n\"\"\"Set [`PSS2B`](@ref) `T3`.\"\"\"\nset_T3!(value::PSS2B, val) = value.T3 = val\n\"\"\"Set [`PSS2B`](@ref) `T4`.\"\"\"\nset_T4!(value::PSS2B, val) = value.T4 = val\n\"\"\"Set [`PSS2B`](@ref) `T10`.\"\"\"\nset_T10!(value::PSS2B, val) = value.T10 = val\n\"\"\"Set [`PSS2B`](@ref) `T11`.\"\"\"\nset_T11!(value::PSS2B, val) = value.T11 = val\n\"\"\"Set [`PSS2B`](@ref) `Vs1_lim`.\"\"\"\nset_Vs1_lim!(value::PSS2B, val) = value.Vs1_lim = val\n\"\"\"Set [`PSS2B`](@ref) `Vs2_lim`.\"\"\"\nset_Vs2_lim!(value::PSS2B, val) = value.Vs2_lim = val\n\"\"\"Set [`PSS2B`](@ref) `Vst_lim`.\"\"\"\nset_Vst_lim!(value::PSS2B, val) = value.Vst_lim = val\n\"\"\"Set [`PSS2B`](@ref) `ext`.\"\"\"\nset_ext!(value::PSS2B, val) = value.ext = val\n\"\"\"Set [`PSS2B`](@ref) `states_types`.\"\"\"\nset_states_types!(value::PSS2B, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/PSS2C.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PSS2C <: PSS\n        input_code_1::Int\n        remote_bus_control_1::Int\n        input_code_2::Int\n        remote_bus_control_2::Int\n        M_rtf::Int\n        N_rtf::Int\n        Tw1::Float64\n        Tw2::Float64\n        T6::Float64\n        Tw3::Float64\n        Tw4::Float64\n        T7::Float64\n        Ks2::Float64\n        Ks3::Float64\n        T8::Float64\n        T9::Float64\n        Ks1::Float64\n        T1::Float64\n        T2::Float64\n        T3::Float64\n        T4::Float64\n        T10::Float64\n        T11::Float64\n        Vs1_lim::Tuple{Float64, Float64}\n        Vs2_lim::Tuple{Float64, Float64}\n        Vst_lim::Tuple{Float64, Float64}\n        T12::Float64\n        T13::Float64\n        PSS_Hysteresis_param::Tuple{Float64, Float64}\n        Xcomp::Float64\n        Tcomp::Float64\n        hysteresis_binary_logic::Int\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIEEE 421.5 2016 PSS2C IEEE Dual-Input Stabilizer Model\n\n# Arguments\n- `input_code_1::Int`: First Input Code for stabilizer, validation range: `(1, 7)`\n- `remote_bus_control_1::Int`: First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `input_code_2::Int`: Second Input Code for stabilizer, validation range: `(1, 6)`\n- `remote_bus_control_2::Int`: Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\n- `M_rtf::Int`: M parameter for ramp tracking filter, validation range: `(0, 8)`\n- `N_rtf::Int`: N parameter for ramp tracking filter, validation range: `(0, 8)`\n- `Tw1::Float64`: Time constant for first washout filter for first input, validation range: `(eps(), nothing)`\n- `Tw2::Float64`: Time constant for second washout filter for first input, validation range: `(0, nothing)`\n- `T6::Float64`: Time constant for low-pass filter for first input, validation range: `(0, nothing)`\n- `Tw3::Float64`: Time constant for first washout filter for second input, validation range: `(eps(), nothing)`\n- `Tw4::Float64`: Time constant for second washout filter for second input, validation range: `(0, nothing)`\n- `T7::Float64`: Time constant for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks2::Float64`: Gain for low-pass filter for second input, validation range: `(0, nothing)`\n- `Ks3::Float64`: Gain for second input, validation range: `(0, nothing)`\n- `T8::Float64`: Time constant for ramp tracking filter, validation range: `(0, nothing)`\n- `T9::Float64`: Time constant for ramp tracking filter, validation range: `(eps(), nothing)`\n- `Ks1::Float64`: Gain before lead-lag blocks, validation range: `(0, nothing)`\n- `T1::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T2::Float64`: Time constant for first lead-lag block, validation range: `(0, nothing)`\n- `T3::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `T4::Float64`: Time constant for second lead-lag block, validation range: `(0, nothing)`\n- `T10::Float64`: Time constant for third lead-lag block, validation range: `(0, nothing)`\n- `T11::Float64`: Time constant for third lead-lag block, validation range: `(0, nothing)`\n- `Vs1_lim::Tuple{Float64, Float64}`: First input limits `(Vs1_min, Vs1_max)`\n- `Vs2_lim::Tuple{Float64, Float64}`: Second input limits `(Vs2_min, Vs2_max)`\n- `Vst_lim::Tuple{Float64, Float64}`: PSS output limits `(Vst_min, Vst_max)`\n- `T12::Float64`: Time constant for fourth lead-lag block, validation range: `(0, nothing)`\n- `T13::Float64`: Time constant for fourth lead-lag block, validation range: `(0, nothing)`\n- `PSS_Hysteresis_param::Tuple{Float64, Float64}`: PSS output hysteresis parameters `(PSSOFF, PSSON)`\n- `Xcomp::Float64`: Stator Leakage Reactance, validation range: `(0, nothing)`\n- `Tcomp::Float64`: Time measured with compensated frequency, validation range: `(eps(), nothing)`\n- `hysteresis_binary_logic::Int`: (default: `1`) Hysteresis memory variable\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag, \n\tx_p17: 3rd lead-lag, \n\tx_p18: 4th lead-lag, \n\tx_p19: washout block for compensated frequency,\n- `n_states::Int`: (**Do not modify.**) IEEEST has 19 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) IEEEST has 19 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PSS2C <: PSS\n    \"First Input Code for stabilizer\"\n    input_code_1::Int\n    \"First Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_1::Int\n    \"Second Input Code for stabilizer\"\n    input_code_2::Int\n    \"Second Input remote bus identification [`number`](@ref ACBus) for control. `0` identifies the local bus connected to this component\"\n    remote_bus_control_2::Int\n    \"M parameter for ramp tracking filter\"\n    M_rtf::Int\n    \"N parameter for ramp tracking filter\"\n    N_rtf::Int\n    \"Time constant for first washout filter for first input\"\n    Tw1::Float64\n    \"Time constant for second washout filter for first input\"\n    Tw2::Float64\n    \"Time constant for low-pass filter for first input\"\n    T6::Float64\n    \"Time constant for first washout filter for second input\"\n    Tw3::Float64\n    \"Time constant for second washout filter for second input\"\n    Tw4::Float64\n    \"Time constant for low-pass filter for second input\"\n    T7::Float64\n    \"Gain for low-pass filter for second input\"\n    Ks2::Float64\n    \"Gain for second input\"\n    Ks3::Float64\n    \"Time constant for ramp tracking filter\"\n    T8::Float64\n    \"Time constant for ramp tracking filter\"\n    T9::Float64\n    \"Gain before lead-lag blocks\"\n    Ks1::Float64\n    \"Time constant for first lead-lag block\"\n    T1::Float64\n    \"Time constant for first lead-lag block\"\n    T2::Float64\n    \"Time constant for second lead-lag block\"\n    T3::Float64\n    \"Time constant for second lead-lag block\"\n    T4::Float64\n    \"Time constant for third lead-lag block\"\n    T10::Float64\n    \"Time constant for third lead-lag block\"\n    T11::Float64\n    \"First input limits `(Vs1_min, Vs1_max)`\"\n    Vs1_lim::Tuple{Float64, Float64}\n    \"Second input limits `(Vs2_min, Vs2_max)`\"\n    Vs2_lim::Tuple{Float64, Float64}\n    \"PSS output limits `(Vst_min, Vst_max)`\"\n    Vst_lim::Tuple{Float64, Float64}\n    \"Time constant for fourth lead-lag block\"\n    T12::Float64\n    \"Time constant for fourth lead-lag block\"\n    T13::Float64\n    \"PSS output hysteresis parameters `(PSSOFF, PSSON)`\"\n    PSS_Hysteresis_param::Tuple{Float64, Float64}\n    \"Stator Leakage Reactance\"\n    Xcomp::Float64\n    \"Time measured with compensated frequency\"\n    Tcomp::Float64\n    \"Hysteresis memory variable\"\n    hysteresis_binary_logic::Int\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p1: 1st washout 1st input, \n\tx_p2: 2nd washout 1st input, \n\tx_p3: transducer 1st input, \n\tx_p4: 1st washout 2nd input, \n\tx_p5: 2nd washout 2nd input, \n\tx_p6: transducer 2nd input, \n\tx_p7: ramp tracking filter state 1, \n\tx_p8: ramp tracking filter state 2, \n\tx_p9: ramp tracking filter state 3, \n\tx_p10: ramp tracking filter state 4, \n\tx_p11: ramp tracking filter state 5, \n\tx_p12: ramp tracking filter state 6, \n\tx_p13: ramp tracking filter state 7, \n\tx_p14: ramp tracking filter state 8, \n\tx_p15: 1st lead-lag, \n\tx_p16: 2nd lead-lag, \n\tx_p17: 3rd lead-lag, \n\tx_p18: 4th lead-lag, \n\tx_p19: washout block for compensated frequency,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) IEEEST has 19 states\"\n    n_states::Int\n    \"(**Do not modify.**) IEEEST has 19 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PSS2C(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, T12, T13, PSS_Hysteresis_param, Xcomp, Tcomp, hysteresis_binary_logic=1, ext=Dict{String, Any}(), )\n    PSS2C(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, T12, T13, PSS_Hysteresis_param, Xcomp, Tcomp, hysteresis_binary_logic, ext, [:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17, :x_p18, :x_p19], 19, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction PSS2C(; input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, T12, T13, PSS_Hysteresis_param, Xcomp, Tcomp, hysteresis_binary_logic=1, ext=Dict{String, Any}(), states=[:x_p1, :x_p2, :x_p3, :x_p4, :x_p5, :x_p6, :x_p7, :x_p8, :x_p9, :x_p10, :x_p11, :x_p12, :x_p13, :x_p14, :x_p15, :x_p16, :x_p17, :x_p18, :x_p19], n_states=19, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    PSS2C(input_code_1, remote_bus_control_1, input_code_2, remote_bus_control_2, M_rtf, N_rtf, Tw1, Tw2, T6, Tw3, Tw4, T7, Ks2, Ks3, T8, T9, Ks1, T1, T2, T3, T4, T10, T11, Vs1_lim, Vs2_lim, Vst_lim, T12, T13, PSS_Hysteresis_param, Xcomp, Tcomp, hysteresis_binary_logic, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PSS2C(::Nothing)\n    PSS2C(;\n        input_code_1=1,\n        remote_bus_control_1=0,\n        input_code_2=1,\n        remote_bus_control_2=0,\n        M_rtf=0,\n        N_rtf=0,\n        Tw1=0,\n        Tw2=0,\n        T6=0,\n        Tw3=0,\n        Tw4=0,\n        T7=0,\n        Ks2=0,\n        Ks3=0,\n        T8=0,\n        T9=0,\n        Ks1=0,\n        T1=0,\n        T2=0,\n        T3=0,\n        T4=0,\n        T10=0,\n        T11=0,\n        Vs1_lim=(0.0, 0.0),\n        Vs2_lim=(0.0, 0.0),\n        Vst_lim=(0.0, 0.0),\n        T12=0,\n        T13=0,\n        PSS_Hysteresis_param=(0.0, 0.0),\n        Xcomp=0,\n        Tcomp=0,\n        hysteresis_binary_logic=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PSS2C`](@ref) `input_code_1`.\"\"\"\nget_input_code_1(value::PSS2C) = value.input_code_1\n\"\"\"Get [`PSS2C`](@ref) `remote_bus_control_1`.\"\"\"\nget_remote_bus_control_1(value::PSS2C) = value.remote_bus_control_1\n\"\"\"Get [`PSS2C`](@ref) `input_code_2`.\"\"\"\nget_input_code_2(value::PSS2C) = value.input_code_2\n\"\"\"Get [`PSS2C`](@ref) `remote_bus_control_2`.\"\"\"\nget_remote_bus_control_2(value::PSS2C) = value.remote_bus_control_2\n\"\"\"Get [`PSS2C`](@ref) `M_rtf`.\"\"\"\nget_M_rtf(value::PSS2C) = value.M_rtf\n\"\"\"Get [`PSS2C`](@ref) `N_rtf`.\"\"\"\nget_N_rtf(value::PSS2C) = value.N_rtf\n\"\"\"Get [`PSS2C`](@ref) `Tw1`.\"\"\"\nget_Tw1(value::PSS2C) = value.Tw1\n\"\"\"Get [`PSS2C`](@ref) `Tw2`.\"\"\"\nget_Tw2(value::PSS2C) = value.Tw2\n\"\"\"Get [`PSS2C`](@ref) `T6`.\"\"\"\nget_T6(value::PSS2C) = value.T6\n\"\"\"Get [`PSS2C`](@ref) `Tw3`.\"\"\"\nget_Tw3(value::PSS2C) = value.Tw3\n\"\"\"Get [`PSS2C`](@ref) `Tw4`.\"\"\"\nget_Tw4(value::PSS2C) = value.Tw4\n\"\"\"Get [`PSS2C`](@ref) `T7`.\"\"\"\nget_T7(value::PSS2C) = value.T7\n\"\"\"Get [`PSS2C`](@ref) `Ks2`.\"\"\"\nget_Ks2(value::PSS2C) = value.Ks2\n\"\"\"Get [`PSS2C`](@ref) `Ks3`.\"\"\"\nget_Ks3(value::PSS2C) = value.Ks3\n\"\"\"Get [`PSS2C`](@ref) `T8`.\"\"\"\nget_T8(value::PSS2C) = value.T8\n\"\"\"Get [`PSS2C`](@ref) `T9`.\"\"\"\nget_T9(value::PSS2C) = value.T9\n\"\"\"Get [`PSS2C`](@ref) `Ks1`.\"\"\"\nget_Ks1(value::PSS2C) = value.Ks1\n\"\"\"Get [`PSS2C`](@ref) `T1`.\"\"\"\nget_T1(value::PSS2C) = value.T1\n\"\"\"Get [`PSS2C`](@ref) `T2`.\"\"\"\nget_T2(value::PSS2C) = value.T2\n\"\"\"Get [`PSS2C`](@ref) `T3`.\"\"\"\nget_T3(value::PSS2C) = value.T3\n\"\"\"Get [`PSS2C`](@ref) `T4`.\"\"\"\nget_T4(value::PSS2C) = value.T4\n\"\"\"Get [`PSS2C`](@ref) `T10`.\"\"\"\nget_T10(value::PSS2C) = value.T10\n\"\"\"Get [`PSS2C`](@ref) `T11`.\"\"\"\nget_T11(value::PSS2C) = value.T11\n\"\"\"Get [`PSS2C`](@ref) `Vs1_lim`.\"\"\"\nget_Vs1_lim(value::PSS2C) = value.Vs1_lim\n\"\"\"Get [`PSS2C`](@ref) `Vs2_lim`.\"\"\"\nget_Vs2_lim(value::PSS2C) = value.Vs2_lim\n\"\"\"Get [`PSS2C`](@ref) `Vst_lim`.\"\"\"\nget_Vst_lim(value::PSS2C) = value.Vst_lim\n\"\"\"Get [`PSS2C`](@ref) `T12`.\"\"\"\nget_T12(value::PSS2C) = value.T12\n\"\"\"Get [`PSS2C`](@ref) `T13`.\"\"\"\nget_T13(value::PSS2C) = value.T13\n\"\"\"Get [`PSS2C`](@ref) `PSS_Hysteresis_param`.\"\"\"\nget_PSS_Hysteresis_param(value::PSS2C) = value.PSS_Hysteresis_param\n\"\"\"Get [`PSS2C`](@ref) `Xcomp`.\"\"\"\nget_Xcomp(value::PSS2C) = value.Xcomp\n\"\"\"Get [`PSS2C`](@ref) `Tcomp`.\"\"\"\nget_Tcomp(value::PSS2C) = value.Tcomp\n\"\"\"Get [`PSS2C`](@ref) `hysteresis_binary_logic`.\"\"\"\nget_hysteresis_binary_logic(value::PSS2C) = value.hysteresis_binary_logic\n\"\"\"Get [`PSS2C`](@ref) `ext`.\"\"\"\nget_ext(value::PSS2C) = value.ext\n\"\"\"Get [`PSS2C`](@ref) `states`.\"\"\"\nget_states(value::PSS2C) = value.states\n\"\"\"Get [`PSS2C`](@ref) `n_states`.\"\"\"\nget_n_states(value::PSS2C) = value.n_states\n\"\"\"Get [`PSS2C`](@ref) `states_types`.\"\"\"\nget_states_types(value::PSS2C) = value.states_types\n\"\"\"Get [`PSS2C`](@ref) `internal`.\"\"\"\nget_internal(value::PSS2C) = value.internal\n\n\"\"\"Set [`PSS2C`](@ref) `input_code_1`.\"\"\"\nset_input_code_1!(value::PSS2C, val) = value.input_code_1 = val\n\"\"\"Set [`PSS2C`](@ref) `remote_bus_control_1`.\"\"\"\nset_remote_bus_control_1!(value::PSS2C, val) = value.remote_bus_control_1 = val\n\"\"\"Set [`PSS2C`](@ref) `input_code_2`.\"\"\"\nset_input_code_2!(value::PSS2C, val) = value.input_code_2 = val\n\"\"\"Set [`PSS2C`](@ref) `remote_bus_control_2`.\"\"\"\nset_remote_bus_control_2!(value::PSS2C, val) = value.remote_bus_control_2 = val\n\"\"\"Set [`PSS2C`](@ref) `M_rtf`.\"\"\"\nset_M_rtf!(value::PSS2C, val) = value.M_rtf = val\n\"\"\"Set [`PSS2C`](@ref) `N_rtf`.\"\"\"\nset_N_rtf!(value::PSS2C, val) = value.N_rtf = val\n\"\"\"Set [`PSS2C`](@ref) `Tw1`.\"\"\"\nset_Tw1!(value::PSS2C, val) = value.Tw1 = val\n\"\"\"Set [`PSS2C`](@ref) `Tw2`.\"\"\"\nset_Tw2!(value::PSS2C, val) = value.Tw2 = val\n\"\"\"Set [`PSS2C`](@ref) `T6`.\"\"\"\nset_T6!(value::PSS2C, val) = value.T6 = val\n\"\"\"Set [`PSS2C`](@ref) `Tw3`.\"\"\"\nset_Tw3!(value::PSS2C, val) = value.Tw3 = val\n\"\"\"Set [`PSS2C`](@ref) `Tw4`.\"\"\"\nset_Tw4!(value::PSS2C, val) = value.Tw4 = val\n\"\"\"Set [`PSS2C`](@ref) `T7`.\"\"\"\nset_T7!(value::PSS2C, val) = value.T7 = val\n\"\"\"Set [`PSS2C`](@ref) `Ks2`.\"\"\"\nset_Ks2!(value::PSS2C, val) = value.Ks2 = val\n\"\"\"Set [`PSS2C`](@ref) `Ks3`.\"\"\"\nset_Ks3!(value::PSS2C, val) = value.Ks3 = val\n\"\"\"Set [`PSS2C`](@ref) `T8`.\"\"\"\nset_T8!(value::PSS2C, val) = value.T8 = val\n\"\"\"Set [`PSS2C`](@ref) `T9`.\"\"\"\nset_T9!(value::PSS2C, val) = value.T9 = val\n\"\"\"Set [`PSS2C`](@ref) `Ks1`.\"\"\"\nset_Ks1!(value::PSS2C, val) = value.Ks1 = val\n\"\"\"Set [`PSS2C`](@ref) `T1`.\"\"\"\nset_T1!(value::PSS2C, val) = value.T1 = val\n\"\"\"Set [`PSS2C`](@ref) `T2`.\"\"\"\nset_T2!(value::PSS2C, val) = value.T2 = val\n\"\"\"Set [`PSS2C`](@ref) `T3`.\"\"\"\nset_T3!(value::PSS2C, val) = value.T3 = val\n\"\"\"Set [`PSS2C`](@ref) `T4`.\"\"\"\nset_T4!(value::PSS2C, val) = value.T4 = val\n\"\"\"Set [`PSS2C`](@ref) `T10`.\"\"\"\nset_T10!(value::PSS2C, val) = value.T10 = val\n\"\"\"Set [`PSS2C`](@ref) `T11`.\"\"\"\nset_T11!(value::PSS2C, val) = value.T11 = val\n\"\"\"Set [`PSS2C`](@ref) `Vs1_lim`.\"\"\"\nset_Vs1_lim!(value::PSS2C, val) = value.Vs1_lim = val\n\"\"\"Set [`PSS2C`](@ref) `Vs2_lim`.\"\"\"\nset_Vs2_lim!(value::PSS2C, val) = value.Vs2_lim = val\n\"\"\"Set [`PSS2C`](@ref) `Vst_lim`.\"\"\"\nset_Vst_lim!(value::PSS2C, val) = value.Vst_lim = val\n\"\"\"Set [`PSS2C`](@ref) `T12`.\"\"\"\nset_T12!(value::PSS2C, val) = value.T12 = val\n\"\"\"Set [`PSS2C`](@ref) `T13`.\"\"\"\nset_T13!(value::PSS2C, val) = value.T13 = val\n\"\"\"Set [`PSS2C`](@ref) `PSS_Hysteresis_param`.\"\"\"\nset_PSS_Hysteresis_param!(value::PSS2C, val) = value.PSS_Hysteresis_param = val\n\"\"\"Set [`PSS2C`](@ref) `Xcomp`.\"\"\"\nset_Xcomp!(value::PSS2C, val) = value.Xcomp = val\n\"\"\"Set [`PSS2C`](@ref) `Tcomp`.\"\"\"\nset_Tcomp!(value::PSS2C, val) = value.Tcomp = val\n\"\"\"Set [`PSS2C`](@ref) `hysteresis_binary_logic`.\"\"\"\nset_hysteresis_binary_logic!(value::PSS2C, val) = value.hysteresis_binary_logic = val\n\"\"\"Set [`PSS2C`](@ref) `ext`.\"\"\"\nset_ext!(value::PSS2C, val) = value.ext = val\n\"\"\"Set [`PSS2C`](@ref) `states_types`.\"\"\"\nset_states_types!(value::PSS2C, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/PSSFixed.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PSSFixed <: PSS\n        V_pss::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a PSS that returns a fixed voltage to add to the reference for the AVR\n\n# Arguments\n- `V_pss::Float64`: Fixed voltage stabilization signal in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) PSSFixed has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) PSSFixed has no states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PSSFixed <: PSS\n    \"Fixed voltage stabilization signal in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    V_pss::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PSSFixed has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) PSSFixed has no states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PSSFixed(V_pss, ext=Dict{String, Any}(), )\n    PSSFixed(V_pss, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )\nend\n\nfunction PSSFixed(; V_pss, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )\n    PSSFixed(V_pss, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PSSFixed(::Nothing)\n    PSSFixed(;\n        V_pss=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PSSFixed`](@ref) `V_pss`.\"\"\"\nget_V_pss(value::PSSFixed) = value.V_pss\n\"\"\"Get [`PSSFixed`](@ref) `ext`.\"\"\"\nget_ext(value::PSSFixed) = value.ext\n\"\"\"Get [`PSSFixed`](@ref) `states`.\"\"\"\nget_states(value::PSSFixed) = value.states\n\"\"\"Get [`PSSFixed`](@ref) `n_states`.\"\"\"\nget_n_states(value::PSSFixed) = value.n_states\n\"\"\"Get [`PSSFixed`](@ref) `internal`.\"\"\"\nget_internal(value::PSSFixed) = value.internal\n\n\"\"\"Set [`PSSFixed`](@ref) `V_pss`.\"\"\"\nset_V_pss!(value::PSSFixed, val) = value.V_pss = val\n\"\"\"Set [`PSSFixed`](@ref) `ext`.\"\"\"\nset_ext!(value::PSSFixed, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PSSSimple.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PSSSimple <: PSS\n        K_ω::Float64\n        K_p::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a PSS that returns a proportional droop voltage to add to the reference for the AVR\n\n# Arguments\n- `K_ω::Float64`: Proportional gain for frequency, validation range: `(0, nothing)`\n- `K_p::Float64`: Proportional gain for active power, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) PSSSimple has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) PSSSimple has no states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PSSSimple <: PSS\n    \"Proportional gain for frequency\"\n    K_ω::Float64\n    \"Proportional gain for active power\"\n    K_p::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PSSSimple has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) PSSSimple has no states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PSSSimple(K_ω, K_p, ext=Dict{String, Any}(), )\n    PSSSimple(K_ω, K_p, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )\nend\n\nfunction PSSSimple(; K_ω, K_p, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )\n    PSSSimple(K_ω, K_p, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PSSSimple(::Nothing)\n    PSSSimple(;\n        K_ω=0,\n        K_p=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PSSSimple`](@ref) `K_ω`.\"\"\"\nget_K_ω(value::PSSSimple) = value.K_ω\n\"\"\"Get [`PSSSimple`](@ref) `K_p`.\"\"\"\nget_K_p(value::PSSSimple) = value.K_p\n\"\"\"Get [`PSSSimple`](@ref) `ext`.\"\"\"\nget_ext(value::PSSSimple) = value.ext\n\"\"\"Get [`PSSSimple`](@ref) `states`.\"\"\"\nget_states(value::PSSSimple) = value.states\n\"\"\"Get [`PSSSimple`](@ref) `n_states`.\"\"\"\nget_n_states(value::PSSSimple) = value.n_states\n\"\"\"Get [`PSSSimple`](@ref) `internal`.\"\"\"\nget_internal(value::PSSSimple) = value.internal\n\n\"\"\"Set [`PSSSimple`](@ref) `K_ω`.\"\"\"\nset_K_ω!(value::PSSSimple, val) = value.K_ω = val\n\"\"\"Set [`PSSSimple`](@ref) `K_p`.\"\"\"\nset_K_p!(value::PSSSimple, val) = value.K_p = val\n\"\"\"Set [`PSSSimple`](@ref) `ext`.\"\"\"\nset_ext!(value::PSSSimple, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PeriodicVariableSource.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PeriodicVariableSource <: DynamicInjection\n        name::String\n        R_th::Float64\n        X_th::Float64\n        internal_voltage_bias::Float64\n        internal_voltage_frequencies::Vector{Float64}\n        internal_voltage_coefficients::Vector{Tuple{Float64,Float64}}\n        internal_angle_bias::Float64\n        internal_angle_frequencies::Vector{Float64}\n        internal_angle_coefficients::Vector{Tuple{Float64,Float64}}\n        base_power::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nThis struct acts as an infinity bus with time varying phasor values magnitude and angle V(t) \theta(t). Time varying functions are represented using fourier series\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `R_th::Float64`: Source Thevenin resistance, validation range: `(0, nothing)`\n- `X_th::Float64`: Source Thevenin reactance, validation range: `(0, nothing)`\n- `internal_voltage_bias::Float64`: (default: `0.0`) a0 term of the Fourier Series for the voltage\n- `internal_voltage_frequencies::Vector{Float64}`: (default: `[0.0]`) Frequencies in radians/s\n- `internal_voltage_coefficients::Vector{Tuple{Float64,Float64}}`: (default: `[(0.0, 0.0)]`) Coefficients for terms n > 1. First component corresponds to sin and second component to cos\n- `internal_angle_bias::Float64`: (default: `0.0`) a0 term of the Fourier Series for the angle\n- `internal_angle_frequencies::Vector{Float64}`: (default: `[0.0]`) Frequencies in radians/s\n- `internal_angle_coefficients::Vector{Tuple{Float64,Float64}}`: (default: `[(0.0, 0.0)]`) Coefficients for terms n > 1. First component corresponds to sin and second component to cos\n- `base_power::Float64`: (default: `100.0`) Base power of the source (MVA) for [per unitization](@ref per_unit)\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) for time, voltage and angle\n- `n_states::Int`: (**Do not modify.**) PeriodicVariableSource has 2 states\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PeriodicVariableSource <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Source Thevenin resistance\"\n    R_th::Float64\n    \"Source Thevenin reactance\"\n    X_th::Float64\n    \"a0 term of the Fourier Series for the voltage\"\n    internal_voltage_bias::Float64\n    \"Frequencies in radians/s\"\n    internal_voltage_frequencies::Vector{Float64}\n    \"Coefficients for terms n > 1. First component corresponds to sin and second component to cos\"\n    internal_voltage_coefficients::Vector{Tuple{Float64,Float64}}\n    \"a0 term of the Fourier Series for the angle\"\n    internal_angle_bias::Float64\n    \"Frequencies in radians/s\"\n    internal_angle_frequencies::Vector{Float64}\n    \"Coefficients for terms n > 1. First component corresponds to sin and second component to cos\"\n    internal_angle_coefficients::Vector{Tuple{Float64,Float64}}\n    \"Base power of the source (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"(**Do not modify.**) The [states](@ref S) for time, voltage and angle\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) PeriodicVariableSource has 2 states\"\n    n_states::Int\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PeriodicVariableSource(name, R_th, X_th, internal_voltage_bias=0.0, internal_voltage_frequencies=[0.0], internal_voltage_coefficients=[(0.0, 0.0)], internal_angle_bias=0.0, internal_angle_frequencies=[0.0], internal_angle_coefficients=[(0.0, 0.0)], base_power=100.0, ext=Dict{String, Any}(), )\n    PeriodicVariableSource(name, R_th, X_th, internal_voltage_bias, internal_voltage_frequencies, internal_voltage_coefficients, internal_angle_bias, internal_angle_frequencies, internal_angle_coefficients, base_power, ext, [:Vt, :θt], 2, InfrastructureSystemsInternal(), )\nend\n\nfunction PeriodicVariableSource(; name, R_th, X_th, internal_voltage_bias=0.0, internal_voltage_frequencies=[0.0], internal_voltage_coefficients=[(0.0, 0.0)], internal_angle_bias=0.0, internal_angle_frequencies=[0.0], internal_angle_coefficients=[(0.0, 0.0)], base_power=100.0, states=[:Vt, :θt], n_states=2, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    PeriodicVariableSource(name, R_th, X_th, internal_voltage_bias, internal_voltage_frequencies, internal_voltage_coefficients, internal_angle_bias, internal_angle_frequencies, internal_angle_coefficients, base_power, states, n_states, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PeriodicVariableSource(::Nothing)\n    PeriodicVariableSource(;\n        name=\"init\",\n        R_th=0,\n        X_th=0,\n        internal_voltage_bias=0,\n        internal_voltage_frequencies=Any[0],\n        internal_voltage_coefficients=[(0.0, 0.0)],\n        internal_angle_bias=0,\n        internal_angle_frequencies=Any[0],\n        internal_angle_coefficients=[(0.0, 0.0)],\n        base_power=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PeriodicVariableSource`](@ref) `name`.\"\"\"\nget_name(value::PeriodicVariableSource) = value.name\n\"\"\"Get [`PeriodicVariableSource`](@ref) `R_th`.\"\"\"\nget_R_th(value::PeriodicVariableSource) = value.R_th\n\"\"\"Get [`PeriodicVariableSource`](@ref) `X_th`.\"\"\"\nget_X_th(value::PeriodicVariableSource) = value.X_th\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_voltage_bias`.\"\"\"\nget_internal_voltage_bias(value::PeriodicVariableSource) = value.internal_voltage_bias\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_voltage_frequencies`.\"\"\"\nget_internal_voltage_frequencies(value::PeriodicVariableSource) = value.internal_voltage_frequencies\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_voltage_coefficients`.\"\"\"\nget_internal_voltage_coefficients(value::PeriodicVariableSource) = value.internal_voltage_coefficients\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_angle_bias`.\"\"\"\nget_internal_angle_bias(value::PeriodicVariableSource) = value.internal_angle_bias\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_angle_frequencies`.\"\"\"\nget_internal_angle_frequencies(value::PeriodicVariableSource) = value.internal_angle_frequencies\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal_angle_coefficients`.\"\"\"\nget_internal_angle_coefficients(value::PeriodicVariableSource) = value.internal_angle_coefficients\n\"\"\"Get [`PeriodicVariableSource`](@ref) `base_power`.\"\"\"\nget_base_power(value::PeriodicVariableSource) = value.base_power\n\"\"\"Get [`PeriodicVariableSource`](@ref) `states`.\"\"\"\nget_states(value::PeriodicVariableSource) = value.states\n\"\"\"Get [`PeriodicVariableSource`](@ref) `n_states`.\"\"\"\nget_n_states(value::PeriodicVariableSource) = value.n_states\n\"\"\"Get [`PeriodicVariableSource`](@ref) `ext`.\"\"\"\nget_ext(value::PeriodicVariableSource) = value.ext\n\"\"\"Get [`PeriodicVariableSource`](@ref) `internal`.\"\"\"\nget_internal(value::PeriodicVariableSource) = value.internal\n\n\"\"\"Set [`PeriodicVariableSource`](@ref) `R_th`.\"\"\"\nset_R_th!(value::PeriodicVariableSource, val) = value.R_th = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `X_th`.\"\"\"\nset_X_th!(value::PeriodicVariableSource, val) = value.X_th = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_voltage_bias`.\"\"\"\nset_internal_voltage_bias!(value::PeriodicVariableSource, val) = value.internal_voltage_bias = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_voltage_frequencies`.\"\"\"\nset_internal_voltage_frequencies!(value::PeriodicVariableSource, val) = value.internal_voltage_frequencies = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_voltage_coefficients`.\"\"\"\nset_internal_voltage_coefficients!(value::PeriodicVariableSource, val) = value.internal_voltage_coefficients = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_angle_bias`.\"\"\"\nset_internal_angle_bias!(value::PeriodicVariableSource, val) = value.internal_angle_bias = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_angle_frequencies`.\"\"\"\nset_internal_angle_frequencies!(value::PeriodicVariableSource, val) = value.internal_angle_frequencies = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `internal_angle_coefficients`.\"\"\"\nset_internal_angle_coefficients!(value::PeriodicVariableSource, val) = value.internal_angle_coefficients = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `base_power`.\"\"\"\nset_base_power!(value::PeriodicVariableSource, val) = value.base_power = val\n\"\"\"Set [`PeriodicVariableSource`](@ref) `ext`.\"\"\"\nset_ext!(value::PeriodicVariableSource, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PhaseShiftingTransformer.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PhaseShiftingTransformer <: TwoWindingTransformer\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        primary_shunt::Complex{Float64}\n        tap::Float64\n        α::Float64\n        rating::Union{Nothing, Float64}\n        base_power::Float64\n        base_voltage_primary::Union{Nothing, Float64}\n        base_voltage_secondary::Union{Nothing, Float64}\n        rating_b::Union{Nothing, Float64}\n        rating_c::Union{Nothing, Float64}\n        phase_angle_limits::MinMax\n        control_objective::TransformerControlObjective\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA phase-shifting transformer regulating the phase angle between two buses to control active power flow in the system.\n\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow through the transformer (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow through the transformer (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(0, 4)`\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(-2, 4)`\n- `primary_shunt::Complex{Float64}`: Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `tap::Float64`: Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage, validation range: `(0, 2)`\n- `α::Float64`: Initial condition of phase shift (radians) between the `from` and `to` buses , validation range: `(-1.571, 1.571)`\n- `rating::Union{Nothing, Float64}`: Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `base_voltage_primary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(arc))`) Primary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_secondary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_to(arc))`) Secondary base voltage in kV, validation range: `(0, nothing)`\n- `rating_b::Union{Nothing, Float64}`: (default: `nothing`) Second current rating; entered in MVA.\n- `rating_c::Union{Nothing, Float64}`: (default: `nothing`) Third current rating; entered in MVA.\n- `phase_angle_limits::MinMax`: (default: `(min=-3.1416, max=3.1416)`) Minimum and maximum phase angle limits (radians)\n- `control_objective::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PhaseShiftingTransformer <: TwoWindingTransformer\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow through the transformer (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow through the transformer (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    primary_shunt::Complex{Float64}\n    \"Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage\"\n    tap::Float64\n    \"Initial condition of phase shift (radians) between the `from` and `to` buses \"\n    α::Float64\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Union{Nothing, Float64}\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Primary base voltage in kV\"\n    base_voltage_primary::Union{Nothing, Float64}\n    \"Secondary base voltage in kV\"\n    base_voltage_secondary::Union{Nothing, Float64}\n    \"Second current rating; entered in MVA.\"\n    rating_b::Union{Nothing, Float64}\n    \"Third current rating; entered in MVA.\"\n    rating_c::Union{Nothing, Float64}\n    \"Minimum and maximum phase angle limits (radians)\"\n    phase_angle_limits::MinMax\n    \"Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective::TransformerControlObjective\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PhaseShiftingTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, α, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, phase_angle_limits=(min=-3.1416, max=3.1416), control_objective=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), )\n    PhaseShiftingTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, α, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, phase_angle_limits, control_objective, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction PhaseShiftingTransformer(; name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, α, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, phase_angle_limits=(min=-3.1416, max=3.1416), control_objective=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    PhaseShiftingTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, α, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, phase_angle_limits, control_objective, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PhaseShiftingTransformer(::Nothing)\n    PhaseShiftingTransformer(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        primary_shunt=0.0,\n        tap=1.0,\n        α=0.0,\n        rating=0.0,\n        base_power=100.0,\n        base_voltage_primary=nothing,\n        base_voltage_secondary=nothing,\n        rating_b=0.0,\n        rating_c=0.0,\n        phase_angle_limits=(min=-3.1416, max=3.1416),\n        control_objective=TransformerControlObjective.UNDEFINED,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `name`.\"\"\"\nget_name(value::PhaseShiftingTransformer) = value.name\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `available`.\"\"\"\nget_available(value::PhaseShiftingTransformer) = value.available\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::PhaseShiftingTransformer) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::PhaseShiftingTransformer) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `arc`.\"\"\"\nget_arc(value::PhaseShiftingTransformer) = value.arc\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `r`.\"\"\"\nget_r(value::PhaseShiftingTransformer) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `x`.\"\"\"\nget_x(value::PhaseShiftingTransformer) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `primary_shunt`.\"\"\"\nget_primary_shunt(value::PhaseShiftingTransformer) = get_value(value, Val(:primary_shunt), Val(:siemens))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `tap`.\"\"\"\nget_tap(value::PhaseShiftingTransformer) = value.tap\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `α`.\"\"\"\nget_α(value::PhaseShiftingTransformer) = value.α\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `rating`.\"\"\"\nget_rating(value::PhaseShiftingTransformer) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `base_power`.\"\"\"\nget_base_power(value::PhaseShiftingTransformer) = value.base_power\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `base_voltage_primary`.\"\"\"\nget_base_voltage_primary(value::PhaseShiftingTransformer) = value.base_voltage_primary\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `base_voltage_secondary`.\"\"\"\nget_base_voltage_secondary(value::PhaseShiftingTransformer) = value.base_voltage_secondary\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `rating_b`.\"\"\"\nget_rating_b(value::PhaseShiftingTransformer) = get_value(value, Val(:rating_b), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `rating_c`.\"\"\"\nget_rating_c(value::PhaseShiftingTransformer) = get_value(value, Val(:rating_c), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `phase_angle_limits`.\"\"\"\nget_phase_angle_limits(value::PhaseShiftingTransformer) = value.phase_angle_limits\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `control_objective`.\"\"\"\nget_control_objective(value::PhaseShiftingTransformer) = value.control_objective\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `services`.\"\"\"\nget_services(value::PhaseShiftingTransformer) = value.services\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `ext`.\"\"\"\nget_ext(value::PhaseShiftingTransformer) = value.ext\n\"\"\"Get [`PhaseShiftingTransformer`](@ref) `internal`.\"\"\"\nget_internal(value::PhaseShiftingTransformer) = value.internal\n\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `available`.\"\"\"\nset_available!(value::PhaseShiftingTransformer, val) = value.available = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::PhaseShiftingTransformer, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::PhaseShiftingTransformer, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `arc`.\"\"\"\nset_arc!(value::PhaseShiftingTransformer, val) = value.arc = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `r`.\"\"\"\nset_r!(value::PhaseShiftingTransformer, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `x`.\"\"\"\nset_x!(value::PhaseShiftingTransformer, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `primary_shunt`.\"\"\"\nset_primary_shunt!(value::PhaseShiftingTransformer, val) = value.primary_shunt = set_value(value, Val(:primary_shunt), val, Val(:siemens))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `tap`.\"\"\"\nset_tap!(value::PhaseShiftingTransformer, val) = value.tap = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `α`.\"\"\"\nset_α!(value::PhaseShiftingTransformer, val) = value.α = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `rating`.\"\"\"\nset_rating!(value::PhaseShiftingTransformer, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `base_power`.\"\"\"\nset_base_power!(value::PhaseShiftingTransformer, val) = value.base_power = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `base_voltage_primary`.\"\"\"\nset_base_voltage_primary!(value::PhaseShiftingTransformer, val) = value.base_voltage_primary = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `base_voltage_secondary`.\"\"\"\nset_base_voltage_secondary!(value::PhaseShiftingTransformer, val) = value.base_voltage_secondary = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `rating_b`.\"\"\"\nset_rating_b!(value::PhaseShiftingTransformer, val) = value.rating_b = set_value(value, Val(:rating_b), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `rating_c`.\"\"\"\nset_rating_c!(value::PhaseShiftingTransformer, val) = value.rating_c = set_value(value, Val(:rating_c), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `phase_angle_limits`.\"\"\"\nset_phase_angle_limits!(value::PhaseShiftingTransformer, val) = value.phase_angle_limits = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `control_objective`.\"\"\"\nset_control_objective!(value::PhaseShiftingTransformer, val) = value.control_objective = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `services`.\"\"\"\nset_services!(value::PhaseShiftingTransformer, val) = value.services = val\n\"\"\"Set [`PhaseShiftingTransformer`](@ref) `ext`.\"\"\"\nset_ext!(value::PhaseShiftingTransformer, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PhaseShiftingTransformer3W.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PhaseShiftingTransformer3W <: ThreeWindingTransformer\n        name::String\n        available::Bool\n        primary_star_arc::Arc\n        secondary_star_arc::Arc\n        tertiary_star_arc::Arc\n        star_bus::ACBus\n        active_power_flow_primary::Float64\n        reactive_power_flow_primary::Float64\n        active_power_flow_secondary::Float64\n        reactive_power_flow_secondary::Float64\n        active_power_flow_tertiary::Float64\n        reactive_power_flow_tertiary::Float64\n        r_primary::Float64\n        x_primary::Float64\n        r_secondary::Float64\n        x_secondary::Float64\n        r_tertiary::Float64\n        x_tertiary::Float64\n        rating::Union{Nothing, Float64}\n        r_12::Float64\n        x_12::Float64\n        r_23::Float64\n        x_23::Float64\n        r_13::Float64\n        x_13::Float64\n        α_primary::Float64\n        α_secondary::Float64\n        α_tertiary::Float64\n        base_power_12::Float64\n        base_power_23::Float64\n        base_power_13::Float64\n        base_voltage_primary::Union{Nothing, Float64}\n        base_voltage_secondary::Union{Nothing, Float64}\n        base_voltage_tertiary::Union{Nothing, Float64}\n        g::Float64\n        b::Float64\n        primary_turns_ratio::Float64\n        secondary_turns_ratio::Float64\n        tertiary_turns_ratio::Float64\n        available_primary::Bool\n        available_secondary::Bool\n        available_tertiary::Bool\n        rating_primary::Float64\n        rating_secondary::Float64\n        rating_tertiary::Float64\n        phase_angle_limits::MinMax\n        control_objective_primary::TransformerControlObjective\n        control_objective_secondary::TransformerControlObjective\n        control_objective_tertiary::TransformerControlObjective\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA 3-winding phase-shifting transformer.\n\n. Phase shifts are specified in radians for primary, secondary, and tertiary windings.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `primary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\n- `secondary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\n- `tertiary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\n- `star_bus::ACBus`: Star (hidden) Bus that this component (equivalent model) is connected to\n- `active_power_flow_primary::Float64`: Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\n- `reactive_power_flow_primary::Float64`: Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\n- `active_power_flow_secondary::Float64`: Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\n- `reactive_power_flow_secondary::Float64`: Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\n- `active_power_flow_tertiary::Float64`: Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\n- `reactive_power_flow_tertiary::Float64`: Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\n- `r_primary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_primary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus., validation range: `(-2, 4)`\n- `r_secondary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_secondary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus., validation range: `(-2, 4)`\n- `r_tertiary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_tertiary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus., validation range: `(-2, 4)`\n- `rating::Union{Nothing, Float64}`: Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to, validation range: `(0, nothing)`\n- `r_12::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_12::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `r_23::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_23::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `r_13::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_13::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `α_primary::Float64`: Initial condition of primary phase shift (radians) between the `from` and `to` buses , validation range: `(-1.571, 1.571)`\n- `α_secondary::Float64`: Initial condition of secondary phase shift (radians) between the `from` and `to` buses , validation range: `(-1.571, 1.571)`\n- `α_tertiary::Float64`: Initial condition of tertiary phase shift (radians) between the `from` and `to` buses , validation range: `(-1.571, 1.571)`\n- `base_power_12::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings., validation range: `(0, nothing)`\n- `base_power_23::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings., validation range: `(0, nothing)`\n- `base_power_13::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings., validation range: `(0, nothing)`\n- `base_voltage_primary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(primary_star_arc))`) Primary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_secondary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(secondary_star_arc))`) Secondary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_tertiary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(tertiary_star_arc))`) Tertiary base voltage in kV, validation range: `(0, nothing)`\n- `g::Float64`: (default: `0.0`) Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\n- `b::Float64`: (default: `0.0`) Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\n- `primary_turns_ratio::Float64`: (default: `1.0`) Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\n- `secondary_turns_ratio::Float64`: (default: `1.0`) Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\n- `tertiary_turns_ratio::Float64`: (default: `1.0`) Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\n- `available_primary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `available_secondary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `available_tertiary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `rating_primary::Float64`: (default: `0.0`) Rating (in MVA) for primary winding.\n- `rating_secondary::Float64`: (default: `0.0`) Rating (in MVA) for secondary winding.\n- `rating_tertiary::Float64`: (default: `0.0`) Rating (in MVA) for tertiary winding.\n- `phase_angle_limits::MinMax`: (default: `(min=-3.1416, max=3.1416)`) Minimum and maximum phase angle limits (radians)\n- `control_objective_primary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `control_objective_secondary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `control_objective_tertiary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PhaseShiftingTransformer3W <: ThreeWindingTransformer\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\"\n    primary_star_arc::Arc\n    \"An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\"\n    secondary_star_arc::Arc\n    \"An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\"\n    tertiary_star_arc::Arc\n    \"Star (hidden) Bus that this component (equivalent model) is connected to\"\n    star_bus::ACBus\n    \"Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\"\n    active_power_flow_primary::Float64\n    \"Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\"\n    reactive_power_flow_primary::Float64\n    \"Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\"\n    active_power_flow_secondary::Float64\n    \"Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\"\n    reactive_power_flow_secondary::Float64\n    \"Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\"\n    active_power_flow_tertiary::Float64\n    \"Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\"\n    reactive_power_flow_tertiary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\"\n    r_primary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\"\n    x_primary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\"\n    r_secondary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\"\n    x_secondary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\"\n    r_tertiary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\"\n    x_tertiary::Float64\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Union{Nothing, Float64}\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E).\"\n    r_12::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E).\"\n    x_12::Float64\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E).\"\n    r_23::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E).\"\n    x_23::Float64\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E).\"\n    r_13::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E).\"\n    x_13::Float64\n    \"Initial condition of primary phase shift (radians) between the `from` and `to` buses \"\n    α_primary::Float64\n    \"Initial condition of secondary phase shift (radians) between the `from` and `to` buses \"\n    α_secondary::Float64\n    \"Initial condition of tertiary phase shift (radians) between the `from` and `to` buses \"\n    α_tertiary::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings.\"\n    base_power_12::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings.\"\n    base_power_23::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings.\"\n    base_power_13::Float64\n    \"Primary base voltage in kV\"\n    base_voltage_primary::Union{Nothing, Float64}\n    \"Secondary base voltage in kV\"\n    base_voltage_secondary::Union{Nothing, Float64}\n    \"Tertiary base voltage in kV\"\n    base_voltage_tertiary::Union{Nothing, Float64}\n    \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\"\n    g::Float64\n    \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\"\n    b::Float64\n    \"Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\"\n    primary_turns_ratio::Float64\n    \"Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\"\n    secondary_turns_ratio::Float64\n    \"Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\"\n    tertiary_turns_ratio::Float64\n    \"Status if primary winding is available or not.\"\n    available_primary::Bool\n    \"Status if primary winding is available or not.\"\n    available_secondary::Bool\n    \"Status if primary winding is available or not.\"\n    available_tertiary::Bool\n    \"Rating (in MVA) for primary winding.\"\n    rating_primary::Float64\n    \"Rating (in MVA) for secondary winding.\"\n    rating_secondary::Float64\n    \"Rating (in MVA) for tertiary winding.\"\n    rating_tertiary::Float64\n    \"Minimum and maximum phase angle limits (radians)\"\n    phase_angle_limits::MinMax\n    \"Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_primary::TransformerControlObjective\n    \"Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_secondary::TransformerControlObjective\n    \"Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_tertiary::TransformerControlObjective\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PhaseShiftingTransformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, α_primary, α_secondary, α_tertiary, base_power_12, base_power_23, base_power_13, base_voltage_primary=get_base_voltage(get_from(primary_star_arc)), base_voltage_secondary=get_base_voltage(get_from(secondary_star_arc)), base_voltage_tertiary=get_base_voltage(get_from(tertiary_star_arc)), g=0.0, b=0.0, primary_turns_ratio=1.0, secondary_turns_ratio=1.0, tertiary_turns_ratio=1.0, available_primary=true, available_secondary=true, available_tertiary=true, rating_primary=0.0, rating_secondary=0.0, rating_tertiary=0.0, phase_angle_limits=(min=-3.1416, max=3.1416), control_objective_primary=TransformerControlObjective.UNDEFINED, control_objective_secondary=TransformerControlObjective.UNDEFINED, control_objective_tertiary=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), )\n    PhaseShiftingTransformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, α_primary, α_secondary, α_tertiary, base_power_12, base_power_23, base_power_13, base_voltage_primary, base_voltage_secondary, base_voltage_tertiary, g, b, primary_turns_ratio, secondary_turns_ratio, tertiary_turns_ratio, available_primary, available_secondary, available_tertiary, rating_primary, rating_secondary, rating_tertiary, phase_angle_limits, control_objective_primary, control_objective_secondary, control_objective_tertiary, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction PhaseShiftingTransformer3W(; name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, α_primary, α_secondary, α_tertiary, base_power_12, base_power_23, base_power_13, base_voltage_primary=get_base_voltage(get_from(primary_star_arc)), base_voltage_secondary=get_base_voltage(get_from(secondary_star_arc)), base_voltage_tertiary=get_base_voltage(get_from(tertiary_star_arc)), g=0.0, b=0.0, primary_turns_ratio=1.0, secondary_turns_ratio=1.0, tertiary_turns_ratio=1.0, available_primary=true, available_secondary=true, available_tertiary=true, rating_primary=0.0, rating_secondary=0.0, rating_tertiary=0.0, phase_angle_limits=(min=-3.1416, max=3.1416), control_objective_primary=TransformerControlObjective.UNDEFINED, control_objective_secondary=TransformerControlObjective.UNDEFINED, control_objective_tertiary=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    PhaseShiftingTransformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, α_primary, α_secondary, α_tertiary, base_power_12, base_power_23, base_power_13, base_voltage_primary, base_voltage_secondary, base_voltage_tertiary, g, b, primary_turns_ratio, secondary_turns_ratio, tertiary_turns_ratio, available_primary, available_secondary, available_tertiary, rating_primary, rating_secondary, rating_tertiary, phase_angle_limits, control_objective_primary, control_objective_secondary, control_objective_tertiary, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PhaseShiftingTransformer3W(::Nothing)\n    PhaseShiftingTransformer3W(;\n        name=\"init\",\n        available=false,\n        primary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        secondary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        tertiary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        star_bus=ACBus(nothing),\n        active_power_flow_primary=0.0,\n        reactive_power_flow_primary=0.0,\n        active_power_flow_secondary=0.0,\n        reactive_power_flow_secondary=0.0,\n        active_power_flow_tertiary=0.0,\n        reactive_power_flow_tertiary=0.0,\n        r_primary=0.0,\n        x_primary=0.0,\n        r_secondary=0.0,\n        x_secondary=0.0,\n        r_tertiary=0.0,\n        x_tertiary=0.0,\n        rating=nothing,\n        r_12=0.0,\n        x_12=0.0,\n        r_23=0.0,\n        x_23=0.0,\n        r_13=0.0,\n        x_13=0.0,\n        α_primary=0.0,\n        α_secondary=0.0,\n        α_tertiary=0.0,\n        base_power_12=0.0,\n        base_power_23=0.0,\n        base_power_13=0.0,\n        base_voltage_primary=nothing,\n        base_voltage_secondary=nothing,\n        base_voltage_tertiary=nothing,\n        g=0.0,\n        b=0.0,\n        primary_turns_ratio=0.0,\n        secondary_turns_ratio=0.0,\n        tertiary_turns_ratio=0.0,\n        available_primary=false,\n        available_secondary=false,\n        available_tertiary=false,\n        rating_primary=0.0,\n        rating_secondary=0.0,\n        rating_tertiary=0.0,\n        phase_angle_limits=(min=-3.1416, max=3.1416),\n        control_objective_primary=TransformerControlObjective.UNDEFINED,\n        control_objective_secondary=TransformerControlObjective.UNDEFINED,\n        control_objective_tertiary=TransformerControlObjective.UNDEFINED,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `name`.\"\"\"\nget_name(value::PhaseShiftingTransformer3W) = value.name\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `available`.\"\"\"\nget_available(value::PhaseShiftingTransformer3W) = value.available\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `primary_star_arc`.\"\"\"\nget_primary_star_arc(value::PhaseShiftingTransformer3W) = value.primary_star_arc\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `secondary_star_arc`.\"\"\"\nget_secondary_star_arc(value::PhaseShiftingTransformer3W) = value.secondary_star_arc\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `tertiary_star_arc`.\"\"\"\nget_tertiary_star_arc(value::PhaseShiftingTransformer3W) = value.tertiary_star_arc\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `star_bus`.\"\"\"\nget_star_bus(value::PhaseShiftingTransformer3W) = value.star_bus\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_primary`.\"\"\"\nget_active_power_flow_primary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:active_power_flow_primary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_primary`.\"\"\"\nget_reactive_power_flow_primary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:reactive_power_flow_primary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_secondary`.\"\"\"\nget_active_power_flow_secondary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:active_power_flow_secondary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_secondary`.\"\"\"\nget_reactive_power_flow_secondary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:reactive_power_flow_secondary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_tertiary`.\"\"\"\nget_active_power_flow_tertiary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:active_power_flow_tertiary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_tertiary`.\"\"\"\nget_reactive_power_flow_tertiary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:reactive_power_flow_tertiary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_primary`.\"\"\"\nget_r_primary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_primary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_primary`.\"\"\"\nget_x_primary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_primary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_secondary`.\"\"\"\nget_r_secondary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_secondary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_secondary`.\"\"\"\nget_x_secondary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_secondary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_tertiary`.\"\"\"\nget_r_tertiary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_tertiary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_tertiary`.\"\"\"\nget_x_tertiary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_tertiary), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `rating`.\"\"\"\nget_rating(value::PhaseShiftingTransformer3W) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_12`.\"\"\"\nget_r_12(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_12), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_12`.\"\"\"\nget_x_12(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_12), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_23`.\"\"\"\nget_r_23(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_23), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_23`.\"\"\"\nget_x_23(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_23), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `r_13`.\"\"\"\nget_r_13(value::PhaseShiftingTransformer3W) = get_value(value, Val(:r_13), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `x_13`.\"\"\"\nget_x_13(value::PhaseShiftingTransformer3W) = get_value(value, Val(:x_13), Val(:ohm))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `α_primary`.\"\"\"\nget_α_primary(value::PhaseShiftingTransformer3W) = value.α_primary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `α_secondary`.\"\"\"\nget_α_secondary(value::PhaseShiftingTransformer3W) = value.α_secondary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `α_tertiary`.\"\"\"\nget_α_tertiary(value::PhaseShiftingTransformer3W) = value.α_tertiary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_power_12`.\"\"\"\nget_base_power_12(value::PhaseShiftingTransformer3W) = value.base_power_12\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_power_23`.\"\"\"\nget_base_power_23(value::PhaseShiftingTransformer3W) = value.base_power_23\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_power_13`.\"\"\"\nget_base_power_13(value::PhaseShiftingTransformer3W) = value.base_power_13\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_voltage_primary`.\"\"\"\nget_base_voltage_primary(value::PhaseShiftingTransformer3W) = value.base_voltage_primary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_voltage_secondary`.\"\"\"\nget_base_voltage_secondary(value::PhaseShiftingTransformer3W) = value.base_voltage_secondary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `base_voltage_tertiary`.\"\"\"\nget_base_voltage_tertiary(value::PhaseShiftingTransformer3W) = value.base_voltage_tertiary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `g`.\"\"\"\nget_g(value::PhaseShiftingTransformer3W) = get_value(value, Val(:g), Val(:siemens))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `b`.\"\"\"\nget_b(value::PhaseShiftingTransformer3W) = get_value(value, Val(:b), Val(:siemens))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `primary_turns_ratio`.\"\"\"\nget_primary_turns_ratio(value::PhaseShiftingTransformer3W) = value.primary_turns_ratio\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `secondary_turns_ratio`.\"\"\"\nget_secondary_turns_ratio(value::PhaseShiftingTransformer3W) = value.secondary_turns_ratio\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `tertiary_turns_ratio`.\"\"\"\nget_tertiary_turns_ratio(value::PhaseShiftingTransformer3W) = value.tertiary_turns_ratio\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `available_primary`.\"\"\"\nget_available_primary(value::PhaseShiftingTransformer3W) = value.available_primary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `available_secondary`.\"\"\"\nget_available_secondary(value::PhaseShiftingTransformer3W) = value.available_secondary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `available_tertiary`.\"\"\"\nget_available_tertiary(value::PhaseShiftingTransformer3W) = value.available_tertiary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `rating_primary`.\"\"\"\nget_rating_primary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:rating_primary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `rating_secondary`.\"\"\"\nget_rating_secondary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:rating_secondary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `rating_tertiary`.\"\"\"\nget_rating_tertiary(value::PhaseShiftingTransformer3W) = get_value(value, Val(:rating_tertiary), Val(:mva))\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `phase_angle_limits`.\"\"\"\nget_phase_angle_limits(value::PhaseShiftingTransformer3W) = value.phase_angle_limits\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `control_objective_primary`.\"\"\"\nget_control_objective_primary(value::PhaseShiftingTransformer3W) = value.control_objective_primary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `control_objective_secondary`.\"\"\"\nget_control_objective_secondary(value::PhaseShiftingTransformer3W) = value.control_objective_secondary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `control_objective_tertiary`.\"\"\"\nget_control_objective_tertiary(value::PhaseShiftingTransformer3W) = value.control_objective_tertiary\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `services`.\"\"\"\nget_services(value::PhaseShiftingTransformer3W) = value.services\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `ext`.\"\"\"\nget_ext(value::PhaseShiftingTransformer3W) = value.ext\n\"\"\"Get [`PhaseShiftingTransformer3W`](@ref) `internal`.\"\"\"\nget_internal(value::PhaseShiftingTransformer3W) = value.internal\n\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `available`.\"\"\"\nset_available!(value::PhaseShiftingTransformer3W, val) = value.available = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `primary_star_arc`.\"\"\"\nset_primary_star_arc!(value::PhaseShiftingTransformer3W, val) = value.primary_star_arc = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `secondary_star_arc`.\"\"\"\nset_secondary_star_arc!(value::PhaseShiftingTransformer3W, val) = value.secondary_star_arc = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `tertiary_star_arc`.\"\"\"\nset_tertiary_star_arc!(value::PhaseShiftingTransformer3W, val) = value.tertiary_star_arc = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `star_bus`.\"\"\"\nset_star_bus!(value::PhaseShiftingTransformer3W, val) = value.star_bus = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_primary`.\"\"\"\nset_active_power_flow_primary!(value::PhaseShiftingTransformer3W, val) = value.active_power_flow_primary = set_value(value, Val(:active_power_flow_primary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_primary`.\"\"\"\nset_reactive_power_flow_primary!(value::PhaseShiftingTransformer3W, val) = value.reactive_power_flow_primary = set_value(value, Val(:reactive_power_flow_primary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_secondary`.\"\"\"\nset_active_power_flow_secondary!(value::PhaseShiftingTransformer3W, val) = value.active_power_flow_secondary = set_value(value, Val(:active_power_flow_secondary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_secondary`.\"\"\"\nset_reactive_power_flow_secondary!(value::PhaseShiftingTransformer3W, val) = value.reactive_power_flow_secondary = set_value(value, Val(:reactive_power_flow_secondary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `active_power_flow_tertiary`.\"\"\"\nset_active_power_flow_tertiary!(value::PhaseShiftingTransformer3W, val) = value.active_power_flow_tertiary = set_value(value, Val(:active_power_flow_tertiary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `reactive_power_flow_tertiary`.\"\"\"\nset_reactive_power_flow_tertiary!(value::PhaseShiftingTransformer3W, val) = value.reactive_power_flow_tertiary = set_value(value, Val(:reactive_power_flow_tertiary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_primary`.\"\"\"\nset_r_primary!(value::PhaseShiftingTransformer3W, val) = value.r_primary = set_value(value, Val(:r_primary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_primary`.\"\"\"\nset_x_primary!(value::PhaseShiftingTransformer3W, val) = value.x_primary = set_value(value, Val(:x_primary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_secondary`.\"\"\"\nset_r_secondary!(value::PhaseShiftingTransformer3W, val) = value.r_secondary = set_value(value, Val(:r_secondary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_secondary`.\"\"\"\nset_x_secondary!(value::PhaseShiftingTransformer3W, val) = value.x_secondary = set_value(value, Val(:x_secondary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_tertiary`.\"\"\"\nset_r_tertiary!(value::PhaseShiftingTransformer3W, val) = value.r_tertiary = set_value(value, Val(:r_tertiary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_tertiary`.\"\"\"\nset_x_tertiary!(value::PhaseShiftingTransformer3W, val) = value.x_tertiary = set_value(value, Val(:x_tertiary), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `rating`.\"\"\"\nset_rating!(value::PhaseShiftingTransformer3W, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_12`.\"\"\"\nset_r_12!(value::PhaseShiftingTransformer3W, val) = value.r_12 = set_value(value, Val(:r_12), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_12`.\"\"\"\nset_x_12!(value::PhaseShiftingTransformer3W, val) = value.x_12 = set_value(value, Val(:x_12), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_23`.\"\"\"\nset_r_23!(value::PhaseShiftingTransformer3W, val) = value.r_23 = set_value(value, Val(:r_23), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_23`.\"\"\"\nset_x_23!(value::PhaseShiftingTransformer3W, val) = value.x_23 = set_value(value, Val(:x_23), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `r_13`.\"\"\"\nset_r_13!(value::PhaseShiftingTransformer3W, val) = value.r_13 = set_value(value, Val(:r_13), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `x_13`.\"\"\"\nset_x_13!(value::PhaseShiftingTransformer3W, val) = value.x_13 = set_value(value, Val(:x_13), val, Val(:ohm))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `α_primary`.\"\"\"\nset_α_primary!(value::PhaseShiftingTransformer3W, val) = value.α_primary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `α_secondary`.\"\"\"\nset_α_secondary!(value::PhaseShiftingTransformer3W, val) = value.α_secondary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `α_tertiary`.\"\"\"\nset_α_tertiary!(value::PhaseShiftingTransformer3W, val) = value.α_tertiary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_power_12`.\"\"\"\nset_base_power_12!(value::PhaseShiftingTransformer3W, val) = value.base_power_12 = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_power_23`.\"\"\"\nset_base_power_23!(value::PhaseShiftingTransformer3W, val) = value.base_power_23 = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_power_13`.\"\"\"\nset_base_power_13!(value::PhaseShiftingTransformer3W, val) = value.base_power_13 = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_voltage_primary`.\"\"\"\nset_base_voltage_primary!(value::PhaseShiftingTransformer3W, val) = value.base_voltage_primary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_voltage_secondary`.\"\"\"\nset_base_voltage_secondary!(value::PhaseShiftingTransformer3W, val) = value.base_voltage_secondary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `base_voltage_tertiary`.\"\"\"\nset_base_voltage_tertiary!(value::PhaseShiftingTransformer3W, val) = value.base_voltage_tertiary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `g`.\"\"\"\nset_g!(value::PhaseShiftingTransformer3W, val) = value.g = set_value(value, Val(:g), val, Val(:siemens))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `b`.\"\"\"\nset_b!(value::PhaseShiftingTransformer3W, val) = value.b = set_value(value, Val(:b), val, Val(:siemens))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `primary_turns_ratio`.\"\"\"\nset_primary_turns_ratio!(value::PhaseShiftingTransformer3W, val) = value.primary_turns_ratio = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `secondary_turns_ratio`.\"\"\"\nset_secondary_turns_ratio!(value::PhaseShiftingTransformer3W, val) = value.secondary_turns_ratio = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `tertiary_turns_ratio`.\"\"\"\nset_tertiary_turns_ratio!(value::PhaseShiftingTransformer3W, val) = value.tertiary_turns_ratio = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `available_primary`.\"\"\"\nset_available_primary!(value::PhaseShiftingTransformer3W, val) = value.available_primary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `available_secondary`.\"\"\"\nset_available_secondary!(value::PhaseShiftingTransformer3W, val) = value.available_secondary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `available_tertiary`.\"\"\"\nset_available_tertiary!(value::PhaseShiftingTransformer3W, val) = value.available_tertiary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `rating_primary`.\"\"\"\nset_rating_primary!(value::PhaseShiftingTransformer3W, val) = value.rating_primary = set_value(value, Val(:rating_primary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `rating_secondary`.\"\"\"\nset_rating_secondary!(value::PhaseShiftingTransformer3W, val) = value.rating_secondary = set_value(value, Val(:rating_secondary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `rating_tertiary`.\"\"\"\nset_rating_tertiary!(value::PhaseShiftingTransformer3W, val) = value.rating_tertiary = set_value(value, Val(:rating_tertiary), val, Val(:mva))\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `phase_angle_limits`.\"\"\"\nset_phase_angle_limits!(value::PhaseShiftingTransformer3W, val) = value.phase_angle_limits = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `control_objective_primary`.\"\"\"\nset_control_objective_primary!(value::PhaseShiftingTransformer3W, val) = value.control_objective_primary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `control_objective_secondary`.\"\"\"\nset_control_objective_secondary!(value::PhaseShiftingTransformer3W, val) = value.control_objective_secondary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `control_objective_tertiary`.\"\"\"\nset_control_objective_tertiary!(value::PhaseShiftingTransformer3W, val) = value.control_objective_tertiary = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `services`.\"\"\"\nset_services!(value::PhaseShiftingTransformer3W, val) = value.services = val\n\"\"\"Set [`PhaseShiftingTransformer3W`](@ref) `ext`.\"\"\"\nset_ext!(value::PhaseShiftingTransformer3W, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PowerLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PowerLoad <: StaticLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        base_power::Float64\n        max_active_power::Float64\n        max_reactive_power::Float64\n        conformity::LoadConformity\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA [static](@ref S) power load, most commonly used for operational models such as power flow and operational optimizations.\n\nThis load consumes a set amount of power (set by `active_power` for a power flow simulation or a `max_active_power` time series for an operational simulation). For loads that can be compensated for load interruptions through demand response programs, see [`InterruptiblePowerLoad`](@ref). For voltage-dependent loads used in [dynamics](@ref D) modeling, see [`StandardLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial steady-state active power demand (MW)\n- `reactive_power::Float64`: Initial steady-state reactive power demand (MVAR)\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `max_active_power::Float64`: Maximum active power (MW) that this load can demand\n- `max_reactive_power::Float64`: Maximum reactive power (MVAR) that this load can demand\n- `conformity::LoadConformity`: (default: `LoadConformity.UNDEFINED`) Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct PowerLoad <: StaticLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial steady-state active power demand (MW)\"\n    active_power::Float64\n    \"Initial steady-state reactive power demand (MVAR)\"\n    reactive_power::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Maximum active power (MW) that this load can demand\"\n    max_active_power::Float64\n    \"Maximum reactive power (MVAR) that this load can demand\"\n    max_reactive_power::Float64\n    \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\"\n    conformity::LoadConformity\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction PowerLoad(name, available, bus, active_power, reactive_power, base_power, max_active_power, max_reactive_power, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    PowerLoad(name, available, bus, active_power, reactive_power, base_power, max_active_power, max_reactive_power, conformity, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction PowerLoad(; name, available, bus, active_power, reactive_power, base_power, max_active_power, max_reactive_power, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    PowerLoad(name, available, bus, active_power, reactive_power, base_power, max_active_power, max_reactive_power, conformity, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PowerLoad(::Nothing)\n    PowerLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        base_power=100.0,\n        max_active_power=0.0,\n        max_reactive_power=0.0,\n        conformity=LoadConformity.UNDEFINED,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PowerLoad`](@ref) `name`.\"\"\"\nget_name(value::PowerLoad) = value.name\n\"\"\"Get [`PowerLoad`](@ref) `available`.\"\"\"\nget_available(value::PowerLoad) = value.available\n\"\"\"Get [`PowerLoad`](@ref) `bus`.\"\"\"\nget_bus(value::PowerLoad) = value.bus\n\"\"\"Get [`PowerLoad`](@ref) `active_power`.\"\"\"\nget_active_power(value::PowerLoad) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`PowerLoad`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::PowerLoad) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`PowerLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::PowerLoad) = value.base_power\n\"\"\"Get [`PowerLoad`](@ref) `max_active_power`.\"\"\"\nget_max_active_power(value::PowerLoad) = get_value(value, Val(:max_active_power), Val(:mva))\n\"\"\"Get [`PowerLoad`](@ref) `max_reactive_power`.\"\"\"\nget_max_reactive_power(value::PowerLoad) = get_value(value, Val(:max_reactive_power), Val(:mva))\n\"\"\"Get [`PowerLoad`](@ref) `conformity`.\"\"\"\nget_conformity(value::PowerLoad) = value.conformity\n\"\"\"Get [`PowerLoad`](@ref) `services`.\"\"\"\nget_services(value::PowerLoad) = value.services\n\"\"\"Get [`PowerLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::PowerLoad) = value.dynamic_injector\n\"\"\"Get [`PowerLoad`](@ref) `ext`.\"\"\"\nget_ext(value::PowerLoad) = value.ext\n\"\"\"Get [`PowerLoad`](@ref) `internal`.\"\"\"\nget_internal(value::PowerLoad) = value.internal\n\n\"\"\"Set [`PowerLoad`](@ref) `available`.\"\"\"\nset_available!(value::PowerLoad, val) = value.available = val\n\"\"\"Set [`PowerLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::PowerLoad, val) = value.bus = val\n\"\"\"Set [`PowerLoad`](@ref) `active_power`.\"\"\"\nset_active_power!(value::PowerLoad, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`PowerLoad`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::PowerLoad, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`PowerLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::PowerLoad, val) = value.base_power = val\n\"\"\"Set [`PowerLoad`](@ref) `max_active_power`.\"\"\"\nset_max_active_power!(value::PowerLoad, val) = value.max_active_power = set_value(value, Val(:max_active_power), val, Val(:mva))\n\"\"\"Set [`PowerLoad`](@ref) `max_reactive_power`.\"\"\"\nset_max_reactive_power!(value::PowerLoad, val) = value.max_reactive_power = set_value(value, Val(:max_reactive_power), val, Val(:mva))\n\"\"\"Set [`PowerLoad`](@ref) `conformity`.\"\"\"\nset_conformity!(value::PowerLoad, val) = value.conformity = val\n\"\"\"Set [`PowerLoad`](@ref) `services`.\"\"\"\nset_services!(value::PowerLoad, val) = value.services = val\n\"\"\"Set [`PowerLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::PowerLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/PriorityOutputCurrentLimiter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct PriorityOutputCurrentLimiter <: OutputCurrentLimiter\n        I_max::Float64\n        ϕ_I::Float64\n        ext::Dict{String, Any}\n    end\n\nParameters of Priority-Based Current Controller Limiter. Regulates the magnitude of the inverter output current and prioritizes a specific angle for the resultant current signal\n\n# Arguments\n- `I_max::Float64`: Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ϕ_I::Float64`: Pre-defined angle (measured against the d-axis) for I_ref once limit I_max is hit, validation range: `(-1.571, 1.571)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n\"\"\"\nmutable struct PriorityOutputCurrentLimiter <: OutputCurrentLimiter\n    \"Maximum limit on current controller input current in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    I_max::Float64\n    \"Pre-defined angle (measured against the d-axis) for I_ref once limit I_max is hit\"\n    ϕ_I::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\nend\n\n\nfunction PriorityOutputCurrentLimiter(; I_max, ϕ_I, ext=Dict{String, Any}(), )\n    PriorityOutputCurrentLimiter(I_max, ϕ_I, ext, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction PriorityOutputCurrentLimiter(::Nothing)\n    PriorityOutputCurrentLimiter(;\n        I_max=0,\n        ϕ_I=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`PriorityOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nget_I_max(value::PriorityOutputCurrentLimiter) = value.I_max\n\"\"\"Get [`PriorityOutputCurrentLimiter`](@ref) `ϕ_I`.\"\"\"\nget_ϕ_I(value::PriorityOutputCurrentLimiter) = value.ϕ_I\n\"\"\"Get [`PriorityOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nget_ext(value::PriorityOutputCurrentLimiter) = value.ext\n\n\"\"\"Set [`PriorityOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nset_I_max!(value::PriorityOutputCurrentLimiter, val) = value.I_max = val\n\"\"\"Set [`PriorityOutputCurrentLimiter`](@ref) `ϕ_I`.\"\"\"\nset_ϕ_I!(value::PriorityOutputCurrentLimiter, val) = value.ϕ_I = val\n\"\"\"Set [`PriorityOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nset_ext!(value::PriorityOutputCurrentLimiter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RECurrentControlB.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RECurrentControlB <: InnerControl\n        Q_Flag::Int\n        PQ_Flag::Int\n        Vdip_lim::MinMax\n        T_rv::Float64\n        dbd_pnts::Tuple{Float64, Float64}\n        K_qv::Float64\n        Iqinj_lim::MinMax\n        V_ref0::Float64\n        K_vp::Float64\n        K_vi::Float64\n        T_iq::Float64\n        I_max::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of the Inner Control part of the REECB model in PSS/E\n\n# Arguments\n- `Q_Flag::Int`: Q Flag used for I_qinj, validation range: `(0, 1)`\n- `PQ_Flag::Int`: PQ Flag used for the Current Limit Logic, validation range: `(0, 1)`\n- `Vdip_lim::MinMax`: Limits for Voltage Dip Logic `(Vdip, Vup)`\n- `T_rv::Float64`: Voltage Filter Time Constant, validation range: `(0, nothing)`\n- `dbd_pnts::Tuple{Float64, Float64}`: Voltage error deadband thresholds `(dbd1, dbd2)`\n- `K_qv::Float64`: Reactive current injection gain during over and undervoltage conditions, validation range: `(0, nothing)`\n- `Iqinj_lim::MinMax`: Limits for Iqinj `(I_qh1, I_ql1)`\n- `V_ref0::Float64`: User defined reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage, validation range: `(0, nothing)`\n- `K_vp::Float64`: Voltage regulator proportional gain (used when QFlag = 1), validation range: `(0, nothing)`\n- `K_vi::Float64`: Voltage regulator integral gain (used when QFlag = 1), validation range: `(0, nothing)`\n- `T_iq::Float64`: Time constant for low-pass filter for state q_V when QFlag = 0, validation range: `(0, nothing)`\n- `I_max::Float64`: Maximum limit on total converter current, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the RECurrentControlB depends on the Flags\n- `n_states::Int`: (**Do not modify.**) The states of the RECurrentControlB depends on the Flags\n\"\"\"\nmutable struct RECurrentControlB <: InnerControl\n    \"Q Flag used for I_qinj\"\n    Q_Flag::Int\n    \"PQ Flag used for the Current Limit Logic\"\n    PQ_Flag::Int\n    \"Limits for Voltage Dip Logic `(Vdip, Vup)`\"\n    Vdip_lim::MinMax\n    \"Voltage Filter Time Constant\"\n    T_rv::Float64\n    \"Voltage error deadband thresholds `(dbd1, dbd2)`\"\n    dbd_pnts::Tuple{Float64, Float64}\n    \"Reactive current injection gain during over and undervoltage conditions\"\n    K_qv::Float64\n    \"Limits for Iqinj `(I_qh1, I_ql1)`\"\n    Iqinj_lim::MinMax\n    \"User defined reference. If 0, [`PowerSimulationsDynamics.jl`](https://sienna-platform.github.io/PowerSimulationsDynamics.jl/stable/) initializes to initial terminal voltage\"\n    V_ref0::Float64\n    \"Voltage regulator proportional gain (used when QFlag = 1)\"\n    K_vp::Float64\n    \"Voltage regulator integral gain (used when QFlag = 1)\"\n    K_vi::Float64\n    \"Time constant for low-pass filter for state q_V when QFlag = 0\"\n    T_iq::Float64\n    \"Maximum limit on total converter current\"\n    I_max::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the RECurrentControlB depends on the Flags\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The states of the RECurrentControlB depends on the Flags\"\n    n_states::Int\nend\n\nfunction RECurrentControlB(Q_Flag, PQ_Flag, Vdip_lim, T_rv, dbd_pnts, K_qv, Iqinj_lim, V_ref0, K_vp, K_vi, T_iq, I_max, ext=Dict{String, Any}(), )\n    RECurrentControlB(Q_Flag, PQ_Flag, Vdip_lim, T_rv, dbd_pnts, K_qv, Iqinj_lim, V_ref0, K_vp, K_vi, T_iq, I_max, ext, PowerSystems.get_REControlB_states(Q_Flag), 2, )\nend\n\nfunction RECurrentControlB(; Q_Flag, PQ_Flag, Vdip_lim, T_rv, dbd_pnts, K_qv, Iqinj_lim, V_ref0, K_vp, K_vi, T_iq, I_max, ext=Dict{String, Any}(), states=PowerSystems.get_REControlB_states(Q_Flag), n_states=2, )\n    RECurrentControlB(Q_Flag, PQ_Flag, Vdip_lim, T_rv, dbd_pnts, K_qv, Iqinj_lim, V_ref0, K_vp, K_vi, T_iq, I_max, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RECurrentControlB(::Nothing)\n    RECurrentControlB(;\n        Q_Flag=0,\n        PQ_Flag=0,\n        Vdip_lim=(min=0.0, max=0.0),\n        T_rv=0,\n        dbd_pnts=(0.0, 0.0),\n        K_qv=0,\n        Iqinj_lim=(min=0.0, max=0.0),\n        V_ref0=0,\n        K_vp=0,\n        K_vi=0,\n        T_iq=0,\n        I_max=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RECurrentControlB`](@ref) `Q_Flag`.\"\"\"\nget_Q_Flag(value::RECurrentControlB) = value.Q_Flag\n\"\"\"Get [`RECurrentControlB`](@ref) `PQ_Flag`.\"\"\"\nget_PQ_Flag(value::RECurrentControlB) = value.PQ_Flag\n\"\"\"Get [`RECurrentControlB`](@ref) `Vdip_lim`.\"\"\"\nget_Vdip_lim(value::RECurrentControlB) = value.Vdip_lim\n\"\"\"Get [`RECurrentControlB`](@ref) `T_rv`.\"\"\"\nget_T_rv(value::RECurrentControlB) = value.T_rv\n\"\"\"Get [`RECurrentControlB`](@ref) `dbd_pnts`.\"\"\"\nget_dbd_pnts(value::RECurrentControlB) = value.dbd_pnts\n\"\"\"Get [`RECurrentControlB`](@ref) `K_qv`.\"\"\"\nget_K_qv(value::RECurrentControlB) = value.K_qv\n\"\"\"Get [`RECurrentControlB`](@ref) `Iqinj_lim`.\"\"\"\nget_Iqinj_lim(value::RECurrentControlB) = value.Iqinj_lim\n\"\"\"Get [`RECurrentControlB`](@ref) `V_ref0`.\"\"\"\nget_V_ref0(value::RECurrentControlB) = value.V_ref0\n\"\"\"Get [`RECurrentControlB`](@ref) `K_vp`.\"\"\"\nget_K_vp(value::RECurrentControlB) = value.K_vp\n\"\"\"Get [`RECurrentControlB`](@ref) `K_vi`.\"\"\"\nget_K_vi(value::RECurrentControlB) = value.K_vi\n\"\"\"Get [`RECurrentControlB`](@ref) `T_iq`.\"\"\"\nget_T_iq(value::RECurrentControlB) = value.T_iq\n\"\"\"Get [`RECurrentControlB`](@ref) `I_max`.\"\"\"\nget_I_max(value::RECurrentControlB) = value.I_max\n\"\"\"Get [`RECurrentControlB`](@ref) `ext`.\"\"\"\nget_ext(value::RECurrentControlB) = value.ext\n\"\"\"Get [`RECurrentControlB`](@ref) `states`.\"\"\"\nget_states(value::RECurrentControlB) = value.states\n\"\"\"Get [`RECurrentControlB`](@ref) `n_states`.\"\"\"\nget_n_states(value::RECurrentControlB) = value.n_states\n\n\"\"\"Set [`RECurrentControlB`](@ref) `Q_Flag`.\"\"\"\nset_Q_Flag!(value::RECurrentControlB, val) = value.Q_Flag = val\n\"\"\"Set [`RECurrentControlB`](@ref) `PQ_Flag`.\"\"\"\nset_PQ_Flag!(value::RECurrentControlB, val) = value.PQ_Flag = val\n\"\"\"Set [`RECurrentControlB`](@ref) `Vdip_lim`.\"\"\"\nset_Vdip_lim!(value::RECurrentControlB, val) = value.Vdip_lim = val\n\"\"\"Set [`RECurrentControlB`](@ref) `T_rv`.\"\"\"\nset_T_rv!(value::RECurrentControlB, val) = value.T_rv = val\n\"\"\"Set [`RECurrentControlB`](@ref) `dbd_pnts`.\"\"\"\nset_dbd_pnts!(value::RECurrentControlB, val) = value.dbd_pnts = val\n\"\"\"Set [`RECurrentControlB`](@ref) `K_qv`.\"\"\"\nset_K_qv!(value::RECurrentControlB, val) = value.K_qv = val\n\"\"\"Set [`RECurrentControlB`](@ref) `Iqinj_lim`.\"\"\"\nset_Iqinj_lim!(value::RECurrentControlB, val) = value.Iqinj_lim = val\n\"\"\"Set [`RECurrentControlB`](@ref) `V_ref0`.\"\"\"\nset_V_ref0!(value::RECurrentControlB, val) = value.V_ref0 = val\n\"\"\"Set [`RECurrentControlB`](@ref) `K_vp`.\"\"\"\nset_K_vp!(value::RECurrentControlB, val) = value.K_vp = val\n\"\"\"Set [`RECurrentControlB`](@ref) `K_vi`.\"\"\"\nset_K_vi!(value::RECurrentControlB, val) = value.K_vi = val\n\"\"\"Set [`RECurrentControlB`](@ref) `T_iq`.\"\"\"\nset_T_iq!(value::RECurrentControlB, val) = value.T_iq = val\n\"\"\"Set [`RECurrentControlB`](@ref) `I_max`.\"\"\"\nset_I_max!(value::RECurrentControlB, val) = value.I_max = val\n\"\"\"Set [`RECurrentControlB`](@ref) `ext`.\"\"\"\nset_ext!(value::RECurrentControlB, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RLFilter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RLFilter <: Filter\n        rf::Float64\n        lf::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of RL series filter in algebraic representation\n\n# Arguments\n- `rf::Float64`: Series resistance in p.u. of converter filter to the grid, validation range: `(0, nothing)`\n- `lf::Float64`: Series inductance in p.u. of converter filter to the grid, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) RLFilter has zero [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) RLFilter has zero states\n\"\"\"\nmutable struct RLFilter <: Filter\n    \"Series resistance in p.u. of converter filter to the grid\"\n    rf::Float64\n    \"Series inductance in p.u. of converter filter to the grid\"\n    lf::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) RLFilter has zero [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) RLFilter has zero states\"\n    n_states::Int\nend\n\nfunction RLFilter(rf, lf, ext=Dict{String, Any}(), )\n    RLFilter(rf, lf, ext, Vector{Symbol}(), 0, )\nend\n\nfunction RLFilter(; rf, lf, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, )\n    RLFilter(rf, lf, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RLFilter(::Nothing)\n    RLFilter(;\n        rf=0,\n        lf=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RLFilter`](@ref) `rf`.\"\"\"\nget_rf(value::RLFilter) = value.rf\n\"\"\"Get [`RLFilter`](@ref) `lf`.\"\"\"\nget_lf(value::RLFilter) = value.lf\n\"\"\"Get [`RLFilter`](@ref) `ext`.\"\"\"\nget_ext(value::RLFilter) = value.ext\n\"\"\"Get [`RLFilter`](@ref) `states`.\"\"\"\nget_states(value::RLFilter) = value.states\n\"\"\"Get [`RLFilter`](@ref) `n_states`.\"\"\"\nget_n_states(value::RLFilter) = value.n_states\n\n\"\"\"Set [`RLFilter`](@ref) `rf`.\"\"\"\nset_rf!(value::RLFilter, val) = value.rf = val\n\"\"\"Set [`RLFilter`](@ref) `lf`.\"\"\"\nset_lf!(value::RLFilter, val) = value.lf = val\n\"\"\"Set [`RLFilter`](@ref) `ext`.\"\"\"\nset_ext!(value::RLFilter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReactivePowerDroop.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReactivePowerDroop <: ReactivePowerControl\n        kq::Float64\n        ωf::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Reactive Power droop controller\n\n# Arguments\n- `kq::Float64`: frequency droop gain, validation range: `(0, nothing)`\n- `ωf::Float64`: filter frequency cutoff, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ReactivePowerDroop model are:\n\tq_oc: Filtered reactive output power\n- `n_states::Int`: (**Do not modify.**) ReactivePowerDroop has 1 state\n\"\"\"\nmutable struct ReactivePowerDroop <: ReactivePowerControl\n    \"frequency droop gain\"\n    kq::Float64\n    \"filter frequency cutoff\"\n    ωf::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ReactivePowerDroop model are:\n\tq_oc: Filtered reactive output power\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ReactivePowerDroop has 1 state\"\n    n_states::Int\nend\n\nfunction ReactivePowerDroop(kq, ωf, V_ref=1.0, ext=Dict{String, Any}(), )\n    ReactivePowerDroop(kq, ωf, V_ref, ext, [:q_oc], 1, )\nend\n\nfunction ReactivePowerDroop(; kq, ωf, V_ref=1.0, ext=Dict{String, Any}(), states=[:q_oc], n_states=1, )\n    ReactivePowerDroop(kq, ωf, V_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReactivePowerDroop(::Nothing)\n    ReactivePowerDroop(;\n        kq=0,\n        ωf=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReactivePowerDroop`](@ref) `kq`.\"\"\"\nget_kq(value::ReactivePowerDroop) = value.kq\n\"\"\"Get [`ReactivePowerDroop`](@ref) `ωf`.\"\"\"\nget_ωf(value::ReactivePowerDroop) = value.ωf\n\"\"\"Get [`ReactivePowerDroop`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ReactivePowerDroop) = value.V_ref\n\"\"\"Get [`ReactivePowerDroop`](@ref) `ext`.\"\"\"\nget_ext(value::ReactivePowerDroop) = value.ext\n\"\"\"Get [`ReactivePowerDroop`](@ref) `states`.\"\"\"\nget_states(value::ReactivePowerDroop) = value.states\n\"\"\"Get [`ReactivePowerDroop`](@ref) `n_states`.\"\"\"\nget_n_states(value::ReactivePowerDroop) = value.n_states\n\n\"\"\"Set [`ReactivePowerDroop`](@ref) `kq`.\"\"\"\nset_kq!(value::ReactivePowerDroop, val) = value.kq = val\n\"\"\"Set [`ReactivePowerDroop`](@ref) `ωf`.\"\"\"\nset_ωf!(value::ReactivePowerDroop, val) = value.ωf = val\n\"\"\"Set [`ReactivePowerDroop`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ReactivePowerDroop, val) = value.V_ref = val\n\"\"\"Set [`ReactivePowerDroop`](@ref) `ext`.\"\"\"\nset_ext!(value::ReactivePowerDroop, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReactivePowerPI.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReactivePowerPI <: ReactivePowerControl\n        Kp_q::Float64\n        Ki_q::Float64\n        ωf::Float64\n        V_ref::Float64\n        Q_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Proportional-Integral Reactive Power controller for a specified power reference\n\n# Arguments\n- `Kp_q::Float64`: Proportional Gain, validation range: `(0, nothing)`\n- `Ki_q::Float64`: Integral Gain, validation range: `(0, nothing)`\n- `ωf::Float64`: filter frequency cutoff, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Voltage Set-point (pu), validation range: `(0, nothing)`\n- `Q_ref::Float64`: (default: `1.0`) Reactive Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ReactivePowerPI model are:\n\tσq_oc: Integrator state of the PI Controller,\n\tq_oc: Measured reactive power of the inverter model\n- `n_states::Int`: (**Do not modify.**) ReactivePowerPI has two states\n\"\"\"\nmutable struct ReactivePowerPI <: ReactivePowerControl\n    \"Proportional Gain\"\n    Kp_q::Float64\n    \"Integral Gain\"\n    Ki_q::Float64\n    \"filter frequency cutoff\"\n    ωf::Float64\n    \"Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"Reactive Power Set-point (pu)\"\n    Q_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ReactivePowerPI model are:\n\tσq_oc: Integrator state of the PI Controller,\n\tq_oc: Measured reactive power of the inverter model\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ReactivePowerPI has two states\"\n    n_states::Int\nend\n\nfunction ReactivePowerPI(Kp_q, Ki_q, ωf, V_ref=1.0, Q_ref=1.0, ext=Dict{String, Any}(), )\n    ReactivePowerPI(Kp_q, Ki_q, ωf, V_ref, Q_ref, ext, [:σq_oc, :q_oc], 2, )\nend\n\nfunction ReactivePowerPI(; Kp_q, Ki_q, ωf, V_ref=1.0, Q_ref=1.0, ext=Dict{String, Any}(), states=[:σq_oc, :q_oc], n_states=2, )\n    ReactivePowerPI(Kp_q, Ki_q, ωf, V_ref, Q_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReactivePowerPI(::Nothing)\n    ReactivePowerPI(;\n        Kp_q=0,\n        Ki_q=0,\n        ωf=0,\n        V_ref=0,\n        Q_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReactivePowerPI`](@ref) `Kp_q`.\"\"\"\nget_Kp_q(value::ReactivePowerPI) = value.Kp_q\n\"\"\"Get [`ReactivePowerPI`](@ref) `Ki_q`.\"\"\"\nget_Ki_q(value::ReactivePowerPI) = value.Ki_q\n\"\"\"Get [`ReactivePowerPI`](@ref) `ωf`.\"\"\"\nget_ωf(value::ReactivePowerPI) = value.ωf\n\"\"\"Get [`ReactivePowerPI`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ReactivePowerPI) = value.V_ref\n\"\"\"Get [`ReactivePowerPI`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::ReactivePowerPI) = value.Q_ref\n\"\"\"Get [`ReactivePowerPI`](@ref) `ext`.\"\"\"\nget_ext(value::ReactivePowerPI) = value.ext\n\"\"\"Get [`ReactivePowerPI`](@ref) `states`.\"\"\"\nget_states(value::ReactivePowerPI) = value.states\n\"\"\"Get [`ReactivePowerPI`](@ref) `n_states`.\"\"\"\nget_n_states(value::ReactivePowerPI) = value.n_states\n\n\"\"\"Set [`ReactivePowerPI`](@ref) `Kp_q`.\"\"\"\nset_Kp_q!(value::ReactivePowerPI, val) = value.Kp_q = val\n\"\"\"Set [`ReactivePowerPI`](@ref) `Ki_q`.\"\"\"\nset_Ki_q!(value::ReactivePowerPI, val) = value.Ki_q = val\n\"\"\"Set [`ReactivePowerPI`](@ref) `ωf`.\"\"\"\nset_ωf!(value::ReactivePowerPI, val) = value.ωf = val\n\"\"\"Set [`ReactivePowerPI`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ReactivePowerPI, val) = value.V_ref = val\n\"\"\"Set [`ReactivePowerPI`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::ReactivePowerPI, val) = value.Q_ref = val\n\"\"\"Set [`ReactivePowerPI`](@ref) `ext`.\"\"\"\nset_ext!(value::ReactivePowerPI, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReactiveRenewableControllerAB.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReactiveRenewableControllerAB <: ReactivePowerControl\n        bus_control::Int\n        from_branch_control::Int\n        to_branch_control::Int\n        branch_id_control::String\n        VC_Flag::Int\n        Ref_Flag::Int\n        PF_Flag::Int\n        V_Flag::Int\n        T_fltr::Float64\n        K_p::Float64\n        K_i::Float64\n        T_ft::Float64\n        T_fv::Float64\n        V_frz::Float64\n        R_c::Float64\n        X_c::Float64\n        K_c::Float64\n        e_lim::MinMax\n        dbd_pnts::Tuple{Float64, Float64}\n        Q_lim::MinMax\n        T_p::Float64\n        Q_lim_inner::MinMax\n        V_lim::MinMax\n        K_qp::Float64\n        K_qi::Float64\n        Q_ref::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of Reactive Power Controller including REPCA1 and REECB1\n\n# Arguments\n- `bus_control::Int`: ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component, validation range: `(0, nothing)`\n- `from_branch_control::Int`: Monitored branch FROM bus identification number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`\n- `to_branch_control::Int`: Monitored branch TO bus identification number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`\n- `branch_id_control::String`: Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\n- `VC_Flag::Int`: Voltage Compensator Flag for REPCA1, validation range: `(0, 1)`\n- `Ref_Flag::Int`: Flag for Reactive Power Control for REPCA1. 0: Q-control, 1: V-control, validation range: `(0, 1)`\n- `PF_Flag::Int`: Flag for Power Factor Control for Outer Control of REECB1. 0: Q-control, 1: Power Factor Control, validation range: `(0, 1)`\n- `V_Flag::Int`: Flag for Voltage Control for Outer Control of REECB1. 0: Voltage Control, 1: Q-Control, validation range: `(0, 1)`\n- `T_fltr::Float64`: Voltage or Q-power of REPCA Filter Time Constant, validation range: `(0, nothing)`\n- `K_p::Float64`: Reactive power PI control proportional gain, validation range: `(0, nothing)`\n- `K_i::Float64`: Reactive power PI control integral gain, validation range: `(0, nothing)`\n- `T_ft::Float64`: Reactive power lead time constant (s), validation range: `(0, nothing)`\n- `T_fv::Float64`: Reactive power lag time constant (s), validation range: `(0, nothing)`\n- `V_frz::Float64`: Voltage below which state ξq_oc (integrator state) is freeze, validation range: `(0, nothing)`\n- `R_c::Float64`: Line drop compensation resistance (used when VC_Flag = 1), validation range: `(0, nothing)`\n- `X_c::Float64`: Line drop compensation reactance (used when VC_Flag = 1), validation range: `(0, nothing)`\n- `K_c::Float64`: Reactive current compensation gain (pu) (used when VC_Flag = 0), validation range: `(0, nothing)`\n- `e_lim::MinMax`: Upper/Lower limit on Voltage or Q-power deadband output `(e_min, e_max)`\n- `dbd_pnts::Tuple{Float64, Float64}`: Voltage or Q-power error dead band thresholds `(dbd1, dbd2)`\n- `Q_lim::MinMax`: Upper/Lower limit on reactive power V/Q control in REPCA `(Q_min, Q_max)`\n- `T_p::Float64`: Active power lag time constant in REECB (s). Used only when PF_Flag = 1, validation range: `(0, nothing)`\n- `Q_lim_inner::MinMax`: Upper/Lower limit on reactive power input in REECB `(Q_min_inner, Q_max_inner)`. Only used when V_Flag = 1\n- `V_lim::MinMax`: Upper/Lower limit on reactive power PI controller in REECB `(V_min, V_max)`. Only used when V_Flag = 1\n- `K_qp::Float64`: Reactive power regulator proportional gain (used when V_Flag = 1), validation range: `(0, nothing)`\n- `K_qi::Float64`: Reactive power regulator integral gain (used when V_Flag = 1), validation range: `(0, nothing)`\n- `Q_ref::Float64`: (default: `1.0`) Reference Reactive Power Set-point (pu), validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ReactiveRenewableControllerAB model depends on the Flag\n- `n_states::Int`: (**Do not modify.**) The states of the ReactiveRenewableControllerAB model depends on the Flag\n\"\"\"\nmutable struct ReactiveRenewableControllerAB <: ReactivePowerControl\n    \"ACBus identification [`number`](@ref ACBus) for voltage control. `0` identifies the local bus connected to this component\"\n    bus_control::Int\n    \"Monitored branch FROM bus identification number for line drop compensation (if 0 generator power will be used)\"\n    from_branch_control::Int\n    \"Monitored branch TO bus identification number for line drop compensation (if 0 generator power will be used)\"\n    to_branch_control::Int\n    \"Branch circuit id for line drop compensation (as a string). If 0 generator power will be used\"\n    branch_id_control::String\n    \"Voltage Compensator Flag for REPCA1\"\n    VC_Flag::Int\n    \"Flag for Reactive Power Control for REPCA1. 0: Q-control, 1: V-control\"\n    Ref_Flag::Int\n    \"Flag for Power Factor Control for Outer Control of REECB1. 0: Q-control, 1: Power Factor Control\"\n    PF_Flag::Int\n    \"Flag for Voltage Control for Outer Control of REECB1. 0: Voltage Control, 1: Q-Control\"\n    V_Flag::Int\n    \"Voltage or Q-power of REPCA Filter Time Constant\"\n    T_fltr::Float64\n    \"Reactive power PI control proportional gain\"\n    K_p::Float64\n    \"Reactive power PI control integral gain\"\n    K_i::Float64\n    \"Reactive power lead time constant (s)\"\n    T_ft::Float64\n    \"Reactive power lag time constant (s)\"\n    T_fv::Float64\n    \"Voltage below which state ξq_oc (integrator state) is freeze\"\n    V_frz::Float64\n    \"Line drop compensation resistance (used when VC_Flag = 1)\"\n    R_c::Float64\n    \"Line drop compensation reactance (used when VC_Flag = 1)\"\n    X_c::Float64\n    \"Reactive current compensation gain (pu) (used when VC_Flag = 0)\"\n    K_c::Float64\n    \"Upper/Lower limit on Voltage or Q-power deadband output `(e_min, e_max)`\"\n    e_lim::MinMax\n    \"Voltage or Q-power error dead band thresholds `(dbd1, dbd2)`\"\n    dbd_pnts::Tuple{Float64, Float64}\n    \"Upper/Lower limit on reactive power V/Q control in REPCA `(Q_min, Q_max)`\"\n    Q_lim::MinMax\n    \"Active power lag time constant in REECB (s). Used only when PF_Flag = 1\"\n    T_p::Float64\n    \"Upper/Lower limit on reactive power input in REECB `(Q_min_inner, Q_max_inner)`. Only used when V_Flag = 1\"\n    Q_lim_inner::MinMax\n    \"Upper/Lower limit on reactive power PI controller in REECB `(V_min, V_max)`. Only used when V_Flag = 1\"\n    V_lim::MinMax\n    \"Reactive power regulator proportional gain (used when V_Flag = 1)\"\n    K_qp::Float64\n    \"Reactive power regulator integral gain (used when V_Flag = 1)\"\n    K_qi::Float64\n    \"Reference Reactive Power Set-point (pu)\"\n    Q_ref::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ReactiveRenewableControllerAB model depends on the Flag\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) The states of the ReactiveRenewableControllerAB model depends on the Flag\"\n    n_states::Int\nend\n\nfunction ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref=1.0, V_ref=1.0, ext=Dict{String, Any}(), )\n    ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref, V_ref, ext, PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[1], PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[2], )\nend\n\nfunction ReactiveRenewableControllerAB(; bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref=1.0, V_ref=1.0, ext=Dict{String, Any}(), states=PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[1], n_states=PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[2], )\n    ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref, V_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReactiveRenewableControllerAB(::Nothing)\n    ReactiveRenewableControllerAB(;\n        bus_control=0,\n        from_branch_control=0,\n        to_branch_control=0,\n        branch_id_control=\"0\",\n        VC_Flag=0,\n        Ref_Flag=0,\n        PF_Flag=0,\n        V_Flag=0,\n        T_fltr=0,\n        K_p=0,\n        K_i=0,\n        T_ft=0,\n        T_fv=0,\n        V_frz=0,\n        R_c=0,\n        X_c=0,\n        K_c=0,\n        e_lim=(min=0.0, max=0.0),\n        dbd_pnts=(0.0, 0.0),\n        Q_lim=(min=0.0, max=0.0),\n        T_p=0,\n        Q_lim_inner=(min=0.0, max=0.0),\n        V_lim=(min=0.0, max=0.0),\n        K_qp=0,\n        K_qi=0,\n        Q_ref=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `bus_control`.\"\"\"\nget_bus_control(value::ReactiveRenewableControllerAB) = value.bus_control\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `from_branch_control`.\"\"\"\nget_from_branch_control(value::ReactiveRenewableControllerAB) = value.from_branch_control\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `to_branch_control`.\"\"\"\nget_to_branch_control(value::ReactiveRenewableControllerAB) = value.to_branch_control\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `branch_id_control`.\"\"\"\nget_branch_id_control(value::ReactiveRenewableControllerAB) = value.branch_id_control\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `VC_Flag`.\"\"\"\nget_VC_Flag(value::ReactiveRenewableControllerAB) = value.VC_Flag\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `Ref_Flag`.\"\"\"\nget_Ref_Flag(value::ReactiveRenewableControllerAB) = value.Ref_Flag\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `PF_Flag`.\"\"\"\nget_PF_Flag(value::ReactiveRenewableControllerAB) = value.PF_Flag\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `V_Flag`.\"\"\"\nget_V_Flag(value::ReactiveRenewableControllerAB) = value.V_Flag\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `T_fltr`.\"\"\"\nget_T_fltr(value::ReactiveRenewableControllerAB) = value.T_fltr\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `K_p`.\"\"\"\nget_K_p(value::ReactiveRenewableControllerAB) = value.K_p\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `K_i`.\"\"\"\nget_K_i(value::ReactiveRenewableControllerAB) = value.K_i\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `T_ft`.\"\"\"\nget_T_ft(value::ReactiveRenewableControllerAB) = value.T_ft\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `T_fv`.\"\"\"\nget_T_fv(value::ReactiveRenewableControllerAB) = value.T_fv\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `V_frz`.\"\"\"\nget_V_frz(value::ReactiveRenewableControllerAB) = value.V_frz\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `R_c`.\"\"\"\nget_R_c(value::ReactiveRenewableControllerAB) = value.R_c\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `X_c`.\"\"\"\nget_X_c(value::ReactiveRenewableControllerAB) = value.X_c\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `K_c`.\"\"\"\nget_K_c(value::ReactiveRenewableControllerAB) = value.K_c\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `e_lim`.\"\"\"\nget_e_lim(value::ReactiveRenewableControllerAB) = value.e_lim\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `dbd_pnts`.\"\"\"\nget_dbd_pnts(value::ReactiveRenewableControllerAB) = value.dbd_pnts\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `Q_lim`.\"\"\"\nget_Q_lim(value::ReactiveRenewableControllerAB) = value.Q_lim\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `T_p`.\"\"\"\nget_T_p(value::ReactiveRenewableControllerAB) = value.T_p\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `Q_lim_inner`.\"\"\"\nget_Q_lim_inner(value::ReactiveRenewableControllerAB) = value.Q_lim_inner\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `V_lim`.\"\"\"\nget_V_lim(value::ReactiveRenewableControllerAB) = value.V_lim\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `K_qp`.\"\"\"\nget_K_qp(value::ReactiveRenewableControllerAB) = value.K_qp\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `K_qi`.\"\"\"\nget_K_qi(value::ReactiveRenewableControllerAB) = value.K_qi\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::ReactiveRenewableControllerAB) = value.Q_ref\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ReactiveRenewableControllerAB) = value.V_ref\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `ext`.\"\"\"\nget_ext(value::ReactiveRenewableControllerAB) = value.ext\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `states`.\"\"\"\nget_states(value::ReactiveRenewableControllerAB) = value.states\n\"\"\"Get [`ReactiveRenewableControllerAB`](@ref) `n_states`.\"\"\"\nget_n_states(value::ReactiveRenewableControllerAB) = value.n_states\n\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `bus_control`.\"\"\"\nset_bus_control!(value::ReactiveRenewableControllerAB, val) = value.bus_control = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `from_branch_control`.\"\"\"\nset_from_branch_control!(value::ReactiveRenewableControllerAB, val) = value.from_branch_control = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `to_branch_control`.\"\"\"\nset_to_branch_control!(value::ReactiveRenewableControllerAB, val) = value.to_branch_control = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `branch_id_control`.\"\"\"\nset_branch_id_control!(value::ReactiveRenewableControllerAB, val) = value.branch_id_control = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `VC_Flag`.\"\"\"\nset_VC_Flag!(value::ReactiveRenewableControllerAB, val) = value.VC_Flag = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `Ref_Flag`.\"\"\"\nset_Ref_Flag!(value::ReactiveRenewableControllerAB, val) = value.Ref_Flag = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `PF_Flag`.\"\"\"\nset_PF_Flag!(value::ReactiveRenewableControllerAB, val) = value.PF_Flag = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `V_Flag`.\"\"\"\nset_V_Flag!(value::ReactiveRenewableControllerAB, val) = value.V_Flag = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `T_fltr`.\"\"\"\nset_T_fltr!(value::ReactiveRenewableControllerAB, val) = value.T_fltr = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `K_p`.\"\"\"\nset_K_p!(value::ReactiveRenewableControllerAB, val) = value.K_p = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `K_i`.\"\"\"\nset_K_i!(value::ReactiveRenewableControllerAB, val) = value.K_i = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `T_ft`.\"\"\"\nset_T_ft!(value::ReactiveRenewableControllerAB, val) = value.T_ft = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `T_fv`.\"\"\"\nset_T_fv!(value::ReactiveRenewableControllerAB, val) = value.T_fv = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `V_frz`.\"\"\"\nset_V_frz!(value::ReactiveRenewableControllerAB, val) = value.V_frz = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `R_c`.\"\"\"\nset_R_c!(value::ReactiveRenewableControllerAB, val) = value.R_c = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `X_c`.\"\"\"\nset_X_c!(value::ReactiveRenewableControllerAB, val) = value.X_c = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `K_c`.\"\"\"\nset_K_c!(value::ReactiveRenewableControllerAB, val) = value.K_c = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `e_lim`.\"\"\"\nset_e_lim!(value::ReactiveRenewableControllerAB, val) = value.e_lim = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `dbd_pnts`.\"\"\"\nset_dbd_pnts!(value::ReactiveRenewableControllerAB, val) = value.dbd_pnts = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `Q_lim`.\"\"\"\nset_Q_lim!(value::ReactiveRenewableControllerAB, val) = value.Q_lim = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `T_p`.\"\"\"\nset_T_p!(value::ReactiveRenewableControllerAB, val) = value.T_p = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `Q_lim_inner`.\"\"\"\nset_Q_lim_inner!(value::ReactiveRenewableControllerAB, val) = value.Q_lim_inner = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `V_lim`.\"\"\"\nset_V_lim!(value::ReactiveRenewableControllerAB, val) = value.V_lim = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `K_qp`.\"\"\"\nset_K_qp!(value::ReactiveRenewableControllerAB, val) = value.K_qp = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `K_qi`.\"\"\"\nset_K_qi!(value::ReactiveRenewableControllerAB, val) = value.K_qi = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::ReactiveRenewableControllerAB, val) = value.Q_ref = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ReactiveRenewableControllerAB, val) = value.V_ref = val\n\"\"\"Set [`ReactiveRenewableControllerAB`](@ref) `ext`.\"\"\"\nset_ext!(value::ReactiveRenewableControllerAB, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReactiveVirtualOscillator.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReactiveVirtualOscillator <: ReactivePowerControl\n        k2::Float64\n        V_ref::Float64\n        Q_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Reactive Virtual Oscillator controller. Model is based on [\"Model Reduction for Inverters with Current Limiting and Dispatchable Virtual Oscillator Control.\"](https://doi.org/10.1109/TEC.2021.3083488)\n\n# Arguments\n- `k2::Float64`: VOC voltage-amplitude control gain, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `Q_ref::Float64`: (default: `1.0`) Reference Reactive Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ReactiveVirtualOscilator model are:\n\tE_oc: voltage reference state for inner control in the d-axis\n- `n_states::Int`: (**Do not modify.**) ReactiveVirtualOscillator has 1 state\n\"\"\"\nmutable struct ReactiveVirtualOscillator <: ReactivePowerControl\n    \"VOC voltage-amplitude control gain\"\n    k2::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"Reference Reactive Power Set-point (pu)\"\n    Q_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ReactiveVirtualOscilator model are:\n\tE_oc: voltage reference state for inner control in the d-axis\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ReactiveVirtualOscillator has 1 state\"\n    n_states::Int\nend\n\nfunction ReactiveVirtualOscillator(k2, V_ref=1.0, Q_ref=1.0, ext=Dict{String, Any}(), )\n    ReactiveVirtualOscillator(k2, V_ref, Q_ref, ext, [:E_oc], 1, )\nend\n\nfunction ReactiveVirtualOscillator(; k2, V_ref=1.0, Q_ref=1.0, ext=Dict{String, Any}(), states=[:E_oc], n_states=1, )\n    ReactiveVirtualOscillator(k2, V_ref, Q_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReactiveVirtualOscillator(::Nothing)\n    ReactiveVirtualOscillator(;\n        k2=0,\n        V_ref=0,\n        Q_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `k2`.\"\"\"\nget_k2(value::ReactiveVirtualOscillator) = value.k2\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ReactiveVirtualOscillator) = value.V_ref\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::ReactiveVirtualOscillator) = value.Q_ref\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `ext`.\"\"\"\nget_ext(value::ReactiveVirtualOscillator) = value.ext\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `states`.\"\"\"\nget_states(value::ReactiveVirtualOscillator) = value.states\n\"\"\"Get [`ReactiveVirtualOscillator`](@ref) `n_states`.\"\"\"\nget_n_states(value::ReactiveVirtualOscillator) = value.n_states\n\n\"\"\"Set [`ReactiveVirtualOscillator`](@ref) `k2`.\"\"\"\nset_k2!(value::ReactiveVirtualOscillator, val) = value.k2 = val\n\"\"\"Set [`ReactiveVirtualOscillator`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ReactiveVirtualOscillator, val) = value.V_ref = val\n\"\"\"Set [`ReactiveVirtualOscillator`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::ReactiveVirtualOscillator, val) = value.Q_ref = val\n\"\"\"Set [`ReactiveVirtualOscillator`](@ref) `ext`.\"\"\"\nset_ext!(value::ReactiveVirtualOscillator, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReducedOrderPLL.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReducedOrderPLL <: FrequencyEstimator\n        ω_lp::Float64\n        kp_pll::Float64\n        ki_pll::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Phase-Locked Loop (PLL) based on [\"Reduced-order Structure-preserving Model for Parallel-connected Three-phase Grid-tied Inverters.\"](https://doi.org/10.1109/COMPEL.2017.8013389)\n\n# Arguments\n- `ω_lp::Float64`: PLL low-pass filter frequency (rad/sec), validation range: `(0, nothing)`\n- `kp_pll::Float64`: PLL proportional gain, validation range: `(0, nothing)`\n- `ki_pll::Float64`: PLL integral gain, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ReducedOrderPLL model are:\n\tvq_pll: q-axis of the measured voltage in the PLL synchronous reference frame (SRF),\n\tε_pll: Integrator state of the PI controller,\n\tθ_pll: Phase angle displacement in the PLL SRF\n- `n_states::Int`: (**Do not modify.**) ReducedOrderPLL has 3 states\n\"\"\"\nmutable struct ReducedOrderPLL <: FrequencyEstimator\n    \"PLL low-pass filter frequency (rad/sec)\"\n    ω_lp::Float64\n    \"PLL proportional gain\"\n    kp_pll::Float64\n    \"PLL integral gain\"\n    ki_pll::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ReducedOrderPLL model are:\n\tvq_pll: q-axis of the measured voltage in the PLL synchronous reference frame (SRF),\n\tε_pll: Integrator state of the PI controller,\n\tθ_pll: Phase angle displacement in the PLL SRF\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ReducedOrderPLL has 3 states\"\n    n_states::Int\nend\n\nfunction ReducedOrderPLL(ω_lp, kp_pll, ki_pll, ext=Dict{String, Any}(), )\n    ReducedOrderPLL(ω_lp, kp_pll, ki_pll, ext, [:vq_pll, :ε_pll, :θ_pll], 3, )\nend\n\nfunction ReducedOrderPLL(; ω_lp, kp_pll, ki_pll, ext=Dict{String, Any}(), states=[:vq_pll, :ε_pll, :θ_pll], n_states=3, )\n    ReducedOrderPLL(ω_lp, kp_pll, ki_pll, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReducedOrderPLL(::Nothing)\n    ReducedOrderPLL(;\n        ω_lp=0,\n        kp_pll=0,\n        ki_pll=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReducedOrderPLL`](@ref) `ω_lp`.\"\"\"\nget_ω_lp(value::ReducedOrderPLL) = value.ω_lp\n\"\"\"Get [`ReducedOrderPLL`](@ref) `kp_pll`.\"\"\"\nget_kp_pll(value::ReducedOrderPLL) = value.kp_pll\n\"\"\"Get [`ReducedOrderPLL`](@ref) `ki_pll`.\"\"\"\nget_ki_pll(value::ReducedOrderPLL) = value.ki_pll\n\"\"\"Get [`ReducedOrderPLL`](@ref) `ext`.\"\"\"\nget_ext(value::ReducedOrderPLL) = value.ext\n\"\"\"Get [`ReducedOrderPLL`](@ref) `states`.\"\"\"\nget_states(value::ReducedOrderPLL) = value.states\n\"\"\"Get [`ReducedOrderPLL`](@ref) `n_states`.\"\"\"\nget_n_states(value::ReducedOrderPLL) = value.n_states\n\n\"\"\"Set [`ReducedOrderPLL`](@ref) `ω_lp`.\"\"\"\nset_ω_lp!(value::ReducedOrderPLL, val) = value.ω_lp = val\n\"\"\"Set [`ReducedOrderPLL`](@ref) `kp_pll`.\"\"\"\nset_kp_pll!(value::ReducedOrderPLL, val) = value.kp_pll = val\n\"\"\"Set [`ReducedOrderPLL`](@ref) `ki_pll`.\"\"\"\nset_ki_pll!(value::ReducedOrderPLL, val) = value.ki_pll = val\n\"\"\"Set [`ReducedOrderPLL`](@ref) `ext`.\"\"\"\nset_ext!(value::ReducedOrderPLL, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RenewableDispatch.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RenewableDispatch <: RenewableGen\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        prime_mover_type::PrimeMovers\n        reactive_power_limits::Union{Nothing, MinMax}\n        power_factor::Float64\n        operation_cost::Union{RenewableGenerationCost, MarketBidCost}\n        base_power::Float64\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA renewable (e.g., wind or solar) generator whose output can be curtailed to satisfy power system constraints.\n\nThese generators can also participate in reserves markets, including upwards reserves by proactively curtailing some available power (based on its [`max_active_power` time series](@ref ts_data)). Example uses include: a utility-scale wind or solar generator whose PPA allows curtailment. For non-curtailable or must-take renewables, see [`RenewableNonDispatch`](@ref).\n\nRenewable generators do not have a `max_active_power` parameter, which is instead calculated when calling [`get_max_active_power()`](@ref get_max_active_power(d::T) where {T <: RenewableGen})\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `prime_mover_type::PrimeMovers`: Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits, used in some production cost model simulations and in power flow if the unit is connected to a [`PV`](@ref acbustypes_list) bus. Set to `nothing` if not applicable\n- `power_factor::Float64`: Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus, validation range: `(0, 1)`\n- `operation_cost::Union{RenewableGenerationCost, MarketBidCost}`: [`OperationalCost`](@ref) of generation\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct RenewableDispatch <: RenewableGen\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Minimum and maximum reactive power limits, used in some production cost model simulations and in power flow if the unit is connected to a [`PV`](@ref acbustypes_list) bus. Set to `nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus\"\n    power_factor::Float64\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{RenewableGenerationCost, MarketBidCost}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction RenewableDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, reactive_power_limits, power_factor, operation_cost, base_power, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    RenewableDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, reactive_power_limits, power_factor, operation_cost, base_power, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction RenewableDispatch(; name, available, bus, active_power, reactive_power, rating, prime_mover_type, reactive_power_limits, power_factor, operation_cost, base_power, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    RenewableDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, reactive_power_limits, power_factor, operation_cost, base_power, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RenewableDispatch(::Nothing)\n    RenewableDispatch(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        prime_mover_type=PrimeMovers.OT,\n        reactive_power_limits=nothing,\n        power_factor=1.0,\n        operation_cost=RenewableGenerationCost(nothing),\n        base_power=100.0,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RenewableDispatch`](@ref) `name`.\"\"\"\nget_name(value::RenewableDispatch) = value.name\n\"\"\"Get [`RenewableDispatch`](@ref) `available`.\"\"\"\nget_available(value::RenewableDispatch) = value.available\n\"\"\"Get [`RenewableDispatch`](@ref) `bus`.\"\"\"\nget_bus(value::RenewableDispatch) = value.bus\n\"\"\"Get [`RenewableDispatch`](@ref) `active_power`.\"\"\"\nget_active_power(value::RenewableDispatch) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`RenewableDispatch`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::RenewableDispatch) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`RenewableDispatch`](@ref) `rating`.\"\"\"\nget_rating(value::RenewableDispatch) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`RenewableDispatch`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::RenewableDispatch) = value.prime_mover_type\n\"\"\"Get [`RenewableDispatch`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::RenewableDispatch) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`RenewableDispatch`](@ref) `power_factor`.\"\"\"\nget_power_factor(value::RenewableDispatch) = value.power_factor\n\"\"\"Get [`RenewableDispatch`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::RenewableDispatch) = value.operation_cost\n\"\"\"Get [`RenewableDispatch`](@ref) `base_power`.\"\"\"\nget_base_power(value::RenewableDispatch) = value.base_power\n\"\"\"Get [`RenewableDispatch`](@ref) `services`.\"\"\"\nget_services(value::RenewableDispatch) = value.services\n\"\"\"Get [`RenewableDispatch`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::RenewableDispatch) = value.dynamic_injector\n\"\"\"Get [`RenewableDispatch`](@ref) `ext`.\"\"\"\nget_ext(value::RenewableDispatch) = value.ext\n\"\"\"Get [`RenewableDispatch`](@ref) `internal`.\"\"\"\nget_internal(value::RenewableDispatch) = value.internal\n\n\"\"\"Set [`RenewableDispatch`](@ref) `available`.\"\"\"\nset_available!(value::RenewableDispatch, val) = value.available = val\n\"\"\"Set [`RenewableDispatch`](@ref) `bus`.\"\"\"\nset_bus!(value::RenewableDispatch, val) = value.bus = val\n\"\"\"Set [`RenewableDispatch`](@ref) `active_power`.\"\"\"\nset_active_power!(value::RenewableDispatch, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`RenewableDispatch`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::RenewableDispatch, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`RenewableDispatch`](@ref) `rating`.\"\"\"\nset_rating!(value::RenewableDispatch, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`RenewableDispatch`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::RenewableDispatch, val) = value.prime_mover_type = val\n\"\"\"Set [`RenewableDispatch`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::RenewableDispatch, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`RenewableDispatch`](@ref) `power_factor`.\"\"\"\nset_power_factor!(value::RenewableDispatch, val) = value.power_factor = val\n\"\"\"Set [`RenewableDispatch`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::RenewableDispatch, val) = value.operation_cost = val\n\"\"\"Set [`RenewableDispatch`](@ref) `base_power`.\"\"\"\nset_base_power!(value::RenewableDispatch, val) = value.base_power = val\n\"\"\"Set [`RenewableDispatch`](@ref) `services`.\"\"\"\nset_services!(value::RenewableDispatch, val) = value.services = val\n\"\"\"Set [`RenewableDispatch`](@ref) `ext`.\"\"\"\nset_ext!(value::RenewableDispatch, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RenewableEnergyConverterTypeA.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RenewableEnergyConverterTypeA <: Converter\n        T_g::Float64\n        Rrpwr::Float64\n        Brkpt::Float64\n        Zerox::Float64\n        Lvpl1::Float64\n        Vo_lim::Float64\n        Lv_pnts::MinMax\n        Io_lim::Float64\n        T_fltr::Float64\n        K_hv::Float64\n        Iqr_lims::MinMax\n        Accel::Float64\n        Lvpl_sw::Int\n        Q_ref::Float64\n        R_source::Float64\n        X_source::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a renewable energy generator/converter model, this model corresponds to REGCA1 in PSSE\n\n# Arguments\n- `T_g::Float64`: Converter time constant (s), validation range: `(0, nothing)`\n- `Rrpwr::Float64`: Low Voltage Power Logic (LVPL) ramp rate limit (pu/s), validation range: `(0, nothing)`\n- `Brkpt::Float64`: LVPL characteristic voltage 2 (pu), validation range: `(0, nothing)`\n- `Zerox::Float64`: LVPL characteristic voltage 1 (pu), validation range: `(0, nothing)`\n- `Lvpl1::Float64`: LVPL gain (pu), validation range: `(0, nothing)`\n- `Vo_lim::Float64`: Voltage limit for high voltage reactive current management (pu), validation range: `(0, nothing)`\n- `Lv_pnts::MinMax`: Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\n- `Io_lim::Float64`: Current limit (pu) for high voltage reactive current management (specified as a negative value), validation range: `(nothing, 0)`\n- `T_fltr::Float64`: Voltage filter time constant for low voltage active current management (s), validation range: `(0, nothing)`\n- `K_hv::Float64`: Overvoltage compensation gain used in the high voltage reactive current management, validation range: `(0, nothing)`\n- `Iqr_lims::MinMax`: Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\n- `Accel::Float64`: Acceleration factor, validation range: `(0, 1)`\n- `Lvpl_sw::Int`: Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present), validation range: `(0, 1)`\n- `Q_ref::Float64`: (default: `1.0`) Initial condition of reactive power from power flow, validation range: `(0, nothing)`\n- `R_source::Float64`: (default: `0.0`) Output resistor used for the Thevenin Equivalent, validation range: `(0, nothing)`\n- `X_source::Float64`: (default: `1.0e5`) Output reactance used for the Thevenin Equivalent, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\tIp: Converter lag for Ipcmd,\tIq: Converter lag for Iqcmd,\tVmeas: Voltage filter for low voltage active current management\n- `n_states::Int`: (**Do not modify.**) RenewableEnergyConverterTypeA has 3 states\n\"\"\"\nmutable struct RenewableEnergyConverterTypeA <: Converter\n    \"Converter time constant (s)\"\n    T_g::Float64\n    \"Low Voltage Power Logic (LVPL) ramp rate limit (pu/s)\"\n    Rrpwr::Float64\n    \"LVPL characteristic voltage 2 (pu)\"\n    Brkpt::Float64\n    \"LVPL characteristic voltage 1 (pu)\"\n    Zerox::Float64\n    \"LVPL gain (pu)\"\n    Lvpl1::Float64\n    \"Voltage limit for high voltage reactive current management (pu)\"\n    Vo_lim::Float64\n    \"Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\"\n    Lv_pnts::MinMax\n    \"Current limit (pu) for high voltage reactive current management (specified as a negative value)\"\n    Io_lim::Float64\n    \"Voltage filter time constant for low voltage active current management (s)\"\n    T_fltr::Float64\n    \"Overvoltage compensation gain used in the high voltage reactive current management\"\n    K_hv::Float64\n    \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\"\n    Iqr_lims::MinMax\n    \"Acceleration factor\"\n    Accel::Float64\n    \"Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present)\"\n    Lvpl_sw::Int\n    \"Initial condition of reactive power from power flow\"\n    Q_ref::Float64\n    \"Output resistor used for the Thevenin Equivalent\"\n    R_source::Float64\n    \"Output reactance used for the Thevenin Equivalent\"\n    X_source::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\tIp: Converter lag for Ipcmd,\tIq: Converter lag for Iqcmd,\tVmeas: Voltage filter for low voltage active current management\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) RenewableEnergyConverterTypeA has 3 states\"\n    n_states::Int\nend\n\nfunction RenewableEnergyConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref=1.0, R_source=0.0, X_source=1.0e5, ext=Dict{String, Any}(), )\n    RenewableEnergyConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref, R_source, X_source, ext, [:Ip, :Iq, :Vmeas], 3, )\nend\n\nfunction RenewableEnergyConverterTypeA(; T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref=1.0, R_source=0.0, X_source=1.0e5, ext=Dict{String, Any}(), states=[:Ip, :Iq, :Vmeas], n_states=3, )\n    RenewableEnergyConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref, R_source, X_source, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RenewableEnergyConverterTypeA(::Nothing)\n    RenewableEnergyConverterTypeA(;\n        T_g=0,\n        Rrpwr=0,\n        Brkpt=0,\n        Zerox=0,\n        Lvpl1=0,\n        Vo_lim=0,\n        Lv_pnts=(min=0.0, max=0.0),\n        Io_lim=0,\n        T_fltr=0,\n        K_hv=0,\n        Iqr_lims=(min=0.0, max=0.0),\n        Accel=0,\n        Lvpl_sw=0,\n        Q_ref=0,\n        R_source=0,\n        X_source=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `T_g`.\"\"\"\nget_T_g(value::RenewableEnergyConverterTypeA) = value.T_g\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Rrpwr`.\"\"\"\nget_Rrpwr(value::RenewableEnergyConverterTypeA) = value.Rrpwr\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Brkpt`.\"\"\"\nget_Brkpt(value::RenewableEnergyConverterTypeA) = value.Brkpt\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Zerox`.\"\"\"\nget_Zerox(value::RenewableEnergyConverterTypeA) = value.Zerox\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Lvpl1`.\"\"\"\nget_Lvpl1(value::RenewableEnergyConverterTypeA) = value.Lvpl1\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Vo_lim`.\"\"\"\nget_Vo_lim(value::RenewableEnergyConverterTypeA) = value.Vo_lim\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Lv_pnts`.\"\"\"\nget_Lv_pnts(value::RenewableEnergyConverterTypeA) = value.Lv_pnts\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Io_lim`.\"\"\"\nget_Io_lim(value::RenewableEnergyConverterTypeA) = value.Io_lim\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `T_fltr`.\"\"\"\nget_T_fltr(value::RenewableEnergyConverterTypeA) = value.T_fltr\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `K_hv`.\"\"\"\nget_K_hv(value::RenewableEnergyConverterTypeA) = value.K_hv\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Iqr_lims`.\"\"\"\nget_Iqr_lims(value::RenewableEnergyConverterTypeA) = value.Iqr_lims\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Accel`.\"\"\"\nget_Accel(value::RenewableEnergyConverterTypeA) = value.Accel\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Lvpl_sw`.\"\"\"\nget_Lvpl_sw(value::RenewableEnergyConverterTypeA) = value.Lvpl_sw\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::RenewableEnergyConverterTypeA) = value.Q_ref\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `R_source`.\"\"\"\nget_R_source(value::RenewableEnergyConverterTypeA) = value.R_source\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `X_source`.\"\"\"\nget_X_source(value::RenewableEnergyConverterTypeA) = value.X_source\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `ext`.\"\"\"\nget_ext(value::RenewableEnergyConverterTypeA) = value.ext\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `states`.\"\"\"\nget_states(value::RenewableEnergyConverterTypeA) = value.states\n\"\"\"Get [`RenewableEnergyConverterTypeA`](@ref) `n_states`.\"\"\"\nget_n_states(value::RenewableEnergyConverterTypeA) = value.n_states\n\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `T_g`.\"\"\"\nset_T_g!(value::RenewableEnergyConverterTypeA, val) = value.T_g = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Rrpwr`.\"\"\"\nset_Rrpwr!(value::RenewableEnergyConverterTypeA, val) = value.Rrpwr = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Brkpt`.\"\"\"\nset_Brkpt!(value::RenewableEnergyConverterTypeA, val) = value.Brkpt = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Zerox`.\"\"\"\nset_Zerox!(value::RenewableEnergyConverterTypeA, val) = value.Zerox = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Lvpl1`.\"\"\"\nset_Lvpl1!(value::RenewableEnergyConverterTypeA, val) = value.Lvpl1 = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Vo_lim`.\"\"\"\nset_Vo_lim!(value::RenewableEnergyConverterTypeA, val) = value.Vo_lim = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Lv_pnts`.\"\"\"\nset_Lv_pnts!(value::RenewableEnergyConverterTypeA, val) = value.Lv_pnts = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Io_lim`.\"\"\"\nset_Io_lim!(value::RenewableEnergyConverterTypeA, val) = value.Io_lim = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `T_fltr`.\"\"\"\nset_T_fltr!(value::RenewableEnergyConverterTypeA, val) = value.T_fltr = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `K_hv`.\"\"\"\nset_K_hv!(value::RenewableEnergyConverterTypeA, val) = value.K_hv = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Iqr_lims`.\"\"\"\nset_Iqr_lims!(value::RenewableEnergyConverterTypeA, val) = value.Iqr_lims = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Accel`.\"\"\"\nset_Accel!(value::RenewableEnergyConverterTypeA, val) = value.Accel = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Lvpl_sw`.\"\"\"\nset_Lvpl_sw!(value::RenewableEnergyConverterTypeA, val) = value.Lvpl_sw = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::RenewableEnergyConverterTypeA, val) = value.Q_ref = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `R_source`.\"\"\"\nset_R_source!(value::RenewableEnergyConverterTypeA, val) = value.R_source = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `X_source`.\"\"\"\nset_X_source!(value::RenewableEnergyConverterTypeA, val) = value.X_source = val\n\"\"\"Set [`RenewableEnergyConverterTypeA`](@ref) `ext`.\"\"\"\nset_ext!(value::RenewableEnergyConverterTypeA, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RenewableEnergyVoltageConverterTypeA.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RenewableEnergyVoltageConverterTypeA <: Converter\n        T_g::Float64\n        Rrpwr::Float64\n        Brkpt::Float64\n        Zerox::Float64\n        Lvpl1::Float64\n        Vo_lim::Float64\n        Lv_pnts::MinMax\n        Io_lim::Float64\n        T_fltr::Float64\n        K_hv::Float64\n        Iqr_lims::MinMax\n        Accel::Float64\n        Lvpl_sw::Int\n        Q_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a renewable energy generator/converter model, this model corresponds to REGCA1 in PSSE, but to be interfaced using a Voltage Source instead of a Current Source\n\n# Arguments\n- `T_g::Float64`: Converter time constant (s), validation range: `(0, nothing)`\n- `Rrpwr::Float64`: Low Voltage Power Logic (LVPL) ramp rate limit (pu/s), validation range: `(0, nothing)`\n- `Brkpt::Float64`: LVPL characteristic voltage 2 (pu), validation range: `(0, nothing)`\n- `Zerox::Float64`: LVPL characteristic voltage 1 (pu), validation range: `(0, nothing)`\n- `Lvpl1::Float64`: LVPL gain (pu), validation range: `(0, nothing)`\n- `Vo_lim::Float64`: Voltage limit for high voltage reactive current management (pu), validation range: `(0, nothing)`\n- `Lv_pnts::MinMax`: Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\n- `Io_lim::Float64`: Current limit (pu) for high voltage reactive current management (specified as a negative value), validation range: `(nothing, 0)`\n- `T_fltr::Float64`: Voltage filter time constant for low voltage active current management (s), validation range: `(0, nothing)`\n- `K_hv::Float64`: Overvoltage compensation gain used in the high voltage reactive current management, validation range: `(0, nothing)`\n- `Iqr_lims::MinMax`: Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\n- `Accel::Float64`: Acceleration factor, validation range: `(0, 1)`\n- `Lvpl_sw::Int`: Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present), validation range: `(0, 1)`\n- `Q_ref::Float64`: (default: `1.0`) Initial condition of reactive power from power flow, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\tIp: Converter lag for Ipcmd,\tIq: Converter lag for Iqcmd,\tVmeas: Voltage filter for low voltage active current management\n- `n_states::Int`: (**Do not modify.**) RenewableEnergyVoltageConverterTypeA has 3 states\n\"\"\"\nmutable struct RenewableEnergyVoltageConverterTypeA <: Converter\n    \"Converter time constant (s)\"\n    T_g::Float64\n    \"Low Voltage Power Logic (LVPL) ramp rate limit (pu/s)\"\n    Rrpwr::Float64\n    \"LVPL characteristic voltage 2 (pu)\"\n    Brkpt::Float64\n    \"LVPL characteristic voltage 1 (pu)\"\n    Zerox::Float64\n    \"LVPL gain (pu)\"\n    Lvpl1::Float64\n    \"Voltage limit for high voltage reactive current management (pu)\"\n    Vo_lim::Float64\n    \"Voltage points for low voltage active current management (pu) (Lvpnt0, Lvpnt1)\"\n    Lv_pnts::MinMax\n    \"Current limit (pu) for high voltage reactive current management (specified as a negative value)\"\n    Io_lim::Float64\n    \"Voltage filter time constant for low voltage active current management (s)\"\n    T_fltr::Float64\n    \"Overvoltage compensation gain used in the high voltage reactive current management\"\n    K_hv::Float64\n    \"Limit on rate of change for reactive current (pu/s) (Iqr_min, Iqr_max)\"\n    Iqr_lims::MinMax\n    \"Acceleration factor\"\n    Accel::Float64\n    \"Low voltage power logic (LVPL) switch. (0: LVPL not present, 1: LVPL present)\"\n    Lvpl_sw::Int\n    \"Initial condition of reactive power from power flow\"\n    Q_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\tIp: Converter lag for Ipcmd,\tIq: Converter lag for Iqcmd,\tVmeas: Voltage filter for low voltage active current management\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) RenewableEnergyVoltageConverterTypeA has 3 states\"\n    n_states::Int\nend\n\nfunction RenewableEnergyVoltageConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref=1.0, ext=Dict{String, Any}(), )\n    RenewableEnergyVoltageConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref, ext, [:Ip, :Iq, :Vmeas], 3, )\nend\n\nfunction RenewableEnergyVoltageConverterTypeA(; T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref=1.0, ext=Dict{String, Any}(), states=[:Ip, :Iq, :Vmeas], n_states=3, )\n    RenewableEnergyVoltageConverterTypeA(T_g, Rrpwr, Brkpt, Zerox, Lvpl1, Vo_lim, Lv_pnts, Io_lim, T_fltr, K_hv, Iqr_lims, Accel, Lvpl_sw, Q_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RenewableEnergyVoltageConverterTypeA(::Nothing)\n    RenewableEnergyVoltageConverterTypeA(;\n        T_g=0,\n        Rrpwr=0,\n        Brkpt=0,\n        Zerox=0,\n        Lvpl1=0,\n        Vo_lim=0,\n        Lv_pnts=(min=0.0, max=0.0),\n        Io_lim=0,\n        T_fltr=0,\n        K_hv=0,\n        Iqr_lims=(min=0.0, max=0.0),\n        Accel=0,\n        Lvpl_sw=0,\n        Q_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `T_g`.\"\"\"\nget_T_g(value::RenewableEnergyVoltageConverterTypeA) = value.T_g\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Rrpwr`.\"\"\"\nget_Rrpwr(value::RenewableEnergyVoltageConverterTypeA) = value.Rrpwr\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Brkpt`.\"\"\"\nget_Brkpt(value::RenewableEnergyVoltageConverterTypeA) = value.Brkpt\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Zerox`.\"\"\"\nget_Zerox(value::RenewableEnergyVoltageConverterTypeA) = value.Zerox\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lvpl1`.\"\"\"\nget_Lvpl1(value::RenewableEnergyVoltageConverterTypeA) = value.Lvpl1\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Vo_lim`.\"\"\"\nget_Vo_lim(value::RenewableEnergyVoltageConverterTypeA) = value.Vo_lim\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lv_pnts`.\"\"\"\nget_Lv_pnts(value::RenewableEnergyVoltageConverterTypeA) = value.Lv_pnts\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Io_lim`.\"\"\"\nget_Io_lim(value::RenewableEnergyVoltageConverterTypeA) = value.Io_lim\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `T_fltr`.\"\"\"\nget_T_fltr(value::RenewableEnergyVoltageConverterTypeA) = value.T_fltr\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `K_hv`.\"\"\"\nget_K_hv(value::RenewableEnergyVoltageConverterTypeA) = value.K_hv\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Iqr_lims`.\"\"\"\nget_Iqr_lims(value::RenewableEnergyVoltageConverterTypeA) = value.Iqr_lims\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Accel`.\"\"\"\nget_Accel(value::RenewableEnergyVoltageConverterTypeA) = value.Accel\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lvpl_sw`.\"\"\"\nget_Lvpl_sw(value::RenewableEnergyVoltageConverterTypeA) = value.Lvpl_sw\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `Q_ref`.\"\"\"\nget_Q_ref(value::RenewableEnergyVoltageConverterTypeA) = value.Q_ref\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `ext`.\"\"\"\nget_ext(value::RenewableEnergyVoltageConverterTypeA) = value.ext\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `states`.\"\"\"\nget_states(value::RenewableEnergyVoltageConverterTypeA) = value.states\n\"\"\"Get [`RenewableEnergyVoltageConverterTypeA`](@ref) `n_states`.\"\"\"\nget_n_states(value::RenewableEnergyVoltageConverterTypeA) = value.n_states\n\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `T_g`.\"\"\"\nset_T_g!(value::RenewableEnergyVoltageConverterTypeA, val) = value.T_g = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Rrpwr`.\"\"\"\nset_Rrpwr!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Rrpwr = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Brkpt`.\"\"\"\nset_Brkpt!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Brkpt = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Zerox`.\"\"\"\nset_Zerox!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Zerox = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lvpl1`.\"\"\"\nset_Lvpl1!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Lvpl1 = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Vo_lim`.\"\"\"\nset_Vo_lim!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Vo_lim = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lv_pnts`.\"\"\"\nset_Lv_pnts!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Lv_pnts = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Io_lim`.\"\"\"\nset_Io_lim!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Io_lim = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `T_fltr`.\"\"\"\nset_T_fltr!(value::RenewableEnergyVoltageConverterTypeA, val) = value.T_fltr = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `K_hv`.\"\"\"\nset_K_hv!(value::RenewableEnergyVoltageConverterTypeA, val) = value.K_hv = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Iqr_lims`.\"\"\"\nset_Iqr_lims!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Iqr_lims = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Accel`.\"\"\"\nset_Accel!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Accel = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Lvpl_sw`.\"\"\"\nset_Lvpl_sw!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Lvpl_sw = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `Q_ref`.\"\"\"\nset_Q_ref!(value::RenewableEnergyVoltageConverterTypeA, val) = value.Q_ref = val\n\"\"\"Set [`RenewableEnergyVoltageConverterTypeA`](@ref) `ext`.\"\"\"\nset_ext!(value::RenewableEnergyVoltageConverterTypeA, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RenewableNonDispatch.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RenewableNonDispatch <: RenewableGen\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        prime_mover_type::PrimeMovers\n        power_factor::Float64\n        base_power::Float64\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA non-dispatchable (i.e., non-curtailable or must-take) renewable generator.\n\nIts output is equal to its [`max_active_power` time series](@ref ts_data) by default. Example use: an aggregation of behind-the-meter distributed energy resources like rooftop solar. For curtailable or downward dispatachable generation, see [`RenewableDispatch`](@ref).\n\nRenewable generators do not have a `max_active_power` parameter, which is instead calculated when calling [`get_max_active_power()`](@ref get_max_active_power(d::T) where {T <: RenewableGen})\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `prime_mover_type::PrimeMovers`: Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `power_factor::Float64`: Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus, validation range: `(0, 1)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct RenewableNonDispatch <: RenewableGen\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR), used in some production cost modeling simulations. To set the reactive power in a load flow, use `power_factor`\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Power factor [0, 1] set-point, used in some production cost modeling and in load flow if the unit is connected to a [`PQ`](@ref acbustypes_list) bus\"\n    power_factor::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction RenewableNonDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, power_factor, base_power, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    RenewableNonDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, power_factor, base_power, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction RenewableNonDispatch(; name, available, bus, active_power, reactive_power, rating, prime_mover_type, power_factor, base_power, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    RenewableNonDispatch(name, available, bus, active_power, reactive_power, rating, prime_mover_type, power_factor, base_power, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RenewableNonDispatch(::Nothing)\n    RenewableNonDispatch(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        prime_mover_type=PrimeMovers.OT,\n        power_factor=1.0,\n        base_power=100.0,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RenewableNonDispatch`](@ref) `name`.\"\"\"\nget_name(value::RenewableNonDispatch) = value.name\n\"\"\"Get [`RenewableNonDispatch`](@ref) `available`.\"\"\"\nget_available(value::RenewableNonDispatch) = value.available\n\"\"\"Get [`RenewableNonDispatch`](@ref) `bus`.\"\"\"\nget_bus(value::RenewableNonDispatch) = value.bus\n\"\"\"Get [`RenewableNonDispatch`](@ref) `active_power`.\"\"\"\nget_active_power(value::RenewableNonDispatch) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`RenewableNonDispatch`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::RenewableNonDispatch) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`RenewableNonDispatch`](@ref) `rating`.\"\"\"\nget_rating(value::RenewableNonDispatch) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`RenewableNonDispatch`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::RenewableNonDispatch) = value.prime_mover_type\n\"\"\"Get [`RenewableNonDispatch`](@ref) `power_factor`.\"\"\"\nget_power_factor(value::RenewableNonDispatch) = value.power_factor\n\"\"\"Get [`RenewableNonDispatch`](@ref) `base_power`.\"\"\"\nget_base_power(value::RenewableNonDispatch) = value.base_power\n\"\"\"Get [`RenewableNonDispatch`](@ref) `services`.\"\"\"\nget_services(value::RenewableNonDispatch) = value.services\n\"\"\"Get [`RenewableNonDispatch`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::RenewableNonDispatch) = value.dynamic_injector\n\"\"\"Get [`RenewableNonDispatch`](@ref) `ext`.\"\"\"\nget_ext(value::RenewableNonDispatch) = value.ext\n\"\"\"Get [`RenewableNonDispatch`](@ref) `internal`.\"\"\"\nget_internal(value::RenewableNonDispatch) = value.internal\n\n\"\"\"Set [`RenewableNonDispatch`](@ref) `available`.\"\"\"\nset_available!(value::RenewableNonDispatch, val) = value.available = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `bus`.\"\"\"\nset_bus!(value::RenewableNonDispatch, val) = value.bus = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `active_power`.\"\"\"\nset_active_power!(value::RenewableNonDispatch, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`RenewableNonDispatch`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::RenewableNonDispatch, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`RenewableNonDispatch`](@ref) `rating`.\"\"\"\nset_rating!(value::RenewableNonDispatch, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`RenewableNonDispatch`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::RenewableNonDispatch, val) = value.prime_mover_type = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `power_factor`.\"\"\"\nset_power_factor!(value::RenewableNonDispatch, val) = value.power_factor = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `base_power`.\"\"\"\nset_base_power!(value::RenewableNonDispatch, val) = value.base_power = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `services`.\"\"\"\nset_services!(value::RenewableNonDispatch, val) = value.services = val\n\"\"\"Set [`RenewableNonDispatch`](@ref) `ext`.\"\"\"\nset_ext!(value::RenewableNonDispatch, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ReserveDemandCurve.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ReserveDemandCurve{T <: ReserveDirection} <: Reserve{T}\n        variable::Union{Nothing, TimeSeriesKey, CostCurve{PiecewiseIncrementalCurve}}\n        name::String\n        available::Bool\n        time_frame::Float64\n        sustained_time::Float64\n        max_participation_factor::Float64\n        deployed_fraction::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA reserve product with an [Operating Reserve Demand Curve (ORDC)](https://hepg.hks.harvard.edu/files/hepg/files/ordcupdate-final.pdf) for operational simulations.\n\nThe ORDC is modeled as a discretized set of `(Reserve capacity (MW), Price (\\$/MWh))` steps, which can vary with time. Use [`set_variable_cost!`](@ref) to define the ORDCs.\n\nWhen defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref)\n\n# Arguments\n- `variable::Union{Nothing, TimeSeriesKey, CostCurve{PiecewiseIncrementalCurve}}`: Create this object with `variable` = `nothing`, then add assign a cost curve or time-series of `variable_cost` using the [`set_variable_cost!`](@ref) function, which will automatically update this parameter\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `time_frame::Float64`: the saturation time_frame in minutes to provide reserve contribution, validation range: `(0, nothing)`\n- `sustained_time::Float64`: (default: `3600.0`) the time in seconds that the reserve contribution must sustained at a specified level, validation range: `(0, nothing)`\n- `max_participation_factor::Float64`: (default: `1.0`) the maximum portion [0, 1.0] of the reserve that can be contributed per device, validation range: `(0, 1)`\n- `deployed_fraction::Float64`: (default: `0.0`) Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0, validation range: `(0, 1)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ReserveDemandCurve{T <: ReserveDirection} <: Reserve{T}\n    \"Create this object with `variable` = `nothing`, then add assign a cost curve or time-series of `variable_cost` using the [`set_variable_cost!`](@ref) function, which will automatically update this parameter\"\n    variable::Union{Nothing, TimeSeriesKey, CostCurve{PiecewiseIncrementalCurve}}\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the saturation time_frame in minutes to provide reserve contribution\"\n    time_frame::Float64\n    \"the time in seconds that the reserve contribution must sustained at a specified level\"\n    sustained_time::Float64\n    \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\"\n    max_participation_factor::Float64\n    \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\"\n    deployed_fraction::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ReserveDemandCurve{T}(variable, name, available, time_frame, sustained_time=3600.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), ) where T <: ReserveDirection\n    ReserveDemandCurve{T}(variable, name, available, time_frame, sustained_time, max_participation_factor, deployed_fraction, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ReserveDemandCurve{T}(; variable, name, available, time_frame, sustained_time=3600.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), ) where T <: ReserveDirection\n    ReserveDemandCurve{T}(variable, name, available, time_frame, sustained_time, max_participation_factor, deployed_fraction, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ReserveDemandCurve{T}(::Nothing) where T <: ReserveDirection\n    ReserveDemandCurve{T}(;\n        variable=nothing,\n        name=\"init\",\n        available=false,\n        time_frame=0.0,\n        sustained_time=0.0,\n        max_participation_factor=1.0,\n        deployed_fraction=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ReserveDemandCurve`](@ref) `variable`.\"\"\"\nget_variable(value::ReserveDemandCurve) = value.variable\n\"\"\"Get [`ReserveDemandCurve`](@ref) `name`.\"\"\"\nget_name(value::ReserveDemandCurve) = value.name\n\"\"\"Get [`ReserveDemandCurve`](@ref) `available`.\"\"\"\nget_available(value::ReserveDemandCurve) = value.available\n\"\"\"Get [`ReserveDemandCurve`](@ref) `time_frame`.\"\"\"\nget_time_frame(value::ReserveDemandCurve) = value.time_frame\n\"\"\"Get [`ReserveDemandCurve`](@ref) `sustained_time`.\"\"\"\nget_sustained_time(value::ReserveDemandCurve) = value.sustained_time\n\"\"\"Get [`ReserveDemandCurve`](@ref) `max_participation_factor`.\"\"\"\nget_max_participation_factor(value::ReserveDemandCurve) = value.max_participation_factor\n\"\"\"Get [`ReserveDemandCurve`](@ref) `deployed_fraction`.\"\"\"\nget_deployed_fraction(value::ReserveDemandCurve) = value.deployed_fraction\n\"\"\"Get [`ReserveDemandCurve`](@ref) `ext`.\"\"\"\nget_ext(value::ReserveDemandCurve) = value.ext\n\"\"\"Get [`ReserveDemandCurve`](@ref) `internal`.\"\"\"\nget_internal(value::ReserveDemandCurve) = value.internal\n\n\"\"\"Set [`ReserveDemandCurve`](@ref) `variable`.\"\"\"\nset_variable!(value::ReserveDemandCurve, val) = value.variable = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `available`.\"\"\"\nset_available!(value::ReserveDemandCurve, val) = value.available = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `time_frame`.\"\"\"\nset_time_frame!(value::ReserveDemandCurve, val) = value.time_frame = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `sustained_time`.\"\"\"\nset_sustained_time!(value::ReserveDemandCurve, val) = value.sustained_time = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `max_participation_factor`.\"\"\"\nset_max_participation_factor!(value::ReserveDemandCurve, val) = value.max_participation_factor = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `deployed_fraction`.\"\"\"\nset_deployed_fraction!(value::ReserveDemandCurve, val) = value.deployed_fraction = val\n\"\"\"Set [`ReserveDemandCurve`](@ref) `ext`.\"\"\"\nset_ext!(value::ReserveDemandCurve, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/RoundRotorMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct RoundRotorMachine <: Machine\n        R::Float64\n        Td0_p::Float64\n        Td0_pp::Float64\n        Tq0_p::Float64\n        Tq0_pp::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xl::Float64\n        Se::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        γ_d1::Float64\n        γ_q1::Float64\n        γ_d2::Float64\n        γ_q2::Float64\n        γ_qd::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 4-[states](@ref S) round-rotor synchronous machine with quadratic/exponential saturation:\nIEEE Std 1110 §5.3.2 (Model 2.2). GENROU or GENROE model in PSSE and PSLF\n\n# Arguments\n- `R::Float64`: Armature resistance, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp, validation range: `(0, nothing)`\n- `Xl::Float64`: Stator leakage reactance, validation range: `(0, nothing)`\n- `Se::Tuple{Float64, Float64}`: Saturation factor at 1 and 1.2 pu flux: S(1.0) = B(|ψ_pp|-A)^2\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `γ_d1::Float64`: (**Do not modify.**) γ_d1 parameter\n- `γ_q1::Float64`: (**Do not modify.**) γ_q1 parameter\n- `γ_d2::Float64`: (**Do not modify.**) γ_d2 parameter\n- `γ_q2::Float64`: (**Do not modify.**) γ_q2 parameter\n- `γ_qd::Float64`: (**Do not modify.**) γ_qd parameter\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis generator voltage behind the transient reactance,\n\ted_p: d-axis generator voltage behind the transient reactance,\n\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\n\tψ_kq: flux linkage in the first equivalent damping circuit in the d-axis\n- `n_states::Int`: (**Do not modify.**) RoundRotorMachine has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct RoundRotorMachine <: Machine\n    \"Armature resistance\"\n    R::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp\"\n    Xd_pp::Float64\n    \"Stator leakage reactance\"\n    Xl::Float64\n    \"Saturation factor at 1 and 1.2 pu flux: S(1.0) = B(|ψ_pp|-A)^2\"\n    Se::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) γ_d1 parameter\"\n    γ_d1::Float64\n    \"(**Do not modify.**) γ_q1 parameter\"\n    γ_q1::Float64\n    \"(**Do not modify.**) γ_d2 parameter\"\n    γ_d2::Float64\n    \"(**Do not modify.**) γ_q2 parameter\"\n    γ_q2::Float64\n    \"(**Do not modify.**) γ_qd parameter\"\n    γ_qd::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis generator voltage behind the transient reactance,\n\ted_p: d-axis generator voltage behind the transient reactance,\n\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\n\tψ_kq: flux linkage in the first equivalent damping circuit in the d-axis\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) RoundRotorMachine has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction RoundRotorMachine(R, Td0_p, Td0_pp, Tq0_p, Tq0_pp, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xl, Se, ext=Dict{String, Any}(), )\n    RoundRotorMachine(R, Td0_p, Td0_pp, Tq0_p, Tq0_pp, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xl, Se, ext, (Xd_pp - Xl) / (Xd_p - Xl), (Xd_pp - Xl) / (Xq_p - Xl), (Xd_p - Xd_pp) / (Xd_p - Xl)^2, (Xq_p - Xd_pp) / (Xq_p - Xl)^2, (Xq - Xl) / (Xd - Xl), [:eq_p, :ed_p, :ψ_kd, :ψ_kq], 4, InfrastructureSystemsInternal(), )\nend\n\nfunction RoundRotorMachine(; R, Td0_p, Td0_pp, Tq0_p, Tq0_pp, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xl, Se, ext=Dict{String, Any}(), γ_d1=(Xd_pp - Xl) / (Xd_p - Xl), γ_q1=(Xd_pp - Xl) / (Xq_p - Xl), γ_d2=(Xd_p - Xd_pp) / (Xd_p - Xl)^2, γ_q2=(Xq_p - Xd_pp) / (Xq_p - Xl)^2, γ_qd=(Xq - Xl) / (Xd - Xl), states=[:eq_p, :ed_p, :ψ_kd, :ψ_kq], n_states=4, internal=InfrastructureSystemsInternal(), )\n    RoundRotorMachine(R, Td0_p, Td0_pp, Tq0_p, Tq0_pp, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xl, Se, ext, γ_d1, γ_q1, γ_d2, γ_q2, γ_qd, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction RoundRotorMachine(::Nothing)\n    RoundRotorMachine(;\n        R=0,\n        Td0_p=0,\n        Td0_pp=0,\n        Tq0_p=0,\n        Tq0_pp=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xl=0,\n        Se=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`RoundRotorMachine`](@ref) `R`.\"\"\"\nget_R(value::RoundRotorMachine) = value.R\n\"\"\"Get [`RoundRotorMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::RoundRotorMachine) = value.Td0_p\n\"\"\"Get [`RoundRotorMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::RoundRotorMachine) = value.Td0_pp\n\"\"\"Get [`RoundRotorMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::RoundRotorMachine) = value.Tq0_p\n\"\"\"Get [`RoundRotorMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::RoundRotorMachine) = value.Tq0_pp\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::RoundRotorMachine) = value.Xd\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::RoundRotorMachine) = value.Xq\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::RoundRotorMachine) = value.Xd_p\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::RoundRotorMachine) = value.Xq_p\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::RoundRotorMachine) = value.Xd_pp\n\"\"\"Get [`RoundRotorMachine`](@ref) `Xl`.\"\"\"\nget_Xl(value::RoundRotorMachine) = value.Xl\n\"\"\"Get [`RoundRotorMachine`](@ref) `Se`.\"\"\"\nget_Se(value::RoundRotorMachine) = value.Se\n\"\"\"Get [`RoundRotorMachine`](@ref) `ext`.\"\"\"\nget_ext(value::RoundRotorMachine) = value.ext\n\"\"\"Get [`RoundRotorMachine`](@ref) `γ_d1`.\"\"\"\nget_γ_d1(value::RoundRotorMachine) = value.γ_d1\n\"\"\"Get [`RoundRotorMachine`](@ref) `γ_q1`.\"\"\"\nget_γ_q1(value::RoundRotorMachine) = value.γ_q1\n\"\"\"Get [`RoundRotorMachine`](@ref) `γ_d2`.\"\"\"\nget_γ_d2(value::RoundRotorMachine) = value.γ_d2\n\"\"\"Get [`RoundRotorMachine`](@ref) `γ_q2`.\"\"\"\nget_γ_q2(value::RoundRotorMachine) = value.γ_q2\n\"\"\"Get [`RoundRotorMachine`](@ref) `γ_qd`.\"\"\"\nget_γ_qd(value::RoundRotorMachine) = value.γ_qd\n\"\"\"Get [`RoundRotorMachine`](@ref) `states`.\"\"\"\nget_states(value::RoundRotorMachine) = value.states\n\"\"\"Get [`RoundRotorMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::RoundRotorMachine) = value.n_states\n\"\"\"Get [`RoundRotorMachine`](@ref) `internal`.\"\"\"\nget_internal(value::RoundRotorMachine) = value.internal\n\n\"\"\"Set [`RoundRotorMachine`](@ref) `R`.\"\"\"\nset_R!(value::RoundRotorMachine, val) = value.R = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::RoundRotorMachine, val) = value.Td0_p = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::RoundRotorMachine, val) = value.Td0_pp = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::RoundRotorMachine, val) = value.Tq0_p = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::RoundRotorMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::RoundRotorMachine, val) = value.Xd = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::RoundRotorMachine, val) = value.Xq = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::RoundRotorMachine, val) = value.Xd_p = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::RoundRotorMachine, val) = value.Xq_p = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::RoundRotorMachine, val) = value.Xd_pp = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Xl`.\"\"\"\nset_Xl!(value::RoundRotorMachine, val) = value.Xl = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `Se`.\"\"\"\nset_Se!(value::RoundRotorMachine, val) = value.Se = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::RoundRotorMachine, val) = value.ext = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `γ_d1`.\"\"\"\nset_γ_d1!(value::RoundRotorMachine, val) = value.γ_d1 = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `γ_q1`.\"\"\"\nset_γ_q1!(value::RoundRotorMachine, val) = value.γ_q1 = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `γ_d2`.\"\"\"\nset_γ_d2!(value::RoundRotorMachine, val) = value.γ_d2 = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `γ_q2`.\"\"\"\nset_γ_q2!(value::RoundRotorMachine, val) = value.γ_q2 = val\n\"\"\"Set [`RoundRotorMachine`](@ref) `γ_qd`.\"\"\"\nset_γ_qd!(value::RoundRotorMachine, val) = value.γ_qd = val\n"
  },
  {
    "path": "src/models/generated/SCRX.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SCRX <: AVR\n        Ta_Tb::Float64\n        Tb::Float64\n        K::Float64\n        Te::Float64\n        Efd_lim::MinMax\n        switch::Int\n        rc_rfd::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nThis exciter is based on an IEEE type SCRX solid state exciter.  The output field voltage is varied by a control system to maintain the system voltage at Vref.  Please note that this exciter model has no initialization capabilities - this means that it will respond to whatever inputs it receives regardless of the state of the machine model\n\n# Arguments\n- `Ta_Tb::Float64`: Lead input constant ratio, validation range: `(0.05, 0.3)`\n- `Tb::Float64`: Lag input constant in s, validation range: `(5, 20)`\n- `K::Float64`: Regulator Gain, validation range: `(20, 100)`\n- `Te::Float64`: Regulator Time Constant, validation range: `(0, 1)`\n- `Efd_lim::MinMax`: Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\n- `switch::Int`: Switch, validation range: `(0, 1)`\n- `rc_rfd::Float64`: Field current capability. Set = 0 for negative current capability. Typical value 10, validation range: `(0, 10)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVr1: First integrator,\n\tVr2: Second integrator\n- `n_states::Int`: (**Do not modify.**) SCRX has 2 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) SCRX has 2 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SCRX <: AVR\n    \"Lead input constant ratio\"\n    Ta_Tb::Float64\n    \"Lag input constant in s\"\n    Tb::Float64\n    \"Regulator Gain\"\n    K::Float64\n    \"Regulator Time Constant\"\n    Te::Float64\n    \"Field Voltage regulator limits (regulator output) (Efd_min, Efd_max)\"\n    Efd_lim::MinMax\n    \"Switch\"\n    switch::Int\n    \"Field current capability. Set = 0 for negative current capability. Typical value 10\"\n    rc_rfd::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVr1: First integrator,\n\tVr2: Second integrator\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SCRX has 2 states\"\n    n_states::Int\n    \"(**Do not modify.**) SCRX has 2 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SCRX(Ta_Tb, Tb, K, Te, Efd_lim, switch, rc_rfd, V_ref=1.0, ext=Dict{String, Any}(), )\n    SCRX(Ta_Tb, Tb, K, Te, Efd_lim, switch, rc_rfd, V_ref, ext, [:Vr1, :Vr2], 2, [StateTypes.Differential, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction SCRX(; Ta_Tb, Tb, K, Te, Efd_lim, switch, rc_rfd, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vr1, :Vr2], n_states=2, states_types=[StateTypes.Differential, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    SCRX(Ta_Tb, Tb, K, Te, Efd_lim, switch, rc_rfd, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SCRX(::Nothing)\n    SCRX(;\n        Ta_Tb=0,\n        Tb=0,\n        K=0,\n        Te=0,\n        Efd_lim=(min=0.0, max=0.0),\n        switch=0,\n        rc_rfd=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SCRX`](@ref) `Ta_Tb`.\"\"\"\nget_Ta_Tb(value::SCRX) = value.Ta_Tb\n\"\"\"Get [`SCRX`](@ref) `Tb`.\"\"\"\nget_Tb(value::SCRX) = value.Tb\n\"\"\"Get [`SCRX`](@ref) `K`.\"\"\"\nget_K(value::SCRX) = value.K\n\"\"\"Get [`SCRX`](@ref) `Te`.\"\"\"\nget_Te(value::SCRX) = value.Te\n\"\"\"Get [`SCRX`](@ref) `Efd_lim`.\"\"\"\nget_Efd_lim(value::SCRX) = value.Efd_lim\n\"\"\"Get [`SCRX`](@ref) `switch`.\"\"\"\nget_switch(value::SCRX) = value.switch\n\"\"\"Get [`SCRX`](@ref) `rc_rfd`.\"\"\"\nget_rc_rfd(value::SCRX) = value.rc_rfd\n\"\"\"Get [`SCRX`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::SCRX) = value.V_ref\n\"\"\"Get [`SCRX`](@ref) `ext`.\"\"\"\nget_ext(value::SCRX) = value.ext\n\"\"\"Get [`SCRX`](@ref) `states`.\"\"\"\nget_states(value::SCRX) = value.states\n\"\"\"Get [`SCRX`](@ref) `n_states`.\"\"\"\nget_n_states(value::SCRX) = value.n_states\n\"\"\"Get [`SCRX`](@ref) `states_types`.\"\"\"\nget_states_types(value::SCRX) = value.states_types\n\"\"\"Get [`SCRX`](@ref) `internal`.\"\"\"\nget_internal(value::SCRX) = value.internal\n\n\"\"\"Set [`SCRX`](@ref) `Ta_Tb`.\"\"\"\nset_Ta_Tb!(value::SCRX, val) = value.Ta_Tb = val\n\"\"\"Set [`SCRX`](@ref) `Tb`.\"\"\"\nset_Tb!(value::SCRX, val) = value.Tb = val\n\"\"\"Set [`SCRX`](@ref) `K`.\"\"\"\nset_K!(value::SCRX, val) = value.K = val\n\"\"\"Set [`SCRX`](@ref) `Te`.\"\"\"\nset_Te!(value::SCRX, val) = value.Te = val\n\"\"\"Set [`SCRX`](@ref) `Efd_lim`.\"\"\"\nset_Efd_lim!(value::SCRX, val) = value.Efd_lim = val\n\"\"\"Set [`SCRX`](@ref) `switch`.\"\"\"\nset_switch!(value::SCRX, val) = value.switch = val\n\"\"\"Set [`SCRX`](@ref) `rc_rfd`.\"\"\"\nset_rc_rfd!(value::SCRX, val) = value.rc_rfd = val\n\"\"\"Set [`SCRX`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::SCRX, val) = value.V_ref = val\n\"\"\"Set [`SCRX`](@ref) `ext`.\"\"\"\nset_ext!(value::SCRX, val) = value.ext = val\n\"\"\"Set [`SCRX`](@ref) `states_types`.\"\"\"\nset_states_types!(value::SCRX, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/SEXS.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SEXS <: AVR\n        Ta_Tb::Float64\n        Tb::Float64\n        K::Float64\n        Te::Float64\n        V_lim::MinMax\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of Simplified Excitation System Model - SEXS in PSSE\n\n# Arguments\n- `Ta_Tb::Float64`: Ratio of lead and lag time constants, validation range: `(0, nothing)`\n- `Tb::Float64`: Lag time constant, validation range: `(eps(), nothing)`\n- `K::Float64`: Gain, validation range: `(0, nothing)`\n- `Te::Float64`: Field circuit time constant in s, validation range: `(0, nothing)`\n- `V_lim::MinMax`: Field voltage limits\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\tVf: Voltage field,\tVr: Lead-lag state\n- `n_states::Int`: (**Do not modify.**) SEXS has 2 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) SEXS has 2 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SEXS <: AVR\n    \"Ratio of lead and lag time constants\"\n    Ta_Tb::Float64\n    \"Lag time constant\"\n    Tb::Float64\n    \"Gain\"\n    K::Float64\n    \"Field circuit time constant in s\"\n    Te::Float64\n    \"Field voltage limits\"\n    V_lim::MinMax\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\tVf: Voltage field,\tVr: Lead-lag state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SEXS has 2 states\"\n    n_states::Int\n    \"(**Do not modify.**) SEXS has 2 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SEXS(Ta_Tb, Tb, K, Te, V_lim, V_ref=1.0, ext=Dict{String, Any}(), )\n    SEXS(Ta_Tb, Tb, K, Te, V_lim, V_ref, ext, [:Vf, :Vr], 2, [StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction SEXS(; Ta_Tb, Tb, K, Te, V_lim, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vf, :Vr], n_states=2, states_types=[StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    SEXS(Ta_Tb, Tb, K, Te, V_lim, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SEXS(::Nothing)\n    SEXS(;\n        Ta_Tb=0,\n        Tb=0,\n        K=0,\n        Te=0,\n        V_lim=(min=0.0, max=0.0),\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SEXS`](@ref) `Ta_Tb`.\"\"\"\nget_Ta_Tb(value::SEXS) = value.Ta_Tb\n\"\"\"Get [`SEXS`](@ref) `Tb`.\"\"\"\nget_Tb(value::SEXS) = value.Tb\n\"\"\"Get [`SEXS`](@ref) `K`.\"\"\"\nget_K(value::SEXS) = value.K\n\"\"\"Get [`SEXS`](@ref) `Te`.\"\"\"\nget_Te(value::SEXS) = value.Te\n\"\"\"Get [`SEXS`](@ref) `V_lim`.\"\"\"\nget_V_lim(value::SEXS) = value.V_lim\n\"\"\"Get [`SEXS`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::SEXS) = value.V_ref\n\"\"\"Get [`SEXS`](@ref) `ext`.\"\"\"\nget_ext(value::SEXS) = value.ext\n\"\"\"Get [`SEXS`](@ref) `states`.\"\"\"\nget_states(value::SEXS) = value.states\n\"\"\"Get [`SEXS`](@ref) `n_states`.\"\"\"\nget_n_states(value::SEXS) = value.n_states\n\"\"\"Get [`SEXS`](@ref) `states_types`.\"\"\"\nget_states_types(value::SEXS) = value.states_types\n\"\"\"Get [`SEXS`](@ref) `internal`.\"\"\"\nget_internal(value::SEXS) = value.internal\n\n\"\"\"Set [`SEXS`](@ref) `Ta_Tb`.\"\"\"\nset_Ta_Tb!(value::SEXS, val) = value.Ta_Tb = val\n\"\"\"Set [`SEXS`](@ref) `Tb`.\"\"\"\nset_Tb!(value::SEXS, val) = value.Tb = val\n\"\"\"Set [`SEXS`](@ref) `K`.\"\"\"\nset_K!(value::SEXS, val) = value.K = val\n\"\"\"Set [`SEXS`](@ref) `Te`.\"\"\"\nset_Te!(value::SEXS, val) = value.Te = val\n\"\"\"Set [`SEXS`](@ref) `V_lim`.\"\"\"\nset_V_lim!(value::SEXS, val) = value.V_lim = val\n\"\"\"Set [`SEXS`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::SEXS, val) = value.V_ref = val\n\"\"\"Set [`SEXS`](@ref) `ext`.\"\"\"\nset_ext!(value::SEXS, val) = value.ext = val\n\"\"\"Set [`SEXS`](@ref) `states_types`.\"\"\"\nset_states_types!(value::SEXS, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ST6B.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ST6B <: AVR\n        OEL_Flag::Int\n        Tr::Float64\n        K_pa::Float64\n        K_ia::Float64\n        K_da::Float64\n        T_da::Float64\n        Va_lim::MinMax\n        K_ff::Float64\n        K_m::Float64\n        K_ci::Float64\n        K_lr::Float64\n        I_lr::Float64\n        Vr_lim::MinMax\n        Kg::Float64\n        Tg::Float64\n        V_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIn these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\nParameters of IEEE Std 421.5 Type ST6B Excitacion System. ST6B in PSSE and PSLF\n\n# Arguments\n- `OEL_Flag::Int`: OEL Flag for ST6B: 1: before HV gate, 2: after HV gate, validation range: `(0, 2)`\n- `Tr::Float64`: Regulator input filter time constant in s, validation range: `(0, nothing)`\n- `K_pa::Float64`: Regulator proportional gain, validation range: `(0, nothing)`\n- `K_ia::Float64`: Regulator integral gain, validation range: `(0, nothing)`\n- `K_da::Float64`: Regulator derivative gain, validation range: `(0, nothing)`\n- `T_da::Float64`: Voltage regulator derivative channel time constant in s, validation range: `(0, nothing)`\n- `Va_lim::MinMax`: Regulator output limits (Vi_min, Vi_max)\n- `K_ff::Float64`: Pre-control gain of the inner loop field regulator, validation range: `(0, nothing)`\n- `K_m::Float64`: Forward gain of the inner loop field regulator, validation range: `(0, nothing)`\n- `K_ci::Float64`: Exciter output current limit adjustment gain, validation range: `(0, nothing)`\n- `K_lr::Float64`: Exciter output current limiter gain, validation range: `(0, nothing)`\n- `I_lr::Float64`: Exciter current limiter reference, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (Vi_min, Vi_max)\n- `Kg::Float64`: Feedback gain constant of the inner loop field regulator, validation range: `(0, nothing)`\n- `Tg::Float64`: Feedback time constant of the inner loop field voltage regulator in s, validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_i: Regulator Integrator,\n\tx_d: Regulator Derivative,\n\tVg: Regulator Feedback\n- `n_states::Int`: (**Do not modify.**) ST6B has 4 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ST6B has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ST6B <: AVR\n    \"OEL Flag for ST6B: 1: before HV gate, 2: after HV gate\"\n    OEL_Flag::Int\n    \"Regulator input filter time constant in s\"\n    Tr::Float64\n    \"Regulator proportional gain\"\n    K_pa::Float64\n    \"Regulator integral gain\"\n    K_ia::Float64\n    \"Regulator derivative gain\"\n    K_da::Float64\n    \"Voltage regulator derivative channel time constant in s\"\n    T_da::Float64\n    \"Regulator output limits (Vi_min, Vi_max)\"\n    Va_lim::MinMax\n    \"Pre-control gain of the inner loop field regulator\"\n    K_ff::Float64\n    \"Forward gain of the inner loop field regulator\"\n    K_m::Float64\n    \"Exciter output current limit adjustment gain\"\n    K_ci::Float64\n    \"Exciter output current limiter gain\"\n    K_lr::Float64\n    \"Exciter current limiter reference\"\n    I_lr::Float64\n    \"Voltage regulator limits (Vi_min, Vi_max)\"\n    Vr_lim::MinMax\n    \"Feedback gain constant of the inner loop field regulator\"\n    Kg::Float64\n    \"Feedback time constant of the inner loop field voltage regulator in s\"\n    Tg::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_i: Regulator Integrator,\n\tx_d: Regulator Derivative,\n\tVg: Regulator Feedback\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ST6B has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) ST6B has 4 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ST6B(OEL_Flag, Tr, K_pa, K_ia, K_da, T_da, Va_lim, K_ff, K_m, K_ci, K_lr, I_lr, Vr_lim, Kg, Tg, V_ref=1.0, ext=Dict{String, Any}(), )\n    ST6B(OEL_Flag, Tr, K_pa, K_ia, K_da, T_da, Va_lim, K_ff, K_m, K_ci, K_lr, I_lr, Vr_lim, Kg, Tg, V_ref, ext, [:Vm, :x_i, :x_d, :Vg], 4, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction ST6B(; OEL_Flag, Tr, K_pa, K_ia, K_da, T_da, Va_lim, K_ff, K_m, K_ci, K_lr, I_lr, Vr_lim, Kg, Tg, V_ref=1.0, ext=Dict{String, Any}(), states=[:Vm, :x_i, :x_d, :Vg], n_states=4, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    ST6B(OEL_Flag, Tr, K_pa, K_ia, K_da, T_da, Va_lim, K_ff, K_m, K_ci, K_lr, I_lr, Vr_lim, Kg, Tg, V_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ST6B(::Nothing)\n    ST6B(;\n        OEL_Flag=0,\n        Tr=0,\n        K_pa=0,\n        K_ia=0,\n        K_da=0,\n        T_da=0,\n        Va_lim=(min=0.0, max=0.0),\n        K_ff=0,\n        K_m=0,\n        K_ci=0,\n        K_lr=0,\n        I_lr=0,\n        Vr_lim=(min=0.0, max=0.0),\n        Kg=0,\n        Tg=0,\n        V_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ST6B`](@ref) `OEL_Flag`.\"\"\"\nget_OEL_Flag(value::ST6B) = value.OEL_Flag\n\"\"\"Get [`ST6B`](@ref) `Tr`.\"\"\"\nget_Tr(value::ST6B) = value.Tr\n\"\"\"Get [`ST6B`](@ref) `K_pa`.\"\"\"\nget_K_pa(value::ST6B) = value.K_pa\n\"\"\"Get [`ST6B`](@ref) `K_ia`.\"\"\"\nget_K_ia(value::ST6B) = value.K_ia\n\"\"\"Get [`ST6B`](@ref) `K_da`.\"\"\"\nget_K_da(value::ST6B) = value.K_da\n\"\"\"Get [`ST6B`](@ref) `T_da`.\"\"\"\nget_T_da(value::ST6B) = value.T_da\n\"\"\"Get [`ST6B`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::ST6B) = value.Va_lim\n\"\"\"Get [`ST6B`](@ref) `K_ff`.\"\"\"\nget_K_ff(value::ST6B) = value.K_ff\n\"\"\"Get [`ST6B`](@ref) `K_m`.\"\"\"\nget_K_m(value::ST6B) = value.K_m\n\"\"\"Get [`ST6B`](@ref) `K_ci`.\"\"\"\nget_K_ci(value::ST6B) = value.K_ci\n\"\"\"Get [`ST6B`](@ref) `K_lr`.\"\"\"\nget_K_lr(value::ST6B) = value.K_lr\n\"\"\"Get [`ST6B`](@ref) `I_lr`.\"\"\"\nget_I_lr(value::ST6B) = value.I_lr\n\"\"\"Get [`ST6B`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ST6B) = value.Vr_lim\n\"\"\"Get [`ST6B`](@ref) `Kg`.\"\"\"\nget_Kg(value::ST6B) = value.Kg\n\"\"\"Get [`ST6B`](@ref) `Tg`.\"\"\"\nget_Tg(value::ST6B) = value.Tg\n\"\"\"Get [`ST6B`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ST6B) = value.V_ref\n\"\"\"Get [`ST6B`](@ref) `ext`.\"\"\"\nget_ext(value::ST6B) = value.ext\n\"\"\"Get [`ST6B`](@ref) `states`.\"\"\"\nget_states(value::ST6B) = value.states\n\"\"\"Get [`ST6B`](@ref) `n_states`.\"\"\"\nget_n_states(value::ST6B) = value.n_states\n\"\"\"Get [`ST6B`](@ref) `states_types`.\"\"\"\nget_states_types(value::ST6B) = value.states_types\n\"\"\"Get [`ST6B`](@ref) `internal`.\"\"\"\nget_internal(value::ST6B) = value.internal\n\n\"\"\"Set [`ST6B`](@ref) `OEL_Flag`.\"\"\"\nset_OEL_Flag!(value::ST6B, val) = value.OEL_Flag = val\n\"\"\"Set [`ST6B`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ST6B, val) = value.Tr = val\n\"\"\"Set [`ST6B`](@ref) `K_pa`.\"\"\"\nset_K_pa!(value::ST6B, val) = value.K_pa = val\n\"\"\"Set [`ST6B`](@ref) `K_ia`.\"\"\"\nset_K_ia!(value::ST6B, val) = value.K_ia = val\n\"\"\"Set [`ST6B`](@ref) `K_da`.\"\"\"\nset_K_da!(value::ST6B, val) = value.K_da = val\n\"\"\"Set [`ST6B`](@ref) `T_da`.\"\"\"\nset_T_da!(value::ST6B, val) = value.T_da = val\n\"\"\"Set [`ST6B`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::ST6B, val) = value.Va_lim = val\n\"\"\"Set [`ST6B`](@ref) `K_ff`.\"\"\"\nset_K_ff!(value::ST6B, val) = value.K_ff = val\n\"\"\"Set [`ST6B`](@ref) `K_m`.\"\"\"\nset_K_m!(value::ST6B, val) = value.K_m = val\n\"\"\"Set [`ST6B`](@ref) `K_ci`.\"\"\"\nset_K_ci!(value::ST6B, val) = value.K_ci = val\n\"\"\"Set [`ST6B`](@ref) `K_lr`.\"\"\"\nset_K_lr!(value::ST6B, val) = value.K_lr = val\n\"\"\"Set [`ST6B`](@ref) `I_lr`.\"\"\"\nset_I_lr!(value::ST6B, val) = value.I_lr = val\n\"\"\"Set [`ST6B`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ST6B, val) = value.Vr_lim = val\n\"\"\"Set [`ST6B`](@ref) `Kg`.\"\"\"\nset_Kg!(value::ST6B, val) = value.Kg = val\n\"\"\"Set [`ST6B`](@ref) `Tg`.\"\"\"\nset_Tg!(value::ST6B, val) = value.Tg = val\n\"\"\"Set [`ST6B`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ST6B, val) = value.V_ref = val\n\"\"\"Set [`ST6B`](@ref) `ext`.\"\"\"\nset_ext!(value::ST6B, val) = value.ext = val\n\"\"\"Set [`ST6B`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ST6B, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ST8C.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ST8C <: AVR\n        OEL_Flag::Int\n        UEL_Flag::Int\n        SCL_Flag::Int\n        SW1_Flag::Int\n        Tr::Float64\n        K_pr::Float64\n        K_ir::Float64\n        Vpi_lim::MinMax\n        K_pa::Float64\n        K_ia::Float64\n        Va_lim::MinMax\n        K_a::Float64\n        T_a::Float64\n        Vr_lim::MinMax\n        K_f::Float64\n        T_f::Float64\n        K_c1::Float64\n        K_p::Float64\n        K_i1::Float64\n        X_l::Float64\n        θ_p::Float64\n        VB1_max::Float64\n        K_c2::Float64\n        K_i2::Float64\n        VB2_max::Float64\n        V_ref::Float64\n        Ifd_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nIn these excitation systems, voltage (and also current in compounded systems) is transformed to an appropriate level. Rectifiers, either controlled or non-controlled, provide the necessary direct current for the generator field.\nParameters of IEEE Std 421.5 Type ST8C Excitacion System. ST8C in PSSE and PSLF\n\n# Arguments\n- `OEL_Flag::Int`: OEL Flag for ST8C: <2: Summation at Voltage Error, 2: OEL takeover at gate, validation range: `(0, 2)`\n- `UEL_Flag::Int`: UEL Flag for ST8C: <2: Summation at Voltage Error, 2: UEL takeover at gate, validation range: `(0, 2)`\n- `SCL_Flag::Int`: SCL Flag for ST8C: <2: Summation at Voltage Error, 2: SCL Takeover at UEL and OEL gates, validation range: `(0, 2)`\n- `SW1_Flag::Int`: SW1 Flag for Power Source Selector for ST8C: <2: Source from generator terminal voltage, 2: Independent power source, validation range: `(0, 2)`\n- `Tr::Float64`: Regulator input filter time constant in seconds, validation range: `(0, nothing)`\n- `K_pr::Float64`: Regulator proportional gain (pu), validation range: `(0, nothing)`\n- `K_ir::Float64`: Regulator integral gain (pu), validation range: `(0, nothing)`\n- `Vpi_lim::MinMax`: Regulator input limits (Vpi_min, Vpi_max)\n- `K_pa::Float64`: Field current regulator proportional gain (pu), validation range: `(0, nothing)`\n- `K_ia::Float64`: Field current regulator integral gain (pu), validation range: `(0, nothing)`\n- `Va_lim::MinMax`: Field current regulator output limits (Va_min, Va_max)\n- `K_a::Float64`: Field current regulator proportional gain (pu), validation range: `(0, nothing)`\n- `T_a::Float64`: Controlled rectifier bridge equivalent time constant in seconds, validation range: `(0, nothing)`\n- `Vr_lim::MinMax`: Voltage regulator limits (Vr_min, Vr_max)\n- `K_f::Float64`: Exciter field current feedback gain (pu), validation range: `(0, nothing)`\n- `T_f::Float64`: Field current feedback time constant in seconds, validation range: `(0, nothing)`\n- `K_c1::Float64`: Rectifier loading factor proportional to commutating reactance (pu), validation range: `(0, nothing)`\n- `K_p::Float64`: Potential circuit (voltage) gain coefficient (pu), validation range: `(0, nothing)`\n- `K_i1::Float64`: Potential circuit (current) gain coefficient (pu), validation range: `(0, nothing)`\n- `X_l::Float64`: Reactance associated with potential source (pu), validation range: `(0, nothing)`\n- `θ_p::Float64`: Potential circuit phase angle (degrees), validation range: `(0, nothing)`\n- `VB1_max::Float64`: Maximum available exciter voltage (pu), validation range: `(0, nothing)`\n- `K_c2::Float64`: Rectifier loading factor proportional to commutating reactance (pu), validation range: `(0, nothing)`\n- `K_i2::Float64`: Potential circuit (current) gain coefficient (pu), validation range: `(0, nothing)`\n- `VB2_max::Float64`: Maximum available exciter voltage (pu), validation range: `(0, nothing)`\n- `V_ref::Float64`: (default: `1.0`) Reference Voltage Set-point (pu), validation range: `(0, nothing)`\n- `Ifd_ref::Float64`: (default: `1.0`) Reference Field Current Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_a1: Regulator Integrator state,\n\tx_a2: Field Current regulator state,\n\tx_a3: Controller rectifier bridge state,\n\tx_a4: Regulator Feedback state\n- `n_states::Int`: (**Do not modify.**) ST8C has 5 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) ST8C has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ST8C <: AVR\n    \"OEL Flag for ST8C: <2: Summation at Voltage Error, 2: OEL takeover at gate\"\n    OEL_Flag::Int\n    \"UEL Flag for ST8C: <2: Summation at Voltage Error, 2: UEL takeover at gate\"\n    UEL_Flag::Int\n    \"SCL Flag for ST8C: <2: Summation at Voltage Error, 2: SCL Takeover at UEL and OEL gates\"\n    SCL_Flag::Int\n    \"SW1 Flag for Power Source Selector for ST8C: <2: Source from generator terminal voltage, 2: Independent power source\"\n    SW1_Flag::Int\n    \"Regulator input filter time constant in seconds\"\n    Tr::Float64\n    \"Regulator proportional gain (pu)\"\n    K_pr::Float64\n    \"Regulator integral gain (pu)\"\n    K_ir::Float64\n    \"Regulator input limits (Vpi_min, Vpi_max)\"\n    Vpi_lim::MinMax\n    \"Field current regulator proportional gain (pu)\"\n    K_pa::Float64\n    \"Field current regulator integral gain (pu)\"\n    K_ia::Float64\n    \"Field current regulator output limits (Va_min, Va_max)\"\n    Va_lim::MinMax\n    \"Field current regulator proportional gain (pu)\"\n    K_a::Float64\n    \"Controlled rectifier bridge equivalent time constant in seconds\"\n    T_a::Float64\n    \"Voltage regulator limits (Vr_min, Vr_max)\"\n    Vr_lim::MinMax\n    \"Exciter field current feedback gain (pu)\"\n    K_f::Float64\n    \"Field current feedback time constant in seconds\"\n    T_f::Float64\n    \"Rectifier loading factor proportional to commutating reactance (pu)\"\n    K_c1::Float64\n    \"Potential circuit (voltage) gain coefficient (pu)\"\n    K_p::Float64\n    \"Potential circuit (current) gain coefficient (pu)\"\n    K_i1::Float64\n    \"Reactance associated with potential source (pu)\"\n    X_l::Float64\n    \"Potential circuit phase angle (degrees)\"\n    θ_p::Float64\n    \"Maximum available exciter voltage (pu)\"\n    VB1_max::Float64\n    \"Rectifier loading factor proportional to commutating reactance (pu)\"\n    K_c2::Float64\n    \"Potential circuit (current) gain coefficient (pu)\"\n    K_i2::Float64\n    \"Maximum available exciter voltage (pu)\"\n    VB2_max::Float64\n    \"Reference Voltage Set-point (pu)\"\n    V_ref::Float64\n    \"Reference Field Current Set-point (pu)\"\n    Ifd_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tVm: Sensed terminal voltage,\n\tx_a1: Regulator Integrator state,\n\tx_a2: Field Current regulator state,\n\tx_a3: Controller rectifier bridge state,\n\tx_a4: Regulator Feedback state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ST8C has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) ST8C has 5 states\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ST8C(OEL_Flag, UEL_Flag, SCL_Flag, SW1_Flag, Tr, K_pr, K_ir, Vpi_lim, K_pa, K_ia, Va_lim, K_a, T_a, Vr_lim, K_f, T_f, K_c1, K_p, K_i1, X_l, θ_p, VB1_max, K_c2, K_i2, VB2_max, V_ref=1.0, Ifd_ref=1.0, ext=Dict{String, Any}(), )\n    ST8C(OEL_Flag, UEL_Flag, SCL_Flag, SW1_Flag, Tr, K_pr, K_ir, Vpi_lim, K_pa, K_ia, Va_lim, K_a, T_a, Vr_lim, K_f, T_f, K_c1, K_p, K_i1, X_l, θ_p, VB1_max, K_c2, K_i2, VB2_max, V_ref, Ifd_ref, ext, [:Vm, :x_a1, :x_a2, :x_a3, :x_a4], 5, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction ST8C(; OEL_Flag, UEL_Flag, SCL_Flag, SW1_Flag, Tr, K_pr, K_ir, Vpi_lim, K_pa, K_ia, Va_lim, K_a, T_a, Vr_lim, K_f, T_f, K_c1, K_p, K_i1, X_l, θ_p, VB1_max, K_c2, K_i2, VB2_max, V_ref=1.0, Ifd_ref=1.0, ext=Dict{String, Any}(), states=[:Vm, :x_a1, :x_a2, :x_a3, :x_a4], n_states=5, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    ST8C(OEL_Flag, UEL_Flag, SCL_Flag, SW1_Flag, Tr, K_pr, K_ir, Vpi_lim, K_pa, K_ia, Va_lim, K_a, T_a, Vr_lim, K_f, T_f, K_c1, K_p, K_i1, X_l, θ_p, VB1_max, K_c2, K_i2, VB2_max, V_ref, Ifd_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ST8C(::Nothing)\n    ST8C(;\n        OEL_Flag=0,\n        UEL_Flag=0,\n        SCL_Flag=0,\n        SW1_Flag=0,\n        Tr=0,\n        K_pr=0,\n        K_ir=0,\n        Vpi_lim=(min=0.0, max=0.0),\n        K_pa=0,\n        K_ia=0,\n        Va_lim=(min=0.0, max=0.0),\n        K_a=0,\n        T_a=0,\n        Vr_lim=(min=0.0, max=0.0),\n        K_f=0,\n        T_f=0,\n        K_c1=0,\n        K_p=0,\n        K_i1=0,\n        X_l=0,\n        θ_p=0,\n        VB1_max=0,\n        K_c2=0,\n        K_i2=0,\n        VB2_max=0,\n        V_ref=0,\n        Ifd_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ST8C`](@ref) `OEL_Flag`.\"\"\"\nget_OEL_Flag(value::ST8C) = value.OEL_Flag\n\"\"\"Get [`ST8C`](@ref) `UEL_Flag`.\"\"\"\nget_UEL_Flag(value::ST8C) = value.UEL_Flag\n\"\"\"Get [`ST8C`](@ref) `SCL_Flag`.\"\"\"\nget_SCL_Flag(value::ST8C) = value.SCL_Flag\n\"\"\"Get [`ST8C`](@ref) `SW1_Flag`.\"\"\"\nget_SW1_Flag(value::ST8C) = value.SW1_Flag\n\"\"\"Get [`ST8C`](@ref) `Tr`.\"\"\"\nget_Tr(value::ST8C) = value.Tr\n\"\"\"Get [`ST8C`](@ref) `K_pr`.\"\"\"\nget_K_pr(value::ST8C) = value.K_pr\n\"\"\"Get [`ST8C`](@ref) `K_ir`.\"\"\"\nget_K_ir(value::ST8C) = value.K_ir\n\"\"\"Get [`ST8C`](@ref) `Vpi_lim`.\"\"\"\nget_Vpi_lim(value::ST8C) = value.Vpi_lim\n\"\"\"Get [`ST8C`](@ref) `K_pa`.\"\"\"\nget_K_pa(value::ST8C) = value.K_pa\n\"\"\"Get [`ST8C`](@ref) `K_ia`.\"\"\"\nget_K_ia(value::ST8C) = value.K_ia\n\"\"\"Get [`ST8C`](@ref) `Va_lim`.\"\"\"\nget_Va_lim(value::ST8C) = value.Va_lim\n\"\"\"Get [`ST8C`](@ref) `K_a`.\"\"\"\nget_K_a(value::ST8C) = value.K_a\n\"\"\"Get [`ST8C`](@ref) `T_a`.\"\"\"\nget_T_a(value::ST8C) = value.T_a\n\"\"\"Get [`ST8C`](@ref) `Vr_lim`.\"\"\"\nget_Vr_lim(value::ST8C) = value.Vr_lim\n\"\"\"Get [`ST8C`](@ref) `K_f`.\"\"\"\nget_K_f(value::ST8C) = value.K_f\n\"\"\"Get [`ST8C`](@ref) `T_f`.\"\"\"\nget_T_f(value::ST8C) = value.T_f\n\"\"\"Get [`ST8C`](@ref) `K_c1`.\"\"\"\nget_K_c1(value::ST8C) = value.K_c1\n\"\"\"Get [`ST8C`](@ref) `K_p`.\"\"\"\nget_K_p(value::ST8C) = value.K_p\n\"\"\"Get [`ST8C`](@ref) `K_i1`.\"\"\"\nget_K_i1(value::ST8C) = value.K_i1\n\"\"\"Get [`ST8C`](@ref) `X_l`.\"\"\"\nget_X_l(value::ST8C) = value.X_l\n\"\"\"Get [`ST8C`](@ref) `θ_p`.\"\"\"\nget_θ_p(value::ST8C) = value.θ_p\n\"\"\"Get [`ST8C`](@ref) `VB1_max`.\"\"\"\nget_VB1_max(value::ST8C) = value.VB1_max\n\"\"\"Get [`ST8C`](@ref) `K_c2`.\"\"\"\nget_K_c2(value::ST8C) = value.K_c2\n\"\"\"Get [`ST8C`](@ref) `K_i2`.\"\"\"\nget_K_i2(value::ST8C) = value.K_i2\n\"\"\"Get [`ST8C`](@ref) `VB2_max`.\"\"\"\nget_VB2_max(value::ST8C) = value.VB2_max\n\"\"\"Get [`ST8C`](@ref) `V_ref`.\"\"\"\nget_V_ref(value::ST8C) = value.V_ref\n\"\"\"Get [`ST8C`](@ref) `Ifd_ref`.\"\"\"\nget_Ifd_ref(value::ST8C) = value.Ifd_ref\n\"\"\"Get [`ST8C`](@ref) `ext`.\"\"\"\nget_ext(value::ST8C) = value.ext\n\"\"\"Get [`ST8C`](@ref) `states`.\"\"\"\nget_states(value::ST8C) = value.states\n\"\"\"Get [`ST8C`](@ref) `n_states`.\"\"\"\nget_n_states(value::ST8C) = value.n_states\n\"\"\"Get [`ST8C`](@ref) `states_types`.\"\"\"\nget_states_types(value::ST8C) = value.states_types\n\"\"\"Get [`ST8C`](@ref) `internal`.\"\"\"\nget_internal(value::ST8C) = value.internal\n\n\"\"\"Set [`ST8C`](@ref) `OEL_Flag`.\"\"\"\nset_OEL_Flag!(value::ST8C, val) = value.OEL_Flag = val\n\"\"\"Set [`ST8C`](@ref) `UEL_Flag`.\"\"\"\nset_UEL_Flag!(value::ST8C, val) = value.UEL_Flag = val\n\"\"\"Set [`ST8C`](@ref) `SCL_Flag`.\"\"\"\nset_SCL_Flag!(value::ST8C, val) = value.SCL_Flag = val\n\"\"\"Set [`ST8C`](@ref) `SW1_Flag`.\"\"\"\nset_SW1_Flag!(value::ST8C, val) = value.SW1_Flag = val\n\"\"\"Set [`ST8C`](@ref) `Tr`.\"\"\"\nset_Tr!(value::ST8C, val) = value.Tr = val\n\"\"\"Set [`ST8C`](@ref) `K_pr`.\"\"\"\nset_K_pr!(value::ST8C, val) = value.K_pr = val\n\"\"\"Set [`ST8C`](@ref) `K_ir`.\"\"\"\nset_K_ir!(value::ST8C, val) = value.K_ir = val\n\"\"\"Set [`ST8C`](@ref) `Vpi_lim`.\"\"\"\nset_Vpi_lim!(value::ST8C, val) = value.Vpi_lim = val\n\"\"\"Set [`ST8C`](@ref) `K_pa`.\"\"\"\nset_K_pa!(value::ST8C, val) = value.K_pa = val\n\"\"\"Set [`ST8C`](@ref) `K_ia`.\"\"\"\nset_K_ia!(value::ST8C, val) = value.K_ia = val\n\"\"\"Set [`ST8C`](@ref) `Va_lim`.\"\"\"\nset_Va_lim!(value::ST8C, val) = value.Va_lim = val\n\"\"\"Set [`ST8C`](@ref) `K_a`.\"\"\"\nset_K_a!(value::ST8C, val) = value.K_a = val\n\"\"\"Set [`ST8C`](@ref) `T_a`.\"\"\"\nset_T_a!(value::ST8C, val) = value.T_a = val\n\"\"\"Set [`ST8C`](@ref) `Vr_lim`.\"\"\"\nset_Vr_lim!(value::ST8C, val) = value.Vr_lim = val\n\"\"\"Set [`ST8C`](@ref) `K_f`.\"\"\"\nset_K_f!(value::ST8C, val) = value.K_f = val\n\"\"\"Set [`ST8C`](@ref) `T_f`.\"\"\"\nset_T_f!(value::ST8C, val) = value.T_f = val\n\"\"\"Set [`ST8C`](@ref) `K_c1`.\"\"\"\nset_K_c1!(value::ST8C, val) = value.K_c1 = val\n\"\"\"Set [`ST8C`](@ref) `K_p`.\"\"\"\nset_K_p!(value::ST8C, val) = value.K_p = val\n\"\"\"Set [`ST8C`](@ref) `K_i1`.\"\"\"\nset_K_i1!(value::ST8C, val) = value.K_i1 = val\n\"\"\"Set [`ST8C`](@ref) `X_l`.\"\"\"\nset_X_l!(value::ST8C, val) = value.X_l = val\n\"\"\"Set [`ST8C`](@ref) `θ_p`.\"\"\"\nset_θ_p!(value::ST8C, val) = value.θ_p = val\n\"\"\"Set [`ST8C`](@ref) `VB1_max`.\"\"\"\nset_VB1_max!(value::ST8C, val) = value.VB1_max = val\n\"\"\"Set [`ST8C`](@ref) `K_c2`.\"\"\"\nset_K_c2!(value::ST8C, val) = value.K_c2 = val\n\"\"\"Set [`ST8C`](@ref) `K_i2`.\"\"\"\nset_K_i2!(value::ST8C, val) = value.K_i2 = val\n\"\"\"Set [`ST8C`](@ref) `VB2_max`.\"\"\"\nset_VB2_max!(value::ST8C, val) = value.VB2_max = val\n\"\"\"Set [`ST8C`](@ref) `V_ref`.\"\"\"\nset_V_ref!(value::ST8C, val) = value.V_ref = val\n\"\"\"Set [`ST8C`](@ref) `Ifd_ref`.\"\"\"\nset_Ifd_ref!(value::ST8C, val) = value.Ifd_ref = val\n\"\"\"Set [`ST8C`](@ref) `ext`.\"\"\"\nset_ext!(value::ST8C, val) = value.ext = val\n\"\"\"Set [`ST8C`](@ref) `states_types`.\"\"\"\nset_states_types!(value::ST8C, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/STAB1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct STAB1 <: PSS\n        KT::Float64\n        T::Float64\n        T1T3::Float64\n        T3::Float64\n        T2T4::Float64\n        T4::Float64\n        H_lim::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nSpeed-Sensitive Stabilizing Model\n\n# Arguments\n- `KT::Float64`: K/T for washout filter, validation range: `(0, nothing)`\n- `T::Float64`: Time constant for washout filter, validation range: `(0.01, nothing)`\n- `T1T3::Float64`: Time constant division T1/T3, validation range: `(0, nothing)`\n- `T3::Float64`: Time constant, validation range: `(0.01, nothing)`\n- `T2T4::Float64`: Time constant division T2/T4, validation range: `(0, nothing)`\n- `T4::Float64`: Time constant, validation range: `(0.01, nothing)`\n- `H_lim::Float64`: PSS output limit, validation range: `(0, 0.5)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tx_p1: washout filter,\n\tx_p2: T1/T3 lead-lag block, \n\tx_p3: T2/T4 lead-lag block,\n- `n_states::Int`: (**Do not modify.**) STAB1 has 3 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) STAB1 has 3 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct STAB1 <: PSS\n    \"K/T for washout filter\"\n    KT::Float64\n    \"Time constant for washout filter\"\n    T::Float64\n    \"Time constant division T1/T3\"\n    T1T3::Float64\n    \"Time constant\"\n    T3::Float64\n    \"Time constant division T2/T4\"\n    T2T4::Float64\n    \"Time constant\"\n    T4::Float64\n    \"PSS output limit\"\n    H_lim::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tx_p1: washout filter,\n\tx_p2: T1/T3 lead-lag block, \n\tx_p3: T2/T4 lead-lag block,\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) STAB1 has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) STAB1 has 3 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction STAB1(KT, T, T1T3, T3, T2T4, T4, H_lim, ext=Dict{String, Any}(), )\n    STAB1(KT, T, T1T3, T3, T2T4, T4, H_lim, ext, [:x_p1, :x_p2, :x_p3], 3, [StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction STAB1(; KT, T, T1T3, T3, T2T4, T4, H_lim, ext=Dict{String, Any}(), states=[:x_p1, :x_p2, :x_p3], n_states=3, states_types=[StateTypes.Differential, StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    STAB1(KT, T, T1T3, T3, T2T4, T4, H_lim, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction STAB1(::Nothing)\n    STAB1(;\n        KT=0,\n        T=0.01,\n        T1T3=0,\n        T3=0.01,\n        T2T4=0,\n        T4=0.01,\n        H_lim=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`STAB1`](@ref) `KT`.\"\"\"\nget_KT(value::STAB1) = value.KT\n\"\"\"Get [`STAB1`](@ref) `T`.\"\"\"\nget_T(value::STAB1) = value.T\n\"\"\"Get [`STAB1`](@ref) `T1T3`.\"\"\"\nget_T1T3(value::STAB1) = value.T1T3\n\"\"\"Get [`STAB1`](@ref) `T3`.\"\"\"\nget_T3(value::STAB1) = value.T3\n\"\"\"Get [`STAB1`](@ref) `T2T4`.\"\"\"\nget_T2T4(value::STAB1) = value.T2T4\n\"\"\"Get [`STAB1`](@ref) `T4`.\"\"\"\nget_T4(value::STAB1) = value.T4\n\"\"\"Get [`STAB1`](@ref) `H_lim`.\"\"\"\nget_H_lim(value::STAB1) = value.H_lim\n\"\"\"Get [`STAB1`](@ref) `ext`.\"\"\"\nget_ext(value::STAB1) = value.ext\n\"\"\"Get [`STAB1`](@ref) `states`.\"\"\"\nget_states(value::STAB1) = value.states\n\"\"\"Get [`STAB1`](@ref) `n_states`.\"\"\"\nget_n_states(value::STAB1) = value.n_states\n\"\"\"Get [`STAB1`](@ref) `states_types`.\"\"\"\nget_states_types(value::STAB1) = value.states_types\n\"\"\"Get [`STAB1`](@ref) `internal`.\"\"\"\nget_internal(value::STAB1) = value.internal\n\n\"\"\"Set [`STAB1`](@ref) `KT`.\"\"\"\nset_KT!(value::STAB1, val) = value.KT = val\n\"\"\"Set [`STAB1`](@ref) `T`.\"\"\"\nset_T!(value::STAB1, val) = value.T = val\n\"\"\"Set [`STAB1`](@ref) `T1T3`.\"\"\"\nset_T1T3!(value::STAB1, val) = value.T1T3 = val\n\"\"\"Set [`STAB1`](@ref) `T3`.\"\"\"\nset_T3!(value::STAB1, val) = value.T3 = val\n\"\"\"Set [`STAB1`](@ref) `T2T4`.\"\"\"\nset_T2T4!(value::STAB1, val) = value.T2T4 = val\n\"\"\"Set [`STAB1`](@ref) `T4`.\"\"\"\nset_T4!(value::STAB1, val) = value.T4 = val\n\"\"\"Set [`STAB1`](@ref) `H_lim`.\"\"\"\nset_H_lim!(value::STAB1, val) = value.H_lim = val\n\"\"\"Set [`STAB1`](@ref) `ext`.\"\"\"\nset_ext!(value::STAB1, val) = value.ext = val\n\"\"\"Set [`STAB1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::STAB1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/SalientPoleMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SalientPoleMachine <: Machine\n        R::Float64\n        Td0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xd_pp::Float64\n        Xl::Float64\n        Se::Tuple{Float64, Float64}\n        ext::Dict{String, Any}\n        γ_d1::Float64\n        γ_q1::Float64\n        γ_d2::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 3-[states](@ref S) salient-pole synchronous machine with quadratic/exponential saturation:\nIEEE Std 1110 §5.3.1 (Model 2.1). GENSAL or GENSAE model in PSSE and PSLF\n\n# Arguments\n- `R::Float64`: Armature resistance, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp, validation range: `(0, nothing)`\n- `Xl::Float64`: Stator leakage reactance, validation range: `(0, nothing)`\n- `Se::Tuple{Float64, Float64}`: Saturation factor at 1 and 1.2 pu flux: Se(eq_p) = B(eq_p-A)^2\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `γ_d1::Float64`: (**Do not modify.**) γ_d1 parameter\n- `γ_q1::Float64`: (**Do not modify.**) γ_q1 parameter\n- `γ_d2::Float64`: (**Do not modify.**) γ_d2 parameter\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis generator voltage behind the transient reactance,\n\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\n\tψq_pp: phasonf of the subtransient flux linkage in the q-axis\n- `n_states::Int`: (**Do not modify.**) SalientPoleMachine has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SalientPoleMachine <: Machine\n    \"Armature resistance\"\n    R::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit. Note: Xd_pp = Xq_pp\"\n    Xd_pp::Float64\n    \"Stator leakage reactance\"\n    Xl::Float64\n    \"Saturation factor at 1 and 1.2 pu flux: Se(eq_p) = B(eq_p-A)^2\"\n    Se::Tuple{Float64, Float64}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) γ_d1 parameter\"\n    γ_d1::Float64\n    \"(**Do not modify.**) γ_q1 parameter\"\n    γ_q1::Float64\n    \"(**Do not modify.**) γ_d2 parameter\"\n    γ_d2::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis generator voltage behind the transient reactance,\n\tψ_kd: flux linkage in the first equivalent damping circuit in the d-axis,\n\tψq_pp: phasonf of the subtransient flux linkage in the q-axis\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SalientPoleMachine has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SalientPoleMachine(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se, ext=Dict{String, Any}(), )\n    SalientPoleMachine(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se, ext, (Xd_pp - Xl) / (Xd_p - Xl), (Xd_p - Xd_pp) / (Xd_p - Xl), (Xd_p - Xd_pp) / (Xd_p - Xl)^2, [:eq_p, :ψ_kd, :ψq_pp], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction SalientPoleMachine(; R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se, ext=Dict{String, Any}(), γ_d1=(Xd_pp - Xl) / (Xd_p - Xl), γ_q1=(Xd_p - Xd_pp) / (Xd_p - Xl), γ_d2=(Xd_p - Xd_pp) / (Xd_p - Xl)^2, states=[:eq_p, :ψ_kd, :ψq_pp], n_states=3, internal=InfrastructureSystemsInternal(), )\n    SalientPoleMachine(R, Td0_p, Td0_pp, Tq0_pp, Xd, Xq, Xd_p, Xd_pp, Xl, Se, ext, γ_d1, γ_q1, γ_d2, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SalientPoleMachine(::Nothing)\n    SalientPoleMachine(;\n        R=0,\n        Td0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xd_pp=0,\n        Xl=0,\n        Se=(0.0, 0.0),\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SalientPoleMachine`](@ref) `R`.\"\"\"\nget_R(value::SalientPoleMachine) = value.R\n\"\"\"Get [`SalientPoleMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::SalientPoleMachine) = value.Td0_p\n\"\"\"Get [`SalientPoleMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::SalientPoleMachine) = value.Td0_pp\n\"\"\"Get [`SalientPoleMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::SalientPoleMachine) = value.Tq0_pp\n\"\"\"Get [`SalientPoleMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::SalientPoleMachine) = value.Xd\n\"\"\"Get [`SalientPoleMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::SalientPoleMachine) = value.Xq\n\"\"\"Get [`SalientPoleMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::SalientPoleMachine) = value.Xd_p\n\"\"\"Get [`SalientPoleMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::SalientPoleMachine) = value.Xd_pp\n\"\"\"Get [`SalientPoleMachine`](@ref) `Xl`.\"\"\"\nget_Xl(value::SalientPoleMachine) = value.Xl\n\"\"\"Get [`SalientPoleMachine`](@ref) `Se`.\"\"\"\nget_Se(value::SalientPoleMachine) = value.Se\n\"\"\"Get [`SalientPoleMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SalientPoleMachine) = value.ext\n\"\"\"Get [`SalientPoleMachine`](@ref) `γ_d1`.\"\"\"\nget_γ_d1(value::SalientPoleMachine) = value.γ_d1\n\"\"\"Get [`SalientPoleMachine`](@ref) `γ_q1`.\"\"\"\nget_γ_q1(value::SalientPoleMachine) = value.γ_q1\n\"\"\"Get [`SalientPoleMachine`](@ref) `γ_d2`.\"\"\"\nget_γ_d2(value::SalientPoleMachine) = value.γ_d2\n\"\"\"Get [`SalientPoleMachine`](@ref) `states`.\"\"\"\nget_states(value::SalientPoleMachine) = value.states\n\"\"\"Get [`SalientPoleMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SalientPoleMachine) = value.n_states\n\"\"\"Get [`SalientPoleMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SalientPoleMachine) = value.internal\n\n\"\"\"Set [`SalientPoleMachine`](@ref) `R`.\"\"\"\nset_R!(value::SalientPoleMachine, val) = value.R = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::SalientPoleMachine, val) = value.Td0_p = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::SalientPoleMachine, val) = value.Td0_pp = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::SalientPoleMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::SalientPoleMachine, val) = value.Xd = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::SalientPoleMachine, val) = value.Xq = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::SalientPoleMachine, val) = value.Xd_p = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::SalientPoleMachine, val) = value.Xd_pp = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Xl`.\"\"\"\nset_Xl!(value::SalientPoleMachine, val) = value.Xl = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `Se`.\"\"\"\nset_Se!(value::SalientPoleMachine, val) = value.Se = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SalientPoleMachine, val) = value.ext = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `γ_d1`.\"\"\"\nset_γ_d1!(value::SalientPoleMachine, val) = value.γ_d1 = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `γ_q1`.\"\"\"\nset_γ_q1!(value::SalientPoleMachine, val) = value.γ_q1 = val\n\"\"\"Set [`SalientPoleMachine`](@ref) `γ_d2`.\"\"\"\nset_γ_d2!(value::SalientPoleMachine, val) = value.γ_d2 = val\n"
  },
  {
    "path": "src/models/generated/SaturationOutputCurrentLimiter.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SaturationOutputCurrentLimiter <: OutputCurrentLimiter\n        I_max::Float64\n        kw::Float64\n        ext::Dict{String, Any}\n    end\n\nParameters of Saturation Current Controller Limiter. Regulates the magnitude of the inverter output current, and applies a closed loop feedback regulated by a static gain which provides ant-windup\n\n# Arguments\n- `I_max::Float64`: Maximum limit on current controller input current (device base), validation range: `(0, nothing)`\n- `kw::Float64`: Defined feedback gain, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`)\n\"\"\"\nmutable struct SaturationOutputCurrentLimiter <: OutputCurrentLimiter\n    \"Maximum limit on current controller input current (device base)\"\n    I_max::Float64\n    \"Defined feedback gain\"\n    kw::Float64\n    ext::Dict{String, Any}\nend\n\n\nfunction SaturationOutputCurrentLimiter(; I_max, kw, ext=Dict{String, Any}(), )\n    SaturationOutputCurrentLimiter(I_max, kw, ext, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SaturationOutputCurrentLimiter(::Nothing)\n    SaturationOutputCurrentLimiter(;\n        I_max=0,\n        kw=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SaturationOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nget_I_max(value::SaturationOutputCurrentLimiter) = value.I_max\n\"\"\"Get [`SaturationOutputCurrentLimiter`](@ref) `kw`.\"\"\"\nget_kw(value::SaturationOutputCurrentLimiter) = value.kw\n\"\"\"Get [`SaturationOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nget_ext(value::SaturationOutputCurrentLimiter) = value.ext\n\n\"\"\"Set [`SaturationOutputCurrentLimiter`](@ref) `I_max`.\"\"\"\nset_I_max!(value::SaturationOutputCurrentLimiter, val) = value.I_max = val\n\"\"\"Set [`SaturationOutputCurrentLimiter`](@ref) `kw`.\"\"\"\nset_kw!(value::SaturationOutputCurrentLimiter, val) = value.kw = val\n\"\"\"Set [`SaturationOutputCurrentLimiter`](@ref) `ext`.\"\"\"\nset_ext!(value::SaturationOutputCurrentLimiter, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/SauerPaiMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SauerPaiMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xq_pp::Float64\n        Xl::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        ext::Dict{String, Any}\n        γ_d1::Float64\n        γ_q1::Float64\n        γ_d2::Float64\n        γ_q2::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of synchronous machine: Sauer Pai model\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xl::Float64`: Stator Leakage Reactance, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `γ_d1::Float64`: (**Do not modify.**) Internal equation\n- `γ_q1::Float64`: (**Do not modify.**) Internal equation\n- `γ_d2::Float64`: (**Do not modify.**) Internal equation\n- `γ_q2::Float64`: (**Do not modify.**) Internal equation\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage\n\tψd_pp: subtransient flux linkage in the d-axis\n\tψq_pp: subtransient flux linkage in the q-axis\n- `n_states::Int`: (**Do not modify.**) SauerPaiMachine has 6 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SauerPaiMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit\"\n    Xd_pp::Float64\n    \"Sub-Transient reactance after EMF in q-axis per unit\"\n    Xq_pp::Float64\n    \"Stator Leakage Reactance\"\n    Xl::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Internal equation\"\n    γ_d1::Float64\n    \"(**Do not modify.**) Internal equation\"\n    γ_q1::Float64\n    \"(**Do not modify.**) Internal equation\"\n    γ_d2::Float64\n    \"(**Do not modify.**) Internal equation\"\n    γ_q2::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψq: q-axis stator flux,\n\tψd: d-axis stator flux,\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage\n\tψd_pp: subtransient flux linkage in the d-axis\n\tψq_pp: subtransient flux linkage in the q-axis\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SauerPaiMachine has 6 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SauerPaiMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Xl, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), )\n    SauerPaiMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Xl, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, (Xd_pp-Xl)/(Xd_p-Xl), (Xq_pp-Xl)/(Xq_p-Xl), (Xd_p - Xd_pp) / (Xd_p - Xl)^2, (Xq_p - Xq_pp) / (Xq_p - Xl)^2, [:ψq, :ψd, :eq_p, :ed_p, :ψd_pp, :ψq_pp], 6, InfrastructureSystemsInternal(), )\nend\n\nfunction SauerPaiMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Xl, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), γ_d1=(Xd_pp-Xl)/(Xd_p-Xl), γ_q1=(Xq_pp-Xl)/(Xq_p-Xl), γ_d2=(Xd_p - Xd_pp) / (Xd_p - Xl)^2, γ_q2=(Xq_p - Xq_pp) / (Xq_p - Xl)^2, states=[:ψq, :ψd, :eq_p, :ed_p, :ψd_pp, :ψq_pp], n_states=6, internal=InfrastructureSystemsInternal(), )\n    SauerPaiMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Xl, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, γ_d1, γ_q1, γ_d2, γ_q2, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SauerPaiMachine(::Nothing)\n    SauerPaiMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xq_pp=0,\n        Xl=0,\n        Td0_p=0,\n        Tq0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SauerPaiMachine`](@ref) `R`.\"\"\"\nget_R(value::SauerPaiMachine) = value.R\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::SauerPaiMachine) = value.Xd\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::SauerPaiMachine) = value.Xq\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::SauerPaiMachine) = value.Xd_p\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::SauerPaiMachine) = value.Xq_p\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::SauerPaiMachine) = value.Xd_pp\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xq_pp`.\"\"\"\nget_Xq_pp(value::SauerPaiMachine) = value.Xq_pp\n\"\"\"Get [`SauerPaiMachine`](@ref) `Xl`.\"\"\"\nget_Xl(value::SauerPaiMachine) = value.Xl\n\"\"\"Get [`SauerPaiMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::SauerPaiMachine) = value.Td0_p\n\"\"\"Get [`SauerPaiMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::SauerPaiMachine) = value.Tq0_p\n\"\"\"Get [`SauerPaiMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::SauerPaiMachine) = value.Td0_pp\n\"\"\"Get [`SauerPaiMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::SauerPaiMachine) = value.Tq0_pp\n\"\"\"Get [`SauerPaiMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SauerPaiMachine) = value.ext\n\"\"\"Get [`SauerPaiMachine`](@ref) `γ_d1`.\"\"\"\nget_γ_d1(value::SauerPaiMachine) = value.γ_d1\n\"\"\"Get [`SauerPaiMachine`](@ref) `γ_q1`.\"\"\"\nget_γ_q1(value::SauerPaiMachine) = value.γ_q1\n\"\"\"Get [`SauerPaiMachine`](@ref) `γ_d2`.\"\"\"\nget_γ_d2(value::SauerPaiMachine) = value.γ_d2\n\"\"\"Get [`SauerPaiMachine`](@ref) `γ_q2`.\"\"\"\nget_γ_q2(value::SauerPaiMachine) = value.γ_q2\n\"\"\"Get [`SauerPaiMachine`](@ref) `states`.\"\"\"\nget_states(value::SauerPaiMachine) = value.states\n\"\"\"Get [`SauerPaiMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SauerPaiMachine) = value.n_states\n\"\"\"Get [`SauerPaiMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SauerPaiMachine) = value.internal\n\n\"\"\"Set [`SauerPaiMachine`](@ref) `R`.\"\"\"\nset_R!(value::SauerPaiMachine, val) = value.R = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::SauerPaiMachine, val) = value.Xd = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::SauerPaiMachine, val) = value.Xq = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::SauerPaiMachine, val) = value.Xd_p = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::SauerPaiMachine, val) = value.Xq_p = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::SauerPaiMachine, val) = value.Xd_pp = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xq_pp`.\"\"\"\nset_Xq_pp!(value::SauerPaiMachine, val) = value.Xq_pp = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Xl`.\"\"\"\nset_Xl!(value::SauerPaiMachine, val) = value.Xl = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::SauerPaiMachine, val) = value.Td0_p = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::SauerPaiMachine, val) = value.Tq0_p = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::SauerPaiMachine, val) = value.Td0_pp = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::SauerPaiMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SauerPaiMachine, val) = value.ext = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `γ_d1`.\"\"\"\nset_γ_d1!(value::SauerPaiMachine, val) = value.γ_d1 = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `γ_q1`.\"\"\"\nset_γ_q1!(value::SauerPaiMachine, val) = value.γ_q1 = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `γ_d2`.\"\"\"\nset_γ_d2!(value::SauerPaiMachine, val) = value.γ_d2 = val\n\"\"\"Set [`SauerPaiMachine`](@ref) `γ_q2`.\"\"\"\nset_γ_q2!(value::SauerPaiMachine, val) = value.γ_q2 = val\n"
  },
  {
    "path": "src/models/generated/ShiftablePowerLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ShiftablePowerLoad <: ControllableLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        active_power_limits::MinMax\n        reactive_power::Float64\n        max_active_power::Float64\n        max_reactive_power::Float64\n        base_power::Float64\n        load_balance_time_horizon::Int\n        operation_cost::Union{LoadCost, MarketBidCost}\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA [static](@ref S) power load that can be partially or completed shifted to later time periods.\n\n These loads are used to model demand response. This load has a target demand profile (set by a [`max_active_power` time series](@ref ts_data) for an operational simulation). Load in the profile can be shifted to later time periods to aid in satisfying other system needs; however, any shifted load must be served within a designated time horizon (e.g., 24 hours), which is set by `load_balance_time_horizon`.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial steady state active power demand (MW)\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW)\n- `reactive_power::Float64`: Initial steady state reactive power demand (MVAR)\n- `max_active_power::Float64`: Maximum active power (MW) that this load can demand\n- `max_reactive_power::Float64`: Maximum reactive power (MVAR) that this load can demand\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `load_balance_time_horizon::Int`: Number of time periods over which load must be balanced, validation range: `(1, nothing)`\n- `operation_cost::Union{LoadCost, MarketBidCost}`: [`OperationalCost`](@ref) of interrupting load\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ShiftablePowerLoad <: ControllableLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial steady state active power demand (MW)\"\n    active_power::Float64\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Initial steady state reactive power demand (MVAR)\"\n    reactive_power::Float64\n    \"Maximum active power (MW) that this load can demand\"\n    max_active_power::Float64\n    \"Maximum reactive power (MVAR) that this load can demand\"\n    max_reactive_power::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Number of time periods over which load must be balanced\"\n    load_balance_time_horizon::Int\n    \"[`OperationalCost`](@ref) of interrupting load\"\n    operation_cost::Union{LoadCost, MarketBidCost}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ShiftablePowerLoad(name, available, bus, active_power, active_power_limits, reactive_power, max_active_power, max_reactive_power, base_power, load_balance_time_horizon, operation_cost, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    ShiftablePowerLoad(name, available, bus, active_power, active_power_limits, reactive_power, max_active_power, max_reactive_power, base_power, load_balance_time_horizon, operation_cost, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ShiftablePowerLoad(; name, available, bus, active_power, active_power_limits, reactive_power, max_active_power, max_reactive_power, base_power, load_balance_time_horizon, operation_cost, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ShiftablePowerLoad(name, available, bus, active_power, active_power_limits, reactive_power, max_active_power, max_reactive_power, base_power, load_balance_time_horizon, operation_cost, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ShiftablePowerLoad(::Nothing)\n    ShiftablePowerLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power=0.0,\n        max_active_power=0.0,\n        max_reactive_power=0.0,\n        base_power=100.0,\n        load_balance_time_horizon=1,\n        operation_cost=LoadCost(nothing),\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `name`.\"\"\"\nget_name(value::ShiftablePowerLoad) = value.name\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `available`.\"\"\"\nget_available(value::ShiftablePowerLoad) = value.available\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `bus`.\"\"\"\nget_bus(value::ShiftablePowerLoad) = value.bus\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `active_power`.\"\"\"\nget_active_power(value::ShiftablePowerLoad) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::ShiftablePowerLoad) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::ShiftablePowerLoad) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `max_active_power`.\"\"\"\nget_max_active_power(value::ShiftablePowerLoad) = get_value(value, Val(:max_active_power), Val(:mva))\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `max_reactive_power`.\"\"\"\nget_max_reactive_power(value::ShiftablePowerLoad) = get_value(value, Val(:max_reactive_power), Val(:mva))\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::ShiftablePowerLoad) = value.base_power\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `load_balance_time_horizon`.\"\"\"\nget_load_balance_time_horizon(value::ShiftablePowerLoad) = value.load_balance_time_horizon\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::ShiftablePowerLoad) = value.operation_cost\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `services`.\"\"\"\nget_services(value::ShiftablePowerLoad) = value.services\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::ShiftablePowerLoad) = value.dynamic_injector\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `ext`.\"\"\"\nget_ext(value::ShiftablePowerLoad) = value.ext\n\"\"\"Get [`ShiftablePowerLoad`](@ref) `internal`.\"\"\"\nget_internal(value::ShiftablePowerLoad) = value.internal\n\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `available`.\"\"\"\nset_available!(value::ShiftablePowerLoad, val) = value.available = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::ShiftablePowerLoad, val) = value.bus = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `active_power`.\"\"\"\nset_active_power!(value::ShiftablePowerLoad, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::ShiftablePowerLoad, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::ShiftablePowerLoad, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `max_active_power`.\"\"\"\nset_max_active_power!(value::ShiftablePowerLoad, val) = value.max_active_power = set_value(value, Val(:max_active_power), val, Val(:mva))\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `max_reactive_power`.\"\"\"\nset_max_reactive_power!(value::ShiftablePowerLoad, val) = value.max_reactive_power = set_value(value, Val(:max_reactive_power), val, Val(:mva))\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::ShiftablePowerLoad, val) = value.base_power = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `load_balance_time_horizon`.\"\"\"\nset_load_balance_time_horizon!(value::ShiftablePowerLoad, val) = value.load_balance_time_horizon = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::ShiftablePowerLoad, val) = value.operation_cost = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `services`.\"\"\"\nset_services!(value::ShiftablePowerLoad, val) = value.services = val\n\"\"\"Set [`ShiftablePowerLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::ShiftablePowerLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/SimpleAFMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SimpleAFMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xq_pp::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 4-[states](@ref S) simplified Anderson-Fouad (SimpleAFMachine) model.\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when transmission network\n dynamics is neglected.\n If transmission dynamics is considered use the full order Anderson Fouad model\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\n- `n_states::Int`: (**Do not modify.**) SimpleAFMachine has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SimpleAFMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit\"\n    Xd_pp::Float64\n    \"Sub-Transient reactance after EMF in q-axis per unit\"\n    Xq_pp::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SimpleAFMachine has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), )\n    SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, [:eq_p, :ed_p, :eq_pp, :ed_pp], 4, InfrastructureSystemsInternal(), )\nend\n\nfunction SimpleAFMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext=Dict{String, Any}(), states=[:eq_p, :ed_p, :eq_pp, :ed_pp], n_states=4, internal=InfrastructureSystemsInternal(), )\n    SimpleAFMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SimpleAFMachine(::Nothing)\n    SimpleAFMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xq_pp=0,\n        Td0_p=0,\n        Tq0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SimpleAFMachine`](@ref) `R`.\"\"\"\nget_R(value::SimpleAFMachine) = value.R\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::SimpleAFMachine) = value.Xd\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::SimpleAFMachine) = value.Xq\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::SimpleAFMachine) = value.Xd_p\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::SimpleAFMachine) = value.Xq_p\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::SimpleAFMachine) = value.Xd_pp\n\"\"\"Get [`SimpleAFMachine`](@ref) `Xq_pp`.\"\"\"\nget_Xq_pp(value::SimpleAFMachine) = value.Xq_pp\n\"\"\"Get [`SimpleAFMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::SimpleAFMachine) = value.Td0_p\n\"\"\"Get [`SimpleAFMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::SimpleAFMachine) = value.Tq0_p\n\"\"\"Get [`SimpleAFMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::SimpleAFMachine) = value.Td0_pp\n\"\"\"Get [`SimpleAFMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::SimpleAFMachine) = value.Tq0_pp\n\"\"\"Get [`SimpleAFMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SimpleAFMachine) = value.ext\n\"\"\"Get [`SimpleAFMachine`](@ref) `states`.\"\"\"\nget_states(value::SimpleAFMachine) = value.states\n\"\"\"Get [`SimpleAFMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SimpleAFMachine) = value.n_states\n\"\"\"Get [`SimpleAFMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SimpleAFMachine) = value.internal\n\n\"\"\"Set [`SimpleAFMachine`](@ref) `R`.\"\"\"\nset_R!(value::SimpleAFMachine, val) = value.R = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::SimpleAFMachine, val) = value.Xd = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::SimpleAFMachine, val) = value.Xq = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::SimpleAFMachine, val) = value.Xd_p = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::SimpleAFMachine, val) = value.Xq_p = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::SimpleAFMachine, val) = value.Xd_pp = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Xq_pp`.\"\"\"\nset_Xq_pp!(value::SimpleAFMachine, val) = value.Xq_pp = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::SimpleAFMachine, val) = value.Td0_p = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::SimpleAFMachine, val) = value.Tq0_p = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::SimpleAFMachine, val) = value.Td0_pp = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::SimpleAFMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`SimpleAFMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SimpleAFMachine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/SimpleFullMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SimpleFullMachine <: Machine\n        R::Float64\n        R_f::Float64\n        R_1d::Float64\n        R_1q::Float64\n        L_d::Float64\n        L_q::Float64\n        L_ad::Float64\n        L_aq::Float64\n        L_f1d::Float64\n        L_ff::Float64\n        L_1d::Float64\n        L_1q::Float64\n        ext::Dict{String, Any}\n        inv_d_fluxlink::Array{Float64,2}\n        inv_q_fluxlink::Array{Float64,2}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameter of a full order flux stator-rotor model without zero sequence flux in the stator.\n The derivative of stator fluxes (ψd and ψq) is neglected. This is standard when\n transmission network dynamics is neglected. Only one q-axis damping circuit\n is considered. All per unit are in machine per unit.\n Refer to Chapter 3 of Power System Stability and Control by P. Kundur or Chapter 11 of Power System Dynamics: Stability and Control, by J. Machowski, J. Bialek and J. Bumby, for more details.\n Note that the models are somewhat different (but equivalent) due to the different Park Transformation used in both books\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `R_f::Float64`: Field rotor winding resistance in per unit, validation range: `(0, nothing)`\n- `R_1d::Float64`:  Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski, validation range: `(0, nothing)`\n- `R_1q::Float64`: Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski, validation range: `(0, nothing)`\n- `L_d::Float64`: Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski), validation range: `(0, nothing)`\n- `L_q::Float64`: Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur, validation range: `(0, nothing)`\n- `L_ad::Float64`: Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit, validation range: `(0, nothing)`\n- `L_aq::Float64`: Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit, validation range: `(0, nothing)`\n- `L_f1d::Float64`: Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit, validation range: `(0, nothing)`\n- `L_ff::Float64`: Field rotor winding inductance, in per unit, validation range: `(0, nothing)`\n- `L_1d::Float64`: Inductance of the d-axis rotor damping circuit, in per unit, validation range: `(0, nothing)`\n- `L_1q::Float64`: Inductance of the q-axis rotor damping circuit, in per unit, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `inv_d_fluxlink::Array{Float64,2}`: (**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\n- `inv_q_fluxlink::Array{Float64,2}`: (**Do not modify.**) Equations 3.128, 3.132 From Kundur\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψf: field rotor flux,\n\tψ1d: d-axis rotor damping flux,\n\tψ1q: q-axis rotor damping flux\n- `n_states::Int`: (**Do not modify.**) SimpleFullMachine has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SimpleFullMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Field rotor winding resistance in per unit\"\n    R_f::Float64\n    \" Damping rotor winding resistance on d-axis in per unit. This value is denoted as RD in Machowski\"\n    R_1d::Float64\n    \"Damping rotor winding resistance on q-axis in per unit. This value is denoted as RQ in Machowski\"\n    R_1q::Float64\n    \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the d-axis of the rotor, in per unit. This value is denoted as L_ad + L_l in Kundur (and Ld in Machowski)\"\n    L_d::Float64\n    \"Inductance of fictitious damping that represent the effect of the three-phase stator winding in the q-axis of the rotor, in per unit. This value is denoted as L_aq + L_l in Kundur\"\n    L_q::Float64\n    \"Mutual inductance between stator winding and rotor field (and damping) winding inductance on d-axis, in per unit\"\n    L_ad::Float64\n    \"Mutual inductance between stator winding and rotor damping winding inductance on q-axis, in per unit\"\n    L_aq::Float64\n    \"Mutual inductance between rotor field winding and rotor damping winding inductance on d-axis, in per unit\"\n    L_f1d::Float64\n    \"Field rotor winding inductance, in per unit\"\n    L_ff::Float64\n    \"Inductance of the d-axis rotor damping circuit, in per unit\"\n    L_1d::Float64\n    \"Inductance of the q-axis rotor damping circuit, in per unit\"\n    L_1q::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Equations 3.127, 3.130, 3.131 From Kundur\"\n    inv_d_fluxlink::Array{Float64,2}\n    \"(**Do not modify.**) Equations 3.128, 3.132 From Kundur\"\n    inv_q_fluxlink::Array{Float64,2}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψf: field rotor flux,\n\tψ1d: d-axis rotor damping flux,\n\tψ1q: q-axis rotor damping flux\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SimpleFullMachine has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SimpleFullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext=Dict{String, Any}(), )\n    SimpleFullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext, inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]]), inv([[-L_q L_aq]; [-L_aq L_1q]]), [:ψf, :ψ1d, :ψ1q], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction SimpleFullMachine(; R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext=Dict{String, Any}(), inv_d_fluxlink=inv([[-L_d L_ad L_ad]; [-L_ad L_ff L_f1d]; [-L_ad L_f1d L_1d]]), inv_q_fluxlink=inv([[-L_q L_aq]; [-L_aq L_1q]]), states=[:ψf, :ψ1d, :ψ1q], n_states=3, internal=InfrastructureSystemsInternal(), )\n    SimpleFullMachine(R, R_f, R_1d, R_1q, L_d, L_q, L_ad, L_aq, L_f1d, L_ff, L_1d, L_1q, ext, inv_d_fluxlink, inv_q_fluxlink, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SimpleFullMachine(::Nothing)\n    SimpleFullMachine(;\n        R=0,\n        R_f=0,\n        R_1d=0,\n        R_1q=0,\n        L_d=1,\n        L_q=1,\n        L_ad=2,\n        L_aq=1,\n        L_f1d=1,\n        L_ff=2,\n        L_1d=1,\n        L_1q=2,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SimpleFullMachine`](@ref) `R`.\"\"\"\nget_R(value::SimpleFullMachine) = value.R\n\"\"\"Get [`SimpleFullMachine`](@ref) `R_f`.\"\"\"\nget_R_f(value::SimpleFullMachine) = value.R_f\n\"\"\"Get [`SimpleFullMachine`](@ref) `R_1d`.\"\"\"\nget_R_1d(value::SimpleFullMachine) = value.R_1d\n\"\"\"Get [`SimpleFullMachine`](@ref) `R_1q`.\"\"\"\nget_R_1q(value::SimpleFullMachine) = value.R_1q\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_d`.\"\"\"\nget_L_d(value::SimpleFullMachine) = value.L_d\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_q`.\"\"\"\nget_L_q(value::SimpleFullMachine) = value.L_q\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_ad`.\"\"\"\nget_L_ad(value::SimpleFullMachine) = value.L_ad\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_aq`.\"\"\"\nget_L_aq(value::SimpleFullMachine) = value.L_aq\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_f1d`.\"\"\"\nget_L_f1d(value::SimpleFullMachine) = value.L_f1d\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_ff`.\"\"\"\nget_L_ff(value::SimpleFullMachine) = value.L_ff\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_1d`.\"\"\"\nget_L_1d(value::SimpleFullMachine) = value.L_1d\n\"\"\"Get [`SimpleFullMachine`](@ref) `L_1q`.\"\"\"\nget_L_1q(value::SimpleFullMachine) = value.L_1q\n\"\"\"Get [`SimpleFullMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SimpleFullMachine) = value.ext\n\"\"\"Get [`SimpleFullMachine`](@ref) `inv_d_fluxlink`.\"\"\"\nget_inv_d_fluxlink(value::SimpleFullMachine) = value.inv_d_fluxlink\n\"\"\"Get [`SimpleFullMachine`](@ref) `inv_q_fluxlink`.\"\"\"\nget_inv_q_fluxlink(value::SimpleFullMachine) = value.inv_q_fluxlink\n\"\"\"Get [`SimpleFullMachine`](@ref) `states`.\"\"\"\nget_states(value::SimpleFullMachine) = value.states\n\"\"\"Get [`SimpleFullMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SimpleFullMachine) = value.n_states\n\"\"\"Get [`SimpleFullMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SimpleFullMachine) = value.internal\n\n\"\"\"Set [`SimpleFullMachine`](@ref) `R`.\"\"\"\nset_R!(value::SimpleFullMachine, val) = value.R = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `R_f`.\"\"\"\nset_R_f!(value::SimpleFullMachine, val) = value.R_f = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `R_1d`.\"\"\"\nset_R_1d!(value::SimpleFullMachine, val) = value.R_1d = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `R_1q`.\"\"\"\nset_R_1q!(value::SimpleFullMachine, val) = value.R_1q = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_d`.\"\"\"\nset_L_d!(value::SimpleFullMachine, val) = value.L_d = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_q`.\"\"\"\nset_L_q!(value::SimpleFullMachine, val) = value.L_q = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_ad`.\"\"\"\nset_L_ad!(value::SimpleFullMachine, val) = value.L_ad = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_aq`.\"\"\"\nset_L_aq!(value::SimpleFullMachine, val) = value.L_aq = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_f1d`.\"\"\"\nset_L_f1d!(value::SimpleFullMachine, val) = value.L_f1d = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_ff`.\"\"\"\nset_L_ff!(value::SimpleFullMachine, val) = value.L_ff = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_1d`.\"\"\"\nset_L_1d!(value::SimpleFullMachine, val) = value.L_1d = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `L_1q`.\"\"\"\nset_L_1q!(value::SimpleFullMachine, val) = value.L_1q = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SimpleFullMachine, val) = value.ext = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `inv_d_fluxlink`.\"\"\"\nset_inv_d_fluxlink!(value::SimpleFullMachine, val) = value.inv_d_fluxlink = val\n\"\"\"Set [`SimpleFullMachine`](@ref) `inv_q_fluxlink`.\"\"\"\nset_inv_q_fluxlink!(value::SimpleFullMachine, val) = value.inv_q_fluxlink = val\n"
  },
  {
    "path": "src/models/generated/SimpleMarconatoMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SimpleMarconatoMachine <: Machine\n        R::Float64\n        Xd::Float64\n        Xq::Float64\n        Xd_p::Float64\n        Xq_p::Float64\n        Xd_pp::Float64\n        Xq_pp::Float64\n        Td0_p::Float64\n        Tq0_p::Float64\n        Td0_pp::Float64\n        Tq0_pp::Float64\n        T_AA::Float64\n        ext::Dict{String, Any}\n        γd::Float64\n        γq::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 4-[states](@ref S) synchronous machine: Simplified Marconato model\n The derivative of stator fluxes (ψd and ψq) is neglected and ωψd = ψd and\n ωψq = ψq is assumed (i.e. ω=1.0). This is standard when transmission network\n dynamics is neglected\n\n# Arguments\n- `R::Float64`: Resistance after EMF in machine per unit, validation range: `(0, nothing)`\n- `Xd::Float64`: Reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq::Float64`: Reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_p::Float64`: Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_p::Float64`: Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Xd_pp::Float64`: Sub-Transient reactance after EMF in d-axis per unit, validation range: `(0, nothing)`\n- `Xq_pp::Float64`: Sub-Transient reactance after EMF in q-axis per unit, validation range: `(0, nothing)`\n- `Td0_p::Float64`: Time constant of transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_p::Float64`: Time constant of transient q-axis voltage, validation range: `(0, nothing)`\n- `Td0_pp::Float64`: Time constant of sub-transient d-axis voltage, validation range: `(0, nothing)`\n- `Tq0_pp::Float64`: Time constant of sub-transient q-axis voltage, validation range: `(0, nothing)`\n- `T_AA::Float64`: Time constant of d-axis additional leakage, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `γd::Float64`: (**Do not modify.**) Internal equation\n- `γq::Float64`: (**Do not modify.**) Internal equation\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\n- `n_states::Int`: (**Do not modify.**) SimpleMarconatoMachine has 4 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SimpleMarconatoMachine <: Machine\n    \"Resistance after EMF in machine per unit\"\n    R::Float64\n    \"Reactance after EMF in d-axis per unit\"\n    Xd::Float64\n    \"Reactance after EMF in q-axis per unit\"\n    Xq::Float64\n    \"Transient reactance after EMF in d-axis per unit\"\n    Xd_p::Float64\n    \"Transient reactance after EMF in q-axis per unit\"\n    Xq_p::Float64\n    \"Sub-Transient reactance after EMF in d-axis per unit\"\n    Xd_pp::Float64\n    \"Sub-Transient reactance after EMF in q-axis per unit\"\n    Xq_pp::Float64\n    \"Time constant of transient d-axis voltage\"\n    Td0_p::Float64\n    \"Time constant of transient q-axis voltage\"\n    Tq0_p::Float64\n    \"Time constant of sub-transient d-axis voltage\"\n    Td0_pp::Float64\n    \"Time constant of sub-transient q-axis voltage\"\n    Tq0_pp::Float64\n    \"Time constant of d-axis additional leakage\"\n    T_AA::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Internal equation\"\n    γd::Float64\n    \"(**Do not modify.**) Internal equation\"\n    γq::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\teq_p: q-axis transient voltage,\n\ted_p: d-axis transient voltage,\n\teq_pp: q-axis subtransient voltage,\n\ted_pp: d-axis subtransient voltage\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SimpleMarconatoMachine has 4 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SimpleMarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext=Dict{String, Any}(), )\n    SimpleMarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext, ((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p), ((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p), [:eq_p, :ed_p, :eq_pp, :ed_pp], 4, InfrastructureSystemsInternal(), )\nend\n\nfunction SimpleMarconatoMachine(; R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext=Dict{String, Any}(), γd=((Td0_pp*Xd_pp)/(Td0_p*Xd_p) )*(Xd-Xd_p), γq=((Tq0_pp*Xq_pp)/(Tq0_p*Xq_p) )*(Xq-Xq_p), states=[:eq_p, :ed_p, :eq_pp, :ed_pp], n_states=4, internal=InfrastructureSystemsInternal(), )\n    SimpleMarconatoMachine(R, Xd, Xq, Xd_p, Xq_p, Xd_pp, Xq_pp, Td0_p, Tq0_p, Td0_pp, Tq0_pp, T_AA, ext, γd, γq, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SimpleMarconatoMachine(::Nothing)\n    SimpleMarconatoMachine(;\n        R=0,\n        Xd=0,\n        Xq=0,\n        Xd_p=0,\n        Xq_p=0,\n        Xd_pp=0,\n        Xq_pp=0,\n        Td0_p=0,\n        Tq0_p=0,\n        Td0_pp=0,\n        Tq0_pp=0,\n        T_AA=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `R`.\"\"\"\nget_R(value::SimpleMarconatoMachine) = value.R\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xd`.\"\"\"\nget_Xd(value::SimpleMarconatoMachine) = value.Xd\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xq`.\"\"\"\nget_Xq(value::SimpleMarconatoMachine) = value.Xq\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xd_p`.\"\"\"\nget_Xd_p(value::SimpleMarconatoMachine) = value.Xd_p\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xq_p`.\"\"\"\nget_Xq_p(value::SimpleMarconatoMachine) = value.Xq_p\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xd_pp`.\"\"\"\nget_Xd_pp(value::SimpleMarconatoMachine) = value.Xd_pp\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Xq_pp`.\"\"\"\nget_Xq_pp(value::SimpleMarconatoMachine) = value.Xq_pp\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Td0_p`.\"\"\"\nget_Td0_p(value::SimpleMarconatoMachine) = value.Td0_p\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Tq0_p`.\"\"\"\nget_Tq0_p(value::SimpleMarconatoMachine) = value.Tq0_p\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Td0_pp`.\"\"\"\nget_Td0_pp(value::SimpleMarconatoMachine) = value.Td0_pp\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `Tq0_pp`.\"\"\"\nget_Tq0_pp(value::SimpleMarconatoMachine) = value.Tq0_pp\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `T_AA`.\"\"\"\nget_T_AA(value::SimpleMarconatoMachine) = value.T_AA\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SimpleMarconatoMachine) = value.ext\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `γd`.\"\"\"\nget_γd(value::SimpleMarconatoMachine) = value.γd\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `γq`.\"\"\"\nget_γq(value::SimpleMarconatoMachine) = value.γq\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `states`.\"\"\"\nget_states(value::SimpleMarconatoMachine) = value.states\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SimpleMarconatoMachine) = value.n_states\n\"\"\"Get [`SimpleMarconatoMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SimpleMarconatoMachine) = value.internal\n\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `R`.\"\"\"\nset_R!(value::SimpleMarconatoMachine, val) = value.R = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xd`.\"\"\"\nset_Xd!(value::SimpleMarconatoMachine, val) = value.Xd = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xq`.\"\"\"\nset_Xq!(value::SimpleMarconatoMachine, val) = value.Xq = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xd_p`.\"\"\"\nset_Xd_p!(value::SimpleMarconatoMachine, val) = value.Xd_p = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xq_p`.\"\"\"\nset_Xq_p!(value::SimpleMarconatoMachine, val) = value.Xq_p = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xd_pp`.\"\"\"\nset_Xd_pp!(value::SimpleMarconatoMachine, val) = value.Xd_pp = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Xq_pp`.\"\"\"\nset_Xq_pp!(value::SimpleMarconatoMachine, val) = value.Xq_pp = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Td0_p`.\"\"\"\nset_Td0_p!(value::SimpleMarconatoMachine, val) = value.Td0_p = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Tq0_p`.\"\"\"\nset_Tq0_p!(value::SimpleMarconatoMachine, val) = value.Tq0_p = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Td0_pp`.\"\"\"\nset_Td0_pp!(value::SimpleMarconatoMachine, val) = value.Td0_pp = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `Tq0_pp`.\"\"\"\nset_Tq0_pp!(value::SimpleMarconatoMachine, val) = value.Tq0_pp = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `T_AA`.\"\"\"\nset_T_AA!(value::SimpleMarconatoMachine, val) = value.T_AA = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SimpleMarconatoMachine, val) = value.ext = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `γd`.\"\"\"\nset_γd!(value::SimpleMarconatoMachine, val) = value.γd = val\n\"\"\"Set [`SimpleMarconatoMachine`](@ref) `γq`.\"\"\"\nset_γq!(value::SimpleMarconatoMachine, val) = value.γq = val\n"
  },
  {
    "path": "src/models/generated/SimplifiedSingleCageInductionMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SimplifiedSingleCageInductionMachine <: DynamicInjection\n        name::String\n        R_s::Float64\n        R_r::Float64\n        X_ls::Float64\n        X_lr::Float64\n        X_m::Float64\n        H::Float64\n        A::Float64\n        B::Float64\n        base_power::Float64\n        ext::Dict{String, Any}\n        C::Float64\n        τ_ref::Float64\n        B_shunt::Float64\n        X_ss::Float64\n        X_rr::Float64\n        X_p::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 3-states three-phase single cage induction machine with quadratic torque-speed relationship\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `R_s::Float64`: Armature stator resistance, validation range: `(0, nothing)`\n- `R_r::Float64`: Rotor resistance, validation range: `(0, nothing)`\n- `X_ls::Float64`: Stator Leakage Reactance, validation range: `(0, nothing)`\n- `X_lr::Float64`: Rotor Leakage Reactance, validation range: `(0, nothing)`\n- `X_m::Float64`: Stator-Rotor Mutual Reactance, validation range: `(0, nothing)`\n- `H::Float64`: Motor Inertia Constant [s], validation range: `(0, nothing)`\n- `A::Float64`: Torque-Speed Quadratic Term, validation range: `(0, 1)`\n- `B::Float64`: Torque-Speed Linear Term, validation range: `(0, 1)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `C::Float64`: (**Do not modify.**) Torque-Speed Constant Term\n- `τ_ref::Float64`: Reference torque parameter\n- `B_shunt::Float64`: Susceptance Initialization Corrector Term\n- `X_ss::Float64`: (**Do not modify.**) Stator self reactance\n- `X_rr::Float64`: (**Do not modify.**) Rotor self reactance\n- `X_p::Float64`: (**Do not modify.**) Transient reactance\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψ_qr: rotor flux in the q-axis,\n\tψ_dr: rotor flux in the d-axis, \n\tωr: Rotor speed [pu],\n- `n_states::Int`: (**Do not modify.**) SimplifiedSingleCageInductionMachine has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SimplifiedSingleCageInductionMachine <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Armature stator resistance\"\n    R_s::Float64\n    \"Rotor resistance\"\n    R_r::Float64\n    \"Stator Leakage Reactance\"\n    X_ls::Float64\n    \"Rotor Leakage Reactance\"\n    X_lr::Float64\n    \"Stator-Rotor Mutual Reactance\"\n    X_m::Float64\n    \"Motor Inertia Constant [s]\"\n    H::Float64\n    \"Torque-Speed Quadratic Term\"\n    A::Float64\n    \"Torque-Speed Linear Term\"\n    B::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Torque-Speed Constant Term\"\n    C::Float64\n    \"Reference torque parameter\"\n    τ_ref::Float64\n    \"Susceptance Initialization Corrector Term\"\n    B_shunt::Float64\n    \"(**Do not modify.**) Stator self reactance\"\n    X_ss::Float64\n    \"(**Do not modify.**) Rotor self reactance\"\n    X_rr::Float64\n    \"(**Do not modify.**) Transient reactance\"\n    X_p::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψ_qr: rotor flux in the q-axis,\n\tψ_dr: rotor flux in the d-axis, \n\tωr: Rotor speed [pu],\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SimplifiedSingleCageInductionMachine has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SimplifiedSingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext=Dict{String, Any}(), )\n    SimplifiedSingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext, PowerSystems.calculate_IM_torque_params(A, B), 1.0, 0.0, X_ls + X_m, X_lr + X_m, X_ss - X_m^2 / X_rr, [:ψ_qr, :ψ_dr, :ωr], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction SimplifiedSingleCageInductionMachine(; name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext=Dict{String, Any}(), C=PowerSystems.calculate_IM_torque_params(A, B), τ_ref=1.0, B_shunt=0.0, X_ss=X_ls + X_m, X_rr=X_lr + X_m, X_p=X_ss - X_m^2 / X_rr, states=[:ψ_qr, :ψ_dr, :ωr], n_states=3, internal=InfrastructureSystemsInternal(), )\n    SimplifiedSingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext, C, τ_ref, B_shunt, X_ss, X_rr, X_p, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SimplifiedSingleCageInductionMachine(::Nothing)\n    SimplifiedSingleCageInductionMachine(;\n        name=\"init\",\n        R_s=0,\n        R_r=0,\n        X_ls=0,\n        X_lr=0,\n        X_m=0,\n        H=0,\n        A=0.0,\n        B=0.0,\n        base_power=100,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `name`.\"\"\"\nget_name(value::SimplifiedSingleCageInductionMachine) = value.name\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `R_s`.\"\"\"\nget_R_s(value::SimplifiedSingleCageInductionMachine) = value.R_s\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `R_r`.\"\"\"\nget_R_r(value::SimplifiedSingleCageInductionMachine) = value.R_r\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_ls`.\"\"\"\nget_X_ls(value::SimplifiedSingleCageInductionMachine) = value.X_ls\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_lr`.\"\"\"\nget_X_lr(value::SimplifiedSingleCageInductionMachine) = value.X_lr\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_m`.\"\"\"\nget_X_m(value::SimplifiedSingleCageInductionMachine) = value.X_m\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `H`.\"\"\"\nget_H(value::SimplifiedSingleCageInductionMachine) = value.H\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `A`.\"\"\"\nget_A(value::SimplifiedSingleCageInductionMachine) = value.A\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `B`.\"\"\"\nget_B(value::SimplifiedSingleCageInductionMachine) = value.B\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `base_power`.\"\"\"\nget_base_power(value::SimplifiedSingleCageInductionMachine) = value.base_power\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SimplifiedSingleCageInductionMachine) = value.ext\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `C`.\"\"\"\nget_C(value::SimplifiedSingleCageInductionMachine) = value.C\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `τ_ref`.\"\"\"\nget_τ_ref(value::SimplifiedSingleCageInductionMachine) = value.τ_ref\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `B_shunt`.\"\"\"\nget_B_shunt(value::SimplifiedSingleCageInductionMachine) = value.B_shunt\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_ss`.\"\"\"\nget_X_ss(value::SimplifiedSingleCageInductionMachine) = value.X_ss\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_rr`.\"\"\"\nget_X_rr(value::SimplifiedSingleCageInductionMachine) = value.X_rr\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `X_p`.\"\"\"\nget_X_p(value::SimplifiedSingleCageInductionMachine) = value.X_p\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `states`.\"\"\"\nget_states(value::SimplifiedSingleCageInductionMachine) = value.states\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SimplifiedSingleCageInductionMachine) = value.n_states\n\"\"\"Get [`SimplifiedSingleCageInductionMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SimplifiedSingleCageInductionMachine) = value.internal\n\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `R_s`.\"\"\"\nset_R_s!(value::SimplifiedSingleCageInductionMachine, val) = value.R_s = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `R_r`.\"\"\"\nset_R_r!(value::SimplifiedSingleCageInductionMachine, val) = value.R_r = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_ls`.\"\"\"\nset_X_ls!(value::SimplifiedSingleCageInductionMachine, val) = value.X_ls = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_lr`.\"\"\"\nset_X_lr!(value::SimplifiedSingleCageInductionMachine, val) = value.X_lr = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_m`.\"\"\"\nset_X_m!(value::SimplifiedSingleCageInductionMachine, val) = value.X_m = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `H`.\"\"\"\nset_H!(value::SimplifiedSingleCageInductionMachine, val) = value.H = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `A`.\"\"\"\nset_A!(value::SimplifiedSingleCageInductionMachine, val) = value.A = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `B`.\"\"\"\nset_B!(value::SimplifiedSingleCageInductionMachine, val) = value.B = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `base_power`.\"\"\"\nset_base_power!(value::SimplifiedSingleCageInductionMachine, val) = value.base_power = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SimplifiedSingleCageInductionMachine, val) = value.ext = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `C`.\"\"\"\nset_C!(value::SimplifiedSingleCageInductionMachine, val) = value.C = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `τ_ref`.\"\"\"\nset_τ_ref!(value::SimplifiedSingleCageInductionMachine, val) = value.τ_ref = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `B_shunt`.\"\"\"\nset_B_shunt!(value::SimplifiedSingleCageInductionMachine, val) = value.B_shunt = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_ss`.\"\"\"\nset_X_ss!(value::SimplifiedSingleCageInductionMachine, val) = value.X_ss = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_rr`.\"\"\"\nset_X_rr!(value::SimplifiedSingleCageInductionMachine, val) = value.X_rr = val\n\"\"\"Set [`SimplifiedSingleCageInductionMachine`](@ref) `X_p`.\"\"\"\nset_X_p!(value::SimplifiedSingleCageInductionMachine, val) = value.X_p = val\n"
  },
  {
    "path": "src/models/generated/SingleCageInductionMachine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SingleCageInductionMachine <: DynamicInjection\n        name::String\n        R_s::Float64\n        R_r::Float64\n        X_ls::Float64\n        X_lr::Float64\n        X_m::Float64\n        H::Float64\n        A::Float64\n        B::Float64\n        base_power::Float64\n        ext::Dict{String, Any}\n        C::Float64\n        τ_ref::Float64\n        B_shunt::Float64\n        X_ad::Float64\n        X_aq::Float64\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of 5-states three-phase single cage induction machine with quadratic torque-speed relationship\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `R_s::Float64`: Armature stator resistance, validation range: `(0, nothing)`\n- `R_r::Float64`: Rotor resistance, validation range: `(0, nothing)`\n- `X_ls::Float64`: Stator Leakage Reactance, validation range: `(0, nothing)`\n- `X_lr::Float64`: Rotor Leakage Reactance, validation range: `(0, nothing)`\n- `X_m::Float64`: Stator-Rotor Mutual Reactance, validation range: `(0, nothing)`\n- `H::Float64`: Motor Inertia Constant [s], validation range: `(0, nothing)`\n- `A::Float64`: Torque-Speed Quadratic Term, validation range: `(0, 1)`\n- `B::Float64`: Torque-Speed Linear Term, validation range: `(0, 1)`\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `C::Float64`: (**Do not modify.**) Torque-Speed Constant Term\n- `τ_ref::Float64`: Reference torque parameter\n- `B_shunt::Float64`: Susceptance Initialization Corrector Term\n- `X_ad::Float64`: (**Do not modify.**) Equivalent d-axis reactance\n- `X_aq::Float64`: (**Do not modify.**) Equivalent q-axis reactance\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tψ_qs: stator flux in the q-axis,\n\tψ_ds: stator flux in the d-axis,\n\tψ_qr: rotor flux in the q-axis,\n\tψ_dr: rotor flux in the d-axis, \n\tωr: Rotor speed [pu],\n- `n_states::Int`: (**Do not modify.**) SingleCageInductionMachine has 5 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SingleCageInductionMachine <: DynamicInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Armature stator resistance\"\n    R_s::Float64\n    \"Rotor resistance\"\n    R_r::Float64\n    \"Stator Leakage Reactance\"\n    X_ls::Float64\n    \"Rotor Leakage Reactance\"\n    X_lr::Float64\n    \"Stator-Rotor Mutual Reactance\"\n    X_m::Float64\n    \"Motor Inertia Constant [s]\"\n    H::Float64\n    \"Torque-Speed Quadratic Term\"\n    A::Float64\n    \"Torque-Speed Linear Term\"\n    B::Float64\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) Torque-Speed Constant Term\"\n    C::Float64\n    \"Reference torque parameter\"\n    τ_ref::Float64\n    \"Susceptance Initialization Corrector Term\"\n    B_shunt::Float64\n    \"(**Do not modify.**) Equivalent d-axis reactance\"\n    X_ad::Float64\n    \"(**Do not modify.**) Equivalent q-axis reactance\"\n    X_aq::Float64\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tψ_qs: stator flux in the q-axis,\n\tψ_ds: stator flux in the d-axis,\n\tψ_qr: rotor flux in the q-axis,\n\tψ_dr: rotor flux in the d-axis, \n\tωr: Rotor speed [pu],\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SingleCageInductionMachine has 5 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext=Dict{String, Any}(), )\n    SingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext, PowerSystems.calculate_IM_torque_params(A, B), 1.0, 0.0, (1.0 / X_m + 1.0 / X_ls + 1.0 / X_lr)^(-1), X_ad, [:ψ_qs, :ψ_ds, :ψ_qr, :ψ_dr, :ωr], 5, InfrastructureSystemsInternal(), )\nend\n\nfunction SingleCageInductionMachine(; name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext=Dict{String, Any}(), C=PowerSystems.calculate_IM_torque_params(A, B), τ_ref=1.0, B_shunt=0.0, X_ad=(1.0 / X_m + 1.0 / X_ls + 1.0 / X_lr)^(-1), X_aq=X_ad, states=[:ψ_qs, :ψ_ds, :ψ_qr, :ψ_dr, :ωr], n_states=5, internal=InfrastructureSystemsInternal(), )\n    SingleCageInductionMachine(name, R_s, R_r, X_ls, X_lr, X_m, H, A, B, base_power, ext, C, τ_ref, B_shunt, X_ad, X_aq, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SingleCageInductionMachine(::Nothing)\n    SingleCageInductionMachine(;\n        name=\"init\",\n        R_s=0,\n        R_r=0,\n        X_ls=0,\n        X_lr=0,\n        X_m=0,\n        H=0,\n        A=0.0,\n        B=0.0,\n        base_power=100,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `name`.\"\"\"\nget_name(value::SingleCageInductionMachine) = value.name\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `R_s`.\"\"\"\nget_R_s(value::SingleCageInductionMachine) = value.R_s\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `R_r`.\"\"\"\nget_R_r(value::SingleCageInductionMachine) = value.R_r\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `X_ls`.\"\"\"\nget_X_ls(value::SingleCageInductionMachine) = value.X_ls\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `X_lr`.\"\"\"\nget_X_lr(value::SingleCageInductionMachine) = value.X_lr\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `X_m`.\"\"\"\nget_X_m(value::SingleCageInductionMachine) = value.X_m\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `H`.\"\"\"\nget_H(value::SingleCageInductionMachine) = value.H\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `A`.\"\"\"\nget_A(value::SingleCageInductionMachine) = value.A\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `B`.\"\"\"\nget_B(value::SingleCageInductionMachine) = value.B\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `base_power`.\"\"\"\nget_base_power(value::SingleCageInductionMachine) = value.base_power\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `ext`.\"\"\"\nget_ext(value::SingleCageInductionMachine) = value.ext\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `C`.\"\"\"\nget_C(value::SingleCageInductionMachine) = value.C\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `τ_ref`.\"\"\"\nget_τ_ref(value::SingleCageInductionMachine) = value.τ_ref\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `B_shunt`.\"\"\"\nget_B_shunt(value::SingleCageInductionMachine) = value.B_shunt\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `X_ad`.\"\"\"\nget_X_ad(value::SingleCageInductionMachine) = value.X_ad\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `X_aq`.\"\"\"\nget_X_aq(value::SingleCageInductionMachine) = value.X_aq\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `states`.\"\"\"\nget_states(value::SingleCageInductionMachine) = value.states\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `n_states`.\"\"\"\nget_n_states(value::SingleCageInductionMachine) = value.n_states\n\"\"\"Get [`SingleCageInductionMachine`](@ref) `internal`.\"\"\"\nget_internal(value::SingleCageInductionMachine) = value.internal\n\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `R_s`.\"\"\"\nset_R_s!(value::SingleCageInductionMachine, val) = value.R_s = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `R_r`.\"\"\"\nset_R_r!(value::SingleCageInductionMachine, val) = value.R_r = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `X_ls`.\"\"\"\nset_X_ls!(value::SingleCageInductionMachine, val) = value.X_ls = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `X_lr`.\"\"\"\nset_X_lr!(value::SingleCageInductionMachine, val) = value.X_lr = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `X_m`.\"\"\"\nset_X_m!(value::SingleCageInductionMachine, val) = value.X_m = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `H`.\"\"\"\nset_H!(value::SingleCageInductionMachine, val) = value.H = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `A`.\"\"\"\nset_A!(value::SingleCageInductionMachine, val) = value.A = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `B`.\"\"\"\nset_B!(value::SingleCageInductionMachine, val) = value.B = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `base_power`.\"\"\"\nset_base_power!(value::SingleCageInductionMachine, val) = value.base_power = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `ext`.\"\"\"\nset_ext!(value::SingleCageInductionMachine, val) = value.ext = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `C`.\"\"\"\nset_C!(value::SingleCageInductionMachine, val) = value.C = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `τ_ref`.\"\"\"\nset_τ_ref!(value::SingleCageInductionMachine, val) = value.τ_ref = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `B_shunt`.\"\"\"\nset_B_shunt!(value::SingleCageInductionMachine, val) = value.B_shunt = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `X_ad`.\"\"\"\nset_X_ad!(value::SingleCageInductionMachine, val) = value.X_ad = val\n\"\"\"Set [`SingleCageInductionMachine`](@ref) `X_aq`.\"\"\"\nset_X_aq!(value::SingleCageInductionMachine, val) = value.X_aq = val\n"
  },
  {
    "path": "src/models/generated/SingleMass.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SingleMass <: Shaft\n        H::Float64\n        D::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of single mass shaft model. Typically represents the rotor mass\n\n# Arguments\n- `H::Float64`: Rotor inertia constant in MWs/MVA, validation range: `(0, nothing)`\n- `D::Float64`: Rotor natural damping in pu, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) are:\n\tδ: rotor angle,\n\tω: rotor speed\n- `n_states::Int`: (**Do not modify.**) SingleMass has 1 state\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SingleMass <: Shaft\n    \"Rotor inertia constant in MWs/MVA\"\n    H::Float64\n    \"Rotor natural damping in pu\"\n    D::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) are:\n\tδ: rotor angle,\n\tω: rotor speed\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) SingleMass has 1 state\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SingleMass(H, D, ext=Dict{String, Any}(), )\n    SingleMass(H, D, ext, [:δ, :ω], 2, InfrastructureSystemsInternal(), )\nend\n\nfunction SingleMass(; H, D, ext=Dict{String, Any}(), states=[:δ, :ω], n_states=2, internal=InfrastructureSystemsInternal(), )\n    SingleMass(H, D, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SingleMass(::Nothing)\n    SingleMass(;\n        H=0,\n        D=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SingleMass`](@ref) `H`.\"\"\"\nget_H(value::SingleMass) = value.H\n\"\"\"Get [`SingleMass`](@ref) `D`.\"\"\"\nget_D(value::SingleMass) = value.D\n\"\"\"Get [`SingleMass`](@ref) `ext`.\"\"\"\nget_ext(value::SingleMass) = value.ext\n\"\"\"Get [`SingleMass`](@ref) `states`.\"\"\"\nget_states(value::SingleMass) = value.states\n\"\"\"Get [`SingleMass`](@ref) `n_states`.\"\"\"\nget_n_states(value::SingleMass) = value.n_states\n\"\"\"Get [`SingleMass`](@ref) `internal`.\"\"\"\nget_internal(value::SingleMass) = value.internal\n\n\"\"\"Set [`SingleMass`](@ref) `H`.\"\"\"\nset_H!(value::SingleMass, val) = value.H = val\n\"\"\"Set [`SingleMass`](@ref) `D`.\"\"\"\nset_D!(value::SingleMass, val) = value.D = val\n\"\"\"Set [`SingleMass`](@ref) `ext`.\"\"\"\nset_ext!(value::SingleMass, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/Source.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Source <: StaticInjection\n        name::String\n        available::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        R_th::Float64\n        X_th::Float64\n        internal_voltage::Float64\n        internal_angle::Float64\n        base_power::Float64\n        operation_cost::ImportExportCost\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nAn infinite bus with a constant voltage output.\n\nCommonly used in dynamics simulations to represent a very large machine on a single bus or for the representation of import/exports in operational simulations\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: (default: `0.0`) Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\n- `reactive_power::Float64`: (default: `0.0`) Initial reactive power set point of the unit (MVAR)\n- `active_power_limits::MinMax`: (default: `(min=0.0, max=0.0)`) Minimum and maximum stable active power levels (MW)\n- `reactive_power_limits::Union{Nothing, MinMax}`: (default: `(min=0.0, max=0.0)`) Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `R_th::Float64`: (default: `0.0`) Source Thevenin resistance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem), validation range: `(0, nothing)`\n- `X_th::Float64`: (default: `0.0`) Source Thevenin reactance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem), validation range: `(0, nothing)`\n- `internal_voltage::Float64`: (default: `1.0`) Internal Voltage (pu), validation range: `(0, nothing)`\n- `internal_angle::Float64`: (default: `0.0`) Internal Angle\n- `base_power::Float64`: (default: `100.0`) Base Power in MVA\n- `operation_cost::ImportExportCost`: (default: `ImportExportCost(nothing)`) [`ImportExportCost`](@ref) of the source.\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Source <: StaticInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Source Thevenin resistance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem)\"\n    R_th::Float64\n    \"Source Thevenin reactance. [See here:](https://en.wikipedia.org/wiki/Thevenins_theorem)\"\n    X_th::Float64\n    \"Internal Voltage (pu)\"\n    internal_voltage::Float64\n    \"Internal Angle\"\n    internal_angle::Float64\n    \"Base Power in MVA\"\n    base_power::Float64\n    \"[`ImportExportCost`](@ref) of the source.\"\n    operation_cost::ImportExportCost\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Source(name, available, bus, active_power=0.0, reactive_power=0.0, active_power_limits=(min=0.0, max=0.0), reactive_power_limits=(min=0.0, max=0.0), R_th=0.0, X_th=0.0, internal_voltage=1.0, internal_angle=0.0, base_power=100.0, operation_cost=ImportExportCost(nothing), dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), )\n    Source(name, available, bus, active_power, reactive_power, active_power_limits, reactive_power_limits, R_th, X_th, internal_voltage, internal_angle, base_power, operation_cost, dynamic_injector, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction Source(; name, available, bus, active_power=0.0, reactive_power=0.0, active_power_limits=(min=0.0, max=0.0), reactive_power_limits=(min=0.0, max=0.0), R_th=0.0, X_th=0.0, internal_voltage=1.0, internal_angle=0.0, base_power=100.0, operation_cost=ImportExportCost(nothing), dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    Source(name, available, bus, active_power, reactive_power, active_power_limits, reactive_power_limits, R_th, X_th, internal_voltage, internal_angle, base_power, operation_cost, dynamic_injector, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Source(::Nothing)\n    Source(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        R_th=0,\n        X_th=0,\n        internal_voltage=0,\n        internal_angle=0,\n        base_power=0,\n        operation_cost=ImportExportCost(nothing),\n        dynamic_injector=nothing,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`Source`](@ref) `name`.\"\"\"\nget_name(value::Source) = value.name\n\"\"\"Get [`Source`](@ref) `available`.\"\"\"\nget_available(value::Source) = value.available\n\"\"\"Get [`Source`](@ref) `bus`.\"\"\"\nget_bus(value::Source) = value.bus\n\"\"\"Get [`Source`](@ref) `active_power`.\"\"\"\nget_active_power(value::Source) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`Source`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::Source) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`Source`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::Source) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`Source`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::Source) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`Source`](@ref) `R_th`.\"\"\"\nget_R_th(value::Source) = value.R_th\n\"\"\"Get [`Source`](@ref) `X_th`.\"\"\"\nget_X_th(value::Source) = value.X_th\n\"\"\"Get [`Source`](@ref) `internal_voltage`.\"\"\"\nget_internal_voltage(value::Source) = value.internal_voltage\n\"\"\"Get [`Source`](@ref) `internal_angle`.\"\"\"\nget_internal_angle(value::Source) = value.internal_angle\n\"\"\"Get [`Source`](@ref) `base_power`.\"\"\"\nget_base_power(value::Source) = value.base_power\n\"\"\"Get [`Source`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::Source) = value.operation_cost\n\"\"\"Get [`Source`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::Source) = value.dynamic_injector\n\"\"\"Get [`Source`](@ref) `services`.\"\"\"\nget_services(value::Source) = value.services\n\"\"\"Get [`Source`](@ref) `ext`.\"\"\"\nget_ext(value::Source) = value.ext\n\"\"\"Get [`Source`](@ref) `internal`.\"\"\"\nget_internal(value::Source) = value.internal\n\n\"\"\"Set [`Source`](@ref) `available`.\"\"\"\nset_available!(value::Source, val) = value.available = val\n\"\"\"Set [`Source`](@ref) `bus`.\"\"\"\nset_bus!(value::Source, val) = value.bus = val\n\"\"\"Set [`Source`](@ref) `active_power`.\"\"\"\nset_active_power!(value::Source, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`Source`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::Source, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`Source`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::Source, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`Source`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::Source, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`Source`](@ref) `R_th`.\"\"\"\nset_R_th!(value::Source, val) = value.R_th = val\n\"\"\"Set [`Source`](@ref) `X_th`.\"\"\"\nset_X_th!(value::Source, val) = value.X_th = val\n\"\"\"Set [`Source`](@ref) `internal_voltage`.\"\"\"\nset_internal_voltage!(value::Source, val) = value.internal_voltage = val\n\"\"\"Set [`Source`](@ref) `internal_angle`.\"\"\"\nset_internal_angle!(value::Source, val) = value.internal_angle = val\n\"\"\"Set [`Source`](@ref) `base_power`.\"\"\"\nset_base_power!(value::Source, val) = value.base_power = val\n\"\"\"Set [`Source`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::Source, val) = value.operation_cost = val\n\"\"\"Set [`Source`](@ref) `services`.\"\"\"\nset_services!(value::Source, val) = value.services = val\n\"\"\"Set [`Source`](@ref) `ext`.\"\"\"\nset_ext!(value::Source, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/StandardLoad.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct StandardLoad <: StaticLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        base_power::Float64\n        constant_active_power::Float64\n        constant_reactive_power::Float64\n        impedance_active_power::Float64\n        impedance_reactive_power::Float64\n        current_active_power::Float64\n        current_reactive_power::Float64\n        max_constant_active_power::Float64\n        max_constant_reactive_power::Float64\n        max_impedance_active_power::Float64\n        max_impedance_reactive_power::Float64\n        max_current_active_power::Float64\n        max_current_reactive_power::Float64\n        conformity::LoadConformity\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA voltage-dependent [ZIP load](@ref Z), most commonly used for dynamics modeling.\n\nA `StandardLoad` breaks the ZIP into three pieces: Z (constant impedance), I (constant current), and P (constant power), according to `P = P_P * V^0 + P_I * V^1 + P_Z * V^2` for active power and `Q = Q_P * V^0 + Q_I * V^1 + Q_Z * V^2` for reactive power. (Voltage V is in per unit.)\n\nFor an alternative exponential formulation of the ZIP model, see [`ExponentialLoad`](@ref). For a simpler load model with no voltage dependency, see [`PowerLoad`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `base_power::Float64`: Base power of the load (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `constant_active_power::Float64`: (default: `0.0`) Constant active power demand in MW (P_P)\n- `constant_reactive_power::Float64`: (default: `0.0`) Constant reactive power demand in MVAR (Q_P)\n- `impedance_active_power::Float64`: (default: `0.0`) Active power coefficient in MW for constant impedance load (P_Z)\n- `impedance_reactive_power::Float64`: (default: `0.0`) Reactive power coefficient in MVAR for constant impedance load (Q_Z)\n- `current_active_power::Float64`: (default: `0.0`) Active power coefficient in MW for constant current load (P_I)\n- `current_reactive_power::Float64`: (default: `0.0`) Reactive power coefficient in MVAR for constant current load (Q_I)\n- `max_constant_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant power load\n- `max_constant_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant power load\n- `max_impedance_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant impedance load\n- `max_impedance_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant impedance load\n- `max_current_active_power::Float64`: (default: `0.0`) Maximum active power (MW) drawn by constant current load\n- `max_current_reactive_power::Float64`: (default: `0.0`) Maximum reactive power (MVAR) drawn by constant current load\n- `conformity::LoadConformity`: (default: `LoadConformity.UNDEFINED`) Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct StandardLoad <: StaticLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Base power of the load (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Constant active power demand in MW (P_P)\"\n    constant_active_power::Float64\n    \"Constant reactive power demand in MVAR (Q_P)\"\n    constant_reactive_power::Float64\n    \"Active power coefficient in MW for constant impedance load (P_Z)\"\n    impedance_active_power::Float64\n    \"Reactive power coefficient in MVAR for constant impedance load (Q_Z)\"\n    impedance_reactive_power::Float64\n    \"Active power coefficient in MW for constant current load (P_I)\"\n    current_active_power::Float64\n    \"Reactive power coefficient in MVAR for constant current load (Q_I)\"\n    current_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant power load\"\n    max_constant_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant power load\"\n    max_constant_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant impedance load\"\n    max_impedance_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant impedance load\"\n    max_impedance_reactive_power::Float64\n    \"Maximum active power (MW) drawn by constant current load\"\n    max_current_active_power::Float64\n    \"Maximum reactive power (MVAR) drawn by constant current load\"\n    max_current_reactive_power::Float64\n    \"Indicates whether the specified load is conforming or non-conforming. Options are [listed here](@ref loadconform_list).\"\n    conformity::LoadConformity\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction StandardLoad(name, available, bus, base_power, constant_active_power=0.0, constant_reactive_power=0.0, impedance_active_power=0.0, impedance_reactive_power=0.0, current_active_power=0.0, current_reactive_power=0.0, max_constant_active_power=0.0, max_constant_reactive_power=0.0, max_impedance_active_power=0.0, max_impedance_reactive_power=0.0, max_current_active_power=0.0, max_current_reactive_power=0.0, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    StandardLoad(name, available, bus, base_power, constant_active_power, constant_reactive_power, impedance_active_power, impedance_reactive_power, current_active_power, current_reactive_power, max_constant_active_power, max_constant_reactive_power, max_impedance_active_power, max_impedance_reactive_power, max_current_active_power, max_current_reactive_power, conformity, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction StandardLoad(; name, available, bus, base_power, constant_active_power=0.0, constant_reactive_power=0.0, impedance_active_power=0.0, impedance_reactive_power=0.0, current_active_power=0.0, current_reactive_power=0.0, max_constant_active_power=0.0, max_constant_reactive_power=0.0, max_impedance_active_power=0.0, max_impedance_reactive_power=0.0, max_current_active_power=0.0, max_current_reactive_power=0.0, conformity=LoadConformity.UNDEFINED, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    StandardLoad(name, available, bus, base_power, constant_active_power, constant_reactive_power, impedance_active_power, impedance_reactive_power, current_active_power, current_reactive_power, max_constant_active_power, max_constant_reactive_power, max_impedance_active_power, max_impedance_reactive_power, max_current_active_power, max_current_reactive_power, conformity, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction StandardLoad(::Nothing)\n    StandardLoad(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        base_power=100.0,\n        constant_active_power=0.0,\n        constant_reactive_power=0.0,\n        impedance_active_power=0.0,\n        impedance_reactive_power=0.0,\n        current_active_power=0.0,\n        current_reactive_power=0.0,\n        max_constant_active_power=0.0,\n        max_constant_reactive_power=0.0,\n        max_impedance_active_power=0.0,\n        max_impedance_reactive_power=0.0,\n        max_current_active_power=0.0,\n        max_current_reactive_power=0.0,\n        conformity=LoadConformity.UNDEFINED,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`StandardLoad`](@ref) `name`.\"\"\"\nget_name(value::StandardLoad) = value.name\n\"\"\"Get [`StandardLoad`](@ref) `available`.\"\"\"\nget_available(value::StandardLoad) = value.available\n\"\"\"Get [`StandardLoad`](@ref) `bus`.\"\"\"\nget_bus(value::StandardLoad) = value.bus\n\"\"\"Get [`StandardLoad`](@ref) `base_power`.\"\"\"\nget_base_power(value::StandardLoad) = value.base_power\n\"\"\"Get [`StandardLoad`](@ref) `constant_active_power`.\"\"\"\nget_constant_active_power(value::StandardLoad) = get_value(value, Val(:constant_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `constant_reactive_power`.\"\"\"\nget_constant_reactive_power(value::StandardLoad) = get_value(value, Val(:constant_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `impedance_active_power`.\"\"\"\nget_impedance_active_power(value::StandardLoad) = get_value(value, Val(:impedance_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `impedance_reactive_power`.\"\"\"\nget_impedance_reactive_power(value::StandardLoad) = get_value(value, Val(:impedance_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `current_active_power`.\"\"\"\nget_current_active_power(value::StandardLoad) = get_value(value, Val(:current_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `current_reactive_power`.\"\"\"\nget_current_reactive_power(value::StandardLoad) = get_value(value, Val(:current_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_constant_active_power`.\"\"\"\nget_max_constant_active_power(value::StandardLoad) = get_value(value, Val(:max_constant_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_constant_reactive_power`.\"\"\"\nget_max_constant_reactive_power(value::StandardLoad) = get_value(value, Val(:max_constant_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_impedance_active_power`.\"\"\"\nget_max_impedance_active_power(value::StandardLoad) = get_value(value, Val(:max_impedance_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_impedance_reactive_power`.\"\"\"\nget_max_impedance_reactive_power(value::StandardLoad) = get_value(value, Val(:max_impedance_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_current_active_power`.\"\"\"\nget_max_current_active_power(value::StandardLoad) = get_value(value, Val(:max_current_active_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `max_current_reactive_power`.\"\"\"\nget_max_current_reactive_power(value::StandardLoad) = get_value(value, Val(:max_current_reactive_power), Val(:mva))\n\"\"\"Get [`StandardLoad`](@ref) `conformity`.\"\"\"\nget_conformity(value::StandardLoad) = value.conformity\n\"\"\"Get [`StandardLoad`](@ref) `services`.\"\"\"\nget_services(value::StandardLoad) = value.services\n\"\"\"Get [`StandardLoad`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::StandardLoad) = value.dynamic_injector\n\"\"\"Get [`StandardLoad`](@ref) `ext`.\"\"\"\nget_ext(value::StandardLoad) = value.ext\n\"\"\"Get [`StandardLoad`](@ref) `internal`.\"\"\"\nget_internal(value::StandardLoad) = value.internal\n\n\"\"\"Set [`StandardLoad`](@ref) `available`.\"\"\"\nset_available!(value::StandardLoad, val) = value.available = val\n\"\"\"Set [`StandardLoad`](@ref) `bus`.\"\"\"\nset_bus!(value::StandardLoad, val) = value.bus = val\n\"\"\"Set [`StandardLoad`](@ref) `base_power`.\"\"\"\nset_base_power!(value::StandardLoad, val) = value.base_power = val\n\"\"\"Set [`StandardLoad`](@ref) `constant_active_power`.\"\"\"\nset_constant_active_power!(value::StandardLoad, val) = value.constant_active_power = set_value(value, Val(:constant_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `constant_reactive_power`.\"\"\"\nset_constant_reactive_power!(value::StandardLoad, val) = value.constant_reactive_power = set_value(value, Val(:constant_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `impedance_active_power`.\"\"\"\nset_impedance_active_power!(value::StandardLoad, val) = value.impedance_active_power = set_value(value, Val(:impedance_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `impedance_reactive_power`.\"\"\"\nset_impedance_reactive_power!(value::StandardLoad, val) = value.impedance_reactive_power = set_value(value, Val(:impedance_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `current_active_power`.\"\"\"\nset_current_active_power!(value::StandardLoad, val) = value.current_active_power = set_value(value, Val(:current_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `current_reactive_power`.\"\"\"\nset_current_reactive_power!(value::StandardLoad, val) = value.current_reactive_power = set_value(value, Val(:current_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_constant_active_power`.\"\"\"\nset_max_constant_active_power!(value::StandardLoad, val) = value.max_constant_active_power = set_value(value, Val(:max_constant_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_constant_reactive_power`.\"\"\"\nset_max_constant_reactive_power!(value::StandardLoad, val) = value.max_constant_reactive_power = set_value(value, Val(:max_constant_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_impedance_active_power`.\"\"\"\nset_max_impedance_active_power!(value::StandardLoad, val) = value.max_impedance_active_power = set_value(value, Val(:max_impedance_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_impedance_reactive_power`.\"\"\"\nset_max_impedance_reactive_power!(value::StandardLoad, val) = value.max_impedance_reactive_power = set_value(value, Val(:max_impedance_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_current_active_power`.\"\"\"\nset_max_current_active_power!(value::StandardLoad, val) = value.max_current_active_power = set_value(value, Val(:max_current_active_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `max_current_reactive_power`.\"\"\"\nset_max_current_reactive_power!(value::StandardLoad, val) = value.max_current_reactive_power = set_value(value, Val(:max_current_reactive_power), val, Val(:mva))\n\"\"\"Set [`StandardLoad`](@ref) `conformity`.\"\"\"\nset_conformity!(value::StandardLoad, val) = value.conformity = val\n\"\"\"Set [`StandardLoad`](@ref) `services`.\"\"\"\nset_services!(value::StandardLoad, val) = value.services = val\n\"\"\"Set [`StandardLoad`](@ref) `ext`.\"\"\"\nset_ext!(value::StandardLoad, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/SteamTurbineGov1.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SteamTurbineGov1 <: TurbineGov\n        R::Float64\n        T1::Float64\n        valve_position_limits::MinMax\n        T2::Float64\n        T3::Float64\n        D_T::Float64\n        DB_h::Float64\n        DB_l::Float64\n        T_rate::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nSteam Turbine-Governor. This model considers both TGOV1 or TGOV1DU in PSS/E\n\n# Arguments\n- `R::Float64`: Droop parameter, validation range: `(0, 0.1)`\n- `T1::Float64`: Governor time constant, validation range: `(eps(), 0.5)`\n- `valve_position_limits::MinMax`: Valve position limits\n- `T2::Float64`: Lead Lag Lead Time constant , validation range: `(0, nothing)`\n- `T3::Float64`: Lead Lag Lag Time constant , validation range: `(eps(), 10)`\n- `D_T::Float64`: Turbine Damping, validation range: `(0, 0.5)`\n- `DB_h::Float64`: Deadband for overspeed, validation range: `(0, nothing)`\n- `DB_l::Float64`: Deadband for underspeed, validation range: `(nothing, 0)`\n- `T_rate::Float64`: Turbine Rate (MW). If zero, generator base is used, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the SteamTurbineGov1 model are:\n\tx_g1: Valve Opening,\n\tx_g2: Lead-lag state\n- `n_states::Int`: (**Do not modify.**) TGOV1 has 2 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) TGOV1 has 2 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SteamTurbineGov1 <: TurbineGov\n    \"Droop parameter\"\n    R::Float64\n    \"Governor time constant\"\n    T1::Float64\n    \"Valve position limits\"\n    valve_position_limits::MinMax\n    \"Lead Lag Lead Time constant \"\n    T2::Float64\n    \"Lead Lag Lag Time constant \"\n    T3::Float64\n    \"Turbine Damping\"\n    D_T::Float64\n    \"Deadband for overspeed\"\n    DB_h::Float64\n    \"Deadband for underspeed\"\n    DB_l::Float64\n    \"Turbine Rate (MW). If zero, generator base is used\"\n    T_rate::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the SteamTurbineGov1 model are:\n\tx_g1: Valve Opening,\n\tx_g2: Lead-lag state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) TGOV1 has 2 states\"\n    n_states::Int\n    \"(**Do not modify.**) TGOV1 has 2 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SteamTurbineGov1(R, T1, valve_position_limits, T2, T3, D_T, DB_h, DB_l, T_rate, P_ref=1.0, ext=Dict{String, Any}(), )\n    SteamTurbineGov1(R, T1, valve_position_limits, T2, T3, D_T, DB_h, DB_l, T_rate, P_ref, ext, [:x_g1, :x_g2], 2, [StateTypes.Differential, StateTypes.Differential], InfrastructureSystemsInternal(), )\nend\n\nfunction SteamTurbineGov1(; R, T1, valve_position_limits, T2, T3, D_T, DB_h, DB_l, T_rate, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2], n_states=2, states_types=[StateTypes.Differential, StateTypes.Differential], internal=InfrastructureSystemsInternal(), )\n    SteamTurbineGov1(R, T1, valve_position_limits, T2, T3, D_T, DB_h, DB_l, T_rate, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SteamTurbineGov1(::Nothing)\n    SteamTurbineGov1(;\n        R=0,\n        T1=0,\n        valve_position_limits=(min=0.0, max=0.0),\n        T2=0,\n        T3=0,\n        D_T=0,\n        DB_h=0,\n        DB_l=0,\n        T_rate=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SteamTurbineGov1`](@ref) `R`.\"\"\"\nget_R(value::SteamTurbineGov1) = value.R\n\"\"\"Get [`SteamTurbineGov1`](@ref) `T1`.\"\"\"\nget_T1(value::SteamTurbineGov1) = value.T1\n\"\"\"Get [`SteamTurbineGov1`](@ref) `valve_position_limits`.\"\"\"\nget_valve_position_limits(value::SteamTurbineGov1) = value.valve_position_limits\n\"\"\"Get [`SteamTurbineGov1`](@ref) `T2`.\"\"\"\nget_T2(value::SteamTurbineGov1) = value.T2\n\"\"\"Get [`SteamTurbineGov1`](@ref) `T3`.\"\"\"\nget_T3(value::SteamTurbineGov1) = value.T3\n\"\"\"Get [`SteamTurbineGov1`](@ref) `D_T`.\"\"\"\nget_D_T(value::SteamTurbineGov1) = value.D_T\n\"\"\"Get [`SteamTurbineGov1`](@ref) `DB_h`.\"\"\"\nget_DB_h(value::SteamTurbineGov1) = value.DB_h\n\"\"\"Get [`SteamTurbineGov1`](@ref) `DB_l`.\"\"\"\nget_DB_l(value::SteamTurbineGov1) = value.DB_l\n\"\"\"Get [`SteamTurbineGov1`](@ref) `T_rate`.\"\"\"\nget_T_rate(value::SteamTurbineGov1) = value.T_rate\n\"\"\"Get [`SteamTurbineGov1`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::SteamTurbineGov1) = value.P_ref\n\"\"\"Get [`SteamTurbineGov1`](@ref) `ext`.\"\"\"\nget_ext(value::SteamTurbineGov1) = value.ext\n\"\"\"Get [`SteamTurbineGov1`](@ref) `states`.\"\"\"\nget_states(value::SteamTurbineGov1) = value.states\n\"\"\"Get [`SteamTurbineGov1`](@ref) `n_states`.\"\"\"\nget_n_states(value::SteamTurbineGov1) = value.n_states\n\"\"\"Get [`SteamTurbineGov1`](@ref) `states_types`.\"\"\"\nget_states_types(value::SteamTurbineGov1) = value.states_types\n\"\"\"Get [`SteamTurbineGov1`](@ref) `internal`.\"\"\"\nget_internal(value::SteamTurbineGov1) = value.internal\n\n\"\"\"Set [`SteamTurbineGov1`](@ref) `R`.\"\"\"\nset_R!(value::SteamTurbineGov1, val) = value.R = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `T1`.\"\"\"\nset_T1!(value::SteamTurbineGov1, val) = value.T1 = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `valve_position_limits`.\"\"\"\nset_valve_position_limits!(value::SteamTurbineGov1, val) = value.valve_position_limits = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `T2`.\"\"\"\nset_T2!(value::SteamTurbineGov1, val) = value.T2 = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `T3`.\"\"\"\nset_T3!(value::SteamTurbineGov1, val) = value.T3 = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `D_T`.\"\"\"\nset_D_T!(value::SteamTurbineGov1, val) = value.D_T = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `DB_h`.\"\"\"\nset_DB_h!(value::SteamTurbineGov1, val) = value.DB_h = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `DB_l`.\"\"\"\nset_DB_l!(value::SteamTurbineGov1, val) = value.DB_l = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `T_rate`.\"\"\"\nset_T_rate!(value::SteamTurbineGov1, val) = value.T_rate = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::SteamTurbineGov1, val) = value.P_ref = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `ext`.\"\"\"\nset_ext!(value::SteamTurbineGov1, val) = value.ext = val\n\"\"\"Set [`SteamTurbineGov1`](@ref) `states_types`.\"\"\"\nset_states_types!(value::SteamTurbineGov1, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/SwitchedAdmittance.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SwitchedAdmittance <: ElectricLoad\n        name::String\n        available::Bool\n        bus::ACBus\n        Y::Complex{Float64}\n        initial_status::Vector{Int}\n        number_of_steps::Vector{Int}\n        Y_increase::Vector{Complex{Float64}}\n        admittance_limits::MinMax\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA switched admittance, with discrete steps to adjust the admittance.\n\nMost often used in power flow studies, iterating over the steps to see impacts of admittance on the results. Total admittance is calculated as: `Y` + `number_of_steps` * `Y_increase`\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `Y::Complex{Float64}`: Initial admittance at N = 0\n- `initial_status::Vector{Int}`: (default: `Int[]`) Vector of initial switched shunt status, one for in-service and zero for out-of-service for block i (1 through 8)\n- `number_of_steps::Vector{Int}`: (default: `Int[]`) Vector with number of steps for each adjustable shunt block. For example, `number_of_steps[2]` are the number of available steps for admittance increment at block 2.\n- `Y_increase::Vector{Complex{Float64}}`: (default: `Complex{Float64}[]`) Vector with admittance increment step for each adjustable shunt block. For example, `Y_increase[2]` is the complex admittance increment for each step at block 2.\n- `admittance_limits::MinMax`: (default: `(min=1.0, max=1.0)`) Shunt admittance limits for switched shunt model\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection model for admittance\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SwitchedAdmittance <: ElectricLoad\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial admittance at N = 0\"\n    Y::Complex{Float64}\n    \"Vector of initial switched shunt status, one for in-service and zero for out-of-service for block i (1 through 8)\"\n    initial_status::Vector{Int}\n    \"Vector with number of steps for each adjustable shunt block. For example, `number_of_steps[2]` are the number of available steps for admittance increment at block 2.\"\n    number_of_steps::Vector{Int}\n    \"Vector with admittance increment step for each adjustable shunt block. For example, `Y_increase[2]` is the complex admittance increment for each step at block 2.\"\n    Y_increase::Vector{Complex{Float64}}\n    \"Shunt admittance limits for switched shunt model\"\n    admittance_limits::MinMax\n    \"corresponding dynamic injection model for admittance\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SwitchedAdmittance(name, available, bus, Y, initial_status=Int[], number_of_steps=Int[], Y_increase=Complex{Float64}[], admittance_limits=(min=1.0, max=1.0), dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), )\n    SwitchedAdmittance(name, available, bus, Y, initial_status, number_of_steps, Y_increase, admittance_limits, dynamic_injector, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction SwitchedAdmittance(; name, available, bus, Y, initial_status=Int[], number_of_steps=Int[], Y_increase=Complex{Float64}[], admittance_limits=(min=1.0, max=1.0), dynamic_injector=nothing, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    SwitchedAdmittance(name, available, bus, Y, initial_status, number_of_steps, Y_increase, admittance_limits, dynamic_injector, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SwitchedAdmittance(::Nothing)\n    SwitchedAdmittance(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        Y=0.0 + 0.0im,\n        initial_status=Int[],\n        number_of_steps=Int[],\n        Y_increase=Complex{Float64}[],\n        admittance_limits=(min=0.0, max=0.0),\n        dynamic_injector=nothing,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SwitchedAdmittance`](@ref) `name`.\"\"\"\nget_name(value::SwitchedAdmittance) = value.name\n\"\"\"Get [`SwitchedAdmittance`](@ref) `available`.\"\"\"\nget_available(value::SwitchedAdmittance) = value.available\n\"\"\"Get [`SwitchedAdmittance`](@ref) `bus`.\"\"\"\nget_bus(value::SwitchedAdmittance) = value.bus\n\"\"\"Get [`SwitchedAdmittance`](@ref) `Y`.\"\"\"\nget_Y(value::SwitchedAdmittance) = value.Y\n\"\"\"Get [`SwitchedAdmittance`](@ref) `initial_status`.\"\"\"\nget_initial_status(value::SwitchedAdmittance) = value.initial_status\n\"\"\"Get [`SwitchedAdmittance`](@ref) `number_of_steps`.\"\"\"\nget_number_of_steps(value::SwitchedAdmittance) = value.number_of_steps\n\"\"\"Get [`SwitchedAdmittance`](@ref) `Y_increase`.\"\"\"\nget_Y_increase(value::SwitchedAdmittance) = value.Y_increase\n\"\"\"Get [`SwitchedAdmittance`](@ref) `admittance_limits`.\"\"\"\nget_admittance_limits(value::SwitchedAdmittance) = value.admittance_limits\n\"\"\"Get [`SwitchedAdmittance`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::SwitchedAdmittance) = value.dynamic_injector\n\"\"\"Get [`SwitchedAdmittance`](@ref) `services`.\"\"\"\nget_services(value::SwitchedAdmittance) = value.services\n\"\"\"Get [`SwitchedAdmittance`](@ref) `ext`.\"\"\"\nget_ext(value::SwitchedAdmittance) = value.ext\n\"\"\"Get [`SwitchedAdmittance`](@ref) `internal`.\"\"\"\nget_internal(value::SwitchedAdmittance) = value.internal\n\n\"\"\"Set [`SwitchedAdmittance`](@ref) `available`.\"\"\"\nset_available!(value::SwitchedAdmittance, val) = value.available = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `bus`.\"\"\"\nset_bus!(value::SwitchedAdmittance, val) = value.bus = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `Y`.\"\"\"\nset_Y!(value::SwitchedAdmittance, val) = value.Y = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `initial_status`.\"\"\"\nset_initial_status!(value::SwitchedAdmittance, val) = value.initial_status = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `number_of_steps`.\"\"\"\nset_number_of_steps!(value::SwitchedAdmittance, val) = value.number_of_steps = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `Y_increase`.\"\"\"\nset_Y_increase!(value::SwitchedAdmittance, val) = value.Y_increase = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `admittance_limits`.\"\"\"\nset_admittance_limits!(value::SwitchedAdmittance, val) = value.admittance_limits = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `services`.\"\"\"\nset_services!(value::SwitchedAdmittance, val) = value.services = val\n\"\"\"Set [`SwitchedAdmittance`](@ref) `ext`.\"\"\"\nset_ext!(value::SwitchedAdmittance, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/SynchronousCondenser.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct SynchronousCondenser <: StaticInjection\n        name::String\n        available::Bool\n        bus::ACBus\n        reactive_power::Float64\n        rating::Float64\n        reactive_power_limits::Union{Nothing, MinMax}\n        base_power::Float64\n        active_power_losses::Float64\n        services::Vector{Service}\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA Synchronous Machine connected to the system to provide inertia or reactive power support\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `bus::ACBus`: Bus that this component is connected to\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `active_power_losses::Float64`: (default: `0.0`) Active Power Loss incurred by having the unit online., validation range: `(0, nothing)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct SynchronousCondenser <: StaticInjection\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Active Power Loss incurred by having the unit online.\"\n    active_power_losses::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction SynchronousCondenser(name, available, bus, reactive_power, rating, reactive_power_limits, base_power, active_power_losses=0.0, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    SynchronousCondenser(name, available, bus, reactive_power, rating, reactive_power_limits, base_power, active_power_losses, services, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction SynchronousCondenser(; name, available, bus, reactive_power, rating, reactive_power_limits, base_power, active_power_losses=0.0, services=Device[], dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    SynchronousCondenser(name, available, bus, reactive_power, rating, reactive_power_limits, base_power, active_power_losses, services, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction SynchronousCondenser(::Nothing)\n    SynchronousCondenser(;\n        name=\"init\",\n        available=false,\n        bus=ACBus(nothing),\n        reactive_power=0.0,\n        rating=0.0,\n        reactive_power_limits=nothing,\n        base_power=100.0,\n        active_power_losses=0.0,\n        services=Device[],\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`SynchronousCondenser`](@ref) `name`.\"\"\"\nget_name(value::SynchronousCondenser) = value.name\n\"\"\"Get [`SynchronousCondenser`](@ref) `available`.\"\"\"\nget_available(value::SynchronousCondenser) = value.available\n\"\"\"Get [`SynchronousCondenser`](@ref) `bus`.\"\"\"\nget_bus(value::SynchronousCondenser) = value.bus\n\"\"\"Get [`SynchronousCondenser`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::SynchronousCondenser) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`SynchronousCondenser`](@ref) `rating`.\"\"\"\nget_rating(value::SynchronousCondenser) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`SynchronousCondenser`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::SynchronousCondenser) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`SynchronousCondenser`](@ref) `base_power`.\"\"\"\nget_base_power(value::SynchronousCondenser) = value.base_power\n\"\"\"Get [`SynchronousCondenser`](@ref) `active_power_losses`.\"\"\"\nget_active_power_losses(value::SynchronousCondenser) = get_value(value, Val(:active_power_losses), Val(:mva))\n\"\"\"Get [`SynchronousCondenser`](@ref) `services`.\"\"\"\nget_services(value::SynchronousCondenser) = value.services\n\"\"\"Get [`SynchronousCondenser`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::SynchronousCondenser) = value.dynamic_injector\n\"\"\"Get [`SynchronousCondenser`](@ref) `ext`.\"\"\"\nget_ext(value::SynchronousCondenser) = value.ext\n\"\"\"Get [`SynchronousCondenser`](@ref) `internal`.\"\"\"\nget_internal(value::SynchronousCondenser) = value.internal\n\n\"\"\"Set [`SynchronousCondenser`](@ref) `available`.\"\"\"\nset_available!(value::SynchronousCondenser, val) = value.available = val\n\"\"\"Set [`SynchronousCondenser`](@ref) `bus`.\"\"\"\nset_bus!(value::SynchronousCondenser, val) = value.bus = val\n\"\"\"Set [`SynchronousCondenser`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::SynchronousCondenser, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`SynchronousCondenser`](@ref) `rating`.\"\"\"\nset_rating!(value::SynchronousCondenser, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`SynchronousCondenser`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::SynchronousCondenser, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`SynchronousCondenser`](@ref) `base_power`.\"\"\"\nset_base_power!(value::SynchronousCondenser, val) = value.base_power = val\n\"\"\"Set [`SynchronousCondenser`](@ref) `active_power_losses`.\"\"\"\nset_active_power_losses!(value::SynchronousCondenser, val) = value.active_power_losses = set_value(value, Val(:active_power_losses), val, Val(:mva))\n\"\"\"Set [`SynchronousCondenser`](@ref) `services`.\"\"\"\nset_services!(value::SynchronousCondenser, val) = value.services = val\n\"\"\"Set [`SynchronousCondenser`](@ref) `ext`.\"\"\"\nset_ext!(value::SynchronousCondenser, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TGFixed.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TGFixed <: TurbineGov\n        efficiency::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a fixed Turbine Governor that returns a fixed mechanical torque\n given by the product of P_ref*efficiency\n\n# Arguments\n- `efficiency::Float64`: Efficiency factor that multiplies `P_ref`, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) TGFixed has no [states](@ref S)\n- `n_states::Int`: (**Do not modify.**) TGFixed has no states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TGFixed <: TurbineGov\n    \"Efficiency factor that multiplies `P_ref`\"\n    efficiency::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) TGFixed has no [states](@ref S)\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) TGFixed has no states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TGFixed(efficiency, P_ref=1.0, ext=Dict{String, Any}(), )\n    TGFixed(efficiency, P_ref, ext, Vector{Symbol}(), 0, InfrastructureSystemsInternal(), )\nend\n\nfunction TGFixed(; efficiency, P_ref=1.0, ext=Dict{String, Any}(), states=Vector{Symbol}(), n_states=0, internal=InfrastructureSystemsInternal(), )\n    TGFixed(efficiency, P_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TGFixed(::Nothing)\n    TGFixed(;\n        efficiency=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TGFixed`](@ref) `efficiency`.\"\"\"\nget_efficiency(value::TGFixed) = value.efficiency\n\"\"\"Get [`TGFixed`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::TGFixed) = value.P_ref\n\"\"\"Get [`TGFixed`](@ref) `ext`.\"\"\"\nget_ext(value::TGFixed) = value.ext\n\"\"\"Get [`TGFixed`](@ref) `states`.\"\"\"\nget_states(value::TGFixed) = value.states\n\"\"\"Get [`TGFixed`](@ref) `n_states`.\"\"\"\nget_n_states(value::TGFixed) = value.n_states\n\"\"\"Get [`TGFixed`](@ref) `internal`.\"\"\"\nget_internal(value::TGFixed) = value.internal\n\n\"\"\"Set [`TGFixed`](@ref) `efficiency`.\"\"\"\nset_efficiency!(value::TGFixed, val) = value.efficiency = val\n\"\"\"Set [`TGFixed`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::TGFixed, val) = value.P_ref = val\n\"\"\"Set [`TGFixed`](@ref) `ext`.\"\"\"\nset_ext!(value::TGFixed, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TGSimple.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TGSimple <: TurbineGov\n        d_t::Float64\n        Tm::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Simple one-state Turbine Governor\n\n# Arguments\n- `d_t::Float64`: Inverse Droop parameter, validation range: `(0, nothing)`\n- `Tm::Float64`: Turbine Governor Low-Pass Time Constant [s], validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the TGSimple model are:\n\tτm: mechanical torque\n- `n_states::Int`: (**Do not modify.**) TGSimple has 1 state\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TGSimple <: TurbineGov\n    \"Inverse Droop parameter\"\n    d_t::Float64\n    \"Turbine Governor Low-Pass Time Constant [s]\"\n    Tm::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the TGSimple model are:\n\tτm: mechanical torque\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) TGSimple has 1 state\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TGSimple(d_t, Tm, P_ref=1.0, ext=Dict{String, Any}(), )\n    TGSimple(d_t, Tm, P_ref, ext, [:τm], 1, InfrastructureSystemsInternal(), )\nend\n\nfunction TGSimple(; d_t, Tm, P_ref=1.0, ext=Dict{String, Any}(), states=[:τm], n_states=1, internal=InfrastructureSystemsInternal(), )\n    TGSimple(d_t, Tm, P_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TGSimple(::Nothing)\n    TGSimple(;\n        d_t=0,\n        Tm=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TGSimple`](@ref) `d_t`.\"\"\"\nget_d_t(value::TGSimple) = value.d_t\n\"\"\"Get [`TGSimple`](@ref) `Tm`.\"\"\"\nget_Tm(value::TGSimple) = value.Tm\n\"\"\"Get [`TGSimple`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::TGSimple) = value.P_ref\n\"\"\"Get [`TGSimple`](@ref) `ext`.\"\"\"\nget_ext(value::TGSimple) = value.ext\n\"\"\"Get [`TGSimple`](@ref) `states`.\"\"\"\nget_states(value::TGSimple) = value.states\n\"\"\"Get [`TGSimple`](@ref) `n_states`.\"\"\"\nget_n_states(value::TGSimple) = value.n_states\n\"\"\"Get [`TGSimple`](@ref) `internal`.\"\"\"\nget_internal(value::TGSimple) = value.internal\n\n\"\"\"Set [`TGSimple`](@ref) `d_t`.\"\"\"\nset_d_t!(value::TGSimple, val) = value.d_t = val\n\"\"\"Set [`TGSimple`](@ref) `Tm`.\"\"\"\nset_Tm!(value::TGSimple, val) = value.Tm = val\n\"\"\"Set [`TGSimple`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::TGSimple, val) = value.P_ref = val\n\"\"\"Set [`TGSimple`](@ref) `ext`.\"\"\"\nset_ext!(value::TGSimple, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TGTypeI.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TGTypeI <: TurbineGov\n        R::Float64\n        Ts::Float64\n        Tc::Float64\n        T3::Float64\n        T4::Float64\n        T5::Float64\n        valve_position_limits::MinMax\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Turbine Governor Type I\n\n# Arguments\n- `R::Float64`: Droop parameter, validation range: `(0, nothing)`\n- `Ts::Float64`: Governor time constant, validation range: `(0, nothing)`\n- `Tc::Float64`: Servo time constant, validation range: `(0, nothing)`\n- `T3::Float64`: Transient gain time constant, validation range: `(0, nothing)`\n- `T4::Float64`: Power fraction time constant, validation range: `(0, nothing)`\n- `T5::Float64`: Reheat time constant, validation range: `(0, nothing)`\n- `valve_position_limits::MinMax`: Valve position limits in MW\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\n\tx_g1: Governor state,\n\tx_g2: Servo state,\n\tx_g3: Reheat state\n- `n_states::Int`: (**Do not modify.**) TGTypeI has 3 states\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TGTypeI <: TurbineGov\n    \"Droop parameter\"\n    R::Float64\n    \"Governor time constant\"\n    Ts::Float64\n    \"Servo time constant\"\n    Tc::Float64\n    \"Transient gain time constant\"\n    T3::Float64\n    \"Power fraction time constant\"\n    T4::Float64\n    \"Reheat time constant\"\n    T5::Float64\n    \"Valve position limits in MW\"\n    valve_position_limits::MinMax\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\n\tx_g1: Governor state,\n\tx_g2: Servo state,\n\tx_g3: Reheat state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) TGTypeI has 3 states\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TGTypeI(R, Ts, Tc, T3, T4, T5, valve_position_limits, P_ref=1.0, ext=Dict{String, Any}(), )\n    TGTypeI(R, Ts, Tc, T3, T4, T5, valve_position_limits, P_ref, ext, [:x_g1, :x_g2, :x_g3], 3, InfrastructureSystemsInternal(), )\nend\n\nfunction TGTypeI(; R, Ts, Tc, T3, T4, T5, valve_position_limits, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3], n_states=3, internal=InfrastructureSystemsInternal(), )\n    TGTypeI(R, Ts, Tc, T3, T4, T5, valve_position_limits, P_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TGTypeI(::Nothing)\n    TGTypeI(;\n        R=0,\n        Ts=0,\n        Tc=0,\n        T3=0,\n        T4=0,\n        T5=0,\n        valve_position_limits=(min=0.0, max=0.0),\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TGTypeI`](@ref) `R`.\"\"\"\nget_R(value::TGTypeI) = value.R\n\"\"\"Get [`TGTypeI`](@ref) `Ts`.\"\"\"\nget_Ts(value::TGTypeI) = value.Ts\n\"\"\"Get [`TGTypeI`](@ref) `Tc`.\"\"\"\nget_Tc(value::TGTypeI) = value.Tc\n\"\"\"Get [`TGTypeI`](@ref) `T3`.\"\"\"\nget_T3(value::TGTypeI) = value.T3\n\"\"\"Get [`TGTypeI`](@ref) `T4`.\"\"\"\nget_T4(value::TGTypeI) = value.T4\n\"\"\"Get [`TGTypeI`](@ref) `T5`.\"\"\"\nget_T5(value::TGTypeI) = value.T5\n\"\"\"Get [`TGTypeI`](@ref) `valve_position_limits`.\"\"\"\nget_valve_position_limits(value::TGTypeI) = value.valve_position_limits\n\"\"\"Get [`TGTypeI`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::TGTypeI) = value.P_ref\n\"\"\"Get [`TGTypeI`](@ref) `ext`.\"\"\"\nget_ext(value::TGTypeI) = value.ext\n\"\"\"Get [`TGTypeI`](@ref) `states`.\"\"\"\nget_states(value::TGTypeI) = value.states\n\"\"\"Get [`TGTypeI`](@ref) `n_states`.\"\"\"\nget_n_states(value::TGTypeI) = value.n_states\n\"\"\"Get [`TGTypeI`](@ref) `internal`.\"\"\"\nget_internal(value::TGTypeI) = value.internal\n\n\"\"\"Set [`TGTypeI`](@ref) `R`.\"\"\"\nset_R!(value::TGTypeI, val) = value.R = val\n\"\"\"Set [`TGTypeI`](@ref) `Ts`.\"\"\"\nset_Ts!(value::TGTypeI, val) = value.Ts = val\n\"\"\"Set [`TGTypeI`](@ref) `Tc`.\"\"\"\nset_Tc!(value::TGTypeI, val) = value.Tc = val\n\"\"\"Set [`TGTypeI`](@ref) `T3`.\"\"\"\nset_T3!(value::TGTypeI, val) = value.T3 = val\n\"\"\"Set [`TGTypeI`](@ref) `T4`.\"\"\"\nset_T4!(value::TGTypeI, val) = value.T4 = val\n\"\"\"Set [`TGTypeI`](@ref) `T5`.\"\"\"\nset_T5!(value::TGTypeI, val) = value.T5 = val\n\"\"\"Set [`TGTypeI`](@ref) `valve_position_limits`.\"\"\"\nset_valve_position_limits!(value::TGTypeI, val) = value.valve_position_limits = val\n\"\"\"Set [`TGTypeI`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::TGTypeI, val) = value.P_ref = val\n\"\"\"Set [`TGTypeI`](@ref) `ext`.\"\"\"\nset_ext!(value::TGTypeI, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TGTypeII.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TGTypeII <: TurbineGov\n        R::Float64\n        T1::Float64\n        T2::Float64\n        τ_limits::MinMax\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        internal::InfrastructureSystemsInternal\n    end\n\nParameters of a Turbine Governor Type II\n\n# Arguments\n- `R::Float64`: Droop parameter, validation range: `(0, nothing)`\n- `T1::Float64`: Transient gain time constant, validation range: `(0, nothing)`\n- `T2::Float64`: Power fraction time constant, validation range: `(0, nothing)`\n- `τ_limits::MinMax`: Power into the governor limits\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\n\tx_g1: lead-lag state\n- `n_states::Int`: (**Do not modify.**) TGTypeII has 1 state\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TGTypeII <: TurbineGov\n    \"Droop parameter\"\n    R::Float64\n    \"Transient gain time constant\"\n    T1::Float64\n    \"Power fraction time constant\"\n    T2::Float64\n    \"Power into the governor limits\"\n    τ_limits::MinMax\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the TGTypeI model are:\n\tx_g1: lead-lag state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) TGTypeII has 1 state\"\n    n_states::Int\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TGTypeII(R, T1, T2, τ_limits, P_ref=1.0, ext=Dict{String, Any}(), )\n    TGTypeII(R, T1, T2, τ_limits, P_ref, ext, [:xg], 1, InfrastructureSystemsInternal(), )\nend\n\nfunction TGTypeII(; R, T1, T2, τ_limits, P_ref=1.0, ext=Dict{String, Any}(), states=[:xg], n_states=1, internal=InfrastructureSystemsInternal(), )\n    TGTypeII(R, T1, T2, τ_limits, P_ref, ext, states, n_states, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TGTypeII(::Nothing)\n    TGTypeII(;\n        R=0,\n        T1=0,\n        T2=0,\n        τ_limits=(min=0.0, max=0.0),\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TGTypeII`](@ref) `R`.\"\"\"\nget_R(value::TGTypeII) = value.R\n\"\"\"Get [`TGTypeII`](@ref) `T1`.\"\"\"\nget_T1(value::TGTypeII) = value.T1\n\"\"\"Get [`TGTypeII`](@ref) `T2`.\"\"\"\nget_T2(value::TGTypeII) = value.T2\n\"\"\"Get [`TGTypeII`](@ref) `τ_limits`.\"\"\"\nget_τ_limits(value::TGTypeII) = value.τ_limits\n\"\"\"Get [`TGTypeII`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::TGTypeII) = value.P_ref\n\"\"\"Get [`TGTypeII`](@ref) `ext`.\"\"\"\nget_ext(value::TGTypeII) = value.ext\n\"\"\"Get [`TGTypeII`](@ref) `states`.\"\"\"\nget_states(value::TGTypeII) = value.states\n\"\"\"Get [`TGTypeII`](@ref) `n_states`.\"\"\"\nget_n_states(value::TGTypeII) = value.n_states\n\"\"\"Get [`TGTypeII`](@ref) `internal`.\"\"\"\nget_internal(value::TGTypeII) = value.internal\n\n\"\"\"Set [`TGTypeII`](@ref) `R`.\"\"\"\nset_R!(value::TGTypeII, val) = value.R = val\n\"\"\"Set [`TGTypeII`](@ref) `T1`.\"\"\"\nset_T1!(value::TGTypeII, val) = value.T1 = val\n\"\"\"Set [`TGTypeII`](@ref) `T2`.\"\"\"\nset_T2!(value::TGTypeII, val) = value.T2 = val\n\"\"\"Set [`TGTypeII`](@ref) `τ_limits`.\"\"\"\nset_τ_limits!(value::TGTypeII, val) = value.τ_limits = val\n\"\"\"Set [`TGTypeII`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::TGTypeII, val) = value.P_ref = val\n\"\"\"Set [`TGTypeII`](@ref) `ext`.\"\"\"\nset_ext!(value::TGTypeII, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TModelHVDCLine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TModelHVDCLine <: DCBranch\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        arc::Arc\n        r::Float64\n        l::Float64\n        c::Float64\n        active_power_limits_from::MinMax\n        active_power_limits_to::MinMax\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA High Voltage DC transmission line for modeling DC transmission networks.\n\nThis line must be connected to a [`DCBus`](@ref) on each end. It uses a T-Model of the line impedance. This is suitable for operational simulations with a multi-terminal DC network\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `r::Float64`: Total series Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\n- `l::Float64`: Total series Inductance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\n- `c::Float64`: Shunt capacitance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `active_power_limits_from::MinMax`: Minimum and maximum active power flows to the FROM node (MW)\n- `active_power_limits_to::MinMax`: Minimum and maximum active power flows to the TO node (MW)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TModelHVDCLine <: DCBranch\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Total series Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\"\n    r::Float64\n    \"Total series Inductance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), split equally on both sides of the shunt capacitance\"\n    l::Float64\n    \"Shunt capacitance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    c::Float64\n    \"Minimum and maximum active power flows to the FROM node (MW)\"\n    active_power_limits_from::MinMax\n    \"Minimum and maximum active power flows to the TO node (MW)\"\n    active_power_limits_to::MinMax\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TModelHVDCLine(name, available, active_power_flow, arc, r, l, c, active_power_limits_from, active_power_limits_to, services=Device[], ext=Dict{String, Any}(), )\n    TModelHVDCLine(name, available, active_power_flow, arc, r, l, c, active_power_limits_from, active_power_limits_to, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction TModelHVDCLine(; name, available, active_power_flow, arc, r, l, c, active_power_limits_from, active_power_limits_to, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    TModelHVDCLine(name, available, active_power_flow, arc, r, l, c, active_power_limits_from, active_power_limits_to, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TModelHVDCLine(::Nothing)\n    TModelHVDCLine(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        arc=Arc(DCBus(nothing), DCBus(nothing)),\n        r=0.0,\n        l=0.0,\n        c=0.0,\n        active_power_limits_from=(min=0.0, max=0.0),\n        active_power_limits_to=(min=0.0, max=0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TModelHVDCLine`](@ref) `name`.\"\"\"\nget_name(value::TModelHVDCLine) = value.name\n\"\"\"Get [`TModelHVDCLine`](@ref) `available`.\"\"\"\nget_available(value::TModelHVDCLine) = value.available\n\"\"\"Get [`TModelHVDCLine`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::TModelHVDCLine) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`TModelHVDCLine`](@ref) `arc`.\"\"\"\nget_arc(value::TModelHVDCLine) = value.arc\n\"\"\"Get [`TModelHVDCLine`](@ref) `r`.\"\"\"\nget_r(value::TModelHVDCLine) = value.r\n\"\"\"Get [`TModelHVDCLine`](@ref) `l`.\"\"\"\nget_l(value::TModelHVDCLine) = value.l\n\"\"\"Get [`TModelHVDCLine`](@ref) `c`.\"\"\"\nget_c(value::TModelHVDCLine) = value.c\n\"\"\"Get [`TModelHVDCLine`](@ref) `active_power_limits_from`.\"\"\"\nget_active_power_limits_from(value::TModelHVDCLine) = get_value(value, Val(:active_power_limits_from), Val(:mva))\n\"\"\"Get [`TModelHVDCLine`](@ref) `active_power_limits_to`.\"\"\"\nget_active_power_limits_to(value::TModelHVDCLine) = get_value(value, Val(:active_power_limits_to), Val(:mva))\n\"\"\"Get [`TModelHVDCLine`](@ref) `services`.\"\"\"\nget_services(value::TModelHVDCLine) = value.services\n\"\"\"Get [`TModelHVDCLine`](@ref) `ext`.\"\"\"\nget_ext(value::TModelHVDCLine) = value.ext\n\"\"\"Get [`TModelHVDCLine`](@ref) `internal`.\"\"\"\nget_internal(value::TModelHVDCLine) = value.internal\n\n\"\"\"Set [`TModelHVDCLine`](@ref) `available`.\"\"\"\nset_available!(value::TModelHVDCLine, val) = value.available = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::TModelHVDCLine, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`TModelHVDCLine`](@ref) `arc`.\"\"\"\nset_arc!(value::TModelHVDCLine, val) = value.arc = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `r`.\"\"\"\nset_r!(value::TModelHVDCLine, val) = value.r = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `l`.\"\"\"\nset_l!(value::TModelHVDCLine, val) = value.l = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `c`.\"\"\"\nset_c!(value::TModelHVDCLine, val) = value.c = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `active_power_limits_from`.\"\"\"\nset_active_power_limits_from!(value::TModelHVDCLine, val) = value.active_power_limits_from = set_value(value, Val(:active_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TModelHVDCLine`](@ref) `active_power_limits_to`.\"\"\"\nset_active_power_limits_to!(value::TModelHVDCLine, val) = value.active_power_limits_to = set_value(value, Val(:active_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TModelHVDCLine`](@ref) `services`.\"\"\"\nset_services!(value::TModelHVDCLine, val) = value.services = val\n\"\"\"Set [`TModelHVDCLine`](@ref) `ext`.\"\"\"\nset_ext!(value::TModelHVDCLine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TapTransformer.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TapTransformer <: TwoWindingTransformer\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        primary_shunt::Complex{Float64}\n        tap::Float64\n        rating::Union{Nothing, Float64}\n        base_power::Float64\n        base_voltage_primary::Union{Nothing, Float64}\n        base_voltage_secondary::Union{Nothing, Float64}\n        rating_b::Union{Nothing, Float64}\n        rating_c::Union{Nothing, Float64}\n        winding_group_number::WindingGroupNumber\n        control_objective::TransformerControlObjective\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA 2-winding transformer, with a tap changer for variable turns ratio.\n\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow through the transformer (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow through the transformer (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\n- `r::Float64`: Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(-2, 2)`\n- `x::Float64`: Reactance in p.u. ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(-2, 4)`\n- `primary_shunt::Complex{Float64}`: Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `tap::Float64`: Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage, validation range: `(0, 2)`\n- `rating::Union{Nothing, Float64}`: Thermal rating (MVA). Flow through the transformer must be between -`rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `base_voltage_primary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(arc))`) Primary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_secondary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_to(arc))`) Secondary base voltage in kV, validation range: `(0, nothing)`\n- `rating_b::Union{Nothing, Float64}`: (default: `nothing`) Second current rating; entered in MVA.\n- `rating_c::Union{Nothing, Float64}`: (default: `nothing`) Third current rating; entered in MVA.\n- `winding_group_number::WindingGroupNumber`: (default: `WindingGroupNumber.UNDEFINED`) Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\n- `control_objective::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TapTransformer <: TwoWindingTransformer\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow through the transformer (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow through the transformer (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    primary_shunt::Complex{Float64}\n    \"Normalized tap changer position for voltage control, varying between 0 and 2, with 1 centered at the nominal voltage\"\n    tap::Float64\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Union{Nothing, Float64}\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Primary base voltage in kV\"\n    base_voltage_primary::Union{Nothing, Float64}\n    \"Secondary base voltage in kV\"\n    base_voltage_secondary::Union{Nothing, Float64}\n    \"Second current rating; entered in MVA.\"\n    rating_b::Union{Nothing, Float64}\n    \"Third current rating; entered in MVA.\"\n    rating_c::Union{Nothing, Float64}\n    \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\"\n    winding_group_number::WindingGroupNumber\n    \"Control objective for the tap changer for power flow calculations. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective::TransformerControlObjective\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TapTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, winding_group_number=WindingGroupNumber.UNDEFINED, control_objective=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), )\n    TapTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, winding_group_number, control_objective, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction TapTransformer(; name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, winding_group_number=WindingGroupNumber.UNDEFINED, control_objective=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    TapTransformer(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, tap, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, winding_group_number, control_objective, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TapTransformer(::Nothing)\n    TapTransformer(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        primary_shunt=0.0,\n        tap=1.0,\n        rating=0.0,\n        base_power=100.0,\n        base_voltage_primary=nothing,\n        base_voltage_secondary=nothing,\n        rating_b=0.0,\n        rating_c=0.0,\n        winding_group_number=WindingGroupNumber.UNDEFINED,\n        control_objective=TransformerControlObjective.UNDEFINED,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TapTransformer`](@ref) `name`.\"\"\"\nget_name(value::TapTransformer) = value.name\n\"\"\"Get [`TapTransformer`](@ref) `available`.\"\"\"\nget_available(value::TapTransformer) = value.available\n\"\"\"Get [`TapTransformer`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::TapTransformer) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`TapTransformer`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::TapTransformer) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`TapTransformer`](@ref) `arc`.\"\"\"\nget_arc(value::TapTransformer) = value.arc\n\"\"\"Get [`TapTransformer`](@ref) `r`.\"\"\"\nget_r(value::TapTransformer) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`TapTransformer`](@ref) `x`.\"\"\"\nget_x(value::TapTransformer) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`TapTransformer`](@ref) `primary_shunt`.\"\"\"\nget_primary_shunt(value::TapTransformer) = get_value(value, Val(:primary_shunt), Val(:siemens))\n\"\"\"Get [`TapTransformer`](@ref) `tap`.\"\"\"\nget_tap(value::TapTransformer) = value.tap\n\"\"\"Get [`TapTransformer`](@ref) `rating`.\"\"\"\nget_rating(value::TapTransformer) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`TapTransformer`](@ref) `base_power`.\"\"\"\nget_base_power(value::TapTransformer) = value.base_power\n\"\"\"Get [`TapTransformer`](@ref) `base_voltage_primary`.\"\"\"\nget_base_voltage_primary(value::TapTransformer) = value.base_voltage_primary\n\"\"\"Get [`TapTransformer`](@ref) `base_voltage_secondary`.\"\"\"\nget_base_voltage_secondary(value::TapTransformer) = value.base_voltage_secondary\n\"\"\"Get [`TapTransformer`](@ref) `rating_b`.\"\"\"\nget_rating_b(value::TapTransformer) = get_value(value, Val(:rating_b), Val(:mva))\n\"\"\"Get [`TapTransformer`](@ref) `rating_c`.\"\"\"\nget_rating_c(value::TapTransformer) = get_value(value, Val(:rating_c), Val(:mva))\n\"\"\"Get [`TapTransformer`](@ref) `winding_group_number`.\"\"\"\nget_winding_group_number(value::TapTransformer) = value.winding_group_number\n\"\"\"Get [`TapTransformer`](@ref) `control_objective`.\"\"\"\nget_control_objective(value::TapTransformer) = value.control_objective\n\"\"\"Get [`TapTransformer`](@ref) `services`.\"\"\"\nget_services(value::TapTransformer) = value.services\n\"\"\"Get [`TapTransformer`](@ref) `ext`.\"\"\"\nget_ext(value::TapTransformer) = value.ext\n\"\"\"Get [`TapTransformer`](@ref) `internal`.\"\"\"\nget_internal(value::TapTransformer) = value.internal\n\n\"\"\"Set [`TapTransformer`](@ref) `available`.\"\"\"\nset_available!(value::TapTransformer, val) = value.available = val\n\"\"\"Set [`TapTransformer`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::TapTransformer, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`TapTransformer`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::TapTransformer, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`TapTransformer`](@ref) `arc`.\"\"\"\nset_arc!(value::TapTransformer, val) = value.arc = val\n\"\"\"Set [`TapTransformer`](@ref) `r`.\"\"\"\nset_r!(value::TapTransformer, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`TapTransformer`](@ref) `x`.\"\"\"\nset_x!(value::TapTransformer, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`TapTransformer`](@ref) `primary_shunt`.\"\"\"\nset_primary_shunt!(value::TapTransformer, val) = value.primary_shunt = set_value(value, Val(:primary_shunt), val, Val(:siemens))\n\"\"\"Set [`TapTransformer`](@ref) `tap`.\"\"\"\nset_tap!(value::TapTransformer, val) = value.tap = val\n\"\"\"Set [`TapTransformer`](@ref) `rating`.\"\"\"\nset_rating!(value::TapTransformer, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`TapTransformer`](@ref) `base_power`.\"\"\"\nset_base_power!(value::TapTransformer, val) = value.base_power = val\n\"\"\"Set [`TapTransformer`](@ref) `base_voltage_primary`.\"\"\"\nset_base_voltage_primary!(value::TapTransformer, val) = value.base_voltage_primary = val\n\"\"\"Set [`TapTransformer`](@ref) `base_voltage_secondary`.\"\"\"\nset_base_voltage_secondary!(value::TapTransformer, val) = value.base_voltage_secondary = val\n\"\"\"Set [`TapTransformer`](@ref) `rating_b`.\"\"\"\nset_rating_b!(value::TapTransformer, val) = value.rating_b = set_value(value, Val(:rating_b), val, Val(:mva))\n\"\"\"Set [`TapTransformer`](@ref) `rating_c`.\"\"\"\nset_rating_c!(value::TapTransformer, val) = value.rating_c = set_value(value, Val(:rating_c), val, Val(:mva))\n\"\"\"Set [`TapTransformer`](@ref) `winding_group_number`.\"\"\"\nset_winding_group_number!(value::TapTransformer, val) = value.winding_group_number = val\n\"\"\"Set [`TapTransformer`](@ref) `control_objective`.\"\"\"\nset_control_objective!(value::TapTransformer, val) = value.control_objective = val\n\"\"\"Set [`TapTransformer`](@ref) `services`.\"\"\"\nset_services!(value::TapTransformer, val) = value.services = val\n\"\"\"Set [`TapTransformer`](@ref) `ext`.\"\"\"\nset_ext!(value::TapTransformer, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ThermalMultiStart.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ThermalMultiStart <: ThermalGen\n        name::String\n        available::Bool\n        status::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        prime_mover_type::PrimeMovers\n        fuel::ThermalFuels\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        ramp_limits::Union{Nothing, UpDown}\n        power_trajectory::Union{Nothing, StartUpShutDown}\n        time_limits::Union{Nothing, UpDown}\n        start_time_limits::Union{Nothing, StartUpStages}\n        start_types::Int\n        operation_cost::Union{ThermalGenerationCost, MarketBidCost}\n        base_power::Float64\n        services::Vector{Service}\n        time_at_status::Float64\n        must_run::Bool\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA thermal generator, such as a fossil fuel or nuclear generator, that can start-up again from a *hot*, *warm*, or *cold* state.\n\n`ThermalMultiStart` has a detailed representation of the start-up process based on the time elapsed since the last shut down, as well as a detailed shut-down process. The model is based on [\"Tight and Compact MILP Formulation for the Thermal Unit Commitment Problem.\"](https://doi.org/10.1109/TPWRS.2013.2251373). For a simplified representation of the start-up and shut-down processes, see [`ThermalStandard`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `status::Bool`: Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used, validation range: `active_power_limits`\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `prime_mover_type::PrimeMovers`: Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `fuel::ThermalFuels`: Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW)\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `ramp_limits::Union{Nothing, UpDown}`:, validation range: `(0, nothing)`\n- `power_trajectory::Union{Nothing, StartUpShutDown}`: Power trajectory the unit will take during the start-up and shut-down ramp process, validation range: `(0, nothing)`\n- `time_limits::Union{Nothing, UpDown}`: Minimum up and Minimum down time limits in hours, validation range: `(0, nothing)`\n- `start_time_limits::Union{Nothing, StartUpStages}`: Time limits for start-up based on turbine temperature in hours\n- `start_types::Int`: Number of start-up based on turbine temperature, where `1` = *hot*, `2` = *warm*, and `3` = *cold*, validation range: `(1, 3)`\n- `operation_cost::Union{ThermalGenerationCost, MarketBidCost}`: [`OperationalCost`](@ref) of generation\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `time_at_status::Float64`: (default: `INFINITE_TIME`) Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\n- `must_run::Bool`: (default: `false`) Set to `true` if the unit is must run\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ThermalMultiStart <: ThermalGen\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\"\n    status::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\"\n    fuel::ThermalFuels\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    ramp_limits::Union{Nothing, UpDown}\n    \"Power trajectory the unit will take during the start-up and shut-down ramp process\"\n    power_trajectory::Union{Nothing, StartUpShutDown}\n    \"Minimum up and Minimum down time limits in hours\"\n    time_limits::Union{Nothing, UpDown}\n    \"Time limits for start-up based on turbine temperature in hours\"\n    start_time_limits::Union{Nothing, StartUpStages}\n    \"Number of start-up based on turbine temperature, where `1` = *hot*, `2` = *warm*, and `3` = *cold*\"\n    start_types::Int\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{ThermalGenerationCost, MarketBidCost}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\"\n    time_at_status::Float64\n    \"Set to `true` if the unit is must run\"\n    must_run::Bool\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ThermalMultiStart(name, available, status, bus, active_power, reactive_power, rating, prime_mover_type, fuel, active_power_limits, reactive_power_limits, ramp_limits, power_trajectory, time_limits, start_time_limits, start_types, operation_cost, base_power, services=Device[], time_at_status=INFINITE_TIME, must_run=false, dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    ThermalMultiStart(name, available, status, bus, active_power, reactive_power, rating, prime_mover_type, fuel, active_power_limits, reactive_power_limits, ramp_limits, power_trajectory, time_limits, start_time_limits, start_types, operation_cost, base_power, services, time_at_status, must_run, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ThermalMultiStart(; name, available, status, bus, active_power, reactive_power, rating, prime_mover_type, fuel, active_power_limits, reactive_power_limits, ramp_limits, power_trajectory, time_limits, start_time_limits, start_types, operation_cost, base_power, services=Device[], time_at_status=INFINITE_TIME, must_run=false, dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ThermalMultiStart(name, available, status, bus, active_power, reactive_power, rating, prime_mover_type, fuel, active_power_limits, reactive_power_limits, ramp_limits, power_trajectory, time_limits, start_time_limits, start_types, operation_cost, base_power, services, time_at_status, must_run, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ThermalMultiStart(::Nothing)\n    ThermalMultiStart(;\n        name=\"init\",\n        available=false,\n        status=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        prime_mover_type=PrimeMovers.OT,\n        fuel=ThermalFuels.OTHER,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        ramp_limits=nothing,\n        power_trajectory=nothing,\n        time_limits=nothing,\n        start_time_limits=nothing,\n        start_types=1,\n        operation_cost=ThermalGenerationCost(nothing),\n        base_power=100.0,\n        services=Device[],\n        time_at_status=INFINITE_TIME,\n        must_run=false,\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ThermalMultiStart`](@ref) `name`.\"\"\"\nget_name(value::ThermalMultiStart) = value.name\n\"\"\"Get [`ThermalMultiStart`](@ref) `available`.\"\"\"\nget_available(value::ThermalMultiStart) = value.available\n\"\"\"Get [`ThermalMultiStart`](@ref) `status`.\"\"\"\nget_status(value::ThermalMultiStart) = value.status\n\"\"\"Get [`ThermalMultiStart`](@ref) `bus`.\"\"\"\nget_bus(value::ThermalMultiStart) = value.bus\n\"\"\"Get [`ThermalMultiStart`](@ref) `active_power`.\"\"\"\nget_active_power(value::ThermalMultiStart) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::ThermalMultiStart) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `rating`.\"\"\"\nget_rating(value::ThermalMultiStart) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::ThermalMultiStart) = value.prime_mover_type\n\"\"\"Get [`ThermalMultiStart`](@ref) `fuel`.\"\"\"\nget_fuel(value::ThermalMultiStart) = value.fuel\n\"\"\"Get [`ThermalMultiStart`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::ThermalMultiStart) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::ThermalMultiStart) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `ramp_limits`.\"\"\"\nget_ramp_limits(value::ThermalMultiStart) = get_value(value, Val(:ramp_limits), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `power_trajectory`.\"\"\"\nget_power_trajectory(value::ThermalMultiStart) = get_value(value, Val(:power_trajectory), Val(:mva))\n\"\"\"Get [`ThermalMultiStart`](@ref) `time_limits`.\"\"\"\nget_time_limits(value::ThermalMultiStart) = value.time_limits\n\"\"\"Get [`ThermalMultiStart`](@ref) `start_time_limits`.\"\"\"\nget_start_time_limits(value::ThermalMultiStart) = value.start_time_limits\n\"\"\"Get [`ThermalMultiStart`](@ref) `start_types`.\"\"\"\nget_start_types(value::ThermalMultiStart) = value.start_types\n\"\"\"Get [`ThermalMultiStart`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::ThermalMultiStart) = value.operation_cost\n\"\"\"Get [`ThermalMultiStart`](@ref) `base_power`.\"\"\"\nget_base_power(value::ThermalMultiStart) = value.base_power\n\"\"\"Get [`ThermalMultiStart`](@ref) `services`.\"\"\"\nget_services(value::ThermalMultiStart) = value.services\n\"\"\"Get [`ThermalMultiStart`](@ref) `time_at_status`.\"\"\"\nget_time_at_status(value::ThermalMultiStart) = value.time_at_status\n\"\"\"Get [`ThermalMultiStart`](@ref) `must_run`.\"\"\"\nget_must_run(value::ThermalMultiStart) = value.must_run\n\"\"\"Get [`ThermalMultiStart`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::ThermalMultiStart) = value.dynamic_injector\n\"\"\"Get [`ThermalMultiStart`](@ref) `ext`.\"\"\"\nget_ext(value::ThermalMultiStart) = value.ext\n\"\"\"Get [`ThermalMultiStart`](@ref) `internal`.\"\"\"\nget_internal(value::ThermalMultiStart) = value.internal\n\n\"\"\"Set [`ThermalMultiStart`](@ref) `available`.\"\"\"\nset_available!(value::ThermalMultiStart, val) = value.available = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `status`.\"\"\"\nset_status!(value::ThermalMultiStart, val) = value.status = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `bus`.\"\"\"\nset_bus!(value::ThermalMultiStart, val) = value.bus = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `active_power`.\"\"\"\nset_active_power!(value::ThermalMultiStart, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::ThermalMultiStart, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `rating`.\"\"\"\nset_rating!(value::ThermalMultiStart, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::ThermalMultiStart, val) = value.prime_mover_type = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `fuel`.\"\"\"\nset_fuel!(value::ThermalMultiStart, val) = value.fuel = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::ThermalMultiStart, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::ThermalMultiStart, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `ramp_limits`.\"\"\"\nset_ramp_limits!(value::ThermalMultiStart, val) = value.ramp_limits = set_value(value, Val(:ramp_limits), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `power_trajectory`.\"\"\"\nset_power_trajectory!(value::ThermalMultiStart, val) = value.power_trajectory = set_value(value, Val(:power_trajectory), val, Val(:mva))\n\"\"\"Set [`ThermalMultiStart`](@ref) `time_limits`.\"\"\"\nset_time_limits!(value::ThermalMultiStart, val) = value.time_limits = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `start_time_limits`.\"\"\"\nset_start_time_limits!(value::ThermalMultiStart, val) = value.start_time_limits = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `start_types`.\"\"\"\nset_start_types!(value::ThermalMultiStart, val) = value.start_types = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::ThermalMultiStart, val) = value.operation_cost = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `base_power`.\"\"\"\nset_base_power!(value::ThermalMultiStart, val) = value.base_power = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `services`.\"\"\"\nset_services!(value::ThermalMultiStart, val) = value.services = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `time_at_status`.\"\"\"\nset_time_at_status!(value::ThermalMultiStart, val) = value.time_at_status = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `must_run`.\"\"\"\nset_must_run!(value::ThermalMultiStart, val) = value.must_run = val\n\"\"\"Set [`ThermalMultiStart`](@ref) `ext`.\"\"\"\nset_ext!(value::ThermalMultiStart, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/ThermalStandard.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ThermalStandard <: ThermalGen\n        name::String\n        available::Bool\n        status::Bool\n        bus::ACBus\n        active_power::Float64\n        reactive_power::Float64\n        rating::Float64\n        active_power_limits::MinMax\n        reactive_power_limits::Union{Nothing, MinMax}\n        ramp_limits::Union{Nothing, UpDown}\n        operation_cost::Union{ThermalGenerationCost, MarketBidCost}\n        base_power::Float64\n        time_limits::Union{Nothing, UpDown}\n        must_run::Bool\n        prime_mover_type::PrimeMovers\n        fuel::ThermalFuels\n        services::Vector{Service}\n        time_at_status::Float64\n        dynamic_injector::Union{Nothing, DynamicInjection}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA thermal generator, such as a fossil fuel and nuclear generator.\n\nThis is a standard representation with options to include a minimum up time, minimum down time, and ramp limits. For a more detailed representation the start-up and shut-down processes, including hot starts, see [`ThermalMultiStart`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `status::Bool`: Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\n- `bus::ACBus`: Bus that this component is connected to\n- `active_power::Float64`: Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used, validation range: `active_power_limits`\n- `reactive_power::Float64`: Initial reactive power set point of the unit (MVAR), validation range: `reactive_power_limits`\n- `rating::Float64`: Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power, validation range: `(0, nothing)`\n- `active_power_limits::MinMax`: Minimum and maximum stable active power levels (MW), validation range: `(0, nothing)`\n- `reactive_power_limits::Union{Nothing, MinMax}`: Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\n- `ramp_limits::Union{Nothing, UpDown}`: ramp up and ramp down limits in MW/min, validation range: `(0, nothing)`\n- `operation_cost::Union{ThermalGenerationCost, MarketBidCost}`: [`OperationalCost`](@ref) of generation\n- `base_power::Float64`: Base power of the unit (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `time_limits::Union{Nothing, UpDown}`: (default: `nothing`) Minimum up and Minimum down time limits in hours, validation range: `(0, nothing)`\n- `must_run::Bool`: (default: `false`) Set to `true` if the unit is must run\n- `prime_mover_type::PrimeMovers`: (default: `PrimeMovers.OT`) Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\n- `fuel::ThermalFuels`: (default: `ThermalFuels.OTHER`) Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `time_at_status::Float64`: (default: `INFINITE_TIME`) Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\n- `dynamic_injector::Union{Nothing, DynamicInjection}`: (default: `nothing`) corresponding dynamic injection device\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct ThermalStandard <: ThermalGen\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial commitment condition at the start of a simulation (`true` = on or `false` = off)\"\n    status::Bool\n    \"Bus that this component is connected to\"\n    bus::ACBus\n    \"Initial active power set point of the unit in MW. For power flow, this is the steady state operating point of the system. For production cost modeling, this may or may not be used as the initial starting point for the solver, depending on the solver used\"\n    active_power::Float64\n    \"Initial reactive power set point of the unit (MVAR)\"\n    reactive_power::Float64\n    \"Maximum AC side output power rating of the unit. Stored in per unit of the device and not to be confused with base_power\"\n    rating::Float64\n    \"Minimum and maximum stable active power levels (MW)\"\n    active_power_limits::MinMax\n    \"Minimum and maximum reactive power limits. Set to `Nothing` if not applicable\"\n    reactive_power_limits::Union{Nothing, MinMax}\n    \"ramp up and ramp down limits in MW/min\"\n    ramp_limits::Union{Nothing, UpDown}\n    \"[`OperationalCost`](@ref) of generation\"\n    operation_cost::Union{ThermalGenerationCost, MarketBidCost}\n    \"Base power of the unit (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Minimum up and Minimum down time limits in hours\"\n    time_limits::Union{Nothing, UpDown}\n    \"Set to `true` if the unit is must run\"\n    must_run::Bool\n    \"Prime mover technology according to EIA 923. Options are listed [here](@ref pm_list)\"\n    prime_mover_type::PrimeMovers\n    \"Prime mover fuel according to EIA 923. Options are listed [here](@ref tf_list)\"\n    fuel::ThermalFuels\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"Time (e.g., `Hours(6)`) the generator has been on or off, as indicated by `status`\"\n    time_at_status::Float64\n    \"corresponding dynamic injection device\"\n    dynamic_injector::Union{Nothing, DynamicInjection}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction ThermalStandard(name, available, status, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, ramp_limits, operation_cost, base_power, time_limits=nothing, must_run=false, prime_mover_type=PrimeMovers.OT, fuel=ThermalFuels.OTHER, services=Device[], time_at_status=INFINITE_TIME, dynamic_injector=nothing, ext=Dict{String, Any}(), )\n    ThermalStandard(name, available, status, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, ramp_limits, operation_cost, base_power, time_limits, must_run, prime_mover_type, fuel, services, time_at_status, dynamic_injector, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction ThermalStandard(; name, available, status, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, ramp_limits, operation_cost, base_power, time_limits=nothing, must_run=false, prime_mover_type=PrimeMovers.OT, fuel=ThermalFuels.OTHER, services=Device[], time_at_status=INFINITE_TIME, dynamic_injector=nothing, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    ThermalStandard(name, available, status, bus, active_power, reactive_power, rating, active_power_limits, reactive_power_limits, ramp_limits, operation_cost, base_power, time_limits, must_run, prime_mover_type, fuel, services, time_at_status, dynamic_injector, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ThermalStandard(::Nothing)\n    ThermalStandard(;\n        name=\"init\",\n        available=false,\n        status=false,\n        bus=ACBus(nothing),\n        active_power=0.0,\n        reactive_power=0.0,\n        rating=0.0,\n        active_power_limits=(min=0.0, max=0.0),\n        reactive_power_limits=nothing,\n        ramp_limits=nothing,\n        operation_cost=ThermalGenerationCost(nothing),\n        base_power=100.0,\n        time_limits=nothing,\n        must_run=false,\n        prime_mover_type=PrimeMovers.OT,\n        fuel=ThermalFuels.OTHER,\n        services=Device[],\n        time_at_status=INFINITE_TIME,\n        dynamic_injector=nothing,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ThermalStandard`](@ref) `name`.\"\"\"\nget_name(value::ThermalStandard) = value.name\n\"\"\"Get [`ThermalStandard`](@ref) `available`.\"\"\"\nget_available(value::ThermalStandard) = value.available\n\"\"\"Get [`ThermalStandard`](@ref) `status`.\"\"\"\nget_status(value::ThermalStandard) = value.status\n\"\"\"Get [`ThermalStandard`](@ref) `bus`.\"\"\"\nget_bus(value::ThermalStandard) = value.bus\n\"\"\"Get [`ThermalStandard`](@ref) `active_power`.\"\"\"\nget_active_power(value::ThermalStandard) = get_value(value, Val(:active_power), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `reactive_power`.\"\"\"\nget_reactive_power(value::ThermalStandard) = get_value(value, Val(:reactive_power), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `rating`.\"\"\"\nget_rating(value::ThermalStandard) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `active_power_limits`.\"\"\"\nget_active_power_limits(value::ThermalStandard) = get_value(value, Val(:active_power_limits), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `reactive_power_limits`.\"\"\"\nget_reactive_power_limits(value::ThermalStandard) = get_value(value, Val(:reactive_power_limits), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `ramp_limits`.\"\"\"\nget_ramp_limits(value::ThermalStandard) = get_value(value, Val(:ramp_limits), Val(:mva))\n\"\"\"Get [`ThermalStandard`](@ref) `operation_cost`.\"\"\"\nget_operation_cost(value::ThermalStandard) = value.operation_cost\n\"\"\"Get [`ThermalStandard`](@ref) `base_power`.\"\"\"\nget_base_power(value::ThermalStandard) = value.base_power\n\"\"\"Get [`ThermalStandard`](@ref) `time_limits`.\"\"\"\nget_time_limits(value::ThermalStandard) = value.time_limits\n\"\"\"Get [`ThermalStandard`](@ref) `must_run`.\"\"\"\nget_must_run(value::ThermalStandard) = value.must_run\n\"\"\"Get [`ThermalStandard`](@ref) `prime_mover_type`.\"\"\"\nget_prime_mover_type(value::ThermalStandard) = value.prime_mover_type\n\"\"\"Get [`ThermalStandard`](@ref) `fuel`.\"\"\"\nget_fuel(value::ThermalStandard) = value.fuel\n\"\"\"Get [`ThermalStandard`](@ref) `services`.\"\"\"\nget_services(value::ThermalStandard) = value.services\n\"\"\"Get [`ThermalStandard`](@ref) `time_at_status`.\"\"\"\nget_time_at_status(value::ThermalStandard) = value.time_at_status\n\"\"\"Get [`ThermalStandard`](@ref) `dynamic_injector`.\"\"\"\nget_dynamic_injector(value::ThermalStandard) = value.dynamic_injector\n\"\"\"Get [`ThermalStandard`](@ref) `ext`.\"\"\"\nget_ext(value::ThermalStandard) = value.ext\n\"\"\"Get [`ThermalStandard`](@ref) `internal`.\"\"\"\nget_internal(value::ThermalStandard) = value.internal\n\n\"\"\"Set [`ThermalStandard`](@ref) `available`.\"\"\"\nset_available!(value::ThermalStandard, val) = value.available = val\n\"\"\"Set [`ThermalStandard`](@ref) `status`.\"\"\"\nset_status!(value::ThermalStandard, val) = value.status = val\n\"\"\"Set [`ThermalStandard`](@ref) `bus`.\"\"\"\nset_bus!(value::ThermalStandard, val) = value.bus = val\n\"\"\"Set [`ThermalStandard`](@ref) `active_power`.\"\"\"\nset_active_power!(value::ThermalStandard, val) = value.active_power = set_value(value, Val(:active_power), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `reactive_power`.\"\"\"\nset_reactive_power!(value::ThermalStandard, val) = value.reactive_power = set_value(value, Val(:reactive_power), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `rating`.\"\"\"\nset_rating!(value::ThermalStandard, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `active_power_limits`.\"\"\"\nset_active_power_limits!(value::ThermalStandard, val) = value.active_power_limits = set_value(value, Val(:active_power_limits), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `reactive_power_limits`.\"\"\"\nset_reactive_power_limits!(value::ThermalStandard, val) = value.reactive_power_limits = set_value(value, Val(:reactive_power_limits), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `ramp_limits`.\"\"\"\nset_ramp_limits!(value::ThermalStandard, val) = value.ramp_limits = set_value(value, Val(:ramp_limits), val, Val(:mva))\n\"\"\"Set [`ThermalStandard`](@ref) `operation_cost`.\"\"\"\nset_operation_cost!(value::ThermalStandard, val) = value.operation_cost = val\n\"\"\"Set [`ThermalStandard`](@ref) `base_power`.\"\"\"\nset_base_power!(value::ThermalStandard, val) = value.base_power = val\n\"\"\"Set [`ThermalStandard`](@ref) `time_limits`.\"\"\"\nset_time_limits!(value::ThermalStandard, val) = value.time_limits = val\n\"\"\"Set [`ThermalStandard`](@ref) `must_run`.\"\"\"\nset_must_run!(value::ThermalStandard, val) = value.must_run = val\n\"\"\"Set [`ThermalStandard`](@ref) `prime_mover_type`.\"\"\"\nset_prime_mover_type!(value::ThermalStandard, val) = value.prime_mover_type = val\n\"\"\"Set [`ThermalStandard`](@ref) `fuel`.\"\"\"\nset_fuel!(value::ThermalStandard, val) = value.fuel = val\n\"\"\"Set [`ThermalStandard`](@ref) `services`.\"\"\"\nset_services!(value::ThermalStandard, val) = value.services = val\n\"\"\"Set [`ThermalStandard`](@ref) `time_at_status`.\"\"\"\nset_time_at_status!(value::ThermalStandard, val) = value.time_at_status = val\n\"\"\"Set [`ThermalStandard`](@ref) `ext`.\"\"\"\nset_ext!(value::ThermalStandard, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/Transformer2W.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Transformer2W <: TwoWindingTransformer\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        reactive_power_flow::Float64\n        arc::Arc\n        r::Float64\n        x::Float64\n        primary_shunt::Complex{Float64}\n        rating::Union{Nothing, Float64}\n        base_power::Float64\n        base_voltage_primary::Union{Nothing, Float64}\n        base_voltage_secondary::Union{Nothing, Float64}\n        rating_b::Union{Nothing, Float64}\n        rating_c::Union{Nothing, Float64}\n        winding_group_number::WindingGroupNumber\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA basic 2-winding transformer.\n\nThe model uses an equivalent circuit assuming the impedance is on the High Voltage Side of the transformer. The model allocates the iron losses and magnetizing susceptance to the primary side\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow through the transformer (MW)\n- `reactive_power_flow::Float64`: Initial condition of reactive power flow through the transformer (MVAR)\n- `arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\n- `r::Float64`: Resistance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(-2, 4)`\n- `x::Float64`: Reactance in pu ([`SYSTEM_BASE`](@ref per_unit)), validation range: `(-2, 4)`\n- `primary_shunt::Complex{Float64}`: Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `rating::Union{Nothing, Float64}`: Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to, validation range: `(0, nothing)`\n- `base_power::Float64`: Base power (MVA) for [per unitization](@ref per_unit), validation range: `(0.0001, nothing)`\n- `base_voltage_primary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(arc))`) Primary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_secondary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_to(arc))`) Secondary base voltage in kV, validation range: `(0, nothing)`\n- `rating_b::Union{Nothing, Float64}`: (default: `nothing`) Second current rating; entered in MVA.\n- `rating_c::Union{Nothing, Float64}`: (default: `nothing`) Third current rating; entered in MVA.\n- `winding_group_number::WindingGroupNumber`: (default: `WindingGroupNumber.UNDEFINED`) Vector group number ('clock number') indicating phase shift (radians) between the `from` and `to` buses\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Transformer2W <: TwoWindingTransformer\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow through the transformer (MW)\"\n    active_power_flow::Float64\n    \"Initial condition of reactive power flow through the transformer (MVAR)\"\n    reactive_power_flow::Float64\n    \"An [`Arc`](@ref) defining this transformer `from` a bus `to` another bus\"\n    arc::Arc\n    \"Resistance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Reactance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    x::Float64\n    \"Primary shunt admittance in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    primary_shunt::Complex{Float64}\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Union{Nothing, Float64}\n    \"Base power (MVA) for [per unitization](@ref per_unit)\"\n    base_power::Float64\n    \"Primary base voltage in kV\"\n    base_voltage_primary::Union{Nothing, Float64}\n    \"Secondary base voltage in kV\"\n    base_voltage_secondary::Union{Nothing, Float64}\n    \"Second current rating; entered in MVA.\"\n    rating_b::Union{Nothing, Float64}\n    \"Third current rating; entered in MVA.\"\n    rating_c::Union{Nothing, Float64}\n    \"Vector group number ('clock number') indicating phase shift (radians) between the `from` and `to` buses\"\n    winding_group_number::WindingGroupNumber\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, winding_group_number=WindingGroupNumber.UNDEFINED, services=Device[], ext=Dict{String, Any}(), )\n    Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, winding_group_number, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction Transformer2W(; name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rating, base_power, base_voltage_primary=get_base_voltage(get_from(arc)), base_voltage_secondary=get_base_voltage(get_to(arc)), rating_b=nothing, rating_c=nothing, winding_group_number=WindingGroupNumber.UNDEFINED, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    Transformer2W(name, available, active_power_flow, reactive_power_flow, arc, r, x, primary_shunt, rating, base_power, base_voltage_primary, base_voltage_secondary, rating_b, rating_c, winding_group_number, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Transformer2W(::Nothing)\n    Transformer2W(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        reactive_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        r=0.0,\n        x=0.0,\n        primary_shunt=0.0,\n        rating=nothing,\n        base_power=100.0,\n        base_voltage_primary=nothing,\n        base_voltage_secondary=nothing,\n        rating_b=0.0,\n        rating_c=0.0,\n        winding_group_number=WindingGroupNumber.UNDEFINED,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`Transformer2W`](@ref) `name`.\"\"\"\nget_name(value::Transformer2W) = value.name\n\"\"\"Get [`Transformer2W`](@ref) `available`.\"\"\"\nget_available(value::Transformer2W) = value.available\n\"\"\"Get [`Transformer2W`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::Transformer2W) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`Transformer2W`](@ref) `reactive_power_flow`.\"\"\"\nget_reactive_power_flow(value::Transformer2W) = get_value(value, Val(:reactive_power_flow), Val(:mva))\n\"\"\"Get [`Transformer2W`](@ref) `arc`.\"\"\"\nget_arc(value::Transformer2W) = value.arc\n\"\"\"Get [`Transformer2W`](@ref) `r`.\"\"\"\nget_r(value::Transformer2W) = get_value(value, Val(:r), Val(:ohm))\n\"\"\"Get [`Transformer2W`](@ref) `x`.\"\"\"\nget_x(value::Transformer2W) = get_value(value, Val(:x), Val(:ohm))\n\"\"\"Get [`Transformer2W`](@ref) `primary_shunt`.\"\"\"\nget_primary_shunt(value::Transformer2W) = get_value(value, Val(:primary_shunt), Val(:siemens))\n\"\"\"Get [`Transformer2W`](@ref) `rating`.\"\"\"\nget_rating(value::Transformer2W) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`Transformer2W`](@ref) `base_power`.\"\"\"\nget_base_power(value::Transformer2W) = value.base_power\n\"\"\"Get [`Transformer2W`](@ref) `base_voltage_primary`.\"\"\"\nget_base_voltage_primary(value::Transformer2W) = value.base_voltage_primary\n\"\"\"Get [`Transformer2W`](@ref) `base_voltage_secondary`.\"\"\"\nget_base_voltage_secondary(value::Transformer2W) = value.base_voltage_secondary\n\"\"\"Get [`Transformer2W`](@ref) `rating_b`.\"\"\"\nget_rating_b(value::Transformer2W) = get_value(value, Val(:rating_b), Val(:mva))\n\"\"\"Get [`Transformer2W`](@ref) `rating_c`.\"\"\"\nget_rating_c(value::Transformer2W) = get_value(value, Val(:rating_c), Val(:mva))\n\"\"\"Get [`Transformer2W`](@ref) `winding_group_number`.\"\"\"\nget_winding_group_number(value::Transformer2W) = value.winding_group_number\n\"\"\"Get [`Transformer2W`](@ref) `services`.\"\"\"\nget_services(value::Transformer2W) = value.services\n\"\"\"Get [`Transformer2W`](@ref) `ext`.\"\"\"\nget_ext(value::Transformer2W) = value.ext\n\"\"\"Get [`Transformer2W`](@ref) `internal`.\"\"\"\nget_internal(value::Transformer2W) = value.internal\n\n\"\"\"Set [`Transformer2W`](@ref) `available`.\"\"\"\nset_available!(value::Transformer2W, val) = value.available = val\n\"\"\"Set [`Transformer2W`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::Transformer2W, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`Transformer2W`](@ref) `reactive_power_flow`.\"\"\"\nset_reactive_power_flow!(value::Transformer2W, val) = value.reactive_power_flow = set_value(value, Val(:reactive_power_flow), val, Val(:mva))\n\"\"\"Set [`Transformer2W`](@ref) `arc`.\"\"\"\nset_arc!(value::Transformer2W, val) = value.arc = val\n\"\"\"Set [`Transformer2W`](@ref) `r`.\"\"\"\nset_r!(value::Transformer2W, val) = value.r = set_value(value, Val(:r), val, Val(:ohm))\n\"\"\"Set [`Transformer2W`](@ref) `x`.\"\"\"\nset_x!(value::Transformer2W, val) = value.x = set_value(value, Val(:x), val, Val(:ohm))\n\"\"\"Set [`Transformer2W`](@ref) `primary_shunt`.\"\"\"\nset_primary_shunt!(value::Transformer2W, val) = value.primary_shunt = set_value(value, Val(:primary_shunt), val, Val(:siemens))\n\"\"\"Set [`Transformer2W`](@ref) `rating`.\"\"\"\nset_rating!(value::Transformer2W, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`Transformer2W`](@ref) `base_power`.\"\"\"\nset_base_power!(value::Transformer2W, val) = value.base_power = val\n\"\"\"Set [`Transformer2W`](@ref) `base_voltage_primary`.\"\"\"\nset_base_voltage_primary!(value::Transformer2W, val) = value.base_voltage_primary = val\n\"\"\"Set [`Transformer2W`](@ref) `base_voltage_secondary`.\"\"\"\nset_base_voltage_secondary!(value::Transformer2W, val) = value.base_voltage_secondary = val\n\"\"\"Set [`Transformer2W`](@ref) `rating_b`.\"\"\"\nset_rating_b!(value::Transformer2W, val) = value.rating_b = set_value(value, Val(:rating_b), val, Val(:mva))\n\"\"\"Set [`Transformer2W`](@ref) `rating_c`.\"\"\"\nset_rating_c!(value::Transformer2W, val) = value.rating_c = set_value(value, Val(:rating_c), val, Val(:mva))\n\"\"\"Set [`Transformer2W`](@ref) `winding_group_number`.\"\"\"\nset_winding_group_number!(value::Transformer2W, val) = value.winding_group_number = val\n\"\"\"Set [`Transformer2W`](@ref) `services`.\"\"\"\nset_services!(value::Transformer2W, val) = value.services = val\n\"\"\"Set [`Transformer2W`](@ref) `ext`.\"\"\"\nset_ext!(value::Transformer2W, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/Transformer3W.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct Transformer3W <: ThreeWindingTransformer\n        name::String\n        available::Bool\n        primary_star_arc::Arc\n        secondary_star_arc::Arc\n        tertiary_star_arc::Arc\n        star_bus::ACBus\n        active_power_flow_primary::Float64\n        reactive_power_flow_primary::Float64\n        active_power_flow_secondary::Float64\n        reactive_power_flow_secondary::Float64\n        active_power_flow_tertiary::Float64\n        reactive_power_flow_tertiary::Float64\n        r_primary::Float64\n        x_primary::Float64\n        r_secondary::Float64\n        x_secondary::Float64\n        r_tertiary::Float64\n        x_tertiary::Float64\n        rating::Union{Nothing, Float64}\n        r_12::Float64\n        x_12::Float64\n        r_23::Float64\n        x_23::Float64\n        r_13::Float64\n        x_13::Float64\n        base_power_12::Float64\n        base_power_23::Float64\n        base_power_13::Float64\n        base_voltage_primary::Union{Nothing, Float64}\n        base_voltage_secondary::Union{Nothing, Float64}\n        base_voltage_tertiary::Union{Nothing, Float64}\n        g::Float64\n        b::Float64\n        primary_turns_ratio::Float64\n        secondary_turns_ratio::Float64\n        tertiary_turns_ratio::Float64\n        available_primary::Bool\n        available_secondary::Bool\n        available_tertiary::Bool\n        rating_primary::Float64\n        rating_secondary::Float64\n        rating_tertiary::Float64\n        primary_group_number::WindingGroupNumber\n        secondary_group_number::WindingGroupNumber\n        tertiary_group_number::WindingGroupNumber\n        control_objective_primary::TransformerControlObjective\n        control_objective_secondary::TransformerControlObjective\n        control_objective_tertiary::TransformerControlObjective\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA 3-winding transformer.\n\nThe model uses an equivalent star model with a star (hidden) bus. The user must transform the data to use `CW = CZ = CM = 1` and `COD1 = COD2 = COD3 = 0` (no voltage control) if taken from a PSS/E 3W transformer model. Three equivalent impedances (connecting each side to the star bus) are required to define the model. Shunt conductance (iron losses) and magnetizing susceptance can be considered from the star bus to ground. The model is described in Chapter 3.6 in J.D. Glover, M.S. Sarma and T. Overbye: Power Systems Analysis and Design.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `primary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\n- `secondary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\n- `tertiary_star_arc::Arc`: An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\n- `star_bus::ACBus`: Star (hidden) Bus that this component (equivalent model) is connected to\n- `active_power_flow_primary::Float64`: Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\n- `reactive_power_flow_primary::Float64`: Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\n- `active_power_flow_secondary::Float64`: Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\n- `reactive_power_flow_secondary::Float64`: Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\n- `active_power_flow_tertiary::Float64`: Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\n- `reactive_power_flow_tertiary::Float64`: Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\n- `r_primary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_primary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus., validation range: `(-2, 4)`\n- `r_secondary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_secondary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus., validation range: `(-2, 4)`\n- `r_tertiary::Float64`: Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus., validation range: `(-2, 4)`\n- `x_tertiary::Float64`: Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus., validation range: `(-2, 4)`\n- `rating::Union{Nothing, Float64}`: Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to, validation range: `(0, nothing)`\n- `r_12::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_12::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `r_23::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_23::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `r_13::Float64`: Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `x_13::Float64`: Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E)., validation range: `(0, 4)`\n- `base_power_12::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings., validation range: `(0, nothing)`\n- `base_power_23::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings., validation range: `(0, nothing)`\n- `base_power_13::Float64`: Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings., validation range: `(0, nothing)`\n- `base_voltage_primary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(primary_star_arc))`) Primary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_secondary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(secondary_star_arc))`) Secondary base voltage in kV, validation range: `(0, nothing)`\n- `base_voltage_tertiary::Union{Nothing, Float64}`: (default: `get_base_voltage(get_from(tertiary_star_arc))`) Tertiary base voltage in kV, validation range: `(0, nothing)`\n- `g::Float64`: (default: `0.0`) Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\n- `b::Float64`: (default: `0.0`) Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\n- `primary_turns_ratio::Float64`: (default: `1.0`) Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\n- `secondary_turns_ratio::Float64`: (default: `1.0`) Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\n- `tertiary_turns_ratio::Float64`: (default: `1.0`) Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\n- `available_primary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `available_secondary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `available_tertiary::Bool`: (default: `true`) Status if primary winding is available or not.\n- `rating_primary::Float64`: (default: `0.0`) Rating (in MVA) for primary winding.\n- `rating_secondary::Float64`: (default: `0.0`) Rating (in MVA) for secondary winding.\n- `rating_tertiary::Float64`: (default: `0.0`) Rating (in MVA) for tertiary winding.\n- `primary_group_number::WindingGroupNumber`: (default: `WindingGroupNumber.UNDEFINED`) Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\n- `secondary_group_number::WindingGroupNumber`: (default: `WindingGroupNumber.UNDEFINED`) Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\n- `tertiary_group_number::WindingGroupNumber`: (default: `WindingGroupNumber.UNDEFINED`) Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\n- `control_objective_primary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `control_objective_secondary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `control_objective_tertiary::TransformerControlObjective`: (default: `TransformerControlObjective.UNDEFINED`) Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct Transformer3W <: ThreeWindingTransformer\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"An [`Arc`](@ref) defining this transformer `from` a primary bus `to` the star bus\"\n    primary_star_arc::Arc\n    \"An [`Arc`](@ref) defining this transformer `from` a secondary bus `to` the star bus\"\n    secondary_star_arc::Arc\n    \"An [`Arc`](@ref) defining this transformer `from` a tertiary bus `to` the star bus\"\n    tertiary_star_arc::Arc\n    \"Star (hidden) Bus that this component (equivalent model) is connected to\"\n    star_bus::ACBus\n    \"Initial condition of active power flow through the transformer primary side to star (hidden) bus (MW)\"\n    active_power_flow_primary::Float64\n    \"Initial condition of reactive power flow through the transformer primary side to star (hidden) bus (MW)\"\n    reactive_power_flow_primary::Float64\n    \"Initial condition of active power flow through the transformer secondary side to star (hidden) bus (MW)\"\n    active_power_flow_secondary::Float64\n    \"Initial condition of reactive power flow through the transformer secondary side to star (hidden) bus (MW)\"\n    reactive_power_flow_secondary::Float64\n    \"Initial condition of active power flow through the transformer tertiary side to star (hidden) bus (MW)\"\n    active_power_flow_tertiary::Float64\n    \"Initial condition of reactive power flow through the transformer tertiary side to star (hidden) bus (MW)\"\n    reactive_power_flow_tertiary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\"\n    r_primary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to star (hidden) bus.\"\n    x_primary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\"\n    r_secondary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to star (hidden) bus.\"\n    x_secondary::Float64\n    \"Equivalent resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\"\n    r_tertiary::Float64\n    \"Equivalent reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from tertiary to star (hidden) bus.\"\n    x_tertiary::Float64\n    \"Thermal rating (MVA). Flow through the transformer must be between -`rating` and `rating`. When defining a transformer before it is attached to a `System`, `rating` must be in pu ([`SYSTEM_BASE`](@ref per_unit)) using the base power of the `System` it will be attached to\"\n    rating::Union{Nothing, Float64}\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (R1-2 with CZ = 1 in PSS/E).\"\n    r_12::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to secondary windings (X1-2 with CZ = 1 in PSS/E).\"\n    x_12::Float64\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (R2-3 with CZ = 1 in PSS/E).\"\n    r_23::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from secondary to tertiary windings (X2-3 with CZ = 1 in PSS/E).\"\n    x_23::Float64\n    \"Measured resistance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (R1-3 with CZ = 1 in PSS/E).\"\n    r_13::Float64\n    \"Measured reactance in pu ([`SYSTEM_BASE`](@ref per_unit)) from primary to tertiary windings (X1-3 with CZ = 1 in PSS/E).\"\n    x_13::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for primary-secondary windings.\"\n    base_power_12::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for secondary-tertiary windings.\"\n    base_power_23::Float64\n    \"Base power (MVA) for [per unitization](@ref per_unit) for primary-tertiary windings.\"\n    base_power_13::Float64\n    \"Primary base voltage in kV\"\n    base_voltage_primary::Union{Nothing, Float64}\n    \"Secondary base voltage in kV\"\n    base_voltage_secondary::Union{Nothing, Float64}\n    \"Tertiary base voltage in kV\"\n    base_voltage_tertiary::Union{Nothing, Float64}\n    \"Shunt conductance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG1 in PSS/E).\"\n    g::Float64\n    \"Shunt susceptance in pu ([`SYSTEM_BASE`](@ref per_unit)) from star (hidden) bus to ground (MAG2 in PSS/E).\"\n    b::Float64\n    \"Primary side off-nominal turns ratio in p.u. with respect to connected primary bus (WINDV1 with CW = 1 in PSS/E).\"\n    primary_turns_ratio::Float64\n    \"Secondary side off-nominal turns ratio in p.u. with respect to connected secondary bus (WINDV2 with CW = 1 in PSS/E).\"\n    secondary_turns_ratio::Float64\n    \"Tertiary side off-nominal turns ratio in p.u. with respect to connected tertiary bus (WINDV3 with CW = 1 in PSS/E).\"\n    tertiary_turns_ratio::Float64\n    \"Status if primary winding is available or not.\"\n    available_primary::Bool\n    \"Status if primary winding is available or not.\"\n    available_secondary::Bool\n    \"Status if primary winding is available or not.\"\n    available_tertiary::Bool\n    \"Rating (in MVA) for primary winding.\"\n    rating_primary::Float64\n    \"Rating (in MVA) for secondary winding.\"\n    rating_secondary::Float64\n    \"Rating (in MVA) for tertiary winding.\"\n    rating_tertiary::Float64\n    \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\"\n    primary_group_number::WindingGroupNumber\n    \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\"\n    secondary_group_number::WindingGroupNumber\n    \"Vector group number ('clock number') indicating fixed phase shift (radians) between the `from` and `to` buses due to the connection group configuration\"\n    tertiary_group_number::WindingGroupNumber\n    \"Control objective for the tap changer for winding 1. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_primary::TransformerControlObjective\n    \"Control objective for the tap changer for winding 2. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_secondary::TransformerControlObjective\n    \"Control objective for the tap changer for winding 3. See [`TransformerControlObjective`](@ref xtf_crtl)\"\n    control_objective_tertiary::TransformerControlObjective\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction Transformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, base_power_12, base_power_23, base_power_13, base_voltage_primary=get_base_voltage(get_from(primary_star_arc)), base_voltage_secondary=get_base_voltage(get_from(secondary_star_arc)), base_voltage_tertiary=get_base_voltage(get_from(tertiary_star_arc)), g=0.0, b=0.0, primary_turns_ratio=1.0, secondary_turns_ratio=1.0, tertiary_turns_ratio=1.0, available_primary=true, available_secondary=true, available_tertiary=true, rating_primary=0.0, rating_secondary=0.0, rating_tertiary=0.0, primary_group_number=WindingGroupNumber.UNDEFINED, secondary_group_number=WindingGroupNumber.UNDEFINED, tertiary_group_number=WindingGroupNumber.UNDEFINED, control_objective_primary=TransformerControlObjective.UNDEFINED, control_objective_secondary=TransformerControlObjective.UNDEFINED, control_objective_tertiary=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), )\n    Transformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, base_power_12, base_power_23, base_power_13, base_voltage_primary, base_voltage_secondary, base_voltage_tertiary, g, b, primary_turns_ratio, secondary_turns_ratio, tertiary_turns_ratio, available_primary, available_secondary, available_tertiary, rating_primary, rating_secondary, rating_tertiary, primary_group_number, secondary_group_number, tertiary_group_number, control_objective_primary, control_objective_secondary, control_objective_tertiary, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction Transformer3W(; name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, base_power_12, base_power_23, base_power_13, base_voltage_primary=get_base_voltage(get_from(primary_star_arc)), base_voltage_secondary=get_base_voltage(get_from(secondary_star_arc)), base_voltage_tertiary=get_base_voltage(get_from(tertiary_star_arc)), g=0.0, b=0.0, primary_turns_ratio=1.0, secondary_turns_ratio=1.0, tertiary_turns_ratio=1.0, available_primary=true, available_secondary=true, available_tertiary=true, rating_primary=0.0, rating_secondary=0.0, rating_tertiary=0.0, primary_group_number=WindingGroupNumber.UNDEFINED, secondary_group_number=WindingGroupNumber.UNDEFINED, tertiary_group_number=WindingGroupNumber.UNDEFINED, control_objective_primary=TransformerControlObjective.UNDEFINED, control_objective_secondary=TransformerControlObjective.UNDEFINED, control_objective_tertiary=TransformerControlObjective.UNDEFINED, services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    Transformer3W(name, available, primary_star_arc, secondary_star_arc, tertiary_star_arc, star_bus, active_power_flow_primary, reactive_power_flow_primary, active_power_flow_secondary, reactive_power_flow_secondary, active_power_flow_tertiary, reactive_power_flow_tertiary, r_primary, x_primary, r_secondary, x_secondary, r_tertiary, x_tertiary, rating, r_12, x_12, r_23, x_23, r_13, x_13, base_power_12, base_power_23, base_power_13, base_voltage_primary, base_voltage_secondary, base_voltage_tertiary, g, b, primary_turns_ratio, secondary_turns_ratio, tertiary_turns_ratio, available_primary, available_secondary, available_tertiary, rating_primary, rating_secondary, rating_tertiary, primary_group_number, secondary_group_number, tertiary_group_number, control_objective_primary, control_objective_secondary, control_objective_tertiary, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction Transformer3W(::Nothing)\n    Transformer3W(;\n        name=\"init\",\n        available=false,\n        primary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        secondary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        tertiary_star_arc=Arc(ACBus(nothing), ACBus(nothing)),\n        star_bus=ACBus(nothing),\n        active_power_flow_primary=0.0,\n        reactive_power_flow_primary=0.0,\n        active_power_flow_secondary=0.0,\n        reactive_power_flow_secondary=0.0,\n        active_power_flow_tertiary=0.0,\n        reactive_power_flow_tertiary=0.0,\n        r_primary=0.0,\n        x_primary=0.0,\n        r_secondary=0.0,\n        x_secondary=0.0,\n        r_tertiary=0.0,\n        x_tertiary=0.0,\n        rating=nothing,\n        r_12=0.0,\n        x_12=0.0,\n        r_23=0.0,\n        x_23=0.0,\n        r_13=0.0,\n        x_13=0.0,\n        base_power_12=0.0,\n        base_power_23=0.0,\n        base_power_13=0.0,\n        base_voltage_primary=nothing,\n        base_voltage_secondary=nothing,\n        base_voltage_tertiary=nothing,\n        g=0.0,\n        b=0.0,\n        primary_turns_ratio=0.0,\n        secondary_turns_ratio=0.0,\n        tertiary_turns_ratio=0.0,\n        available_primary=false,\n        available_secondary=false,\n        available_tertiary=false,\n        rating_primary=0.0,\n        rating_secondary=0.0,\n        rating_tertiary=0.0,\n        primary_group_number=WindingGroupNumber.UNDEFINED,\n        secondary_group_number=WindingGroupNumber.UNDEFINED,\n        tertiary_group_number=WindingGroupNumber.UNDEFINED,\n        control_objective_primary=TransformerControlObjective.UNDEFINED,\n        control_objective_secondary=TransformerControlObjective.UNDEFINED,\n        control_objective_tertiary=TransformerControlObjective.UNDEFINED,\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`Transformer3W`](@ref) `name`.\"\"\"\nget_name(value::Transformer3W) = value.name\n\"\"\"Get [`Transformer3W`](@ref) `available`.\"\"\"\nget_available(value::Transformer3W) = value.available\n\"\"\"Get [`Transformer3W`](@ref) `primary_star_arc`.\"\"\"\nget_primary_star_arc(value::Transformer3W) = value.primary_star_arc\n\"\"\"Get [`Transformer3W`](@ref) `secondary_star_arc`.\"\"\"\nget_secondary_star_arc(value::Transformer3W) = value.secondary_star_arc\n\"\"\"Get [`Transformer3W`](@ref) `tertiary_star_arc`.\"\"\"\nget_tertiary_star_arc(value::Transformer3W) = value.tertiary_star_arc\n\"\"\"Get [`Transformer3W`](@ref) `star_bus`.\"\"\"\nget_star_bus(value::Transformer3W) = value.star_bus\n\"\"\"Get [`Transformer3W`](@ref) `active_power_flow_primary`.\"\"\"\nget_active_power_flow_primary(value::Transformer3W) = get_value(value, Val(:active_power_flow_primary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `reactive_power_flow_primary`.\"\"\"\nget_reactive_power_flow_primary(value::Transformer3W) = get_value(value, Val(:reactive_power_flow_primary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `active_power_flow_secondary`.\"\"\"\nget_active_power_flow_secondary(value::Transformer3W) = get_value(value, Val(:active_power_flow_secondary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `reactive_power_flow_secondary`.\"\"\"\nget_reactive_power_flow_secondary(value::Transformer3W) = get_value(value, Val(:reactive_power_flow_secondary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `active_power_flow_tertiary`.\"\"\"\nget_active_power_flow_tertiary(value::Transformer3W) = get_value(value, Val(:active_power_flow_tertiary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `reactive_power_flow_tertiary`.\"\"\"\nget_reactive_power_flow_tertiary(value::Transformer3W) = get_value(value, Val(:reactive_power_flow_tertiary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `r_primary`.\"\"\"\nget_r_primary(value::Transformer3W) = get_value(value, Val(:r_primary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_primary`.\"\"\"\nget_x_primary(value::Transformer3W) = get_value(value, Val(:x_primary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `r_secondary`.\"\"\"\nget_r_secondary(value::Transformer3W) = get_value(value, Val(:r_secondary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_secondary`.\"\"\"\nget_x_secondary(value::Transformer3W) = get_value(value, Val(:x_secondary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `r_tertiary`.\"\"\"\nget_r_tertiary(value::Transformer3W) = get_value(value, Val(:r_tertiary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_tertiary`.\"\"\"\nget_x_tertiary(value::Transformer3W) = get_value(value, Val(:x_tertiary), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `rating`.\"\"\"\nget_rating(value::Transformer3W) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `r_12`.\"\"\"\nget_r_12(value::Transformer3W) = get_value(value, Val(:r_12), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_12`.\"\"\"\nget_x_12(value::Transformer3W) = get_value(value, Val(:x_12), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `r_23`.\"\"\"\nget_r_23(value::Transformer3W) = get_value(value, Val(:r_23), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_23`.\"\"\"\nget_x_23(value::Transformer3W) = get_value(value, Val(:x_23), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `r_13`.\"\"\"\nget_r_13(value::Transformer3W) = get_value(value, Val(:r_13), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `x_13`.\"\"\"\nget_x_13(value::Transformer3W) = get_value(value, Val(:x_13), Val(:ohm))\n\"\"\"Get [`Transformer3W`](@ref) `base_power_12`.\"\"\"\nget_base_power_12(value::Transformer3W) = value.base_power_12\n\"\"\"Get [`Transformer3W`](@ref) `base_power_23`.\"\"\"\nget_base_power_23(value::Transformer3W) = value.base_power_23\n\"\"\"Get [`Transformer3W`](@ref) `base_power_13`.\"\"\"\nget_base_power_13(value::Transformer3W) = value.base_power_13\n\"\"\"Get [`Transformer3W`](@ref) `base_voltage_primary`.\"\"\"\nget_base_voltage_primary(value::Transformer3W) = value.base_voltage_primary\n\"\"\"Get [`Transformer3W`](@ref) `base_voltage_secondary`.\"\"\"\nget_base_voltage_secondary(value::Transformer3W) = value.base_voltage_secondary\n\"\"\"Get [`Transformer3W`](@ref) `base_voltage_tertiary`.\"\"\"\nget_base_voltage_tertiary(value::Transformer3W) = value.base_voltage_tertiary\n\"\"\"Get [`Transformer3W`](@ref) `g`.\"\"\"\nget_g(value::Transformer3W) = get_value(value, Val(:g), Val(:siemens))\n\"\"\"Get [`Transformer3W`](@ref) `b`.\"\"\"\nget_b(value::Transformer3W) = get_value(value, Val(:b), Val(:siemens))\n\"\"\"Get [`Transformer3W`](@ref) `primary_turns_ratio`.\"\"\"\nget_primary_turns_ratio(value::Transformer3W) = value.primary_turns_ratio\n\"\"\"Get [`Transformer3W`](@ref) `secondary_turns_ratio`.\"\"\"\nget_secondary_turns_ratio(value::Transformer3W) = value.secondary_turns_ratio\n\"\"\"Get [`Transformer3W`](@ref) `tertiary_turns_ratio`.\"\"\"\nget_tertiary_turns_ratio(value::Transformer3W) = value.tertiary_turns_ratio\n\"\"\"Get [`Transformer3W`](@ref) `available_primary`.\"\"\"\nget_available_primary(value::Transformer3W) = value.available_primary\n\"\"\"Get [`Transformer3W`](@ref) `available_secondary`.\"\"\"\nget_available_secondary(value::Transformer3W) = value.available_secondary\n\"\"\"Get [`Transformer3W`](@ref) `available_tertiary`.\"\"\"\nget_available_tertiary(value::Transformer3W) = value.available_tertiary\n\"\"\"Get [`Transformer3W`](@ref) `rating_primary`.\"\"\"\nget_rating_primary(value::Transformer3W) = get_value(value, Val(:rating_primary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `rating_secondary`.\"\"\"\nget_rating_secondary(value::Transformer3W) = get_value(value, Val(:rating_secondary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `rating_tertiary`.\"\"\"\nget_rating_tertiary(value::Transformer3W) = get_value(value, Val(:rating_tertiary), Val(:mva))\n\"\"\"Get [`Transformer3W`](@ref) `primary_group_number`.\"\"\"\nget_primary_group_number(value::Transformer3W) = value.primary_group_number\n\"\"\"Get [`Transformer3W`](@ref) `secondary_group_number`.\"\"\"\nget_secondary_group_number(value::Transformer3W) = value.secondary_group_number\n\"\"\"Get [`Transformer3W`](@ref) `tertiary_group_number`.\"\"\"\nget_tertiary_group_number(value::Transformer3W) = value.tertiary_group_number\n\"\"\"Get [`Transformer3W`](@ref) `control_objective_primary`.\"\"\"\nget_control_objective_primary(value::Transformer3W) = value.control_objective_primary\n\"\"\"Get [`Transformer3W`](@ref) `control_objective_secondary`.\"\"\"\nget_control_objective_secondary(value::Transformer3W) = value.control_objective_secondary\n\"\"\"Get [`Transformer3W`](@ref) `control_objective_tertiary`.\"\"\"\nget_control_objective_tertiary(value::Transformer3W) = value.control_objective_tertiary\n\"\"\"Get [`Transformer3W`](@ref) `services`.\"\"\"\nget_services(value::Transformer3W) = value.services\n\"\"\"Get [`Transformer3W`](@ref) `ext`.\"\"\"\nget_ext(value::Transformer3W) = value.ext\n\"\"\"Get [`Transformer3W`](@ref) `internal`.\"\"\"\nget_internal(value::Transformer3W) = value.internal\n\n\"\"\"Set [`Transformer3W`](@ref) `available`.\"\"\"\nset_available!(value::Transformer3W, val) = value.available = val\n\"\"\"Set [`Transformer3W`](@ref) `primary_star_arc`.\"\"\"\nset_primary_star_arc!(value::Transformer3W, val) = value.primary_star_arc = val\n\"\"\"Set [`Transformer3W`](@ref) `secondary_star_arc`.\"\"\"\nset_secondary_star_arc!(value::Transformer3W, val) = value.secondary_star_arc = val\n\"\"\"Set [`Transformer3W`](@ref) `tertiary_star_arc`.\"\"\"\nset_tertiary_star_arc!(value::Transformer3W, val) = value.tertiary_star_arc = val\n\"\"\"Set [`Transformer3W`](@ref) `star_bus`.\"\"\"\nset_star_bus!(value::Transformer3W, val) = value.star_bus = val\n\"\"\"Set [`Transformer3W`](@ref) `active_power_flow_primary`.\"\"\"\nset_active_power_flow_primary!(value::Transformer3W, val) = value.active_power_flow_primary = set_value(value, Val(:active_power_flow_primary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `reactive_power_flow_primary`.\"\"\"\nset_reactive_power_flow_primary!(value::Transformer3W, val) = value.reactive_power_flow_primary = set_value(value, Val(:reactive_power_flow_primary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `active_power_flow_secondary`.\"\"\"\nset_active_power_flow_secondary!(value::Transformer3W, val) = value.active_power_flow_secondary = set_value(value, Val(:active_power_flow_secondary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `reactive_power_flow_secondary`.\"\"\"\nset_reactive_power_flow_secondary!(value::Transformer3W, val) = value.reactive_power_flow_secondary = set_value(value, Val(:reactive_power_flow_secondary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `active_power_flow_tertiary`.\"\"\"\nset_active_power_flow_tertiary!(value::Transformer3W, val) = value.active_power_flow_tertiary = set_value(value, Val(:active_power_flow_tertiary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `reactive_power_flow_tertiary`.\"\"\"\nset_reactive_power_flow_tertiary!(value::Transformer3W, val) = value.reactive_power_flow_tertiary = set_value(value, Val(:reactive_power_flow_tertiary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `r_primary`.\"\"\"\nset_r_primary!(value::Transformer3W, val) = value.r_primary = set_value(value, Val(:r_primary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_primary`.\"\"\"\nset_x_primary!(value::Transformer3W, val) = value.x_primary = set_value(value, Val(:x_primary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `r_secondary`.\"\"\"\nset_r_secondary!(value::Transformer3W, val) = value.r_secondary = set_value(value, Val(:r_secondary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_secondary`.\"\"\"\nset_x_secondary!(value::Transformer3W, val) = value.x_secondary = set_value(value, Val(:x_secondary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `r_tertiary`.\"\"\"\nset_r_tertiary!(value::Transformer3W, val) = value.r_tertiary = set_value(value, Val(:r_tertiary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_tertiary`.\"\"\"\nset_x_tertiary!(value::Transformer3W, val) = value.x_tertiary = set_value(value, Val(:x_tertiary), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `rating`.\"\"\"\nset_rating!(value::Transformer3W, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `r_12`.\"\"\"\nset_r_12!(value::Transformer3W, val) = value.r_12 = set_value(value, Val(:r_12), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_12`.\"\"\"\nset_x_12!(value::Transformer3W, val) = value.x_12 = set_value(value, Val(:x_12), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `r_23`.\"\"\"\nset_r_23!(value::Transformer3W, val) = value.r_23 = set_value(value, Val(:r_23), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_23`.\"\"\"\nset_x_23!(value::Transformer3W, val) = value.x_23 = set_value(value, Val(:x_23), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `r_13`.\"\"\"\nset_r_13!(value::Transformer3W, val) = value.r_13 = set_value(value, Val(:r_13), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `x_13`.\"\"\"\nset_x_13!(value::Transformer3W, val) = value.x_13 = set_value(value, Val(:x_13), val, Val(:ohm))\n\"\"\"Set [`Transformer3W`](@ref) `base_power_12`.\"\"\"\nset_base_power_12!(value::Transformer3W, val) = value.base_power_12 = val\n\"\"\"Set [`Transformer3W`](@ref) `base_power_23`.\"\"\"\nset_base_power_23!(value::Transformer3W, val) = value.base_power_23 = val\n\"\"\"Set [`Transformer3W`](@ref) `base_power_13`.\"\"\"\nset_base_power_13!(value::Transformer3W, val) = value.base_power_13 = val\n\"\"\"Set [`Transformer3W`](@ref) `base_voltage_primary`.\"\"\"\nset_base_voltage_primary!(value::Transformer3W, val) = value.base_voltage_primary = val\n\"\"\"Set [`Transformer3W`](@ref) `base_voltage_secondary`.\"\"\"\nset_base_voltage_secondary!(value::Transformer3W, val) = value.base_voltage_secondary = val\n\"\"\"Set [`Transformer3W`](@ref) `base_voltage_tertiary`.\"\"\"\nset_base_voltage_tertiary!(value::Transformer3W, val) = value.base_voltage_tertiary = val\n\"\"\"Set [`Transformer3W`](@ref) `g`.\"\"\"\nset_g!(value::Transformer3W, val) = value.g = set_value(value, Val(:g), val, Val(:siemens))\n\"\"\"Set [`Transformer3W`](@ref) `b`.\"\"\"\nset_b!(value::Transformer3W, val) = value.b = set_value(value, Val(:b), val, Val(:siemens))\n\"\"\"Set [`Transformer3W`](@ref) `primary_turns_ratio`.\"\"\"\nset_primary_turns_ratio!(value::Transformer3W, val) = value.primary_turns_ratio = val\n\"\"\"Set [`Transformer3W`](@ref) `secondary_turns_ratio`.\"\"\"\nset_secondary_turns_ratio!(value::Transformer3W, val) = value.secondary_turns_ratio = val\n\"\"\"Set [`Transformer3W`](@ref) `tertiary_turns_ratio`.\"\"\"\nset_tertiary_turns_ratio!(value::Transformer3W, val) = value.tertiary_turns_ratio = val\n\"\"\"Set [`Transformer3W`](@ref) `available_primary`.\"\"\"\nset_available_primary!(value::Transformer3W, val) = value.available_primary = val\n\"\"\"Set [`Transformer3W`](@ref) `available_secondary`.\"\"\"\nset_available_secondary!(value::Transformer3W, val) = value.available_secondary = val\n\"\"\"Set [`Transformer3W`](@ref) `available_tertiary`.\"\"\"\nset_available_tertiary!(value::Transformer3W, val) = value.available_tertiary = val\n\"\"\"Set [`Transformer3W`](@ref) `rating_primary`.\"\"\"\nset_rating_primary!(value::Transformer3W, val) = value.rating_primary = set_value(value, Val(:rating_primary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `rating_secondary`.\"\"\"\nset_rating_secondary!(value::Transformer3W, val) = value.rating_secondary = set_value(value, Val(:rating_secondary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `rating_tertiary`.\"\"\"\nset_rating_tertiary!(value::Transformer3W, val) = value.rating_tertiary = set_value(value, Val(:rating_tertiary), val, Val(:mva))\n\"\"\"Set [`Transformer3W`](@ref) `primary_group_number`.\"\"\"\nset_primary_group_number!(value::Transformer3W, val) = value.primary_group_number = val\n\"\"\"Set [`Transformer3W`](@ref) `secondary_group_number`.\"\"\"\nset_secondary_group_number!(value::Transformer3W, val) = value.secondary_group_number = val\n\"\"\"Set [`Transformer3W`](@ref) `tertiary_group_number`.\"\"\"\nset_tertiary_group_number!(value::Transformer3W, val) = value.tertiary_group_number = val\n\"\"\"Set [`Transformer3W`](@ref) `control_objective_primary`.\"\"\"\nset_control_objective_primary!(value::Transformer3W, val) = value.control_objective_primary = val\n\"\"\"Set [`Transformer3W`](@ref) `control_objective_secondary`.\"\"\"\nset_control_objective_secondary!(value::Transformer3W, val) = value.control_objective_secondary = val\n\"\"\"Set [`Transformer3W`](@ref) `control_objective_tertiary`.\"\"\"\nset_control_objective_tertiary!(value::Transformer3W, val) = value.control_objective_tertiary = val\n\"\"\"Set [`Transformer3W`](@ref) `services`.\"\"\"\nset_services!(value::Transformer3W, val) = value.services = val\n\"\"\"Set [`Transformer3W`](@ref) `ext`.\"\"\"\nset_ext!(value::Transformer3W, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TransmissionInterface.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TransmissionInterface <: Service\n        name::String\n        available::Bool\n        active_power_flow_limits::MinMax\n        violation_penalty::Float64\n        direction_mapping::Dict{String, Int}\n        internal::InfrastructureSystemsInternal\n    end\n\nA collection of branches that make up an interface or corridor for the transfer of power, such as between different [`Areas`](@ref Area) or [`LoadZones`](@ref LoadZone).\n\nThe interface can be used to constrain the power flow across it\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow_limits::MinMax`: Minimum and maximum active power flow limits on the interface (MW)\n- `violation_penalty::Float64`: (default: `INFINITE_COST`) Penalty cost for violating the flow limits in the interface\n- `direction_mapping::Dict{String, Int}`: (default: `Dict{String, Int}()`) Dictionary of the line `name`s in the interface and their direction of flow (1 or -1) relative to the flow of the interface\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TransmissionInterface <: Service\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Minimum and maximum active power flow limits on the interface (MW)\"\n    active_power_flow_limits::MinMax\n    \"Penalty cost for violating the flow limits in the interface\"\n    violation_penalty::Float64\n    \"Dictionary of the line `name`s in the interface and their direction of flow (1 or -1) relative to the flow of the interface\"\n    direction_mapping::Dict{String, Int}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TransmissionInterface(name, available, active_power_flow_limits, violation_penalty=INFINITE_COST, direction_mapping=Dict{String, Int}(), )\n    TransmissionInterface(name, available, active_power_flow_limits, violation_penalty, direction_mapping, InfrastructureSystemsInternal(), )\nend\n\nfunction TransmissionInterface(; name, available, active_power_flow_limits, violation_penalty=INFINITE_COST, direction_mapping=Dict{String, Int}(), internal=InfrastructureSystemsInternal(), )\n    TransmissionInterface(name, available, active_power_flow_limits, violation_penalty, direction_mapping, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TransmissionInterface(::Nothing)\n    TransmissionInterface(;\n        name=\"init\",\n        available=false,\n        active_power_flow_limits=(min=0.0, max=0.0),\n        violation_penalty=0.0,\n        direction_mapping=Dict{String, Int}(),\n    )\nend\n\n\"\"\"Get [`TransmissionInterface`](@ref) `name`.\"\"\"\nget_name(value::TransmissionInterface) = value.name\n\"\"\"Get [`TransmissionInterface`](@ref) `available`.\"\"\"\nget_available(value::TransmissionInterface) = value.available\n\"\"\"Get [`TransmissionInterface`](@ref) `active_power_flow_limits`.\"\"\"\nget_active_power_flow_limits(value::TransmissionInterface) = get_value(value, Val(:active_power_flow_limits), Val(:mva))\n\"\"\"Get [`TransmissionInterface`](@ref) `violation_penalty`.\"\"\"\nget_violation_penalty(value::TransmissionInterface) = value.violation_penalty\n\"\"\"Get [`TransmissionInterface`](@ref) `direction_mapping`.\"\"\"\nget_direction_mapping(value::TransmissionInterface) = value.direction_mapping\n\"\"\"Get [`TransmissionInterface`](@ref) `internal`.\"\"\"\nget_internal(value::TransmissionInterface) = value.internal\n\n\"\"\"Set [`TransmissionInterface`](@ref) `available`.\"\"\"\nset_available!(value::TransmissionInterface, val) = value.available = val\n\"\"\"Set [`TransmissionInterface`](@ref) `active_power_flow_limits`.\"\"\"\nset_active_power_flow_limits!(value::TransmissionInterface, val) = value.active_power_flow_limits = set_value(value, Val(:active_power_flow_limits), val, Val(:mva))\n\"\"\"Set [`TransmissionInterface`](@ref) `violation_penalty`.\"\"\"\nset_violation_penalty!(value::TransmissionInterface, val) = value.violation_penalty = val\n\"\"\"Set [`TransmissionInterface`](@ref) `direction_mapping`.\"\"\"\nset_direction_mapping!(value::TransmissionInterface, val) = value.direction_mapping = val\n"
  },
  {
    "path": "src/models/generated/TwoTerminalGenericHVDCLine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TwoTerminalGenericHVDCLine <: TwoTerminalHVDC\n        name::String\n        available::Bool\n        active_power_flow::Float64\n        arc::Arc\n        active_power_limits_from::MinMax\n        active_power_limits_to::MinMax\n        reactive_power_limits_from::MinMax\n        reactive_power_limits_to::MinMax\n        loss::Union{LinearCurve, PiecewiseIncrementalCurve}\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA High Voltage DC line, which must be connected to an [`ACBus`](@ref) on each end.\n\nThis model is appropriate for operational simulations with a linearized DC power flow approximation with losses proportional to the power flow. For modeling a DC network, see [`TModelHVDCLine`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `active_power_limits_from::MinMax`: Minimum and maximum active power flows to the FROM node (MW)\n- `active_power_limits_to::MinMax`: Minimum and maximum active power flows to the TO node (MW)\n- `reactive_power_limits_from::MinMax`: Minimum and maximum reactive power limits to the FROM node (MVAR)\n- `reactive_power_limits_to::MinMax`: Minimum and maximum reactive power limits to the TO node (MVAR)\n- `loss::Union{LinearCurve, PiecewiseIncrementalCurve}`: (default: `LinearCurve(0.0)`) Loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TwoTerminalGenericHVDCLine <: TwoTerminalHVDC\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Minimum and maximum active power flows to the FROM node (MW)\"\n    active_power_limits_from::MinMax\n    \"Minimum and maximum active power flows to the TO node (MW)\"\n    active_power_limits_to::MinMax\n    \"Minimum and maximum reactive power limits to the FROM node (MVAR)\"\n    reactive_power_limits_from::MinMax\n    \"Minimum and maximum reactive power limits to the TO node (MVAR)\"\n    reactive_power_limits_to::MinMax\n    \"Loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\"\n    loss::Union{LinearCurve, PiecewiseIncrementalCurve}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TwoTerminalGenericHVDCLine(name, available, active_power_flow, arc, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss=LinearCurve(0.0), services=Device[], ext=Dict{String, Any}(), )\n    TwoTerminalGenericHVDCLine(name, available, active_power_flow, arc, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction TwoTerminalGenericHVDCLine(; name, available, active_power_flow, arc, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss=LinearCurve(0.0), services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    TwoTerminalGenericHVDCLine(name, available, active_power_flow, arc, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TwoTerminalGenericHVDCLine(::Nothing)\n    TwoTerminalGenericHVDCLine(;\n        name=\"init\",\n        available=false,\n        active_power_flow=0.0,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        active_power_limits_from=(min=0.0, max=0.0),\n        active_power_limits_to=(min=0.0, max=0.0),\n        reactive_power_limits_from=(min=0.0, max=0.0),\n        reactive_power_limits_to=(min=0.0, max=0.0),\n        loss=LinearCurve(0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `name`.\"\"\"\nget_name(value::TwoTerminalGenericHVDCLine) = value.name\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `available`.\"\"\"\nget_available(value::TwoTerminalGenericHVDCLine) = value.available\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::TwoTerminalGenericHVDCLine) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `arc`.\"\"\"\nget_arc(value::TwoTerminalGenericHVDCLine) = value.arc\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `active_power_limits_from`.\"\"\"\nget_active_power_limits_from(value::TwoTerminalGenericHVDCLine) = get_value(value, Val(:active_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `active_power_limits_to`.\"\"\"\nget_active_power_limits_to(value::TwoTerminalGenericHVDCLine) = get_value(value, Val(:active_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nget_reactive_power_limits_from(value::TwoTerminalGenericHVDCLine) = get_value(value, Val(:reactive_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nget_reactive_power_limits_to(value::TwoTerminalGenericHVDCLine) = get_value(value, Val(:reactive_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `loss`.\"\"\"\nget_loss(value::TwoTerminalGenericHVDCLine) = value.loss\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `services`.\"\"\"\nget_services(value::TwoTerminalGenericHVDCLine) = value.services\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `ext`.\"\"\"\nget_ext(value::TwoTerminalGenericHVDCLine) = value.ext\n\"\"\"Get [`TwoTerminalGenericHVDCLine`](@ref) `internal`.\"\"\"\nget_internal(value::TwoTerminalGenericHVDCLine) = value.internal\n\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `available`.\"\"\"\nset_available!(value::TwoTerminalGenericHVDCLine, val) = value.available = val\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::TwoTerminalGenericHVDCLine, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `arc`.\"\"\"\nset_arc!(value::TwoTerminalGenericHVDCLine, val) = value.arc = val\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `active_power_limits_from`.\"\"\"\nset_active_power_limits_from!(value::TwoTerminalGenericHVDCLine, val) = value.active_power_limits_from = set_value(value, Val(:active_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `active_power_limits_to`.\"\"\"\nset_active_power_limits_to!(value::TwoTerminalGenericHVDCLine, val) = value.active_power_limits_to = set_value(value, Val(:active_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nset_reactive_power_limits_from!(value::TwoTerminalGenericHVDCLine, val) = value.reactive_power_limits_from = set_value(value, Val(:reactive_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nset_reactive_power_limits_to!(value::TwoTerminalGenericHVDCLine, val) = value.reactive_power_limits_to = set_value(value, Val(:reactive_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `loss`.\"\"\"\nset_loss!(value::TwoTerminalGenericHVDCLine, val) = value.loss = val\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `services`.\"\"\"\nset_services!(value::TwoTerminalGenericHVDCLine, val) = value.services = val\n\"\"\"Set [`TwoTerminalGenericHVDCLine`](@ref) `ext`.\"\"\"\nset_ext!(value::TwoTerminalGenericHVDCLine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TwoTerminalLCCLine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TwoTerminalLCCLine <: TwoTerminalHVDC\n        name::String\n        available::Bool\n        arc::Arc\n        active_power_flow::Float64\n        r::Float64\n        transfer_setpoint::Float64\n        scheduled_dc_voltage::Float64\n        rectifier_bridges::Int\n        rectifier_delay_angle_limits::MinMax\n        rectifier_rc::Float64\n        rectifier_xc::Float64\n        rectifier_base_voltage::Float64\n        inverter_bridges::Int\n        inverter_extinction_angle_limits::MinMax\n        inverter_rc::Float64\n        inverter_xc::Float64\n        inverter_base_voltage::Float64\n        power_mode::Bool\n        switch_mode_voltage::Float64\n        compounding_resistance::Float64\n        min_compounding_voltage::Float64\n        rectifier_transformer_ratio::Float64\n        rectifier_tap_setting::Float64\n        rectifier_tap_limits::MinMax\n        rectifier_tap_step::Float64\n        rectifier_delay_angle::Float64\n        rectifier_capacitor_reactance::Float64\n        inverter_transformer_ratio::Float64\n        inverter_tap_setting::Float64\n        inverter_tap_limits::MinMax\n        inverter_tap_step::Float64\n        inverter_extinction_angle::Float64\n        inverter_capacitor_reactance::Float64\n        active_power_limits_from::MinMax\n        active_power_limits_to::MinMax\n        reactive_power_limits_from::MinMax\n        reactive_power_limits_to::MinMax\n        loss::Union{LinearCurve, PiecewiseIncrementalCurve}\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA Non-Capacitor Line Commutated Converter (LCC)-HVDC transmission line.\n\nAs implemented in PSS/E.\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a rectifier bus `to` an inverter bus. The rectifier bus must be specified in the `from` bus and inverter bus in the `to` bus.\n- `active_power_flow::Float64`: Initial condition of active power flow on the line (MW)\n- `r::Float64`: Series resistance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `transfer_setpoint::Float64`: Desired set-point of power. If `power_mode = true` this value is in MW units, and if `power_mode = false` is in Amperes units. This parameter must not be specified in per-unit. A positive value represents the desired consumed power at the rectifier bus, while a negative value represents the desired power at the inverter bus (i.e. the absolute value of `transfer_setpoint` is the generated power at the inverter bus).\n- `scheduled_dc_voltage::Float64`: Scheduled compounded DC voltage in kV. By default this parameter is the scheduled DC voltage in the inverter bus This parameter must not be specified in per-unit.\n- `rectifier_bridges::Int`: Number of bridges in series in the rectifier side.\n- `rectifier_delay_angle_limits::MinMax`: Minimum and maximum rectifier firing delay angle (α) (radians)\n- `rectifier_rc::Float64`: Rectifier commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `rectifier_xc::Float64`: Rectifier commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `rectifier_base_voltage::Float64`: Rectifier primary base AC voltage in kV, entered in kV.\n- `inverter_bridges::Int`: Number of bridges in series in the inverter side.\n- `inverter_extinction_angle_limits::MinMax`: Minimum and maximum inverter extinction angle (γ) (radians)\n- `inverter_rc::Float64`: Inverter commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `inverter_xc::Float64`: Inverter commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\n- `inverter_base_voltage::Float64`: Inverter primary base AC voltage in kV, entered in kV.\n- `power_mode::Bool`: (default: `true`) Boolean flag to identify if the LCC line is in power mode or current mode. If `power_mode = true`, setpoint values must be specified in MW, and if `power_mode = false` setpoint values must be specified in Amperes.\n- `switch_mode_voltage::Float64`: (default: `0.0`) Mode switch DC voltage, in kV. This parameter must not be added in per-unit. If LCC line is in power mode control, and DC voltage falls below this value, the line switch to current mode control.\n- `compounding_resistance::Float64`: (default: `0.0`) Compounding Resistance, in ohms. This parameter is for control of the DC voltage in the rectifier or inverter end. For inverter DC voltage control, the paremeter is set to zero; for rectifier DC voltage control, the paremeter is set to the DC line resistance; otherwise, set to a fraction of the DC line resistance.\n- `min_compounding_voltage::Float64`: (default: `0.0`) Minimum compounded voltage, in kV. This parameter must not be added in per-unit. Only used in constant gamma operation (γ_min = γ_max), and the AC transformer is used to control the DC voltage.\n- `rectifier_transformer_ratio::Float64`: (default: `1.0`) Rectifier transformer ratio between the primary and secondary side AC voltages.\n- `rectifier_tap_setting::Float64`: (default: `1.0`) Rectifier transformer tap setting.\n- `rectifier_tap_limits::MinMax`: (default: `(min=0.51, max=1.5)`) Minimum and maximum rectifier tap limits as a ratio between the primary and secondary side AC voltages.\n- `rectifier_tap_step::Float64`: (default: `0.00625`) Rectifier transformer tap step value\n- `rectifier_delay_angle::Float64`: (default: `0.0`) Rectifier firing delay angle (α).\n- `rectifier_capacitor_reactance::Float64`: (default: `0.0`) Commutating rectifier capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\n- `inverter_transformer_ratio::Float64`: (default: `1.0`) Inverter transformer ratio between the primary and secondary side AC voltages.\n- `inverter_tap_setting::Float64`: (default: `1.0`) Inverter transformer tap setting.\n- `inverter_tap_limits::MinMax`: (default: `(min=0.51, max=1.5)`) Minimum and maximum inverter tap limits as a ratio between the primary and secondary side AC voltages.\n- `inverter_tap_step::Float64`: (default: `0.00625`) Inverter transformer tap step value.\n- `inverter_extinction_angle::Float64`: (default: `0.0`) Inverter extinction angle (γ).\n- `inverter_capacitor_reactance::Float64`: (default: `0.0`) Commutating inverter capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\n- `active_power_limits_from::MinMax`: (default: `(min=0.0, max=0.0)`) Minimum and maximum active power flows to the FROM node (MW)\n- `active_power_limits_to::MinMax`: (default: `(min=0.0, max=0.0)`) Minimum and maximum active power flows to the TO node (MW)\n- `reactive_power_limits_from::MinMax`: (default: `(min=0.0, max=0.0)`) Minimum and maximum reactive power limits to the FROM node (MVAR)\n- `reactive_power_limits_to::MinMax`: (default: `(min=0.0, max=0.0)`) Minimum and maximum reactive power limits to the TO node (MVAR)\n- `loss::Union{LinearCurve, PiecewiseIncrementalCurve}`: (default: `LinearCurve(0.0)`) A generic loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TwoTerminalLCCLine <: TwoTerminalHVDC\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"An [`Arc`](@ref) defining this line `from` a rectifier bus `to` an inverter bus. The rectifier bus must be specified in the `from` bus and inverter bus in the `to` bus.\"\n    arc::Arc\n    \"Initial condition of active power flow on the line (MW)\"\n    active_power_flow::Float64\n    \"Series resistance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    r::Float64\n    \"Desired set-point of power. If `power_mode = true` this value is in MW units, and if `power_mode = false` is in Amperes units. This parameter must not be specified in per-unit. A positive value represents the desired consumed power at the rectifier bus, while a negative value represents the desired power at the inverter bus (i.e. the absolute value of `transfer_setpoint` is the generated power at the inverter bus).\"\n    transfer_setpoint::Float64\n    \"Scheduled compounded DC voltage in kV. By default this parameter is the scheduled DC voltage in the inverter bus This parameter must not be specified in per-unit.\"\n    scheduled_dc_voltage::Float64\n    \"Number of bridges in series in the rectifier side.\"\n    rectifier_bridges::Int\n    \"Minimum and maximum rectifier firing delay angle (α) (radians)\"\n    rectifier_delay_angle_limits::MinMax\n    \"Rectifier commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    rectifier_rc::Float64\n    \"Rectifier commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    rectifier_xc::Float64\n    \"Rectifier primary base AC voltage in kV, entered in kV.\"\n    rectifier_base_voltage::Float64\n    \"Number of bridges in series in the inverter side.\"\n    inverter_bridges::Int\n    \"Minimum and maximum inverter extinction angle (γ) (radians)\"\n    inverter_extinction_angle_limits::MinMax\n    \"Inverter commutating transformer resistance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    inverter_rc::Float64\n    \"Inverter commutating transformer reactance per bridge in system p.u. ([`SYSTEM_BASE`](@ref per_unit))\"\n    inverter_xc::Float64\n    \"Inverter primary base AC voltage in kV, entered in kV.\"\n    inverter_base_voltage::Float64\n    \"Boolean flag to identify if the LCC line is in power mode or current mode. If `power_mode = true`, setpoint values must be specified in MW, and if `power_mode = false` setpoint values must be specified in Amperes.\"\n    power_mode::Bool\n    \"Mode switch DC voltage, in kV. This parameter must not be added in per-unit. If LCC line is in power mode control, and DC voltage falls below this value, the line switch to current mode control.\"\n    switch_mode_voltage::Float64\n    \"Compounding Resistance, in ohms. This parameter is for control of the DC voltage in the rectifier or inverter end. For inverter DC voltage control, the paremeter is set to zero; for rectifier DC voltage control, the paremeter is set to the DC line resistance; otherwise, set to a fraction of the DC line resistance.\"\n    compounding_resistance::Float64\n    \"Minimum compounded voltage, in kV. This parameter must not be added in per-unit. Only used in constant gamma operation (γ_min = γ_max), and the AC transformer is used to control the DC voltage.\"\n    min_compounding_voltage::Float64\n    \"Rectifier transformer ratio between the primary and secondary side AC voltages.\"\n    rectifier_transformer_ratio::Float64\n    \"Rectifier transformer tap setting.\"\n    rectifier_tap_setting::Float64\n    \"Minimum and maximum rectifier tap limits as a ratio between the primary and secondary side AC voltages.\"\n    rectifier_tap_limits::MinMax\n    \"Rectifier transformer tap step value\"\n    rectifier_tap_step::Float64\n    \"Rectifier firing delay angle (α).\"\n    rectifier_delay_angle::Float64\n    \"Commutating rectifier capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\"\n    rectifier_capacitor_reactance::Float64\n    \"Inverter transformer ratio between the primary and secondary side AC voltages.\"\n    inverter_transformer_ratio::Float64\n    \"Inverter transformer tap setting.\"\n    inverter_tap_setting::Float64\n    \"Minimum and maximum inverter tap limits as a ratio between the primary and secondary side AC voltages.\"\n    inverter_tap_limits::MinMax\n    \"Inverter transformer tap step value.\"\n    inverter_tap_step::Float64\n    \"Inverter extinction angle (γ).\"\n    inverter_extinction_angle::Float64\n    \"Commutating inverter capacitor reactance magnitude per bridge, in system p.u. ([`SYSTEM_BASE`](@ref per_unit)).\"\n    inverter_capacitor_reactance::Float64\n    \"Minimum and maximum active power flows to the FROM node (MW)\"\n    active_power_limits_from::MinMax\n    \"Minimum and maximum active power flows to the TO node (MW)\"\n    active_power_limits_to::MinMax\n    \"Minimum and maximum reactive power limits to the FROM node (MVAR)\"\n    reactive_power_limits_from::MinMax\n    \"Minimum and maximum reactive power limits to the TO node (MVAR)\"\n    reactive_power_limits_to::MinMax\n    \"A generic loss model coefficients. It accepts a linear model with a constant loss (MW) and a proportional loss rate (MW of loss per MW of flow). It also accepts a Piecewise loss, with N segments to specify different proportional losses for different segments.\"\n    loss::Union{LinearCurve, PiecewiseIncrementalCurve}\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TwoTerminalLCCLine(name, available, arc, active_power_flow, r, transfer_setpoint, scheduled_dc_voltage, rectifier_bridges, rectifier_delay_angle_limits, rectifier_rc, rectifier_xc, rectifier_base_voltage, inverter_bridges, inverter_extinction_angle_limits, inverter_rc, inverter_xc, inverter_base_voltage, power_mode=true, switch_mode_voltage=0.0, compounding_resistance=0.0, min_compounding_voltage=0.0, rectifier_transformer_ratio=1.0, rectifier_tap_setting=1.0, rectifier_tap_limits=(min=0.51, max=1.5), rectifier_tap_step=0.00625, rectifier_delay_angle=0.0, rectifier_capacitor_reactance=0.0, inverter_transformer_ratio=1.0, inverter_tap_setting=1.0, inverter_tap_limits=(min=0.51, max=1.5), inverter_tap_step=0.00625, inverter_extinction_angle=0.0, inverter_capacitor_reactance=0.0, active_power_limits_from=(min=0.0, max=0.0), active_power_limits_to=(min=0.0, max=0.0), reactive_power_limits_from=(min=0.0, max=0.0), reactive_power_limits_to=(min=0.0, max=0.0), loss=LinearCurve(0.0), services=Device[], ext=Dict{String, Any}(), )\n    TwoTerminalLCCLine(name, available, arc, active_power_flow, r, transfer_setpoint, scheduled_dc_voltage, rectifier_bridges, rectifier_delay_angle_limits, rectifier_rc, rectifier_xc, rectifier_base_voltage, inverter_bridges, inverter_extinction_angle_limits, inverter_rc, inverter_xc, inverter_base_voltage, power_mode, switch_mode_voltage, compounding_resistance, min_compounding_voltage, rectifier_transformer_ratio, rectifier_tap_setting, rectifier_tap_limits, rectifier_tap_step, rectifier_delay_angle, rectifier_capacitor_reactance, inverter_transformer_ratio, inverter_tap_setting, inverter_tap_limits, inverter_tap_step, inverter_extinction_angle, inverter_capacitor_reactance, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction TwoTerminalLCCLine(; name, available, arc, active_power_flow, r, transfer_setpoint, scheduled_dc_voltage, rectifier_bridges, rectifier_delay_angle_limits, rectifier_rc, rectifier_xc, rectifier_base_voltage, inverter_bridges, inverter_extinction_angle_limits, inverter_rc, inverter_xc, inverter_base_voltage, power_mode=true, switch_mode_voltage=0.0, compounding_resistance=0.0, min_compounding_voltage=0.0, rectifier_transformer_ratio=1.0, rectifier_tap_setting=1.0, rectifier_tap_limits=(min=0.51, max=1.5), rectifier_tap_step=0.00625, rectifier_delay_angle=0.0, rectifier_capacitor_reactance=0.0, inverter_transformer_ratio=1.0, inverter_tap_setting=1.0, inverter_tap_limits=(min=0.51, max=1.5), inverter_tap_step=0.00625, inverter_extinction_angle=0.0, inverter_capacitor_reactance=0.0, active_power_limits_from=(min=0.0, max=0.0), active_power_limits_to=(min=0.0, max=0.0), reactive_power_limits_from=(min=0.0, max=0.0), reactive_power_limits_to=(min=0.0, max=0.0), loss=LinearCurve(0.0), services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    TwoTerminalLCCLine(name, available, arc, active_power_flow, r, transfer_setpoint, scheduled_dc_voltage, rectifier_bridges, rectifier_delay_angle_limits, rectifier_rc, rectifier_xc, rectifier_base_voltage, inverter_bridges, inverter_extinction_angle_limits, inverter_rc, inverter_xc, inverter_base_voltage, power_mode, switch_mode_voltage, compounding_resistance, min_compounding_voltage, rectifier_transformer_ratio, rectifier_tap_setting, rectifier_tap_limits, rectifier_tap_step, rectifier_delay_angle, rectifier_capacitor_reactance, inverter_transformer_ratio, inverter_tap_setting, inverter_tap_limits, inverter_tap_step, inverter_extinction_angle, inverter_capacitor_reactance, active_power_limits_from, active_power_limits_to, reactive_power_limits_from, reactive_power_limits_to, loss, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TwoTerminalLCCLine(::Nothing)\n    TwoTerminalLCCLine(;\n        name=\"init\",\n        available=false,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        active_power_flow=0.0,\n        r=0.0,\n        transfer_setpoint=0.0,\n        scheduled_dc_voltage=0.0,\n        rectifier_bridges=0,\n        rectifier_delay_angle_limits=(min=0.0, max=0.0),\n        rectifier_rc=0.0,\n        rectifier_xc=0.0,\n        rectifier_base_voltage=0.0,\n        inverter_bridges=0,\n        inverter_extinction_angle_limits=(min=0.0, max=0.0),\n        inverter_rc=0.0,\n        inverter_xc=0.0,\n        inverter_base_voltage=0.0,\n        power_mode=false,\n        switch_mode_voltage=0.0,\n        compounding_resistance=0.0,\n        min_compounding_voltage=0.0,\n        rectifier_transformer_ratio=0.0,\n        rectifier_tap_setting=0.0,\n        rectifier_tap_limits=(min=0.0, max=0.0),\n        rectifier_tap_step=0.0,\n        rectifier_delay_angle=0.0,\n        rectifier_capacitor_reactance=0.0,\n        inverter_transformer_ratio=0.0,\n        inverter_tap_setting=0.0,\n        inverter_tap_limits=(min=0.0, max=0.0),\n        inverter_tap_step=0.0,\n        inverter_extinction_angle=0.0,\n        inverter_capacitor_reactance=0.0,\n        active_power_limits_from=(min=0.0, max=0.0),\n        active_power_limits_to=(min=0.0, max=0.0),\n        reactive_power_limits_from=(min=0.0, max=0.0),\n        reactive_power_limits_to=(min=0.0, max=0.0),\n        loss=LinearCurve(0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `name`.\"\"\"\nget_name(value::TwoTerminalLCCLine) = value.name\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `available`.\"\"\"\nget_available(value::TwoTerminalLCCLine) = value.available\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `arc`.\"\"\"\nget_arc(value::TwoTerminalLCCLine) = value.arc\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::TwoTerminalLCCLine) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `r`.\"\"\"\nget_r(value::TwoTerminalLCCLine) = value.r\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `transfer_setpoint`.\"\"\"\nget_transfer_setpoint(value::TwoTerminalLCCLine) = value.transfer_setpoint\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `scheduled_dc_voltage`.\"\"\"\nget_scheduled_dc_voltage(value::TwoTerminalLCCLine) = value.scheduled_dc_voltage\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_bridges`.\"\"\"\nget_rectifier_bridges(value::TwoTerminalLCCLine) = value.rectifier_bridges\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_delay_angle_limits`.\"\"\"\nget_rectifier_delay_angle_limits(value::TwoTerminalLCCLine) = value.rectifier_delay_angle_limits\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_rc`.\"\"\"\nget_rectifier_rc(value::TwoTerminalLCCLine) = value.rectifier_rc\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_xc`.\"\"\"\nget_rectifier_xc(value::TwoTerminalLCCLine) = value.rectifier_xc\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_base_voltage`.\"\"\"\nget_rectifier_base_voltage(value::TwoTerminalLCCLine) = value.rectifier_base_voltage\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_bridges`.\"\"\"\nget_inverter_bridges(value::TwoTerminalLCCLine) = value.inverter_bridges\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_extinction_angle_limits`.\"\"\"\nget_inverter_extinction_angle_limits(value::TwoTerminalLCCLine) = value.inverter_extinction_angle_limits\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_rc`.\"\"\"\nget_inverter_rc(value::TwoTerminalLCCLine) = value.inverter_rc\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_xc`.\"\"\"\nget_inverter_xc(value::TwoTerminalLCCLine) = value.inverter_xc\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_base_voltage`.\"\"\"\nget_inverter_base_voltage(value::TwoTerminalLCCLine) = value.inverter_base_voltage\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `power_mode`.\"\"\"\nget_power_mode(value::TwoTerminalLCCLine) = value.power_mode\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `switch_mode_voltage`.\"\"\"\nget_switch_mode_voltage(value::TwoTerminalLCCLine) = value.switch_mode_voltage\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `compounding_resistance`.\"\"\"\nget_compounding_resistance(value::TwoTerminalLCCLine) = value.compounding_resistance\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `min_compounding_voltage`.\"\"\"\nget_min_compounding_voltage(value::TwoTerminalLCCLine) = value.min_compounding_voltage\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_transformer_ratio`.\"\"\"\nget_rectifier_transformer_ratio(value::TwoTerminalLCCLine) = value.rectifier_transformer_ratio\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_tap_setting`.\"\"\"\nget_rectifier_tap_setting(value::TwoTerminalLCCLine) = value.rectifier_tap_setting\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_tap_limits`.\"\"\"\nget_rectifier_tap_limits(value::TwoTerminalLCCLine) = value.rectifier_tap_limits\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_tap_step`.\"\"\"\nget_rectifier_tap_step(value::TwoTerminalLCCLine) = value.rectifier_tap_step\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_delay_angle`.\"\"\"\nget_rectifier_delay_angle(value::TwoTerminalLCCLine) = value.rectifier_delay_angle\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `rectifier_capacitor_reactance`.\"\"\"\nget_rectifier_capacitor_reactance(value::TwoTerminalLCCLine) = value.rectifier_capacitor_reactance\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_transformer_ratio`.\"\"\"\nget_inverter_transformer_ratio(value::TwoTerminalLCCLine) = value.inverter_transformer_ratio\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_tap_setting`.\"\"\"\nget_inverter_tap_setting(value::TwoTerminalLCCLine) = value.inverter_tap_setting\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_tap_limits`.\"\"\"\nget_inverter_tap_limits(value::TwoTerminalLCCLine) = value.inverter_tap_limits\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_tap_step`.\"\"\"\nget_inverter_tap_step(value::TwoTerminalLCCLine) = value.inverter_tap_step\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_extinction_angle`.\"\"\"\nget_inverter_extinction_angle(value::TwoTerminalLCCLine) = value.inverter_extinction_angle\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `inverter_capacitor_reactance`.\"\"\"\nget_inverter_capacitor_reactance(value::TwoTerminalLCCLine) = value.inverter_capacitor_reactance\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `active_power_limits_from`.\"\"\"\nget_active_power_limits_from(value::TwoTerminalLCCLine) = get_value(value, Val(:active_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `active_power_limits_to`.\"\"\"\nget_active_power_limits_to(value::TwoTerminalLCCLine) = get_value(value, Val(:active_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nget_reactive_power_limits_from(value::TwoTerminalLCCLine) = get_value(value, Val(:reactive_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nget_reactive_power_limits_to(value::TwoTerminalLCCLine) = get_value(value, Val(:reactive_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `loss`.\"\"\"\nget_loss(value::TwoTerminalLCCLine) = value.loss\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `services`.\"\"\"\nget_services(value::TwoTerminalLCCLine) = value.services\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `ext`.\"\"\"\nget_ext(value::TwoTerminalLCCLine) = value.ext\n\"\"\"Get [`TwoTerminalLCCLine`](@ref) `internal`.\"\"\"\nget_internal(value::TwoTerminalLCCLine) = value.internal\n\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `available`.\"\"\"\nset_available!(value::TwoTerminalLCCLine, val) = value.available = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `arc`.\"\"\"\nset_arc!(value::TwoTerminalLCCLine, val) = value.arc = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::TwoTerminalLCCLine, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `r`.\"\"\"\nset_r!(value::TwoTerminalLCCLine, val) = value.r = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `transfer_setpoint`.\"\"\"\nset_transfer_setpoint!(value::TwoTerminalLCCLine, val) = value.transfer_setpoint = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `scheduled_dc_voltage`.\"\"\"\nset_scheduled_dc_voltage!(value::TwoTerminalLCCLine, val) = value.scheduled_dc_voltage = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_bridges`.\"\"\"\nset_rectifier_bridges!(value::TwoTerminalLCCLine, val) = value.rectifier_bridges = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_delay_angle_limits`.\"\"\"\nset_rectifier_delay_angle_limits!(value::TwoTerminalLCCLine, val) = value.rectifier_delay_angle_limits = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_rc`.\"\"\"\nset_rectifier_rc!(value::TwoTerminalLCCLine, val) = value.rectifier_rc = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_xc`.\"\"\"\nset_rectifier_xc!(value::TwoTerminalLCCLine, val) = value.rectifier_xc = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_base_voltage`.\"\"\"\nset_rectifier_base_voltage!(value::TwoTerminalLCCLine, val) = value.rectifier_base_voltage = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_bridges`.\"\"\"\nset_inverter_bridges!(value::TwoTerminalLCCLine, val) = value.inverter_bridges = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_extinction_angle_limits`.\"\"\"\nset_inverter_extinction_angle_limits!(value::TwoTerminalLCCLine, val) = value.inverter_extinction_angle_limits = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_rc`.\"\"\"\nset_inverter_rc!(value::TwoTerminalLCCLine, val) = value.inverter_rc = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_xc`.\"\"\"\nset_inverter_xc!(value::TwoTerminalLCCLine, val) = value.inverter_xc = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_base_voltage`.\"\"\"\nset_inverter_base_voltage!(value::TwoTerminalLCCLine, val) = value.inverter_base_voltage = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `power_mode`.\"\"\"\nset_power_mode!(value::TwoTerminalLCCLine, val) = value.power_mode = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `switch_mode_voltage`.\"\"\"\nset_switch_mode_voltage!(value::TwoTerminalLCCLine, val) = value.switch_mode_voltage = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `compounding_resistance`.\"\"\"\nset_compounding_resistance!(value::TwoTerminalLCCLine, val) = value.compounding_resistance = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `min_compounding_voltage`.\"\"\"\nset_min_compounding_voltage!(value::TwoTerminalLCCLine, val) = value.min_compounding_voltage = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_transformer_ratio`.\"\"\"\nset_rectifier_transformer_ratio!(value::TwoTerminalLCCLine, val) = value.rectifier_transformer_ratio = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_tap_setting`.\"\"\"\nset_rectifier_tap_setting!(value::TwoTerminalLCCLine, val) = value.rectifier_tap_setting = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_tap_limits`.\"\"\"\nset_rectifier_tap_limits!(value::TwoTerminalLCCLine, val) = value.rectifier_tap_limits = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_tap_step`.\"\"\"\nset_rectifier_tap_step!(value::TwoTerminalLCCLine, val) = value.rectifier_tap_step = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_delay_angle`.\"\"\"\nset_rectifier_delay_angle!(value::TwoTerminalLCCLine, val) = value.rectifier_delay_angle = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `rectifier_capacitor_reactance`.\"\"\"\nset_rectifier_capacitor_reactance!(value::TwoTerminalLCCLine, val) = value.rectifier_capacitor_reactance = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_transformer_ratio`.\"\"\"\nset_inverter_transformer_ratio!(value::TwoTerminalLCCLine, val) = value.inverter_transformer_ratio = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_tap_setting`.\"\"\"\nset_inverter_tap_setting!(value::TwoTerminalLCCLine, val) = value.inverter_tap_setting = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_tap_limits`.\"\"\"\nset_inverter_tap_limits!(value::TwoTerminalLCCLine, val) = value.inverter_tap_limits = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_tap_step`.\"\"\"\nset_inverter_tap_step!(value::TwoTerminalLCCLine, val) = value.inverter_tap_step = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_extinction_angle`.\"\"\"\nset_inverter_extinction_angle!(value::TwoTerminalLCCLine, val) = value.inverter_extinction_angle = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `inverter_capacitor_reactance`.\"\"\"\nset_inverter_capacitor_reactance!(value::TwoTerminalLCCLine, val) = value.inverter_capacitor_reactance = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `active_power_limits_from`.\"\"\"\nset_active_power_limits_from!(value::TwoTerminalLCCLine, val) = value.active_power_limits_from = set_value(value, Val(:active_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `active_power_limits_to`.\"\"\"\nset_active_power_limits_to!(value::TwoTerminalLCCLine, val) = value.active_power_limits_to = set_value(value, Val(:active_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nset_reactive_power_limits_from!(value::TwoTerminalLCCLine, val) = value.reactive_power_limits_from = set_value(value, Val(:reactive_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nset_reactive_power_limits_to!(value::TwoTerminalLCCLine, val) = value.reactive_power_limits_to = set_value(value, Val(:reactive_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `loss`.\"\"\"\nset_loss!(value::TwoTerminalLCCLine, val) = value.loss = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `services`.\"\"\"\nset_services!(value::TwoTerminalLCCLine, val) = value.services = val\n\"\"\"Set [`TwoTerminalLCCLine`](@ref) `ext`.\"\"\"\nset_ext!(value::TwoTerminalLCCLine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/TwoTerminalVSCLine.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct TwoTerminalVSCLine <: TwoTerminalHVDC\n        name::String\n        available::Bool\n        arc::Arc\n        active_power_flow::Float64\n        rating::Float64\n        active_power_limits_from::MinMax\n        active_power_limits_to::MinMax\n        g::Float64\n        dc_current::Float64\n        reactive_power_from::Float64\n        dc_voltage_control_from::Bool\n        ac_voltage_control_from::Bool\n        dc_setpoint_from::Float64\n        ac_setpoint_from::Float64\n        converter_loss_from::Union{LinearCurve, QuadraticCurve}\n        max_dc_current_from::Float64\n        rating_from::Float64\n        reactive_power_limits_from::MinMax\n        power_factor_weighting_fraction_from::Float64\n        voltage_limits_from::MinMax\n        reactive_power_to::Float64\n        dc_voltage_control_to::Bool\n        ac_voltage_control_to::Bool\n        dc_setpoint_to::Float64\n        ac_setpoint_to::Float64\n        converter_loss_to::Union{LinearCurve, QuadraticCurve}\n        max_dc_current_to::Float64\n        rating_to::Float64\n        reactive_power_limits_to::MinMax\n        power_factor_weighting_fraction_to::Float64\n        voltage_limits_to::MinMax\n        services::Vector{Service}\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA High Voltage Voltage-Source Converter DC line, which must be connected to an [`ACBus`](@ref) on each end.\n\nThis model is appropriate for operational simulations with a linearized DC power flow approximation with losses using a voltage-current model. For modeling a DC network, see [`TModelHVDCLine`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `arc::Arc`: An [`Arc`](@ref) defining this line `from` a bus `to` another bus\n- `active_power_flow::Float64`: Initial condition of active power flowing from the from-bus to the to-bus in DC.\n- `rating::Float64`: Maximum output power rating of the converter (MVA), validation range: `(0, nothing)`\n- `active_power_limits_from::MinMax`: Minimum and maximum active power flows to the FROM node (MW)\n- `active_power_limits_to::MinMax`: Minimum and maximum active power flows to the TO node (MW)\n- `g::Float64`: (default: `0.0`) Series conductance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\n- `dc_current::Float64`: (default: `0.0`) DC current (A) on the converter flowing in the DC line, from `from` bus to `to` bus.\n- `reactive_power_from::Float64`: (default: `0.0`) Initial condition of reactive power flowing into the from-bus.\n- `dc_voltage_control_from::Bool`: (default: `true`) Converter control type in the `from` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\n- `ac_voltage_control_from::Bool`: (default: `true`) Converter control type in the `from` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\n- `dc_setpoint_from::Float64`: (default: `0.0`) Converter DC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_from = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `from` bus; if negative, the converter is withdrawing power from the AC network at the `from` bus.\n- `ac_setpoint_from::Float64`: (default: `1.0`) Converter AC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_from = false`, this value is the power factor setpoint.\n- `converter_loss_from::Union{LinearCurve, QuadraticCurve}`: (default: `LinearCurve(0.0)`) Loss model coefficients in the `from` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\n- `max_dc_current_from::Float64`: (default: `1e8`) Maximum stable dc current limits (A).\n- `rating_from::Float64`: (default: `1e8`) Converter rating in MVA in the `from` bus.\n- `reactive_power_limits_from::MinMax`: (default: `(min=0.0, max=0.0)`) Limits on the Reactive Power at the `from` side.\n- `power_factor_weighting_fraction_from::Float64`: (default: `1.0`) Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied., validation range: `(0, 1)`\n- `voltage_limits_from::MinMax`: (default: `(min=0.0, max=999.9)`) Limits on the Voltage at the DC `from` Bus in [per unit](@ref per_unit.\n- `reactive_power_to::Float64`: (default: `0.0`) Initial condition of reactive power flowing into the to-bus.\n- `dc_voltage_control_to::Bool`: (default: `true`) Converter control type in the `to` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\n- `ac_voltage_control_to::Bool`: (default: `true`) Converter control type in the `to` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\n- `dc_setpoint_to::Float64`: (default: `0.0`) Converter DC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_to = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `to` bus; if negative, the converter is withdrawing power from the AC network at the `to` bus.\n- `ac_setpoint_to::Float64`: (default: `1.0`) Converter AC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_to = false`, this value is the power factor setpoint.\n- `converter_loss_to::Union{LinearCurve, QuadraticCurve}`: (default: `LinearCurve(0.0)`) Loss model coefficients in the `to` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\n- `max_dc_current_to::Float64`: (default: `1e8`) Maximum stable dc current limits (A).\n- `rating_to::Float64`: (default: `1e8`) Converter rating in MVA in the `to` bus.\n- `reactive_power_limits_to::MinMax`: (default: `(min=0.0, max=0.0)`) Limits on the Reactive Power at the `to` side.\n- `power_factor_weighting_fraction_to::Float64`: (default: `1.0`) Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied., validation range: `(0, 1)`\n- `voltage_limits_to::MinMax`: (default: `(min=0.0, max=999.9)`) Limits on the Voltage at the DC `to` Bus.\n- `services::Vector{Service}`: (default: `Device[]`) Services that this device contributes to\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct TwoTerminalVSCLine <: TwoTerminalHVDC\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"An [`Arc`](@ref) defining this line `from` a bus `to` another bus\"\n    arc::Arc\n    \"Initial condition of active power flowing from the from-bus to the to-bus in DC.\"\n    active_power_flow::Float64\n    \"Maximum output power rating of the converter (MVA)\"\n    rating::Float64\n    \"Minimum and maximum active power flows to the FROM node (MW)\"\n    active_power_limits_from::MinMax\n    \"Minimum and maximum active power flows to the TO node (MW)\"\n    active_power_limits_to::MinMax\n    \"Series conductance of the DC line in pu ([`SYSTEM_BASE`](@ref per_unit))\"\n    g::Float64\n    \"DC current (A) on the converter flowing in the DC line, from `from` bus to `to` bus.\"\n    dc_current::Float64\n    \"Initial condition of reactive power flowing into the from-bus.\"\n    reactive_power_from::Float64\n    \"Converter control type in the `from` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\"\n    dc_voltage_control_from::Bool\n    \"Converter control type in the `from` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\"\n    ac_voltage_control_from::Bool\n    \"Converter DC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_from = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `from` bus; if negative, the converter is withdrawing power from the AC network at the `from` bus.\"\n    dc_setpoint_from::Float64\n    \"Converter AC setpoint in the `from` bus converter. If `voltage_control_from = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_from = false`, this value is the power factor setpoint.\"\n    ac_setpoint_from::Float64\n    \"Loss model coefficients in the `from` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\"\n    converter_loss_from::Union{LinearCurve, QuadraticCurve}\n    \"Maximum stable dc current limits (A).\"\n    max_dc_current_from::Float64\n    \"Converter rating in MVA in the `from` bus.\"\n    rating_from::Float64\n    \"Limits on the Reactive Power at the `from` side.\"\n    reactive_power_limits_from::MinMax\n    \"Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied.\"\n    power_factor_weighting_fraction_from::Float64\n    \"Limits on the Voltage at the DC `from` Bus in [per unit](@ref per_unit.\"\n    voltage_limits_from::MinMax\n    \"Initial condition of reactive power flowing into the to-bus.\"\n    reactive_power_to::Float64\n    \"Converter control type in the `to` bus converter. Set true for DC Voltage Control (set DC voltage on the DC side of the converter), and false for power demand in the converter.\"\n    dc_voltage_control_to::Bool\n    \"Converter control type in the `to` bus converter. Set true for AC Voltage Control (set AC voltage on the AC side of the converter), and false for fixed power AC factor.\"\n    ac_voltage_control_to::Bool\n    \"Converter DC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the DC voltage on the DC side of the converter, entered in kV. If `voltage_control_to = false`, this value is the power demand in MW, if positive the converter is supplying power to the AC network at the `to` bus; if negative, the converter is withdrawing power from the AC network at the `to` bus.\"\n    dc_setpoint_to::Float64\n    \"Converter AC setpoint in the `to` bus converter. If `voltage_control_to = true` this number is the AC voltage on the AC side of the converter, entered in [per unit](@ref per_unit). If `voltage_control_to = false`, this value is the power factor setpoint.\"\n    ac_setpoint_to::Float64\n    \"Loss model coefficients in the `to` bus converter. It accepts a linear model or quadratic. Same converter data is used in both ends.\"\n    converter_loss_to::Union{LinearCurve, QuadraticCurve}\n    \"Maximum stable dc current limits (A).\"\n    max_dc_current_to::Float64\n    \"Converter rating in MVA in the `to` bus.\"\n    rating_to::Float64\n    \"Limits on the Reactive Power at the `to` side.\"\n    reactive_power_limits_to::MinMax\n    \"Power weighting factor fraction used in reducing the active power order and either the reactive power order when the converter rating is violated. When is 0.0, only the active power is reduced; when is 1.0, only the reactive power is reduced; otherwise, a weighted reduction of both active and reactive power is applied.\"\n    power_factor_weighting_fraction_to::Float64\n    \"Limits on the Voltage at the DC `to` Bus.\"\n    voltage_limits_to::MinMax\n    \"Services that this device contributes to\"\n    services::Vector{Service}\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction TwoTerminalVSCLine(name, available, arc, active_power_flow, rating, active_power_limits_from, active_power_limits_to, g=0.0, dc_current=0.0, reactive_power_from=0.0, dc_voltage_control_from=true, ac_voltage_control_from=true, dc_setpoint_from=0.0, ac_setpoint_from=1.0, converter_loss_from=LinearCurve(0.0), max_dc_current_from=1e8, rating_from=1e8, reactive_power_limits_from=(min=0.0, max=0.0), power_factor_weighting_fraction_from=1.0, voltage_limits_from=(min=0.0, max=999.9), reactive_power_to=0.0, dc_voltage_control_to=true, ac_voltage_control_to=true, dc_setpoint_to=0.0, ac_setpoint_to=1.0, converter_loss_to=LinearCurve(0.0), max_dc_current_to=1e8, rating_to=1e8, reactive_power_limits_to=(min=0.0, max=0.0), power_factor_weighting_fraction_to=1.0, voltage_limits_to=(min=0.0, max=999.9), services=Device[], ext=Dict{String, Any}(), )\n    TwoTerminalVSCLine(name, available, arc, active_power_flow, rating, active_power_limits_from, active_power_limits_to, g, dc_current, reactive_power_from, dc_voltage_control_from, ac_voltage_control_from, dc_setpoint_from, ac_setpoint_from, converter_loss_from, max_dc_current_from, rating_from, reactive_power_limits_from, power_factor_weighting_fraction_from, voltage_limits_from, reactive_power_to, dc_voltage_control_to, ac_voltage_control_to, dc_setpoint_to, ac_setpoint_to, converter_loss_to, max_dc_current_to, rating_to, reactive_power_limits_to, power_factor_weighting_fraction_to, voltage_limits_to, services, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction TwoTerminalVSCLine(; name, available, arc, active_power_flow, rating, active_power_limits_from, active_power_limits_to, g=0.0, dc_current=0.0, reactive_power_from=0.0, dc_voltage_control_from=true, ac_voltage_control_from=true, dc_setpoint_from=0.0, ac_setpoint_from=1.0, converter_loss_from=LinearCurve(0.0), max_dc_current_from=1e8, rating_from=1e8, reactive_power_limits_from=(min=0.0, max=0.0), power_factor_weighting_fraction_from=1.0, voltage_limits_from=(min=0.0, max=999.9), reactive_power_to=0.0, dc_voltage_control_to=true, ac_voltage_control_to=true, dc_setpoint_to=0.0, ac_setpoint_to=1.0, converter_loss_to=LinearCurve(0.0), max_dc_current_to=1e8, rating_to=1e8, reactive_power_limits_to=(min=0.0, max=0.0), power_factor_weighting_fraction_to=1.0, voltage_limits_to=(min=0.0, max=999.9), services=Device[], ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    TwoTerminalVSCLine(name, available, arc, active_power_flow, rating, active_power_limits_from, active_power_limits_to, g, dc_current, reactive_power_from, dc_voltage_control_from, ac_voltage_control_from, dc_setpoint_from, ac_setpoint_from, converter_loss_from, max_dc_current_from, rating_from, reactive_power_limits_from, power_factor_weighting_fraction_from, voltage_limits_from, reactive_power_to, dc_voltage_control_to, ac_voltage_control_to, dc_setpoint_to, ac_setpoint_to, converter_loss_to, max_dc_current_to, rating_to, reactive_power_limits_to, power_factor_weighting_fraction_to, voltage_limits_to, services, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction TwoTerminalVSCLine(::Nothing)\n    TwoTerminalVSCLine(;\n        name=\"init\",\n        available=false,\n        arc=Arc(ACBus(nothing), ACBus(nothing)),\n        active_power_flow=0.0,\n        rating=0.0,\n        active_power_limits_from=(min=0.0, max=0.0),\n        active_power_limits_to=(min=0.0, max=0.0),\n        g=0.0,\n        dc_current=0.0,\n        reactive_power_from=0.0,\n        dc_voltage_control_from=false,\n        ac_voltage_control_from=false,\n        dc_setpoint_from=0.0,\n        ac_setpoint_from=0.0,\n        converter_loss_from=LinearCurve(0.0),\n        max_dc_current_from=0.0,\n        rating_from=0.0,\n        reactive_power_limits_from=(min=0.0, max=0.0),\n        power_factor_weighting_fraction_from=0.0,\n        voltage_limits_from=(min=0.0, max=0.0),\n        reactive_power_to=0.0,\n        dc_voltage_control_to=false,\n        ac_voltage_control_to=false,\n        dc_setpoint_to=0.0,\n        ac_setpoint_to=0.0,\n        converter_loss_to=LinearCurve(0.0),\n        max_dc_current_to=0.0,\n        rating_to=0.0,\n        reactive_power_limits_to=(min=0.0, max=0.0),\n        power_factor_weighting_fraction_to=0.0,\n        voltage_limits_to=(min=0.0, max=0.0),\n        services=Device[],\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `name`.\"\"\"\nget_name(value::TwoTerminalVSCLine) = value.name\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `available`.\"\"\"\nget_available(value::TwoTerminalVSCLine) = value.available\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `arc`.\"\"\"\nget_arc(value::TwoTerminalVSCLine) = value.arc\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `active_power_flow`.\"\"\"\nget_active_power_flow(value::TwoTerminalVSCLine) = get_value(value, Val(:active_power_flow), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `rating`.\"\"\"\nget_rating(value::TwoTerminalVSCLine) = get_value(value, Val(:rating), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `active_power_limits_from`.\"\"\"\nget_active_power_limits_from(value::TwoTerminalVSCLine) = get_value(value, Val(:active_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `active_power_limits_to`.\"\"\"\nget_active_power_limits_to(value::TwoTerminalVSCLine) = get_value(value, Val(:active_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `g`.\"\"\"\nget_g(value::TwoTerminalVSCLine) = value.g\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `dc_current`.\"\"\"\nget_dc_current(value::TwoTerminalVSCLine) = value.dc_current\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `reactive_power_from`.\"\"\"\nget_reactive_power_from(value::TwoTerminalVSCLine) = get_value(value, Val(:reactive_power_from), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `dc_voltage_control_from`.\"\"\"\nget_dc_voltage_control_from(value::TwoTerminalVSCLine) = value.dc_voltage_control_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `ac_voltage_control_from`.\"\"\"\nget_ac_voltage_control_from(value::TwoTerminalVSCLine) = value.ac_voltage_control_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `dc_setpoint_from`.\"\"\"\nget_dc_setpoint_from(value::TwoTerminalVSCLine) = value.dc_setpoint_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `ac_setpoint_from`.\"\"\"\nget_ac_setpoint_from(value::TwoTerminalVSCLine) = value.ac_setpoint_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `converter_loss_from`.\"\"\"\nget_converter_loss_from(value::TwoTerminalVSCLine) = value.converter_loss_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `max_dc_current_from`.\"\"\"\nget_max_dc_current_from(value::TwoTerminalVSCLine) = value.max_dc_current_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `rating_from`.\"\"\"\nget_rating_from(value::TwoTerminalVSCLine) = get_value(value, Val(:rating_from), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nget_reactive_power_limits_from(value::TwoTerminalVSCLine) = get_value(value, Val(:reactive_power_limits_from), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `power_factor_weighting_fraction_from`.\"\"\"\nget_power_factor_weighting_fraction_from(value::TwoTerminalVSCLine) = value.power_factor_weighting_fraction_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `voltage_limits_from`.\"\"\"\nget_voltage_limits_from(value::TwoTerminalVSCLine) = value.voltage_limits_from\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `reactive_power_to`.\"\"\"\nget_reactive_power_to(value::TwoTerminalVSCLine) = get_value(value, Val(:reactive_power_to), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `dc_voltage_control_to`.\"\"\"\nget_dc_voltage_control_to(value::TwoTerminalVSCLine) = value.dc_voltage_control_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `ac_voltage_control_to`.\"\"\"\nget_ac_voltage_control_to(value::TwoTerminalVSCLine) = value.ac_voltage_control_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `dc_setpoint_to`.\"\"\"\nget_dc_setpoint_to(value::TwoTerminalVSCLine) = value.dc_setpoint_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `ac_setpoint_to`.\"\"\"\nget_ac_setpoint_to(value::TwoTerminalVSCLine) = value.ac_setpoint_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `converter_loss_to`.\"\"\"\nget_converter_loss_to(value::TwoTerminalVSCLine) = value.converter_loss_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `max_dc_current_to`.\"\"\"\nget_max_dc_current_to(value::TwoTerminalVSCLine) = value.max_dc_current_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `rating_to`.\"\"\"\nget_rating_to(value::TwoTerminalVSCLine) = get_value(value, Val(:rating_to), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nget_reactive_power_limits_to(value::TwoTerminalVSCLine) = get_value(value, Val(:reactive_power_limits_to), Val(:mva))\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `power_factor_weighting_fraction_to`.\"\"\"\nget_power_factor_weighting_fraction_to(value::TwoTerminalVSCLine) = value.power_factor_weighting_fraction_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `voltage_limits_to`.\"\"\"\nget_voltage_limits_to(value::TwoTerminalVSCLine) = value.voltage_limits_to\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `services`.\"\"\"\nget_services(value::TwoTerminalVSCLine) = value.services\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `ext`.\"\"\"\nget_ext(value::TwoTerminalVSCLine) = value.ext\n\"\"\"Get [`TwoTerminalVSCLine`](@ref) `internal`.\"\"\"\nget_internal(value::TwoTerminalVSCLine) = value.internal\n\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `available`.\"\"\"\nset_available!(value::TwoTerminalVSCLine, val) = value.available = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `arc`.\"\"\"\nset_arc!(value::TwoTerminalVSCLine, val) = value.arc = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `active_power_flow`.\"\"\"\nset_active_power_flow!(value::TwoTerminalVSCLine, val) = value.active_power_flow = set_value(value, Val(:active_power_flow), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `rating`.\"\"\"\nset_rating!(value::TwoTerminalVSCLine, val) = value.rating = set_value(value, Val(:rating), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `active_power_limits_from`.\"\"\"\nset_active_power_limits_from!(value::TwoTerminalVSCLine, val) = value.active_power_limits_from = set_value(value, Val(:active_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `active_power_limits_to`.\"\"\"\nset_active_power_limits_to!(value::TwoTerminalVSCLine, val) = value.active_power_limits_to = set_value(value, Val(:active_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `g`.\"\"\"\nset_g!(value::TwoTerminalVSCLine, val) = value.g = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `dc_current`.\"\"\"\nset_dc_current!(value::TwoTerminalVSCLine, val) = value.dc_current = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `reactive_power_from`.\"\"\"\nset_reactive_power_from!(value::TwoTerminalVSCLine, val) = value.reactive_power_from = set_value(value, Val(:reactive_power_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `dc_voltage_control_from`.\"\"\"\nset_dc_voltage_control_from!(value::TwoTerminalVSCLine, val) = value.dc_voltage_control_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `ac_voltage_control_from`.\"\"\"\nset_ac_voltage_control_from!(value::TwoTerminalVSCLine, val) = value.ac_voltage_control_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `dc_setpoint_from`.\"\"\"\nset_dc_setpoint_from!(value::TwoTerminalVSCLine, val) = value.dc_setpoint_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `ac_setpoint_from`.\"\"\"\nset_ac_setpoint_from!(value::TwoTerminalVSCLine, val) = value.ac_setpoint_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `converter_loss_from`.\"\"\"\nset_converter_loss_from!(value::TwoTerminalVSCLine, val) = value.converter_loss_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `max_dc_current_from`.\"\"\"\nset_max_dc_current_from!(value::TwoTerminalVSCLine, val) = value.max_dc_current_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `rating_from`.\"\"\"\nset_rating_from!(value::TwoTerminalVSCLine, val) = value.rating_from = set_value(value, Val(:rating_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `reactive_power_limits_from`.\"\"\"\nset_reactive_power_limits_from!(value::TwoTerminalVSCLine, val) = value.reactive_power_limits_from = set_value(value, Val(:reactive_power_limits_from), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `power_factor_weighting_fraction_from`.\"\"\"\nset_power_factor_weighting_fraction_from!(value::TwoTerminalVSCLine, val) = value.power_factor_weighting_fraction_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `voltage_limits_from`.\"\"\"\nset_voltage_limits_from!(value::TwoTerminalVSCLine, val) = value.voltage_limits_from = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `reactive_power_to`.\"\"\"\nset_reactive_power_to!(value::TwoTerminalVSCLine, val) = value.reactive_power_to = set_value(value, Val(:reactive_power_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `dc_voltage_control_to`.\"\"\"\nset_dc_voltage_control_to!(value::TwoTerminalVSCLine, val) = value.dc_voltage_control_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `ac_voltage_control_to`.\"\"\"\nset_ac_voltage_control_to!(value::TwoTerminalVSCLine, val) = value.ac_voltage_control_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `dc_setpoint_to`.\"\"\"\nset_dc_setpoint_to!(value::TwoTerminalVSCLine, val) = value.dc_setpoint_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `ac_setpoint_to`.\"\"\"\nset_ac_setpoint_to!(value::TwoTerminalVSCLine, val) = value.ac_setpoint_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `converter_loss_to`.\"\"\"\nset_converter_loss_to!(value::TwoTerminalVSCLine, val) = value.converter_loss_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `max_dc_current_to`.\"\"\"\nset_max_dc_current_to!(value::TwoTerminalVSCLine, val) = value.max_dc_current_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `rating_to`.\"\"\"\nset_rating_to!(value::TwoTerminalVSCLine, val) = value.rating_to = set_value(value, Val(:rating_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `reactive_power_limits_to`.\"\"\"\nset_reactive_power_limits_to!(value::TwoTerminalVSCLine, val) = value.reactive_power_limits_to = set_value(value, Val(:reactive_power_limits_to), val, Val(:mva))\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `power_factor_weighting_fraction_to`.\"\"\"\nset_power_factor_weighting_fraction_to!(value::TwoTerminalVSCLine, val) = value.power_factor_weighting_fraction_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `voltage_limits_to`.\"\"\"\nset_voltage_limits_to!(value::TwoTerminalVSCLine, val) = value.voltage_limits_to = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `services`.\"\"\"\nset_services!(value::TwoTerminalVSCLine, val) = value.services = val\n\"\"\"Set [`TwoTerminalVSCLine`](@ref) `ext`.\"\"\"\nset_ext!(value::TwoTerminalVSCLine, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/VariableReserve.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct VariableReserve{T <: ReserveDirection} <: Reserve{T}\n        name::String\n        available::Bool\n        time_frame::Float64\n        requirement::Float64\n        sustained_time::Float64\n        max_output_fraction::Float64\n        max_participation_factor::Float64\n        deployed_fraction::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA reserve product with a time-varying procurement requirement, such as a higher requirement during hours with an expected high load or high ramp.\n\nThis reserve product includes online generators that can respond right away after an unexpected contingency, such as a transmission line or generator outage. When defining the reserve, the `ReserveDirection` must be specified to define this as a [`ReserveUp`](@ref), [`ReserveDown`](@ref), or [`ReserveSymmetric`](@ref). To model the time varying requirement, a [\"`requirement`\" time series should be added](@ref ts_data) to this reserve\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `time_frame::Float64`: the saturation time_frame in minutes to provide reserve contribution, validation range: `(0, nothing)`\n- `requirement::Float64`: the required quantity of the product should be scaled by a TimeSeriesData\n- `sustained_time::Float64`: (default: `3600.0`) the time in seconds reserve contribution must sustained at a specified level, validation range: `(0, nothing)`\n- `max_output_fraction::Float64`: (default: `1.0`) the maximum fraction of each device's output that can be assigned to the service, validation range: `(0, 1)`\n- `max_participation_factor::Float64`: (default: `1.0`) the maximum portion [0, 1.0] of the reserve that can be contributed per device, validation range: `(0, 1)`\n- `deployed_fraction::Float64`: (default: `0.0`) Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0, validation range: `(0, 1)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct VariableReserve{T <: ReserveDirection} <: Reserve{T}\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the saturation time_frame in minutes to provide reserve contribution\"\n    time_frame::Float64\n    \"the required quantity of the product should be scaled by a TimeSeriesData\"\n    requirement::Float64\n    \"the time in seconds reserve contribution must sustained at a specified level\"\n    sustained_time::Float64\n    \"the maximum fraction of each device's output that can be assigned to the service\"\n    max_output_fraction::Float64\n    \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\"\n    max_participation_factor::Float64\n    \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\"\n    deployed_fraction::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction VariableReserve{T}(name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), ) where T <: ReserveDirection\n    VariableReserve{T}(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction VariableReserve{T}(; name, available, time_frame, requirement, sustained_time=3600.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), ) where T <: ReserveDirection\n    VariableReserve{T}(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction VariableReserve{T}(::Nothing) where T <: ReserveDirection\n    VariableReserve{T}(;\n        name=\"init\",\n        available=false,\n        time_frame=0.0,\n        requirement=0.0,\n        sustained_time=0.0,\n        max_output_fraction=1.0,\n        max_participation_factor=1.0,\n        deployed_fraction=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`VariableReserve`](@ref) `name`.\"\"\"\nget_name(value::VariableReserve) = value.name\n\"\"\"Get [`VariableReserve`](@ref) `available`.\"\"\"\nget_available(value::VariableReserve) = value.available\n\"\"\"Get [`VariableReserve`](@ref) `time_frame`.\"\"\"\nget_time_frame(value::VariableReserve) = value.time_frame\n\"\"\"Get [`VariableReserve`](@ref) `requirement`.\"\"\"\nget_requirement(value::VariableReserve) = value.requirement\n\"\"\"Get [`VariableReserve`](@ref) `sustained_time`.\"\"\"\nget_sustained_time(value::VariableReserve) = value.sustained_time\n\"\"\"Get [`VariableReserve`](@ref) `max_output_fraction`.\"\"\"\nget_max_output_fraction(value::VariableReserve) = value.max_output_fraction\n\"\"\"Get [`VariableReserve`](@ref) `max_participation_factor`.\"\"\"\nget_max_participation_factor(value::VariableReserve) = value.max_participation_factor\n\"\"\"Get [`VariableReserve`](@ref) `deployed_fraction`.\"\"\"\nget_deployed_fraction(value::VariableReserve) = value.deployed_fraction\n\"\"\"Get [`VariableReserve`](@ref) `ext`.\"\"\"\nget_ext(value::VariableReserve) = value.ext\n\"\"\"Get [`VariableReserve`](@ref) `internal`.\"\"\"\nget_internal(value::VariableReserve) = value.internal\n\n\"\"\"Set [`VariableReserve`](@ref) `available`.\"\"\"\nset_available!(value::VariableReserve, val) = value.available = val\n\"\"\"Set [`VariableReserve`](@ref) `time_frame`.\"\"\"\nset_time_frame!(value::VariableReserve, val) = value.time_frame = val\n\"\"\"Set [`VariableReserve`](@ref) `requirement`.\"\"\"\nset_requirement!(value::VariableReserve, val) = value.requirement = val\n\"\"\"Set [`VariableReserve`](@ref) `sustained_time`.\"\"\"\nset_sustained_time!(value::VariableReserve, val) = value.sustained_time = val\n\"\"\"Set [`VariableReserve`](@ref) `max_output_fraction`.\"\"\"\nset_max_output_fraction!(value::VariableReserve, val) = value.max_output_fraction = val\n\"\"\"Set [`VariableReserve`](@ref) `max_participation_factor`.\"\"\"\nset_max_participation_factor!(value::VariableReserve, val) = value.max_participation_factor = val\n\"\"\"Set [`VariableReserve`](@ref) `deployed_fraction`.\"\"\"\nset_deployed_fraction!(value::VariableReserve, val) = value.deployed_fraction = val\n\"\"\"Set [`VariableReserve`](@ref) `ext`.\"\"\"\nset_ext!(value::VariableReserve, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/VariableReserveNonSpinning.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct VariableReserveNonSpinning <: ReserveNonSpinning\n        name::String\n        available::Bool\n        time_frame::Float64\n        requirement::Float64\n        sustained_time::Float64\n        max_output_fraction::Float64\n        max_participation_factor::Float64\n        deployed_fraction::Float64\n        ext::Dict{String, Any}\n        internal::InfrastructureSystemsInternal\n    end\n\nA non-spinning reserve product with a time-varying procurement requirement, such as a higher requirement during hours with an expected high load or high ramp.\n\nThis reserve product includes back-up generators that might not be currently synchronized with the power system, but can come online quickly after an unexpected contingency, such as a transmission line or generator outage. To model the time varying requirement, a [\"`requirement`\" time series should be added](@ref ts_data) to this reserve.\n\nThis is only an upwards reserve. For faster-responding upwards or downwards reserves from components already synchronized with the system, see [`VariableReserve`](@ref)\n\n# Arguments\n- `name::String`: Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\n- `available::Bool`: Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\n- `time_frame::Float64`: the saturation time_frame in minutes to provide reserve contribution, validation range: `(0, nothing)`\n- `requirement::Float64`: the required quantity of the product should be scaled by a TimeSeriesData\n- `sustained_time::Float64`: (default: `14400.0`) the time in seconds reserve contribution must sustained at a specified level, validation range: `(0, nothing)`\n- `max_output_fraction::Float64`: (default: `1.0`) the maximum fraction of each device's output that can be assigned to the service, validation range: `(0, 1)`\n- `max_participation_factor::Float64`: (default: `1.0`) the maximum portion [0, 1.0] of the reserve that can be contributed per device, validation range: `(0, 1)`\n- `deployed_fraction::Float64`: (default: `0.0`) Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0, validation range: `(0, 1)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct VariableReserveNonSpinning <: ReserveNonSpinning\n    \"Name of the component. Components of the same type (e.g., `PowerLoad`) must have unique names, but components of different types (e.g., `PowerLoad` and `ACBus`) can have the same name\"\n    name::String\n    \"Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations\"\n    available::Bool\n    \"the saturation time_frame in minutes to provide reserve contribution\"\n    time_frame::Float64\n    \"the required quantity of the product should be scaled by a TimeSeriesData\"\n    requirement::Float64\n    \"the time in seconds reserve contribution must sustained at a specified level\"\n    sustained_time::Float64\n    \"the maximum fraction of each device's output that can be assigned to the service\"\n    max_output_fraction::Float64\n    \"the maximum portion [0, 1.0] of the reserve that can be contributed per device\"\n    max_participation_factor::Float64\n    \"Fraction of service procurement that is assumed to be actually deployed. Most commonly, this is assumed to be either 0.0 or 1.0\"\n    deployed_fraction::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction VariableReserveNonSpinning(name, available, time_frame, requirement, sustained_time=14400.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), )\n    VariableReserveNonSpinning(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, InfrastructureSystemsInternal(), )\nend\n\nfunction VariableReserveNonSpinning(; name, available, time_frame, requirement, sustained_time=14400.0, max_output_fraction=1.0, max_participation_factor=1.0, deployed_fraction=0.0, ext=Dict{String, Any}(), internal=InfrastructureSystemsInternal(), )\n    VariableReserveNonSpinning(name, available, time_frame, requirement, sustained_time, max_output_fraction, max_participation_factor, deployed_fraction, ext, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction VariableReserveNonSpinning(::Nothing)\n    VariableReserveNonSpinning(;\n        name=\"init\",\n        available=false,\n        time_frame=0.0,\n        requirement=0.0,\n        sustained_time=0.0,\n        max_output_fraction=1.0,\n        max_participation_factor=1.0,\n        deployed_fraction=0.0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `name`.\"\"\"\nget_name(value::VariableReserveNonSpinning) = value.name\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `available`.\"\"\"\nget_available(value::VariableReserveNonSpinning) = value.available\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `time_frame`.\"\"\"\nget_time_frame(value::VariableReserveNonSpinning) = value.time_frame\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `requirement`.\"\"\"\nget_requirement(value::VariableReserveNonSpinning) = get_value(value, Val(:requirement), Val(:mva))\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `sustained_time`.\"\"\"\nget_sustained_time(value::VariableReserveNonSpinning) = value.sustained_time\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `max_output_fraction`.\"\"\"\nget_max_output_fraction(value::VariableReserveNonSpinning) = value.max_output_fraction\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `max_participation_factor`.\"\"\"\nget_max_participation_factor(value::VariableReserveNonSpinning) = value.max_participation_factor\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `deployed_fraction`.\"\"\"\nget_deployed_fraction(value::VariableReserveNonSpinning) = value.deployed_fraction\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `ext`.\"\"\"\nget_ext(value::VariableReserveNonSpinning) = value.ext\n\"\"\"Get [`VariableReserveNonSpinning`](@ref) `internal`.\"\"\"\nget_internal(value::VariableReserveNonSpinning) = value.internal\n\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `available`.\"\"\"\nset_available!(value::VariableReserveNonSpinning, val) = value.available = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `time_frame`.\"\"\"\nset_time_frame!(value::VariableReserveNonSpinning, val) = value.time_frame = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `requirement`.\"\"\"\nset_requirement!(value::VariableReserveNonSpinning, val) = value.requirement = set_value(value, Val(:requirement), val, Val(:mva))\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `sustained_time`.\"\"\"\nset_sustained_time!(value::VariableReserveNonSpinning, val) = value.sustained_time = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `max_output_fraction`.\"\"\"\nset_max_output_fraction!(value::VariableReserveNonSpinning, val) = value.max_output_fraction = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `max_participation_factor`.\"\"\"\nset_max_participation_factor!(value::VariableReserveNonSpinning, val) = value.max_participation_factor = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `deployed_fraction`.\"\"\"\nset_deployed_fraction!(value::VariableReserveNonSpinning, val) = value.deployed_fraction = val\n\"\"\"Set [`VariableReserveNonSpinning`](@ref) `ext`.\"\"\"\nset_ext!(value::VariableReserveNonSpinning, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/VirtualInertia.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct VirtualInertia <: ActivePowerControl\n        Ta::Float64\n        kd::Float64\n        kω::Float64\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of a Virtual Inertia with SRF using VSM for active power controller\n\n# Arguments\n- `Ta::Float64`: VSM inertia constant, validation range: `(0, nothing)`\n- `kd::Float64`: VSM damping constant, validation range: `(0, nothing)`\n- `kω::Float64`: frequency droop gain, validation range: `(0, nothing)`\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the VirtualInertia model are:\n\tθ_oc: Phase angle displacement of the virtual synchronous generator model\n\tω_oc: Speed of the rotating reference frame of the virtual synchronous generator model\n- `n_states::Int`: (**Do not modify.**) VirtualInertia has two states\n\"\"\"\nmutable struct VirtualInertia <: ActivePowerControl\n    \"VSM inertia constant\"\n    Ta::Float64\n    \"VSM damping constant\"\n    kd::Float64\n    \"frequency droop gain\"\n    kω::Float64\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the VirtualInertia model are:\n\tθ_oc: Phase angle displacement of the virtual synchronous generator model\n\tω_oc: Speed of the rotating reference frame of the virtual synchronous generator model\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) VirtualInertia has two states\"\n    n_states::Int\nend\n\nfunction VirtualInertia(Ta, kd, kω, P_ref=1.0, ext=Dict{String, Any}(), )\n    VirtualInertia(Ta, kd, kω, P_ref, ext, [:θ_oc, :ω_oc], 2, )\nend\n\nfunction VirtualInertia(; Ta, kd, kω, P_ref=1.0, ext=Dict{String, Any}(), states=[:θ_oc, :ω_oc], n_states=2, )\n    VirtualInertia(Ta, kd, kω, P_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction VirtualInertia(::Nothing)\n    VirtualInertia(;\n        Ta=0,\n        kd=0,\n        kω=0,\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`VirtualInertia`](@ref) `Ta`.\"\"\"\nget_Ta(value::VirtualInertia) = value.Ta\n\"\"\"Get [`VirtualInertia`](@ref) `kd`.\"\"\"\nget_kd(value::VirtualInertia) = value.kd\n\"\"\"Get [`VirtualInertia`](@ref) `kω`.\"\"\"\nget_kω(value::VirtualInertia) = value.kω\n\"\"\"Get [`VirtualInertia`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::VirtualInertia) = value.P_ref\n\"\"\"Get [`VirtualInertia`](@ref) `ext`.\"\"\"\nget_ext(value::VirtualInertia) = value.ext\n\"\"\"Get [`VirtualInertia`](@ref) `states`.\"\"\"\nget_states(value::VirtualInertia) = value.states\n\"\"\"Get [`VirtualInertia`](@ref) `n_states`.\"\"\"\nget_n_states(value::VirtualInertia) = value.n_states\n\n\"\"\"Set [`VirtualInertia`](@ref) `Ta`.\"\"\"\nset_Ta!(value::VirtualInertia, val) = value.Ta = val\n\"\"\"Set [`VirtualInertia`](@ref) `kd`.\"\"\"\nset_kd!(value::VirtualInertia, val) = value.kd = val\n\"\"\"Set [`VirtualInertia`](@ref) `kω`.\"\"\"\nset_kω!(value::VirtualInertia, val) = value.kω = val\n\"\"\"Set [`VirtualInertia`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::VirtualInertia, val) = value.P_ref = val\n\"\"\"Set [`VirtualInertia`](@ref) `ext`.\"\"\"\nset_ext!(value::VirtualInertia, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/VoltageModeControl.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct VoltageModeControl <: InnerControl\n        kpv::Float64\n        kiv::Float64\n        kffv::Float64\n        rv::Float64\n        lv::Float64\n        kpc::Float64\n        kic::Float64\n        kffi::Float64\n        ωad::Float64\n        kad::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters of an inner loop current control PID using virtual impedance based on [\"A Virtual Synchronous Machine implementation for distributed control of power converters in SmartGrids.\"](https://doi.org/10.1016/j.epsr.2015.01.001)\n\n# Arguments\n- `kpv::Float64`: voltage controller proportional gain, validation range: `(0, nothing)`\n- `kiv::Float64`: voltage controller integral gain, validation range: `(0, nothing)`\n- `kffv::Float64`: Binary variable to enable feed-forward gain of voltage, validation range: `(0, nothing)`\n- `rv::Float64`: virtual resistance, validation range: `(0, nothing)`\n- `lv::Float64`: virtual inductance, validation range: `(0, nothing)`\n- `kpc::Float64`: current controller proportional gain, validation range: `(0, nothing)`\n- `kic::Float64`: current controller integral gain, validation range: `(0, nothing)`\n- `kffi::Float64`: Binary variable to enable feed-forward gain of current, validation range: `(0, nothing)`\n- `ωad::Float64`: active damping filter cutoff frequency (rad/sec), validation range: `(0, nothing)`\n- `kad::Float64`: active damping gain, validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the VoltageModeControl model are:\n\tξd_ic: d-axis integrator state of the PI voltage controller,\n\tξq_ic: q-axis integrator state of the PI voltage controller,\n\tγd_ic: d-axis integrator state of the PI current controller,\n\tγq_ic: q-axis integrator state of the PI current controller,\n\tϕd_ic: d-axis low-pass filter of active damping,\n\tϕq_ic: q-axis low-pass filter of active damping\n- `n_states::Int`: (**Do not modify.**) VoltageModeControl has 6 states\n\"\"\"\nmutable struct VoltageModeControl <: InnerControl\n    \"voltage controller proportional gain\"\n    kpv::Float64\n    \"voltage controller integral gain\"\n    kiv::Float64\n    \"Binary variable to enable feed-forward gain of voltage\"\n    kffv::Float64\n    \"virtual resistance\"\n    rv::Float64\n    \"virtual inductance\"\n    lv::Float64\n    \"current controller proportional gain\"\n    kpc::Float64\n    \"current controller integral gain\"\n    kic::Float64\n    \"Binary variable to enable feed-forward gain of current\"\n    kffi::Float64\n    \"active damping filter cutoff frequency (rad/sec)\"\n    ωad::Float64\n    \"active damping gain\"\n    kad::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the VoltageModeControl model are:\n\tξd_ic: d-axis integrator state of the PI voltage controller,\n\tξq_ic: q-axis integrator state of the PI voltage controller,\n\tγd_ic: d-axis integrator state of the PI current controller,\n\tγq_ic: q-axis integrator state of the PI current controller,\n\tϕd_ic: d-axis low-pass filter of active damping,\n\tϕq_ic: q-axis low-pass filter of active damping\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) VoltageModeControl has 6 states\"\n    n_states::Int\nend\n\nfunction VoltageModeControl(kpv, kiv, kffv, rv, lv, kpc, kic, kffi, ωad, kad, ext=Dict{String, Any}(), )\n    VoltageModeControl(kpv, kiv, kffv, rv, lv, kpc, kic, kffi, ωad, kad, ext, [:ξd_ic, :ξq_ic, :γd_ic, :γq_ic, :ϕd_ic, :ϕq_ic], 6, )\nend\n\nfunction VoltageModeControl(; kpv, kiv, kffv, rv, lv, kpc, kic, kffi, ωad, kad, ext=Dict{String, Any}(), states=[:ξd_ic, :ξq_ic, :γd_ic, :γq_ic, :ϕd_ic, :ϕq_ic], n_states=6, )\n    VoltageModeControl(kpv, kiv, kffv, rv, lv, kpc, kic, kffi, ωad, kad, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction VoltageModeControl(::Nothing)\n    VoltageModeControl(;\n        kpv=0,\n        kiv=0,\n        kffv=0,\n        rv=0,\n        lv=0,\n        kpc=0,\n        kic=0,\n        kffi=0,\n        ωad=0,\n        kad=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`VoltageModeControl`](@ref) `kpv`.\"\"\"\nget_kpv(value::VoltageModeControl) = value.kpv\n\"\"\"Get [`VoltageModeControl`](@ref) `kiv`.\"\"\"\nget_kiv(value::VoltageModeControl) = value.kiv\n\"\"\"Get [`VoltageModeControl`](@ref) `kffv`.\"\"\"\nget_kffv(value::VoltageModeControl) = value.kffv\n\"\"\"Get [`VoltageModeControl`](@ref) `rv`.\"\"\"\nget_rv(value::VoltageModeControl) = value.rv\n\"\"\"Get [`VoltageModeControl`](@ref) `lv`.\"\"\"\nget_lv(value::VoltageModeControl) = value.lv\n\"\"\"Get [`VoltageModeControl`](@ref) `kpc`.\"\"\"\nget_kpc(value::VoltageModeControl) = value.kpc\n\"\"\"Get [`VoltageModeControl`](@ref) `kic`.\"\"\"\nget_kic(value::VoltageModeControl) = value.kic\n\"\"\"Get [`VoltageModeControl`](@ref) `kffi`.\"\"\"\nget_kffi(value::VoltageModeControl) = value.kffi\n\"\"\"Get [`VoltageModeControl`](@ref) `ωad`.\"\"\"\nget_ωad(value::VoltageModeControl) = value.ωad\n\"\"\"Get [`VoltageModeControl`](@ref) `kad`.\"\"\"\nget_kad(value::VoltageModeControl) = value.kad\n\"\"\"Get [`VoltageModeControl`](@ref) `ext`.\"\"\"\nget_ext(value::VoltageModeControl) = value.ext\n\"\"\"Get [`VoltageModeControl`](@ref) `states`.\"\"\"\nget_states(value::VoltageModeControl) = value.states\n\"\"\"Get [`VoltageModeControl`](@ref) `n_states`.\"\"\"\nget_n_states(value::VoltageModeControl) = value.n_states\n\n\"\"\"Set [`VoltageModeControl`](@ref) `kpv`.\"\"\"\nset_kpv!(value::VoltageModeControl, val) = value.kpv = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kiv`.\"\"\"\nset_kiv!(value::VoltageModeControl, val) = value.kiv = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kffv`.\"\"\"\nset_kffv!(value::VoltageModeControl, val) = value.kffv = val\n\"\"\"Set [`VoltageModeControl`](@ref) `rv`.\"\"\"\nset_rv!(value::VoltageModeControl, val) = value.rv = val\n\"\"\"Set [`VoltageModeControl`](@ref) `lv`.\"\"\"\nset_lv!(value::VoltageModeControl, val) = value.lv = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kpc`.\"\"\"\nset_kpc!(value::VoltageModeControl, val) = value.kpc = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kic`.\"\"\"\nset_kic!(value::VoltageModeControl, val) = value.kic = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kffi`.\"\"\"\nset_kffi!(value::VoltageModeControl, val) = value.kffi = val\n\"\"\"Set [`VoltageModeControl`](@ref) `ωad`.\"\"\"\nset_ωad!(value::VoltageModeControl, val) = value.ωad = val\n\"\"\"Set [`VoltageModeControl`](@ref) `kad`.\"\"\"\nset_kad!(value::VoltageModeControl, val) = value.kad = val\n\"\"\"Set [`VoltageModeControl`](@ref) `ext`.\"\"\"\nset_ext!(value::VoltageModeControl, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/WPIDHY.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct WPIDHY <: TurbineGov\n        T_reg::Float64\n        reg::Float64\n        Kp::Float64\n        Ki::Float64\n        Kd::Float64\n        Ta::Float64\n        Tb::Float64\n        V_lim::MinMax\n        G_lim::MinMax\n        Tw::Float64\n        P_lim::MinMax\n        D::Float64\n        gate_openings::Tuple{Float64, Float64, Float64}\n        power_gate_openings::Tuple{Float64, Float64, Float64}\n        P_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n        states_types::Vector{StateTypes}\n        internal::InfrastructureSystemsInternal\n    end\n\nWoodward PID Hydro Governor\n\n# Arguments\n- `T_reg::Float64`: Input time constant of the governor in s, validation range: `(0, nothing)`\n- `reg::Float64`: Input governor gain, validation range: `(0, nothing)`\n- `Kp::Float64`: Governor proportional gain, validation range: `(0, nothing)`\n- `Ki::Float64`: Governor integral gain, validation range: `(0, nothing)`\n- `Kd::Float64`: Governor derivative gain, validation range: `(0, nothing)`\n- `Ta::Float64`: Governor derivative/high-frequency time constant, validation range: `(0, nothing)`\n- `Tb::Float64`: Gate-servo time constant, validation range: `(0, nothing)`\n- `V_lim::MinMax`: Gate opening velocity limits `(G_min, G_max)`.\n- `G_lim::MinMax`: Minimum/Maximum Gate velocity `(G_min, G_max)`.\n- `Tw::Float64`: Water inertia time constant, sec, validation range: `(eps(), nothing)`\n- `P_lim::MinMax`: Minimum/Maximum Gate openings `(P_min, P_max)`.\n- `D::Float64`: Turbine damping coefficient, validation range: `(0, nothing)`\n- `gate_openings::Tuple{Float64, Float64, Float64}`: Gate-opening speed at different loads\n- `power_gate_openings::Tuple{Float64, Float64, Float64}`: Power at gate_openings\n- `P_ref::Float64`: (default: `1.0`) Reference Power Set-point (pu), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\n\tx_g1: Filtered input measurement,\n\tx_g2: PI block internal state,\n\tx_g3: First regulator state, \n\tx_g4: Derivative block internal state, \n\tx_g5: Second regulator state, \n\tx_g6: Gate position state, \n\tx_g7: Water inertia state\n- `n_states::Int`: (**Do not modify.**) PIDGOV has 7 states\n- `states_types::Vector{StateTypes}`: (**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems.jl internal reference\n\"\"\"\nmutable struct WPIDHY <: TurbineGov\n    \"Input time constant of the governor in s\"\n    T_reg::Float64\n    \"Input governor gain\"\n    reg::Float64\n    \"Governor proportional gain\"\n    Kp::Float64\n    \"Governor integral gain\"\n    Ki::Float64\n    \"Governor derivative gain\"\n    Kd::Float64\n    \"Governor derivative/high-frequency time constant\"\n    Ta::Float64\n    \"Gate-servo time constant\"\n    Tb::Float64\n    \"Gate opening velocity limits `(G_min, G_max)`.\"\n    V_lim::MinMax\n    \"Minimum/Maximum Gate velocity `(G_min, G_max)`.\"\n    G_lim::MinMax\n    \"Water inertia time constant, sec\"\n    Tw::Float64\n    \"Minimum/Maximum Gate openings `(P_min, P_max)`.\"\n    P_lim::MinMax\n    \"Turbine damping coefficient\"\n    D::Float64\n    \"Gate-opening speed at different loads\"\n    gate_openings::Tuple{Float64, Float64, Float64}\n    \"Power at gate_openings\"\n    power_gate_openings::Tuple{Float64, Float64, Float64}\n    \"Reference Power Set-point (pu)\"\n    P_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the PIDGOV model are:\n\tx_g1: Filtered input measurement,\n\tx_g2: PI block internal state,\n\tx_g3: First regulator state, \n\tx_g4: Derivative block internal state, \n\tx_g5: Second regulator state, \n\tx_g6: Gate position state, \n\tx_g7: Water inertia state\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) PIDGOV has 7 states\"\n    n_states::Int\n    \"(**Do not modify.**) PIDGOV has 7 [differential](@ref states_list) [states](@ref S)\"\n    states_types::Vector{StateTypes}\n    \"(**Do not modify.**) PowerSystems.jl internal reference\"\n    internal::InfrastructureSystemsInternal\nend\n\nfunction WPIDHY(T_reg, reg, Kp, Ki, Kd, Ta, Tb, V_lim, G_lim, Tw, P_lim, D, gate_openings, power_gate_openings, P_ref=1.0, ext=Dict{String, Any}(), )\n    WPIDHY(T_reg, reg, Kp, Ki, Kd, Ta, Tb, V_lim, G_lim, Tw, P_lim, D, gate_openings, power_gate_openings, P_ref, ext, [:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], 7, [StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], InfrastructureSystemsInternal(), )\nend\n\nfunction WPIDHY(; T_reg, reg, Kp, Ki, Kd, Ta, Tb, V_lim, G_lim, Tw, P_lim, D, gate_openings, power_gate_openings, P_ref=1.0, ext=Dict{String, Any}(), states=[:x_g1, :x_g2, :x_g3, :x_g4, :x_g5, :x_g6, :x_g7], n_states=7, states_types=[StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid, StateTypes.Hybrid], internal=InfrastructureSystemsInternal(), )\n    WPIDHY(T_reg, reg, Kp, Ki, Kd, Ta, Tb, V_lim, G_lim, Tw, P_lim, D, gate_openings, power_gate_openings, P_ref, ext, states, n_states, states_types, internal, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction WPIDHY(::Nothing)\n    WPIDHY(;\n        T_reg=0,\n        reg=0,\n        Kp=0,\n        Ki=0,\n        Kd=0,\n        Ta=0,\n        Tb=0,\n        V_lim=(min=0.0, max=0.0),\n        G_lim=(min=0.0, max=0.0),\n        Tw=0,\n        P_lim=(min=0.0, max=0.0),\n        D=0,\n        gate_openings=(0.0, 0.0, 0.0),\n        power_gate_openings=(0.0, 0.0, 0.0),\n        P_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`WPIDHY`](@ref) `T_reg`.\"\"\"\nget_T_reg(value::WPIDHY) = value.T_reg\n\"\"\"Get [`WPIDHY`](@ref) `reg`.\"\"\"\nget_reg(value::WPIDHY) = value.reg\n\"\"\"Get [`WPIDHY`](@ref) `Kp`.\"\"\"\nget_Kp(value::WPIDHY) = value.Kp\n\"\"\"Get [`WPIDHY`](@ref) `Ki`.\"\"\"\nget_Ki(value::WPIDHY) = value.Ki\n\"\"\"Get [`WPIDHY`](@ref) `Kd`.\"\"\"\nget_Kd(value::WPIDHY) = value.Kd\n\"\"\"Get [`WPIDHY`](@ref) `Ta`.\"\"\"\nget_Ta(value::WPIDHY) = value.Ta\n\"\"\"Get [`WPIDHY`](@ref) `Tb`.\"\"\"\nget_Tb(value::WPIDHY) = value.Tb\n\"\"\"Get [`WPIDHY`](@ref) `V_lim`.\"\"\"\nget_V_lim(value::WPIDHY) = value.V_lim\n\"\"\"Get [`WPIDHY`](@ref) `G_lim`.\"\"\"\nget_G_lim(value::WPIDHY) = value.G_lim\n\"\"\"Get [`WPIDHY`](@ref) `Tw`.\"\"\"\nget_Tw(value::WPIDHY) = value.Tw\n\"\"\"Get [`WPIDHY`](@ref) `P_lim`.\"\"\"\nget_P_lim(value::WPIDHY) = value.P_lim\n\"\"\"Get [`WPIDHY`](@ref) `D`.\"\"\"\nget_D(value::WPIDHY) = value.D\n\"\"\"Get [`WPIDHY`](@ref) `gate_openings`.\"\"\"\nget_gate_openings(value::WPIDHY) = value.gate_openings\n\"\"\"Get [`WPIDHY`](@ref) `power_gate_openings`.\"\"\"\nget_power_gate_openings(value::WPIDHY) = value.power_gate_openings\n\"\"\"Get [`WPIDHY`](@ref) `P_ref`.\"\"\"\nget_P_ref(value::WPIDHY) = value.P_ref\n\"\"\"Get [`WPIDHY`](@ref) `ext`.\"\"\"\nget_ext(value::WPIDHY) = value.ext\n\"\"\"Get [`WPIDHY`](@ref) `states`.\"\"\"\nget_states(value::WPIDHY) = value.states\n\"\"\"Get [`WPIDHY`](@ref) `n_states`.\"\"\"\nget_n_states(value::WPIDHY) = value.n_states\n\"\"\"Get [`WPIDHY`](@ref) `states_types`.\"\"\"\nget_states_types(value::WPIDHY) = value.states_types\n\"\"\"Get [`WPIDHY`](@ref) `internal`.\"\"\"\nget_internal(value::WPIDHY) = value.internal\n\n\"\"\"Set [`WPIDHY`](@ref) `T_reg`.\"\"\"\nset_T_reg!(value::WPIDHY, val) = value.T_reg = val\n\"\"\"Set [`WPIDHY`](@ref) `reg`.\"\"\"\nset_reg!(value::WPIDHY, val) = value.reg = val\n\"\"\"Set [`WPIDHY`](@ref) `Kp`.\"\"\"\nset_Kp!(value::WPIDHY, val) = value.Kp = val\n\"\"\"Set [`WPIDHY`](@ref) `Ki`.\"\"\"\nset_Ki!(value::WPIDHY, val) = value.Ki = val\n\"\"\"Set [`WPIDHY`](@ref) `Kd`.\"\"\"\nset_Kd!(value::WPIDHY, val) = value.Kd = val\n\"\"\"Set [`WPIDHY`](@ref) `Ta`.\"\"\"\nset_Ta!(value::WPIDHY, val) = value.Ta = val\n\"\"\"Set [`WPIDHY`](@ref) `Tb`.\"\"\"\nset_Tb!(value::WPIDHY, val) = value.Tb = val\n\"\"\"Set [`WPIDHY`](@ref) `V_lim`.\"\"\"\nset_V_lim!(value::WPIDHY, val) = value.V_lim = val\n\"\"\"Set [`WPIDHY`](@ref) `G_lim`.\"\"\"\nset_G_lim!(value::WPIDHY, val) = value.G_lim = val\n\"\"\"Set [`WPIDHY`](@ref) `Tw`.\"\"\"\nset_Tw!(value::WPIDHY, val) = value.Tw = val\n\"\"\"Set [`WPIDHY`](@ref) `P_lim`.\"\"\"\nset_P_lim!(value::WPIDHY, val) = value.P_lim = val\n\"\"\"Set [`WPIDHY`](@ref) `D`.\"\"\"\nset_D!(value::WPIDHY, val) = value.D = val\n\"\"\"Set [`WPIDHY`](@ref) `gate_openings`.\"\"\"\nset_gate_openings!(value::WPIDHY, val) = value.gate_openings = val\n\"\"\"Set [`WPIDHY`](@ref) `power_gate_openings`.\"\"\"\nset_power_gate_openings!(value::WPIDHY, val) = value.power_gate_openings = val\n\"\"\"Set [`WPIDHY`](@ref) `P_ref`.\"\"\"\nset_P_ref!(value::WPIDHY, val) = value.P_ref = val\n\"\"\"Set [`WPIDHY`](@ref) `ext`.\"\"\"\nset_ext!(value::WPIDHY, val) = value.ext = val\n\"\"\"Set [`WPIDHY`](@ref) `states_types`.\"\"\"\nset_states_types!(value::WPIDHY, val) = value.states_types = val\n"
  },
  {
    "path": "src/models/generated/ZeroOrderBESS.jl",
    "content": "#=\nThis file is auto-generated. Do not edit.\n=#\n\n#! format: off\n\n\"\"\"\n    mutable struct ZeroOrderBESS <: DCSource\n        rated_voltage::Float64\n        rated_current::Float64\n        battery_voltage::Float64\n        battery_resistance::Float64\n        dc_dc_inductor::Float64\n        dc_link_capacitance::Float64\n        fs::Float64\n        kpv::Float64\n        kiv::Float64\n        kpi::Float64\n        kii::Float64\n        Vdc_ref::Float64\n        ext::Dict{String, Any}\n        states::Vector{Symbol}\n        n_states::Int\n    end\n\nParameters for the DC-side with a Battery Energy Storage System from [\"Grid-Coupled Dynamic Response of Battery-Driven Voltage Source Converters.\"](https://arxiv.org/abs/2007.11776)\n\n# Arguments\n- `rated_voltage::Float64`: Rated voltage (V), validation range: `(0, nothing)`\n- `rated_current::Float64`: Rated current (A), validation range: `(0, nothing)`\n- `battery_voltage::Float64`: battery voltage in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `battery_resistance::Float64`: Battery resistance in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `dc_dc_inductor::Float64`: DC/DC inductance in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `dc_link_capacitance::Float64`: DC-link capacitance in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `fs::Float64`: DC/DC converter switching frequency (kHz), validation range: `(0, nothing)`\n- `kpv::Float64`: voltage controller proportional gain, validation range: `(0, nothing)`\n- `kiv::Float64`: voltage controller integral gain, validation range: `(0, nothing)`\n- `kpi::Float64`: current controller proportional gain, validation range: `(0, nothing)`\n- `kii::Float64`: current controller integral gain, validation range: `(0, nothing)`\n- `Vdc_ref::Float64`: (default: `1.1`) Reference DC-Voltage Set-point in pu ([`DEVICE_BASE`](@ref per_unit)), validation range: `(0, nothing)`\n- `ext::Dict{String, Any}`: (default: `Dict{String, Any}()`) An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\n- `states::Vector{Symbol}`: (**Do not modify.**) The [states](@ref S) of the ZeroOrderBESS model are:\n\tv_dc: DC-link voltage,\n\ti_b: Battery current,\n\t ν: integrator state of the voltage controller,\n\t ζ: integrator state of the PI current controller\n- `n_states::Int`: (**Do not modify.**) ZeroOrderBESS has 4 states\n\"\"\"\nmutable struct ZeroOrderBESS <: DCSource\n    \"Rated voltage (V)\"\n    rated_voltage::Float64\n    \"Rated current (A)\"\n    rated_current::Float64\n    \"battery voltage in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    battery_voltage::Float64\n    \"Battery resistance in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    battery_resistance::Float64\n    \"DC/DC inductance in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    dc_dc_inductor::Float64\n    \"DC-link capacitance in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    dc_link_capacitance::Float64\n    \"DC/DC converter switching frequency (kHz)\"\n    fs::Float64\n    \"voltage controller proportional gain\"\n    kpv::Float64\n    \"voltage controller integral gain\"\n    kiv::Float64\n    \"current controller proportional gain\"\n    kpi::Float64\n    \"current controller integral gain\"\n    kii::Float64\n    \"Reference DC-Voltage Set-point in pu ([`DEVICE_BASE`](@ref per_unit))\"\n    Vdc_ref::Float64\n    \"An [*ext*ra dictionary](@ref additional_fields) for users to add metadata that are not used in simulation.\"\n    ext::Dict{String, Any}\n    \"(**Do not modify.**) The [states](@ref S) of the ZeroOrderBESS model are:\n\tv_dc: DC-link voltage,\n\ti_b: Battery current,\n\t ν: integrator state of the voltage controller,\n\t ζ: integrator state of the PI current controller\"\n    states::Vector{Symbol}\n    \"(**Do not modify.**) ZeroOrderBESS has 4 states\"\n    n_states::Int\nend\n\nfunction ZeroOrderBESS(rated_voltage, rated_current, battery_voltage, battery_resistance, dc_dc_inductor, dc_link_capacitance, fs, kpv, kiv, kpi, kii, Vdc_ref=1.1, ext=Dict{String, Any}(), )\n    ZeroOrderBESS(rated_voltage, rated_current, battery_voltage, battery_resistance, dc_dc_inductor, dc_link_capacitance, fs, kpv, kiv, kpi, kii, Vdc_ref, ext, [:v_dc, :i_b, :ν, :ζ], 4, )\nend\n\nfunction ZeroOrderBESS(; rated_voltage, rated_current, battery_voltage, battery_resistance, dc_dc_inductor, dc_link_capacitance, fs, kpv, kiv, kpi, kii, Vdc_ref=1.1, ext=Dict{String, Any}(), states=[:v_dc, :i_b, :ν, :ζ], n_states=4, )\n    ZeroOrderBESS(rated_voltage, rated_current, battery_voltage, battery_resistance, dc_dc_inductor, dc_link_capacitance, fs, kpv, kiv, kpi, kii, Vdc_ref, ext, states, n_states, )\nend\n\n# Constructor for demo purposes; non-functional.\nfunction ZeroOrderBESS(::Nothing)\n    ZeroOrderBESS(;\n        rated_voltage=0,\n        rated_current=0,\n        battery_voltage=0,\n        battery_resistance=0,\n        dc_dc_inductor=0,\n        dc_link_capacitance=0,\n        fs=0,\n        kpv=0,\n        kiv=0,\n        kpi=0,\n        kii=0,\n        Vdc_ref=0,\n        ext=Dict{String, Any}(),\n    )\nend\n\n\"\"\"Get [`ZeroOrderBESS`](@ref) `rated_voltage`.\"\"\"\nget_rated_voltage(value::ZeroOrderBESS) = value.rated_voltage\n\"\"\"Get [`ZeroOrderBESS`](@ref) `rated_current`.\"\"\"\nget_rated_current(value::ZeroOrderBESS) = value.rated_current\n\"\"\"Get [`ZeroOrderBESS`](@ref) `battery_voltage`.\"\"\"\nget_battery_voltage(value::ZeroOrderBESS) = value.battery_voltage\n\"\"\"Get [`ZeroOrderBESS`](@ref) `battery_resistance`.\"\"\"\nget_battery_resistance(value::ZeroOrderBESS) = value.battery_resistance\n\"\"\"Get [`ZeroOrderBESS`](@ref) `dc_dc_inductor`.\"\"\"\nget_dc_dc_inductor(value::ZeroOrderBESS) = value.dc_dc_inductor\n\"\"\"Get [`ZeroOrderBESS`](@ref) `dc_link_capacitance`.\"\"\"\nget_dc_link_capacitance(value::ZeroOrderBESS) = value.dc_link_capacitance\n\"\"\"Get [`ZeroOrderBESS`](@ref) `fs`.\"\"\"\nget_fs(value::ZeroOrderBESS) = value.fs\n\"\"\"Get [`ZeroOrderBESS`](@ref) `kpv`.\"\"\"\nget_kpv(value::ZeroOrderBESS) = value.kpv\n\"\"\"Get [`ZeroOrderBESS`](@ref) `kiv`.\"\"\"\nget_kiv(value::ZeroOrderBESS) = value.kiv\n\"\"\"Get [`ZeroOrderBESS`](@ref) `kpi`.\"\"\"\nget_kpi(value::ZeroOrderBESS) = value.kpi\n\"\"\"Get [`ZeroOrderBESS`](@ref) `kii`.\"\"\"\nget_kii(value::ZeroOrderBESS) = value.kii\n\"\"\"Get [`ZeroOrderBESS`](@ref) `Vdc_ref`.\"\"\"\nget_Vdc_ref(value::ZeroOrderBESS) = value.Vdc_ref\n\"\"\"Get [`ZeroOrderBESS`](@ref) `ext`.\"\"\"\nget_ext(value::ZeroOrderBESS) = value.ext\n\"\"\"Get [`ZeroOrderBESS`](@ref) `states`.\"\"\"\nget_states(value::ZeroOrderBESS) = value.states\n\"\"\"Get [`ZeroOrderBESS`](@ref) `n_states`.\"\"\"\nget_n_states(value::ZeroOrderBESS) = value.n_states\n\n\"\"\"Set [`ZeroOrderBESS`](@ref) `rated_voltage`.\"\"\"\nset_rated_voltage!(value::ZeroOrderBESS, val) = value.rated_voltage = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `rated_current`.\"\"\"\nset_rated_current!(value::ZeroOrderBESS, val) = value.rated_current = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `battery_voltage`.\"\"\"\nset_battery_voltage!(value::ZeroOrderBESS, val) = value.battery_voltage = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `battery_resistance`.\"\"\"\nset_battery_resistance!(value::ZeroOrderBESS, val) = value.battery_resistance = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `dc_dc_inductor`.\"\"\"\nset_dc_dc_inductor!(value::ZeroOrderBESS, val) = value.dc_dc_inductor = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `dc_link_capacitance`.\"\"\"\nset_dc_link_capacitance!(value::ZeroOrderBESS, val) = value.dc_link_capacitance = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `fs`.\"\"\"\nset_fs!(value::ZeroOrderBESS, val) = value.fs = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `kpv`.\"\"\"\nset_kpv!(value::ZeroOrderBESS, val) = value.kpv = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `kiv`.\"\"\"\nset_kiv!(value::ZeroOrderBESS, val) = value.kiv = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `kpi`.\"\"\"\nset_kpi!(value::ZeroOrderBESS, val) = value.kpi = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `kii`.\"\"\"\nset_kii!(value::ZeroOrderBESS, val) = value.kii = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `Vdc_ref`.\"\"\"\nset_Vdc_ref!(value::ZeroOrderBESS, val) = value.Vdc_ref = val\n\"\"\"Set [`ZeroOrderBESS`](@ref) `ext`.\"\"\"\nset_ext!(value::ZeroOrderBESS, val) = value.ext = val\n"
  },
  {
    "path": "src/models/generated/includes.jl",
    "content": "include(\"Area.jl\")\ninclude(\"AreaInterchange.jl\")\ninclude(\"LoadZone.jl\")\ninclude(\"TransmissionInterface.jl\")\ninclude(\"ACBus.jl\")\ninclude(\"DCBus.jl\")\ninclude(\"Arc.jl\")\ninclude(\"Line.jl\")\ninclude(\"GenericArcImpedance.jl\")\ninclude(\"DiscreteControlledACBranch.jl\")\ninclude(\"MonitoredLine.jl\")\ninclude(\"PhaseShiftingTransformer.jl\")\ninclude(\"TapTransformer.jl\")\ninclude(\"Transformer2W.jl\")\ninclude(\"Transformer3W.jl\")\ninclude(\"PhaseShiftingTransformer3W.jl\")\ninclude(\"TwoTerminalGenericHVDCLine.jl\")\ninclude(\"TwoTerminalVSCLine.jl\")\ninclude(\"TwoTerminalLCCLine.jl\")\ninclude(\"TModelHVDCLine.jl\")\ninclude(\"InterruptiblePowerLoad.jl\")\ninclude(\"InterruptibleStandardLoad.jl\")\ninclude(\"ShiftablePowerLoad.jl\")\ninclude(\"FACTSControlDevice.jl\")\ninclude(\"FixedAdmittance.jl\")\ninclude(\"SwitchedAdmittance.jl\")\ninclude(\"PowerLoad.jl\")\ninclude(\"MotorLoad.jl\")\ninclude(\"StandardLoad.jl\")\ninclude(\"ExponentialLoad.jl\")\ninclude(\"SingleCageInductionMachine.jl\")\ninclude(\"SimplifiedSingleCageInductionMachine.jl\")\ninclude(\"DynamicExponentialLoad.jl\")\ninclude(\"ActiveConstantPowerLoad.jl\")\ninclude(\"InterconnectingConverter.jl\")\ninclude(\"CSVGN1.jl\")\ninclude(\"HydroDispatch.jl\")\ninclude(\"HydroTurbine.jl\")\ninclude(\"HydroPumpTurbine.jl\")\ninclude(\"HydroReservoir.jl\")\ninclude(\"RenewableDispatch.jl\")\ninclude(\"RenewableNonDispatch.jl\")\ninclude(\"ThermalStandard.jl\")\ninclude(\"SynchronousCondenser.jl\")\ninclude(\"ThermalMultiStart.jl\")\ninclude(\"EnergyReservoirStorage.jl\")\ninclude(\"ConstantReserve.jl\")\ninclude(\"ConstantReserveNonSpinning.jl\")\ninclude(\"ConstantReserveGroup.jl\")\ninclude(\"ReserveDemandCurve.jl\")\ninclude(\"VariableReserve.jl\")\ninclude(\"VariableReserveNonSpinning.jl\")\ninclude(\"AGC.jl\")\ninclude(\"AVRFixed.jl\")\ninclude(\"AVRSimple.jl\")\ninclude(\"SEXS.jl\")\ninclude(\"ESDC1A.jl\")\ninclude(\"ESDC2A.jl\")\ninclude(\"IEEET1.jl\")\ninclude(\"AVRTypeI.jl\")\ninclude(\"AVRTypeII.jl\")\ninclude(\"SCRX.jl\")\ninclude(\"ESAC1A.jl\")\ninclude(\"EXAC1A.jl\")\ninclude(\"EXAC1.jl\")\ninclude(\"EXAC2.jl\")\ninclude(\"ESAC6A.jl\")\ninclude(\"ESAC8B.jl\")\ninclude(\"ESST1A.jl\")\ninclude(\"EXPIC1.jl\")\ninclude(\"ESST4B.jl\")\ninclude(\"ST6B.jl\")\ninclude(\"ST8C.jl\")\ninclude(\"EXST1.jl\")\ninclude(\"EX4VSA.jl\")\ninclude(\"BaseMachine.jl\")\ninclude(\"RoundRotorMachine.jl\")\ninclude(\"SalientPoleMachine.jl\")\ninclude(\"AndersonFouadMachine.jl\")\ninclude(\"FullMachine.jl\")\ninclude(\"SauerPaiMachine.jl\")\ninclude(\"MarconatoMachine.jl\")\ninclude(\"OneDOneQMachine.jl\")\ninclude(\"SimpleAFMachine.jl\")\ninclude(\"SimpleFullMachine.jl\")\ninclude(\"SimpleMarconatoMachine.jl\")\ninclude(\"PSSFixed.jl\")\ninclude(\"PSSSimple.jl\")\ninclude(\"IEEEST.jl\")\ninclude(\"STAB1.jl\")\ninclude(\"PSS2A.jl\")\ninclude(\"PSS2B.jl\")\ninclude(\"PSS2C.jl\")\ninclude(\"SingleMass.jl\")\ninclude(\"FiveMassShaft.jl\")\ninclude(\"TGFixed.jl\")\ninclude(\"GasTG.jl\")\ninclude(\"DEGOV.jl\")\ninclude(\"DEGOV1.jl\")\ninclude(\"GeneralGovModel.jl\")\ninclude(\"PIDGOV.jl\")\ninclude(\"WPIDHY.jl\")\ninclude(\"SteamTurbineGov1.jl\")\ninclude(\"HydroTurbineGov.jl\")\ninclude(\"IEEETurbineGov1.jl\")\ninclude(\"TGTypeI.jl\")\ninclude(\"TGTypeII.jl\")\ninclude(\"TGSimple.jl\")\ninclude(\"AverageConverter.jl\")\ninclude(\"RenewableEnergyConverterTypeA.jl\")\ninclude(\"RenewableEnergyVoltageConverterTypeA.jl\")\ninclude(\"FixedDCSource.jl\")\ninclude(\"ZeroOrderBESS.jl\")\ninclude(\"LCLFilter.jl\")\ninclude(\"LCFilter.jl\")\ninclude(\"RLFilter.jl\")\ninclude(\"KauraPLL.jl\")\ninclude(\"ReducedOrderPLL.jl\")\ninclude(\"FixedFrequency.jl\")\ninclude(\"VirtualInertia.jl\")\ninclude(\"ActivePowerDroop.jl\")\ninclude(\"ActivePowerPI.jl\")\ninclude(\"ActiveVirtualOscillator.jl\")\ninclude(\"ActiveRenewableControllerAB.jl\")\ninclude(\"ReactiveRenewableControllerAB.jl\")\ninclude(\"ReactivePowerDroop.jl\")\ninclude(\"ReactivePowerPI.jl\")\ninclude(\"ReactiveVirtualOscillator.jl\")\ninclude(\"VoltageModeControl.jl\")\ninclude(\"CurrentModeControl.jl\")\ninclude(\"RECurrentControlB.jl\")\ninclude(\"MagnitudeOutputCurrentLimiter.jl\")\ninclude(\"InstantaneousOutputCurrentLimiter.jl\")\ninclude(\"PriorityOutputCurrentLimiter.jl\")\ninclude(\"SaturationOutputCurrentLimiter.jl\")\ninclude(\"HybridOutputCurrentLimiter.jl\")\ninclude(\"AggregateDistributedGenerationA.jl\")\ninclude(\"Source.jl\")\ninclude(\"PeriodicVariableSource.jl\")\ninclude(\"GenericDER.jl\")\n\nexport get_A\nexport get_A1\nexport get_A2\nexport get_A3\nexport get_A4\nexport get_A5\nexport get_A6\nexport get_AT\nexport get_A_set\nexport get_A_tw\nexport get_Accel\nexport get_Ae\nexport get_At\nexport get_B\nexport get_B_shunt\nexport get_Be\nexport get_Brkpt\nexport get_C\nexport get_CBase\nexport get_D\nexport get_DB_h\nexport get_DB_l\nexport get_D_12\nexport get_D_23\nexport get_D_34\nexport get_D_45\nexport get_D_T\nexport get_D_dn\nexport get_D_ex\nexport get_D_hp\nexport get_D_ip\nexport get_D_lp\nexport get_D_turb\nexport get_D_up\nexport get_Dm\nexport get_E_lim\nexport get_E_sat\nexport get_Efd_lim\nexport get_FES_lim\nexport get_FRT_pnts\nexport get_Freq_Flag\nexport get_Ftrip_Flag\nexport get_G\nexport get_G_lim\nexport get_Gen_Flag\nexport get_H\nexport get_H_ex\nexport get_H_hp\nexport get_H_ip\nexport get_H_lim\nexport get_H_lp\nexport get_I_lr\nexport get_I_max\nexport get_Id_max\nexport get_Ifd_ref\nexport get_Iflim\nexport get_Io_lim\nexport get_Iq_lim\nexport get_Iq_max\nexport get_Iqinj_lim\nexport get_Iqr_lim\nexport get_Iqr_lims\nexport get_K\nexport get_K0\nexport get_K1\nexport get_K2\nexport get_K3\nexport get_K4\nexport get_K5\nexport get_K6\nexport get_K7\nexport get_K8\nexport get_KT\nexport get_K_a\nexport get_K_c\nexport get_K_c1\nexport get_K_c2\nexport get_K_ci\nexport get_K_d\nexport get_K_da\nexport get_K_ex\nexport get_K_f\nexport get_K_ff\nexport get_K_hp\nexport get_K_hv\nexport get_K_i\nexport get_K_i1\nexport get_K_i2\nexport get_K_ia\nexport get_K_ig\nexport get_K_im\nexport get_K_ip\nexport get_K_ir\nexport get_K_lp\nexport get_K_lr\nexport get_K_m\nexport get_K_p\nexport get_K_pa\nexport get_K_pg\nexport get_K_pm\nexport get_K_pr\nexport get_K_qi\nexport get_K_qp\nexport get_K_qv\nexport get_K_turb\nexport get_K_vi\nexport get_K_vp\nexport get_K_ω\nexport get_Ka\nexport get_Kb\nexport get_Kc\nexport get_Kd\nexport get_Kd_gov\nexport get_Ke\nexport get_Kf\nexport get_Kg\nexport get_Kh\nexport get_Ki\nexport get_Ki_gov\nexport get_Ki_load\nexport get_Ki_mw\nexport get_Ki_p\nexport get_Ki_q\nexport get_Kig\nexport get_Kip\nexport get_Kiq\nexport get_Kl\nexport get_Kp\nexport get_Kp_gov\nexport get_Kp_load\nexport get_Kp_p\nexport get_Kp_q\nexport get_Kpg\nexport get_Kpp\nexport get_Kpq\nexport get_Ks\nexport get_Ks1\nexport get_Ks2\nexport get_Ks3\nexport get_Kt\nexport get_Kv\nexport get_L_1d\nexport get_L_1q\nexport get_L_ad\nexport get_L_aq\nexport get_L_d\nexport get_L_f1d\nexport get_L_ff\nexport get_L_q\nexport get_Ld_ref\nexport get_Ls_lim\nexport get_Lv_pnts\nexport get_Lvpl1\nexport get_Lvpl_sw\nexport get_M_rtf\nexport get_N_rtf\nexport get_OEL_Flag\nexport get_Oel_lim\nexport get_PF_Flag\nexport get_PQ_Flag\nexport get_PSS_Hysteresis_param\nexport get_PSS_flags\nexport get_P_lim\nexport get_P_lim_inner\nexport get_P_ref\nexport get_PerOp_Flag\nexport get_Pf_Flag\nexport get_Pfa_ref\nexport get_Q_Flag\nexport get_Q_lim\nexport get_Q_lim_inner\nexport get_Q_ref\nexport get_Qref_Flag\nexport get_R\nexport get_R_1d\nexport get_R_1q\nexport get_R_c\nexport get_R_close\nexport get_R_f\nexport get_R_lim\nexport get_R_open\nexport get_R_r\nexport get_R_s\nexport get_R_source\nexport get_R_th\nexport get_Recon_Flag\nexport get_Ref_Flag\nexport get_Rmin\nexport get_Rp\nexport get_Rperm\nexport get_Rrpwr\nexport get_Rselect\nexport get_SCL_Flag\nexport get_SOC_ini\nexport get_SOC_lim\nexport get_SW1_Flag\nexport get_Se\nexport get_Spar\nexport get_T\nexport get_T1\nexport get_T10\nexport get_T11\nexport get_T12\nexport get_T13\nexport get_T1T3\nexport get_T2\nexport get_T2T4\nexport get_T3\nexport get_T4\nexport get_T5\nexport get_T6\nexport get_T7\nexport get_T8\nexport get_T9\nexport get_TFRT_pnts\nexport get_TVRT_pnts\nexport get_T_AA\nexport get_T_a\nexport get_T_act\nexport get_T_da\nexport get_T_eng\nexport get_T_f\nexport get_T_fltr\nexport get_T_ft\nexport get_T_fv\nexport get_T_g\nexport get_T_iq\nexport get_T_lim\nexport get_T_p\nexport get_T_pord\nexport get_T_q\nexport get_T_rate\nexport get_T_reg\nexport get_T_rv\nexport get_Ta\nexport get_Ta_2\nexport get_Ta_3\nexport get_Ta_4\nexport get_Ta_Tb\nexport get_Tb\nexport get_Tb1\nexport get_Tc\nexport get_Tc1\nexport get_Tcomp\nexport get_Td\nexport get_Td0_p\nexport get_Td0_pp\nexport get_Td_gov\nexport get_Te\nexport get_Tf\nexport get_Tf_1\nexport get_Tf_2\nexport get_Tf_load\nexport get_Tg\nexport get_Th\nexport get_Tj\nexport get_Tk\nexport get_Tm\nexport get_Tp\nexport get_Tpelec\nexport get_Tpord\nexport get_Tq0_p\nexport get_Tq0_pp\nexport get_Tr\nexport get_Trf\nexport get_Trv\nexport get_Ts\nexport get_Tsa\nexport get_Tsb\nexport get_Tv\nexport get_Tw\nexport get_Tw1\nexport get_Tw2\nexport get_Tw3\nexport get_Tw4\nexport get_U0\nexport get_UEL_Flag\nexport get_UEL_flags\nexport get_U_c\nexport get_VB1_max\nexport get_VB2_max\nexport get_VB_max\nexport get_VC_Flag\nexport get_VELM\nexport get_VES_lim\nexport get_VFE_lim\nexport get_VH_max\nexport get_VRT_pnts\nexport get_VV_pnts\nexport get_V_Flag\nexport get_V_frz\nexport get_V_lim\nexport get_V_lr\nexport get_V_pss\nexport get_V_ref\nexport get_V_ref0\nexport get_Va_lim\nexport get_Vcl\nexport get_Vcu\nexport get_Vdc_ref\nexport get_Vdip_lim\nexport get_Vf\nexport get_Vi_lim\nexport get_Vm_lim\nexport get_Vmax\nexport get_Vmin\nexport get_Vo_lim\nexport get_Vpi_lim\nexport get_Vpr\nexport get_Vr_lim\nexport get_Vrfrac\nexport get_Vs1_lim\nexport get_Vs2_lim\nexport get_Vst_lim\nexport get_Vtrip_Flag\nexport get_Wf_nl\nexport get_X_ad\nexport get_X_aq\nexport get_X_c\nexport get_X_l\nexport get_X_lr\nexport get_X_ls\nexport get_X_m\nexport get_X_p\nexport get_X_rr\nexport get_X_source\nexport get_X_ss\nexport get_X_th\nexport get_Xcomp\nexport get_Xd\nexport get_Xd_p\nexport get_Xd_pp\nexport get_Xl\nexport get_Xq\nexport get_Xq_p\nexport get_Xq_pp\nexport get_Y\nexport get_Y_increase\nexport get_Zerox\nexport get_a\nexport get_ac_setpoint_from\nexport get_ac_setpoint_to\nexport get_ac_voltage_control_from\nexport get_ac_voltage_control_to\nexport get_active_power\nexport get_active_power_flow\nexport get_active_power_flow_limits\nexport get_active_power_flow_primary\nexport get_active_power_flow_secondary\nexport get_active_power_flow_tertiary\nexport get_active_power_limits\nexport get_active_power_limits_from\nexport get_active_power_limits_pump\nexport get_active_power_limits_to\nexport get_active_power_losses\nexport get_active_power_pump\nexport get_admittance_limits\nexport get_angle\nexport get_angle_limits\nexport get_arc\nexport get_area\nexport get_available\nexport get_available_primary\nexport get_available_secondary\nexport get_available_tertiary\nexport get_b\nexport get_base_power\nexport get_base_power_12\nexport get_base_power_13\nexport get_base_power_23\nexport get_base_voltage\nexport get_base_voltage_primary\nexport get_base_voltage_secondary\nexport get_base_voltage_tertiary\nexport get_battery_resistance\nexport get_battery_voltage\nexport get_bias\nexport get_branch_id_control\nexport get_branch_status\nexport get_bus\nexport get_bus_control\nexport get_bustype\nexport get_c\nexport get_c_dc\nexport get_cf\nexport get_compounding_resistance\nexport get_conformity\nexport get_constant_active_power\nexport get_constant_reactive_power\nexport get_contributing_services\nexport get_control_mode\nexport get_control_objective\nexport get_control_objective_primary\nexport get_control_objective_secondary\nexport get_control_objective_tertiary\nexport get_conversion_factor\nexport get_converter_loss_from\nexport get_converter_loss_to\nexport get_current_active_power\nexport get_current_reactive_power\nexport get_cycle_limits\nexport get_d\nexport get_dP_lim\nexport get_d_t\nexport get_db\nexport get_dbd_pnts\nexport get_dc_bus\nexport get_dc_current\nexport get_dc_dc_inductor\nexport get_dc_link_capacitance\nexport get_dc_setpoint_from\nexport get_dc_setpoint_to\nexport get_dc_voltage_control_from\nexport get_dc_voltage_control_to\nexport get_delta_t\nexport get_deployed_fraction\nexport get_direction_mapping\nexport get_discrete_branch_type\nexport get_downstream_turbines\nexport get_droop_flag\nexport get_dynamic_injector\nexport get_e_lim\nexport get_efficiency\nexport get_eq_p\nexport get_ext\nexport get_f\nexport get_fdbd_pnts\nexport get_fe_lim\nexport get_feedback_flag\nexport get_fh\nexport get_fl\nexport get_flow_limits\nexport get_frequency\nexport get_from\nexport get_from_area\nexport get_from_branch_control\nexport get_fs\nexport get_fuel\nexport get_fuel_flag\nexport get_g\nexport get_gate_openings\nexport get_gate_position_limits\nexport get_head_to_volume_factor\nexport get_hysteresis_binary_logic\nexport get_impedance_active_power\nexport get_impedance_reactive_power\nexport get_inflow\nexport get_initial_ace\nexport get_initial_level\nexport get_initial_status\nexport get_initial_storage_capacity_level\nexport get_input_active_power_limits\nexport get_input_code\nexport get_input_code_1\nexport get_input_code_2\nexport get_intake_elevation\nexport get_internal_angle\nexport get_internal_angle_bias\nexport get_internal_angle_coefficients\nexport get_internal_angle_frequencies\nexport get_internal_voltage\nexport get_internal_voltage_bias\nexport get_internal_voltage_coefficients\nexport get_internal_voltage_frequencies\nexport get_inv_d_fluxlink\nexport get_inv_q_fluxlink\nexport get_inverter_base_voltage\nexport get_inverter_bridges\nexport get_inverter_capacitor_reactance\nexport get_inverter_extinction_angle\nexport get_inverter_extinction_angle_limits\nexport get_inverter_rc\nexport get_inverter_tap_limits\nexport get_inverter_tap_setting\nexport get_inverter_tap_step\nexport get_inverter_transformer_ratio\nexport get_inverter_xc\nexport get_is_filter_differential\nexport get_k1\nexport get_k2\nexport get_kWh_Cap\nexport get_kad\nexport get_kd\nexport get_kffi\nexport get_kffv\nexport get_ki_pll\nexport get_kic\nexport get_kii\nexport get_kiv\nexport get_kp_pll\nexport get_kpc\nexport get_kpi\nexport get_kpv\nexport get_kq\nexport get_kw\nexport get_kω\nexport get_l\nexport get_level_data_type\nexport get_level_targets\nexport get_lf\nexport get_lg\nexport get_load_balance_time_horizon\nexport get_load_response\nexport get_load_zone\nexport get_loss\nexport get_loss_function\nexport get_lv\nexport get_magnitude\nexport get_max_active_power\nexport get_max_constant_active_power\nexport get_max_constant_reactive_power\nexport get_max_current_active_power\nexport get_max_current_reactive_power\nexport get_max_dc_current\nexport get_max_dc_current_from\nexport get_max_dc_current_to\nexport get_max_flow\nexport get_max_impedance_active_power\nexport get_max_impedance_reactive_power\nexport get_max_output_fraction\nexport get_max_participation_factor\nexport get_max_reactive_power\nexport get_max_shunt_current\nexport get_min_compounding_voltage\nexport get_minimum_time\nexport get_motor_technology\nexport get_must_run\nexport get_n_states\nexport get_name\nexport get_number\nexport get_number_of_steps\nexport get_operation_cost\nexport get_outflow\nexport get_outflow_limits\nexport get_output_active_power_limits\nexport get_peak_active_power\nexport get_peak_reactive_power\nexport get_phase_angle_limits\nexport get_power_factor\nexport get_power_factor_weighting_fraction_from\nexport get_power_factor_weighting_fraction_to\nexport get_power_gate_openings\nexport get_power_mode\nexport get_power_trajectory\nexport get_powerhouse_elevation\nexport get_primary_group_number\nexport get_primary_shunt\nexport get_primary_star_arc\nexport get_primary_turns_ratio\nexport get_prime_mover_type\nexport get_q_nl\nexport get_r\nexport get_r_12\nexport get_r_13\nexport get_r_23\nexport get_r_load\nexport get_r_primary\nexport get_r_secondary\nexport get_r_tertiary\nexport get_ramp_limits\nexport get_rated_current\nexport get_rated_voltage\nexport get_rating\nexport get_rating_b\nexport get_rating_c\nexport get_rating_from\nexport get_rating_primary\nexport get_rating_secondary\nexport get_rating_tertiary\nexport get_rating_to\nexport get_rc_rfd\nexport get_reactive_power\nexport get_reactive_power_flow\nexport get_reactive_power_flow_primary\nexport get_reactive_power_flow_secondary\nexport get_reactive_power_flow_tertiary\nexport get_reactive_power_from\nexport get_reactive_power_limits\nexport get_reactive_power_limits_from\nexport get_reactive_power_limits_to\nexport get_reactive_power_required\nexport get_reactive_power_to\nexport get_rectifier_base_voltage\nexport get_rectifier_bridges\nexport get_rectifier_capacitor_reactance\nexport get_rectifier_delay_angle\nexport get_rectifier_delay_angle_limits\nexport get_rectifier_rc\nexport get_rectifier_tap_limits\nexport get_rectifier_tap_setting\nexport get_rectifier_tap_step\nexport get_rectifier_transformer_ratio\nexport get_rectifier_xc\nexport get_reg\nexport get_remote_bus_control\nexport get_remote_bus_control_1\nexport get_remote_bus_control_2\nexport get_requirement\nexport get_reserves\nexport get_rf\nexport get_rg\nexport get_rrpwr\nexport get_rv\nexport get_saturation_coeffs\nexport get_scheduled_dc_voltage\nexport get_secondary_group_number\nexport get_secondary_star_arc\nexport get_secondary_turns_ratio\nexport get_services\nexport get_speed_error_signal\nexport get_spillage_limits\nexport get_star_bus\nexport get_start_time_limits\nexport get_start_types\nexport get_states\nexport get_states_types\nexport get_status\nexport get_storage_capacity\nexport get_storage_level_limits\nexport get_storage_target\nexport get_storage_technology_type\nexport get_sustained_time\nexport get_switch\nexport get_switch_mode_voltage\nexport get_tF_delay\nexport get_tV_delay\nexport get_tap\nexport get_tertiary_group_number\nexport get_tertiary_star_arc\nexport get_tertiary_turns_ratio\nexport get_tfh\nexport get_tfl\nexport get_time_at_status\nexport get_time_frame\nexport get_time_limits\nexport get_to\nexport get_to_area\nexport get_to_branch_control\nexport get_transfer_setpoint\nexport get_transition_time\nexport get_travel_time\nexport get_turbine_type\nexport get_upstream_reservoirs\nexport get_upstream_turbines\nexport get_valve_position_limits\nexport get_variable\nexport get_vh_pnts\nexport get_violation_penalty\nexport get_vl_pnts\nexport get_voltage\nexport get_voltage_limits\nexport get_voltage_limits_from\nexport get_voltage_limits_to\nexport get_voltage_setpoint\nexport get_winding_group_number\nexport get_x\nexport get_x_12\nexport get_x_13\nexport get_x_23\nexport get_x_primary\nexport get_x_secondary\nexport get_x_tertiary\nexport get_α\nexport get_α_primary\nexport get_α_secondary\nexport get_α_tertiary\nexport get_β\nexport get_γ_d1\nexport get_γ_d2\nexport get_γ_q1\nexport get_γ_q2\nexport get_γ_qd\nexport get_γd\nexport get_γq\nexport get_θ_p\nexport get_θp\nexport get_θp_rad\nexport get_τ_limits\nexport get_τ_ref\nexport get_ψ\nexport get_ω_lp\nexport get_ω_ref\nexport get_ωad\nexport get_ωf\nexport get_ωz\nexport get_ϕ_I\nexport set_A!\nexport set_A1!\nexport set_A2!\nexport set_A3!\nexport set_A4!\nexport set_A5!\nexport set_A6!\nexport set_AT!\nexport set_A_set!\nexport set_A_tw!\nexport set_Accel!\nexport set_Ae!\nexport set_At!\nexport set_B!\nexport set_B_shunt!\nexport set_Be!\nexport set_Brkpt!\nexport set_C!\nexport set_CBase!\nexport set_D!\nexport set_DB_h!\nexport set_DB_l!\nexport set_D_12!\nexport set_D_23!\nexport set_D_34!\nexport set_D_45!\nexport set_D_T!\nexport set_D_dn!\nexport set_D_ex!\nexport set_D_hp!\nexport set_D_ip!\nexport set_D_lp!\nexport set_D_turb!\nexport set_D_up!\nexport set_Dm!\nexport set_E_lim!\nexport set_E_sat!\nexport set_Efd_lim!\nexport set_FES_lim!\nexport set_FRT_pnts!\nexport set_Freq_Flag!\nexport set_Ftrip_Flag!\nexport set_G!\nexport set_G_lim!\nexport set_Gen_Flag!\nexport set_H!\nexport set_H_ex!\nexport set_H_hp!\nexport set_H_ip!\nexport set_H_lim!\nexport set_H_lp!\nexport set_I_lr!\nexport set_I_max!\nexport set_Id_max!\nexport set_Ifd_ref!\nexport set_Iflim!\nexport set_Io_lim!\nexport set_Iq_lim!\nexport set_Iq_max!\nexport set_Iqinj_lim!\nexport set_Iqr_lim!\nexport set_Iqr_lims!\nexport set_K!\nexport set_K0!\nexport set_K1!\nexport set_K2!\nexport set_K3!\nexport set_K4!\nexport set_K5!\nexport set_K6!\nexport set_K7!\nexport set_K8!\nexport set_KT!\nexport set_K_a!\nexport set_K_c!\nexport set_K_c1!\nexport set_K_c2!\nexport set_K_ci!\nexport set_K_d!\nexport set_K_da!\nexport set_K_ex!\nexport set_K_f!\nexport set_K_ff!\nexport set_K_hp!\nexport set_K_hv!\nexport set_K_i!\nexport set_K_i1!\nexport set_K_i2!\nexport set_K_ia!\nexport set_K_ig!\nexport set_K_im!\nexport set_K_ip!\nexport set_K_ir!\nexport set_K_lp!\nexport set_K_lr!\nexport set_K_m!\nexport set_K_p!\nexport set_K_pa!\nexport set_K_pg!\nexport set_K_pm!\nexport set_K_pr!\nexport set_K_qi!\nexport set_K_qp!\nexport set_K_qv!\nexport set_K_turb!\nexport set_K_vi!\nexport set_K_vp!\nexport set_K_ω!\nexport set_Ka!\nexport set_Kb!\nexport set_Kc!\nexport set_Kd!\nexport set_Kd_gov!\nexport set_Ke!\nexport set_Kf!\nexport set_Kg!\nexport set_Kh!\nexport set_Ki!\nexport set_Ki_gov!\nexport set_Ki_load!\nexport set_Ki_mw!\nexport set_Ki_p!\nexport set_Ki_q!\nexport set_Kig!\nexport set_Kip!\nexport set_Kiq!\nexport set_Kl!\nexport set_Kp!\nexport set_Kp_gov!\nexport set_Kp_load!\nexport set_Kp_p!\nexport set_Kp_q!\nexport set_Kpg!\nexport set_Kpp!\nexport set_Kpq!\nexport set_Ks!\nexport set_Ks1!\nexport set_Ks2!\nexport set_Ks3!\nexport set_Kt!\nexport set_Kv!\nexport set_L_1d!\nexport set_L_1q!\nexport set_L_ad!\nexport set_L_aq!\nexport set_L_d!\nexport set_L_f1d!\nexport set_L_ff!\nexport set_L_q!\nexport set_Ld_ref!\nexport set_Ls_lim!\nexport set_Lv_pnts!\nexport set_Lvpl1!\nexport set_Lvpl_sw!\nexport set_M_rtf!\nexport set_N_rtf!\nexport set_OEL_Flag!\nexport set_Oel_lim!\nexport set_PF_Flag!\nexport set_PQ_Flag!\nexport set_PSS_Hysteresis_param!\nexport set_PSS_flags!\nexport set_P_lim!\nexport set_P_lim_inner!\nexport set_P_ref!\nexport set_PerOp_Flag!\nexport set_Pf_Flag!\nexport set_Pfa_ref!\nexport set_Q_Flag!\nexport set_Q_lim!\nexport set_Q_lim_inner!\nexport set_Q_ref!\nexport set_Qref_Flag!\nexport set_R!\nexport set_R_1d!\nexport set_R_1q!\nexport set_R_c!\nexport set_R_close!\nexport set_R_f!\nexport set_R_lim!\nexport set_R_open!\nexport set_R_r!\nexport set_R_s!\nexport set_R_source!\nexport set_R_th!\nexport set_Recon_Flag!\nexport set_Ref_Flag!\nexport set_Rmin!\nexport set_Rp!\nexport set_Rperm!\nexport set_Rrpwr!\nexport set_Rselect!\nexport set_SCL_Flag!\nexport set_SOC_ini!\nexport set_SOC_lim!\nexport set_SW1_Flag!\nexport set_Se!\nexport set_Spar!\nexport set_T!\nexport set_T1!\nexport set_T10!\nexport set_T11!\nexport set_T12!\nexport set_T13!\nexport set_T1T3!\nexport set_T2!\nexport set_T2T4!\nexport set_T3!\nexport set_T4!\nexport set_T5!\nexport set_T6!\nexport set_T7!\nexport set_T8!\nexport set_T9!\nexport set_TFRT_pnts!\nexport set_TVRT_pnts!\nexport set_T_AA!\nexport set_T_a!\nexport set_T_act!\nexport set_T_da!\nexport set_T_eng!\nexport set_T_f!\nexport set_T_fltr!\nexport set_T_ft!\nexport set_T_fv!\nexport set_T_g!\nexport set_T_iq!\nexport set_T_lim!\nexport set_T_p!\nexport set_T_pord!\nexport set_T_q!\nexport set_T_rate!\nexport set_T_reg!\nexport set_T_rv!\nexport set_Ta!\nexport set_Ta_2!\nexport set_Ta_3!\nexport set_Ta_4!\nexport set_Ta_Tb!\nexport set_Tb!\nexport set_Tb1!\nexport set_Tc!\nexport set_Tc1!\nexport set_Tcomp!\nexport set_Td!\nexport set_Td0_p!\nexport set_Td0_pp!\nexport set_Td_gov!\nexport set_Te!\nexport set_Tf!\nexport set_Tf_1!\nexport set_Tf_2!\nexport set_Tf_load!\nexport set_Tg!\nexport set_Th!\nexport set_Tj!\nexport set_Tk!\nexport set_Tm!\nexport set_Tp!\nexport set_Tpelec!\nexport set_Tpord!\nexport set_Tq0_p!\nexport set_Tq0_pp!\nexport set_Tr!\nexport set_Trf!\nexport set_Trv!\nexport set_Ts!\nexport set_Tsa!\nexport set_Tsb!\nexport set_Tv!\nexport set_Tw!\nexport set_Tw1!\nexport set_Tw2!\nexport set_Tw3!\nexport set_Tw4!\nexport set_U0!\nexport set_UEL_Flag!\nexport set_UEL_flags!\nexport set_U_c!\nexport set_VB1_max!\nexport set_VB2_max!\nexport set_VB_max!\nexport set_VC_Flag!\nexport set_VELM!\nexport set_VES_lim!\nexport set_VFE_lim!\nexport set_VH_max!\nexport set_VRT_pnts!\nexport set_VV_pnts!\nexport set_V_Flag!\nexport set_V_frz!\nexport set_V_lim!\nexport set_V_lr!\nexport set_V_pss!\nexport set_V_ref!\nexport set_V_ref0!\nexport set_Va_lim!\nexport set_Vcl!\nexport set_Vcu!\nexport set_Vdc_ref!\nexport set_Vdip_lim!\nexport set_Vf!\nexport set_Vi_lim!\nexport set_Vm_lim!\nexport set_Vmax!\nexport set_Vmin!\nexport set_Vo_lim!\nexport set_Vpi_lim!\nexport set_Vpr!\nexport set_Vr_lim!\nexport set_Vrfrac!\nexport set_Vs1_lim!\nexport set_Vs2_lim!\nexport set_Vst_lim!\nexport set_Vtrip_Flag!\nexport set_Wf_nl!\nexport set_X_ad!\nexport set_X_aq!\nexport set_X_c!\nexport set_X_l!\nexport set_X_lr!\nexport set_X_ls!\nexport set_X_m!\nexport set_X_p!\nexport set_X_rr!\nexport set_X_source!\nexport set_X_ss!\nexport set_X_th!\nexport set_Xcomp!\nexport set_Xd!\nexport set_Xd_p!\nexport set_Xd_pp!\nexport set_Xl!\nexport set_Xq!\nexport set_Xq_p!\nexport set_Xq_pp!\nexport set_Y!\nexport set_Y_increase!\nexport set_Zerox!\nexport set_a!\nexport set_ac_setpoint_from!\nexport set_ac_setpoint_to!\nexport set_ac_voltage_control_from!\nexport set_ac_voltage_control_to!\nexport set_active_power!\nexport set_active_power_flow!\nexport set_active_power_flow_limits!\nexport set_active_power_flow_primary!\nexport set_active_power_flow_secondary!\nexport set_active_power_flow_tertiary!\nexport set_active_power_limits!\nexport set_active_power_limits_from!\nexport set_active_power_limits_pump!\nexport set_active_power_limits_to!\nexport set_active_power_losses!\nexport set_active_power_pump!\nexport set_admittance_limits!\nexport set_angle!\nexport set_angle_limits!\nexport set_arc!\nexport set_area!\nexport set_available!\nexport set_available_primary!\nexport set_available_secondary!\nexport set_available_tertiary!\nexport set_b!\nexport set_base_power!\nexport set_base_power_12!\nexport set_base_power_13!\nexport set_base_power_23!\nexport set_base_voltage!\nexport set_base_voltage_primary!\nexport set_base_voltage_secondary!\nexport set_base_voltage_tertiary!\nexport set_battery_resistance!\nexport set_battery_voltage!\nexport set_bias!\nexport set_branch_id_control!\nexport set_branch_status!\nexport set_bus!\nexport set_bus_control!\nexport set_bustype!\nexport set_c!\nexport set_c_dc!\nexport set_cf!\nexport set_compounding_resistance!\nexport set_conformity!\nexport set_constant_active_power!\nexport set_constant_reactive_power!\nexport set_contributing_services!\nexport set_control_mode!\nexport set_control_objective!\nexport set_control_objective_primary!\nexport set_control_objective_secondary!\nexport set_control_objective_tertiary!\nexport set_conversion_factor!\nexport set_converter_loss_from!\nexport set_converter_loss_to!\nexport set_current_active_power!\nexport set_current_reactive_power!\nexport set_cycle_limits!\nexport set_d!\nexport set_dP_lim!\nexport set_d_t!\nexport set_db!\nexport set_dbd_pnts!\nexport set_dc_bus!\nexport set_dc_current!\nexport set_dc_dc_inductor!\nexport set_dc_link_capacitance!\nexport set_dc_setpoint_from!\nexport set_dc_setpoint_to!\nexport set_dc_voltage_control_from!\nexport set_dc_voltage_control_to!\nexport set_delta_t!\nexport set_deployed_fraction!\nexport set_direction_mapping!\nexport set_discrete_branch_type!\nexport set_downstream_turbines!\nexport set_droop_flag!\nexport set_dynamic_injector!\nexport set_e_lim!\nexport set_efficiency!\nexport set_eq_p!\nexport set_ext!\nexport set_f!\nexport set_fdbd_pnts!\nexport set_fe_lim!\nexport set_feedback_flag!\nexport set_fh!\nexport set_fl!\nexport set_flow_limits!\nexport set_frequency!\nexport set_from!\nexport set_from_area!\nexport set_from_branch_control!\nexport set_fs!\nexport set_fuel!\nexport set_fuel_flag!\nexport set_g!\nexport set_gate_openings!\nexport set_gate_position_limits!\nexport set_head_to_volume_factor!\nexport set_hysteresis_binary_logic!\nexport set_impedance_active_power!\nexport set_impedance_reactive_power!\nexport set_inflow!\nexport set_initial_ace!\nexport set_initial_level!\nexport set_initial_status!\nexport set_initial_storage_capacity_level!\nexport set_input_active_power_limits!\nexport set_input_code!\nexport set_input_code_1!\nexport set_input_code_2!\nexport set_intake_elevation!\nexport set_internal_angle!\nexport set_internal_angle_bias!\nexport set_internal_angle_coefficients!\nexport set_internal_angle_frequencies!\nexport set_internal_voltage!\nexport set_internal_voltage_bias!\nexport set_internal_voltage_coefficients!\nexport set_internal_voltage_frequencies!\nexport set_inv_d_fluxlink!\nexport set_inv_q_fluxlink!\nexport set_inverter_base_voltage!\nexport set_inverter_bridges!\nexport set_inverter_capacitor_reactance!\nexport set_inverter_extinction_angle!\nexport set_inverter_extinction_angle_limits!\nexport set_inverter_rc!\nexport set_inverter_tap_limits!\nexport set_inverter_tap_setting!\nexport set_inverter_tap_step!\nexport set_inverter_transformer_ratio!\nexport set_inverter_xc!\nexport set_is_filter_differential!\nexport set_k1!\nexport set_k2!\nexport set_kWh_Cap!\nexport set_kad!\nexport set_kd!\nexport set_kffi!\nexport set_kffv!\nexport set_ki_pll!\nexport set_kic!\nexport set_kii!\nexport set_kiv!\nexport set_kp_pll!\nexport set_kpc!\nexport set_kpi!\nexport set_kpv!\nexport set_kq!\nexport set_kw!\nexport set_kω!\nexport set_l!\nexport set_level_data_type!\nexport set_level_targets!\nexport set_lf!\nexport set_lg!\nexport set_load_balance_time_horizon!\nexport set_load_response!\nexport set_load_zone!\nexport set_loss!\nexport set_loss_function!\nexport set_lv!\nexport set_magnitude!\nexport set_max_active_power!\nexport set_max_constant_active_power!\nexport set_max_constant_reactive_power!\nexport set_max_current_active_power!\nexport set_max_current_reactive_power!\nexport set_max_dc_current!\nexport set_max_dc_current_from!\nexport set_max_dc_current_to!\nexport set_max_flow!\nexport set_max_impedance_active_power!\nexport set_max_impedance_reactive_power!\nexport set_max_output_fraction!\nexport set_max_participation_factor!\nexport set_max_reactive_power!\nexport set_max_shunt_current!\nexport set_min_compounding_voltage!\nexport set_minimum_time!\nexport set_motor_technology!\nexport set_must_run!\nexport set_n_states!\nexport set_name!\nexport set_number!\nexport set_number_of_steps!\nexport set_operation_cost!\nexport set_outflow!\nexport set_outflow_limits!\nexport set_output_active_power_limits!\nexport set_peak_active_power!\nexport set_peak_reactive_power!\nexport set_phase_angle_limits!\nexport set_power_factor!\nexport set_power_factor_weighting_fraction_from!\nexport set_power_factor_weighting_fraction_to!\nexport set_power_gate_openings!\nexport set_power_mode!\nexport set_power_trajectory!\nexport set_powerhouse_elevation!\nexport set_primary_group_number!\nexport set_primary_shunt!\nexport set_primary_star_arc!\nexport set_primary_turns_ratio!\nexport set_prime_mover_type!\nexport set_q_nl!\nexport set_r!\nexport set_r_12!\nexport set_r_13!\nexport set_r_23!\nexport set_r_load!\nexport set_r_primary!\nexport set_r_secondary!\nexport set_r_tertiary!\nexport set_ramp_limits!\nexport set_rated_current!\nexport set_rated_voltage!\nexport set_rating!\nexport set_rating_b!\nexport set_rating_c!\nexport set_rating_from!\nexport set_rating_primary!\nexport set_rating_secondary!\nexport set_rating_tertiary!\nexport set_rating_to!\nexport set_rc_rfd!\nexport set_reactive_power!\nexport set_reactive_power_flow!\nexport set_reactive_power_flow_primary!\nexport set_reactive_power_flow_secondary!\nexport set_reactive_power_flow_tertiary!\nexport set_reactive_power_from!\nexport set_reactive_power_limits!\nexport set_reactive_power_limits_from!\nexport set_reactive_power_limits_to!\nexport set_reactive_power_required!\nexport set_reactive_power_to!\nexport set_rectifier_base_voltage!\nexport set_rectifier_bridges!\nexport set_rectifier_capacitor_reactance!\nexport set_rectifier_delay_angle!\nexport set_rectifier_delay_angle_limits!\nexport set_rectifier_rc!\nexport set_rectifier_tap_limits!\nexport set_rectifier_tap_setting!\nexport set_rectifier_tap_step!\nexport set_rectifier_transformer_ratio!\nexport set_rectifier_xc!\nexport set_reg!\nexport set_remote_bus_control!\nexport set_remote_bus_control_1!\nexport set_remote_bus_control_2!\nexport set_requirement!\nexport set_reserves!\nexport set_rf!\nexport set_rg!\nexport set_rrpwr!\nexport set_rv!\nexport set_saturation_coeffs!\nexport set_scheduled_dc_voltage!\nexport set_secondary_group_number!\nexport set_secondary_star_arc!\nexport set_secondary_turns_ratio!\nexport set_services!\nexport set_speed_error_signal!\nexport set_spillage_limits!\nexport set_star_bus!\nexport set_start_time_limits!\nexport set_start_types!\nexport set_states!\nexport set_states_types!\nexport set_status!\nexport set_storage_capacity!\nexport set_storage_level_limits!\nexport set_storage_target!\nexport set_storage_technology_type!\nexport set_sustained_time!\nexport set_switch!\nexport set_switch_mode_voltage!\nexport set_tF_delay!\nexport set_tV_delay!\nexport set_tap!\nexport set_tertiary_group_number!\nexport set_tertiary_star_arc!\nexport set_tertiary_turns_ratio!\nexport set_tfh!\nexport set_tfl!\nexport set_time_at_status!\nexport set_time_frame!\nexport set_time_limits!\nexport set_to!\nexport set_to_area!\nexport set_to_branch_control!\nexport set_transfer_setpoint!\nexport set_transition_time!\nexport set_travel_time!\nexport set_turbine_type!\nexport set_upstream_reservoirs!\nexport set_upstream_turbines!\nexport set_valve_position_limits!\nexport set_variable!\nexport set_vh_pnts!\nexport set_violation_penalty!\nexport set_vl_pnts!\nexport set_voltage!\nexport set_voltage_limits!\nexport set_voltage_limits_from!\nexport set_voltage_limits_to!\nexport set_voltage_setpoint!\nexport set_winding_group_number!\nexport set_x!\nexport set_x_12!\nexport set_x_13!\nexport set_x_23!\nexport set_x_primary!\nexport set_x_secondary!\nexport set_x_tertiary!\nexport set_α!\nexport set_α_primary!\nexport set_α_secondary!\nexport set_α_tertiary!\nexport set_β!\nexport set_γ_d1!\nexport set_γ_d2!\nexport set_γ_q1!\nexport set_γ_q2!\nexport set_γ_qd!\nexport set_γd!\nexport set_γq!\nexport set_θ_p!\nexport set_θp!\nexport set_θp_rad!\nexport set_τ_limits!\nexport set_τ_ref!\nexport set_ψ!\nexport set_ω_lp!\nexport set_ω_ref!\nexport set_ωad!\nexport set_ωf!\nexport set_ωz!\nexport set_ϕ_I!\n"
  },
  {
    "path": "src/models/generation.jl",
    "content": "\"\"\" Supertype for all generation technologies\"\"\"\nabstract type Generator <: StaticInjection end\nconst Generators = Array{<:Generator, 1}\n\n\"\"\" Supertype for all Hydropower generation technologies\"\"\"\nabstract type HydroGen <: Generator end\n\n\"\"\" Supertype for all Hydropower generation technologies that are represented as units (i.e. HydroTurbine and HydroPumpTurbine)\"\"\"\nabstract type HydroUnit <: HydroGen end\n\n\"\"\"\nSupertype for all renewable generation technologies\n\nRequires the implementation of `get_rating`and `get_power_factor` methods\n\"\"\"\nabstract type RenewableGen <: Generator end\n\n\"\"\" Supertype for all Thermal generation technologies\"\"\"\nabstract type ThermalGen <: Generator end\n\nfunction IS.get_limits(\n    valid_range::Union{NamedTuple{(:min, :max)}, NamedTuple{(:max, :min)}},\n    unused::T,\n) where {T <: Generator}\n    # Gets min and max value defined for a field,\n    # e.g. \"valid_range\": {\"min\":-1.571, \"max\":1.571}.\n    return (min = valid_range.min, max = valid_range.max, zero = 0.0)\nend\n\n\"\"\"\nReturn the max active power for the Renewable Generation calculated as the `rating` * `power_factor`\n\"\"\"\nfunction get_max_active_power(d::T) where {T <: RenewableGen}\n    return get_rating(d) * get_power_factor(d)\nend\n\n\"\"\"\nReturn the max reactive power for the Renewable Generation calculated as the `rating` * sin(acos(`power_factor`))\n\"\"\"\nfunction get_max_reactive_power(d::T) where {T <: RenewableGen}\n    return get_rating(d) * sin(acos(get_power_factor(d)))\nend\n"
  },
  {
    "path": "src/models/injection.jl",
    "content": "\"\"\"\nAny StaticInjection struct that wants to support dynamic injectors must implement this\nmethod to set the value.\n\nThe method is only for internal uses.\n\"\"\"\nfunction set_dynamic_injector!(\n    static_injector::T,\n    dynamic_injector::U,\n) where {T <: StaticInjection, U <: Union{Nothing, DynamicInjection}}\n    current_dynamic_injector = get_dynamic_injector(static_injector)\n    if !isnothing(current_dynamic_injector) && !isnothing(dynamic_injector)\n        throw(\n            ArgumentError(\n                \"cannot assign a dynamic injector on a device that already has one\",\n            ),\n        )\n    end\n\n    # All of these types implement this field.\n    static_injector.dynamic_injector = dynamic_injector\n    return\nend\n"
  },
  {
    "path": "src/models/loads.jl",
    "content": "\"\"\" Supertype for all electric loads\"\"\"\nabstract type ElectricLoad <: StaticInjection end\n\n\"\"\" Supertype for all [static](@ref S) electric loads\"\"\"\nabstract type StaticLoad <: ElectricLoad end\n\n\"\"\" Supertype for all controllable loads\"\"\"\nabstract type ControllableLoad <: StaticLoad end\n"
  },
  {
    "path": "src/models/reserves.jl",
    "content": "\"\"\"\nUsed to specify if a [`Reserve`](@ref) is upwards, downwards, or symmetric\n\"\"\"\nabstract type ReserveDirection end\n\n\"\"\"\nAn upwards reserve to increase generation or reduce load\n\nUpwards reserves are used when total load exceeds its expected level,\ntypically due to forecast errors or contingencies.\n\nA [`Reserve`](@ref) can be specified as a `ReserveUp` when it is defined.\n\"\"\"\nabstract type ReserveUp <: ReserveDirection end\n\n\"\"\"\nA downwards reserve to decrease generation or increase load\n\nDownwards reserves are used when total load falls below its expected level,\ntypically due to forecast errors or contingencies. Not work\n\nA [`Reserve`](@ref) can be specified as a `ReserveDown` when it is defined.\n\"\"\"\nabstract type ReserveDown <: ReserveDirection end\n\n\"\"\"\nA symmetric reserve, procuring the same quantity (MW) of both upwards and downwards\nreserves\n\nA symmetric reserve is a special case. [`ReserveUp`](@ref) and [`ReserveDown`](@ref)\ncan be used individually to specify different quantities of upwards and downwards\nreserves, respectively.\n\nA [`Reserve`](@ref) can be specified as a `ReserveSymmetric` when it is defined.\n\"\"\"\nabstract type ReserveSymmetric <: ReserveDirection end\n\n\"\"\"\nSupertype for all reserve products, both spinning and non-spinning.\n\nConcrete subtypes include [`Reserve`](@ref) (parameterized by [`ReserveDirection`](@ref))\nand [`ReserveNonSpinning`](@ref).\n\"\"\"\nabstract type AbstractReserve <: Service end\n\n\"\"\"\nA reserve product to be able to respond to unexpected disturbances,\nsuch as the sudden loss of a transmission line or generator.\n\"\"\"\nabstract type Reserve{T <: ReserveDirection} <: AbstractReserve end\n\n\"\"\"\nSupertype for non-spinning (quick-start) reserve products.\n\nNon-spinning reserves can be brought online within a short time but are not\ncurrently synchronized to the grid. See also [`Reserve`](@ref) for spinning reserves.\n\nConcrete subtypes include [`ConstantReserveNonSpinning`](@ref) and\n[`VariableReserveNonSpinning`](@ref).\n\"\"\"\nabstract type ReserveNonSpinning <: AbstractReserve end\n"
  },
  {
    "path": "src/models/serialization.jl",
    "content": "const _ENCODE_AS_UUID_A = (\n    Union{Nothing, Arc},\n    Union{Nothing, Area},\n    Union{Nothing, Bus},\n    Union{Nothing, LoadZone},\n    Union{Nothing, DynamicInjection},\n    Union{Nothing, StaticInjection},\n    Union{Nothing, HydroReservoir},\n    Vector{Service},\n    Vector{Reserve},\n    Vector{HydroUnit},\n    Vector{Device},\n)\n\nconst _ENCODE_AS_UUID_B =\n    (\n        Arc,\n        Area,\n        Bus,\n        LoadZone,\n        DynamicInjection,\n        StaticInjection,\n        HydroReservoir,\n        Vector{Service},\n        Vector{Reserve},\n        Vector{HydroUnit},\n        Vector{Device},\n    )\n@assert length(_ENCODE_AS_UUID_A) == length(_ENCODE_AS_UUID_B)\n\nshould_encode_as_uuid(val) = any(x -> val isa x, _ENCODE_AS_UUID_B)\nshould_encode_as_uuid(::Type{T}) where {T} = any(x -> T <: x, _ENCODE_AS_UUID_A)\n\nconst _CONTAINS_SHOULD_ENCODE = Union{Component, MarketBidCost}  # PSY types with fields that we should_encode_as_uuid\n\nfunction IS.serialize(component::T) where {T <: _CONTAINS_SHOULD_ENCODE}\n    @debug \"serialize\" _group = IS.LOG_GROUP_SERIALIZATION component T\n    data = Dict{String, Any}()\n    for name in fieldnames(T)\n        val = serialize_uuid_handling(getfield(component, name))\n        if name == :ext\n            if !IS.is_ext_valid_for_serialization(val)\n                error(\n                    \"component type=$T name=$(get_name(component)) has a value in its \" *\n                    \"ext field that cannot be serialized.\",\n                )\n            end\n        end\n        data[string(name)] = val\n    end\n\n    IS.add_serialization_metadata!(data, T)\n\n    # This is a temporary workaround until these types are not parameterized.\n    if T <: Reserve || T <: ConstantReserveGroup\n        data[IS.METADATA_KEY][IS.CONSTRUCT_WITH_PARAMETERS_KEY] = true\n    end\n\n    return data\nend\n\n\"\"\"\nSerialize the value, encoding as UUIDs where necessary.\n\"\"\"\nfunction serialize_uuid_handling(val)\n    if should_encode_as_uuid(val)\n        if val isa Array\n            value = IS.get_uuid.(val)\n        elseif val === nothing\n            value = nothing\n        else\n            value = IS.get_uuid(val)\n        end\n    else\n        value = val\n    end\n\n    return serialize(value)\nend\n\nfunction IS.deserialize(\n    ::Type{T},\n    data::Dict,\n    component_cache::Dict,\n) where {T <: _CONTAINS_SHOULD_ENCODE}\n    @debug \"deserialize Component\" _group = IS.LOG_GROUP_SERIALIZATION T data\n    vals = Dict{Symbol, Any}()\n    for (name, type) in zip(fieldnames(T), fieldtypes(T))\n        field_name = string(name)\n        if haskey(data, field_name)\n            val = data[field_name]\n        else\n            continue\n        end\n        if val isa Dict && haskey(val, IS.METADATA_KEY)\n            vals[name] = deserialize_uuid_handling(\n                IS.get_type_from_serialization_metadata(IS.get_serialization_metadata(val)),\n                val,\n                component_cache,\n            )\n        else\n            vals[name] = deserialize_uuid_handling(type, val, component_cache)\n        end\n    end\n\n    type = IS.get_type_from_serialization_metadata(data[IS.METADATA_KEY])\n    return type(; vals...)\nend\n\nfunction IS.deserialize(::Type{Device}, data::Dict)\n    error(\"This form of IS.deserialize is not supported for Devices\")\n    return\nend\n\nfunction _check_uuid_in_component_cache(uuid::Base.UUID, component_cache)\n    if !haskey(component_cache, uuid)\n        error(\n            \"UUID $uuid not found in component cache while deserializing system. \\\n             This may indicate that a component was removed improperly leaving a UUID \\\n             reference inside the top level component. This can happen when removing Arc, Area, ACBus or LoadZone \\\n             components for example. \\\n             Check the documentation for the `remove_component!` function and review your workflow. \\\n             \",\n        )\n    end\n    return\nend\n\n\"\"\"\nDeserialize the value, converting UUIDs to components where necessary.\n\"\"\"\nfunction deserialize_uuid_handling(field_type, val, component_cache)\n    @debug \"deserialize_uuid_handling\" _group = IS.LOG_GROUP_SERIALIZATION field_type val\n    if val === nothing\n        value = val\n    elseif should_encode_as_uuid(field_type)\n        if field_type <: Vector\n            _vals = field_type()\n            for _val in val\n                uuid = deserialize(Base.UUID, _val)\n                _check_uuid_in_component_cache(uuid, component_cache)\n                component = component_cache[uuid]\n                push!(_vals, component)\n            end\n            value = _vals\n        else\n            uuid = deserialize(Base.UUID, val)\n            _check_uuid_in_component_cache(uuid, component_cache)\n            component = component_cache[uuid]\n            value = component\n        end\n    elseif field_type <: _CONTAINS_SHOULD_ENCODE\n        value = IS.deserialize(field_type, val, component_cache)\n    elseif field_type <: Union{Nothing, _CONTAINS_SHOULD_ENCODE}\n        value = IS.deserialize(field_type.b, val, component_cache)\n    elseif field_type <: InfrastructureSystemsType\n        value = deserialize(field_type, val)\n    elseif field_type isa Union && field_type.a <: Nothing && !(field_type.b <: Union)\n        # Nothing has already been handled. Apply the second type as long as there isn't a\n        # third. Julia appears to always put the Nothing in field a.\n        value = deserialize(field_type.b, val)\n    else\n        value = deserialize(field_type, val)\n    end\n\n    return value\nend\n"
  },
  {
    "path": "src/models/services.jl",
    "content": "\"\"\"\nSupertype for all system services\n\nServices (or ancillary services) include additional requirements and support\nto ensure reliable electricity service to customers. Common services are\nreserve products to be able to respond quickly to unexpected disturbances,\nsuch as the sudden loss of a transmission line or generator.\n\"\"\"\nabstract type Service <: Component end\n\n\"\"\"\nAll PowerSystems [Service](@ref) types support time series. This can be overridden for custom \ntypes that do not support time series.\n\"\"\"\nsupports_time_series(::Service) = true\n\n\"\"\"\nAll PowerSystems [Service](@ref) types support supplemental attributes. This can be overridden for \ncustom service types that do not support supplemental attributes.\n\"\"\"\nsupports_supplemental_attributes(::Service) = true\n"
  },
  {
    "path": "src/models/static_injection_subsystem.jl",
    "content": "\"\"\"\nAbstract type for a subsystem that contains multiple instances of StaticInjection\n\nSubtypes must implement:\n- get_subcomponents(subsystem::StaticInjectionSubsystem)\n\nThe subcomponents in subtypes must be attached to the System as masked components.\n\"\"\"\nabstract type StaticInjectionSubsystem <: StaticInjection end\n\n\"\"\"\nEfficiently add all time series data in the subcomponent to the subsystem by copying the\nunderlying references.\n\"\"\"\nfunction copy_subcomponent_time_series!(\n    subsystem::StaticInjectionSubsystem,\n    subcomponent::Component,\n)\n    # the existing_ts can remove entries from the set if the Subsystem has two device of\n    # the same type with the same time series type and label. Currently in the HybridSystem\n    # use case there can only be one devoe of each type.\n    existing_ts = Set(\n        (typeof(ts), get_name(ts)) for\n        ts in IS.get_time_series_multiple(subsystem)\n    )\n    name_mapping = Dict{Tuple{String, String}, String}()\n    device_name = get_name(subcomponent)\n    for ts in get_time_series_multiple(subcomponent)\n        name = get_name(ts)\n        key = (typeof(ts), name)\n        if !(key in existing_ts)\n            new_name = make_subsystem_time_series_name(subcomponent, ts)\n            if name in keys(name_mapping)\n                IS.@assert_op new_name == name_mapping[(device_name, name)]\n                continue\n            end\n            name_mapping[(device_name, name)] = new_name\n        end\n    end\n\n    copy_time_series!(subsystem, subcomponent; name_mapping = name_mapping)\n    @info \"Copied time series from $(summary(subcomponent)) to $(summary(subsystem))\"\nend\n\nfunction make_subsystem_time_series_name(subcomponent::Component, ts::TimeSeriesData)\n    return make_subsystem_time_series_name(typeof(subcomponent), get_name(ts))\nend\n\nfunction make_subsystem_time_series_name(subcomponent::Component, label::String)\n    return make_subsystem_time_series_name(typeof(subcomponent), label)\nend\n\nfunction make_subsystem_time_series_name(subcomponent::Type{<:Component}, label::String)\n    return IS.strip_module_name(subcomponent) * \"__\" * label\nend\n"
  },
  {
    "path": "src/models/static_models.jl",
    "content": "\"\"\"\nAbstract type for devices that [inject](@ref I) power or current\n\nA [static](@ref S) injection is a steady state injection, such as modeling\nthe output power of a generator held constant over a five-minute period.\n\nMany `StaticInjection` models can accept a [`DynamicInjection`](@ref) model\nas an optional add-on for conducting [dynamic](@ref D) simulations.\n\"\"\"\nabstract type StaticInjection <: Device end\n\nfunction supports_services(::T) where {T <: Device}\n    return false\nend\n\nfunction supports_services(::T) where {T <: StaticInjection}\n    return true\nend\n\nfunction get_services(device::Device)\n    if !supports_services(device)\n        error(ArgumentError(\n            \"Device $(get_name(device)) does not support services\",\n        ))\n    end\n    return Vector{Service}()\nend\n\nget_dynamic_injector(d::StaticInjection) = nothing\n\nfunction get_frequency_droop(static_injector::StaticInjection)\n    dynamic_injector = get_dynamic_injector(static_injector)\n    if isnothing(dynamic_injector)\n        throw(\n            ArgumentError(\n                \"cannot get frequency droop for $(summary(static_injector)) because it does not have dynamic data.\",\n            ),\n        )\n    end\n    return get_frequency_droop(dynamic_injector)\nend\n"
  },
  {
    "path": "src/models/storage.jl",
    "content": "\"\"\" Supertype for energy storage technologies\"\"\"\nabstract type Storage <: StaticInjection end\n"
  },
  {
    "path": "src/models/supplemental_accessors.jl",
    "content": "\n\"\"\"\nReturn the appropriate accessor function for the given aggregation topology type.\nFor [`Area`](@ref) types, returns [`get_area`](@ref); for [`LoadZone`](@ref) types, returns [`get_load_zone`](@ref).\n\"\"\"\nget_aggregation_topology_accessor(::Type{Area}) = get_area\n\"\"\"\nReturn the appropriate accessor function for the given aggregation topology type.\nFor [`Area`](@ref) types, returns [`get_area`](@ref); for [`LoadZone`](@ref) types, returns [`get_load_zone`](@ref).\n\"\"\"\nget_aggregation_topology_accessor(::Type{LoadZone}) = get_load_zone\n\n\"\"\"\nSet the [`LoadZone`](@ref) for an [`ACBus`](@ref).\n\"\"\"\nset_load_zone!(bus::ACBus, load_zone::LoadZone) = bus.load_zone = load_zone\n\"\"\"\nSet the [`Area`](@ref) for an [`ACBus`](@ref).\n\"\"\"\nset_area!(bus::ACBus, area::Area) = bus.area = area\n\n\"\"\"\nRemove the aggregation topology in a [`ACBus`](@ref) by setting the corresponding field to `nothing`.\n\"\"\"\n_remove_aggregration_topology!(bus::ACBus, ::LoadZone) = bus.load_zone = nothing\n_remove_aggregration_topology!(bus::ACBus, ::Area) = bus.area = nothing\n\n\"\"\"\nGeneric method to calculate the susceptance of [`ACTransmission`](@ref) devices.\n\"\"\"\nget_series_susceptance(b::ACTransmission) = 1 / get_x(b)\n\n\"\"\"\nReturns the series susceptance of a controllable 2-winding transformer (e.g., [`TapTransformer`](@ref), [`PhaseShiftingTransformer`](@ref)) following the convention\nin power systems to define susceptance as the inverse of the imaginary part of the impedance.\nIn the case of phase shifter transformers the angle is ignored.\n\nSee also: [`get_series_susceptances`](@ref) for 3-winding transformers\n\"\"\"\nfunction get_series_susceptance(b::Union{TapTransformer, PhaseShiftingTransformer})\n    y = 1 / get_x(b)\n    y_a = y / (get_tap(b))\n    return y_a\nend\n\nfunction get_series_susceptance(::Union{PhaseShiftingTransformer3W, Transformer3W})\n    throw(\n        ArgumentError(\n            \"get_series_susceptance not implemented for multi-winding transformers, use get_series_susceptances instead\",\n        ),\n    )\nend\n\n\"\"\"\nReturns the series susceptance of a [`PhaseShiftingTransformer3W`](@ref) as three values\n(for each of the 3 branches) following the convention in power systems to define susceptance as the inverse of the imaginary part of the impedance.\nThe phase shift angles are ignored in the susceptance calculation.\n\nSee also: [`get_series_susceptance`](@ref) for 2-winding transformers and [`get_series_susceptances`](@ref get_series_susceptances(b::Transformer3W)) for [`Transformer3W`](@ref)\n\"\"\"\nfunction get_series_susceptances(b::PhaseShiftingTransformer3W)\n    y1 = 1 / get_x_primary(b)\n    y2 = 1 / get_x_secondary(b)\n    y3 = 1 / get_x_tertiary(b)\n\n    y1_a = y1 / get_primary_turns_ratio(b)\n    y2_a = y2 / get_secondary_turns_ratio(b)\n    y3_a = y3 / get_tertiary_turns_ratio(b)\n\n    return (y1_a, y2_a, y3_a)\nend\n\n\"\"\"\nReturns the series susceptance of a [`Transformer3W`](@ref) as three values\n(for each of the 3 branches) following the convention\nin power systems to define susceptance as the inverse of the imaginary part of the impedance.\n\nSee also: [`get_series_susceptance`](@ref) for 2-winding transformers and [`get_series_susceptances`](@ref get_series_susceptances(b::PhaseShiftingTransformer3W)) for [`PhaseShiftingTransformer3W`](@ref)\n\"\"\"\nfunction get_series_susceptances(b::Transformer3W)\n    Z1s = get_r_primary(b) + get_x_primary(b) * 1im\n    Z2s = get_r_secondary(b) + get_x_secondary(b) * 1im\n    Z3s = get_r_tertiary(b) + get_x_tertiary(b) * 1im\n\n    b1s = imag(1 / Z1s)\n    b2s = imag(1 / Z2s)\n    b3s = imag(1 / Z3s)\n\n    return (b1s, b2s, b3s)\nend\n\n\"\"\"\n    get_base_voltage(line::Union{Line, MonitoredLine})\n\nReturn the base voltage (kV) of a [`Line`](@ref) or [`MonitoredLine`](@ref) by reading the\n`base_voltage` from both endpoints of the line's [`Arc`](@ref).\n\nIf the two bus voltages are identical, that value is returned directly. If they differ but\nare within `BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL` (percent), the value with fewer significant\nfigures is returned (i.e., the rounder number). If the difference exceeds the tolerance, an\nerror is thrown.\n\"\"\"\nfunction get_base_voltage(line::Union{Line, MonitoredLine})\n    v_from = get_base_voltage(get_from_bus(line))\n    v_to = get_base_voltage(get_to_bus(line))\n    v_from == v_to && return v_from\n    percent_diff = abs(v_from - v_to) / ((v_from + v_to) / 2)\n    if percent_diff > BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL\n        error(\n            \"Bus voltage mismatch on $(get_name(line)): \" *\n            \"from=$(v_from) kV, to=$(v_to) kV exceeds \" *\n            \"$(BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL * 100)% tolerance.\",\n        )\n    end\n    return _select_fewer_significant_figures(v_from, v_to)\nend\n\n\"\"\"\nSelect the value with fewer significant figures (the \"rounder\" number).\nUses trailing zeros after stripping the decimal point as a proxy.\n\"\"\"\nfunction _select_fewer_significant_figures(a::Float64, b::Float64)\n    sa = rstrip(string(a), '0')\n    sb = rstrip(string(b), '0')\n    la = length(sa)\n    lb = length(sb)\n    la < lb && return a\n    lb < la && return b\n    return max(a, b)\nend\n\n\"\"\"\n    get_high_voltage(t::TwoWindingTransformer)\n\nReturn the high-side base voltage (kV) of a [`TwoWindingTransformer`](@ref) as the\nmaximum of `base_voltage_primary` and `base_voltage_secondary`.\n\"\"\"\nfunction get_high_voltage(t::TwoWindingTransformer)\n    v_primary = get_base_voltage_primary(t)\n    v_secondary = get_base_voltage_secondary(t)\n    return max(v_primary, v_secondary)\nend\n\n\"\"\"\n    get_low_voltage(t::TwoWindingTransformer)\n\nReturn the low-side base voltage (kV) of a [`TwoWindingTransformer`](@ref) as the\nminimum of `base_voltage_primary` and `base_voltage_secondary`.\n\"\"\"\nfunction get_low_voltage(t::TwoWindingTransformer)\n    v_primary = get_base_voltage_primary(t)\n    v_secondary = get_base_voltage_secondary(t)\n    return min(v_primary, v_secondary)\nend\n\n\"\"\"\nCalculate the series admittance of a [`ACTransmission`](@ref) as the inverse of the complex impedance.\nReturns 1/(R + jX) where R is resistance and X is reactance.\n\"\"\"\nget_series_admittance(b::ACTransmission) = 1 / (get_r(b) + get_x(b) * 1im)\n\n\"\"\"\nCalculate the series admittance of a [`PhaseShiftingTransformer`](@ref) accounting for the tap ratio.\nFor a phase-shifting transformer, the series admittance is calculated as the inverse of the\ncomplex impedance modified by the tap ratio, following the same pattern as the susceptance calculation:\nY = 1/(tap * (R + jX)).\nThe phase angle α affects the admittance matrix construction but not the series impedance magnitude directly.\n\nSee also: [`get_series_susceptance`](@ref)\n\"\"\"\nfunction get_series_admittance(b::PhaseShiftingTransformer)\n    tap = get_tap(b)\n    Z_series = get_r(b) + get_x(b) * 1im\n    return 1 / (tap * Z_series)\nend\n\n\"\"\"\nCalculate the series admittance of a [`TapTransformer`](@ref) accounting for the tap ratio.\nFor a tap transformer, the series admittance is calculated as the inverse of the\ncomplex impedance modified by the tap ratio, following the same pattern as the susceptance calculation:\nY = 1/(tap * (R + jX)).\n\nSee also: [`get_series_susceptance`](@ref)\n\"\"\"\nfunction get_series_admittance(b::TapTransformer)\n    tap = get_tap(b)\n    Z_series = get_r(b) + get_x(b) * 1im\n    return 1 / (tap * Z_series)\nend\n\n\"\"\"\nCalculate the series admittances of a [`PhaseShiftingTransformer3W`](@ref) as three complex values\n(for each of the 3 branches) accounting for turns ratios.\nFor each winding, the series admittance is calculated following the same pattern as the susceptance calculation:\nYi = 1/(turns_ratio_i * (Ri + jXi)).\nThe phase shift angles affect the admittance matrix construction but not the series impedance magnitudes directly.\n\nSee also: [`get_series_admittance`](@ref) for 2-winding transformers\n\"\"\"\nfunction get_series_admittances(b::PhaseShiftingTransformer3W)\n    # Get the turns ratios for each winding\n    tap_primary = get_primary_turns_ratio(b)\n    tap_secondary = get_secondary_turns_ratio(b)\n    tap_tertiary = get_tertiary_turns_ratio(b)\n\n    # Calculate series impedances\n    Z1 = get_r_primary(b) + get_x_primary(b) * 1im\n    Z2 = get_r_secondary(b) + get_x_secondary(b) * 1im\n    Z3 = get_r_tertiary(b) + get_x_tertiary(b) * 1im\n\n    # Calculate admittances accounting for turns ratios (consistent with susceptance pattern)\n    Y1 = 1 / (tap_primary * Z1)\n    Y2 = 1 / (tap_secondary * Z2)\n    Y3 = 1 / (tap_tertiary * Z3)\n\n    return (Y1, Y2, Y3)\nend\n\nfunction get_series_admittance(::Union{PhaseShiftingTransformer3W, Transformer3W})\n    throw(\n        ArgumentError(\n            \"get_series_admittance not implemented for multi-winding transformers, use get_series_admittances instead.\",\n        ),\n    )\nend\n\n\"\"\"\nReturn the max active power for a device as the max field in the named tuple returned by [`get_active_power_limits`](@ref).\n\"\"\"\nfunction get_max_active_power(d::T) where {T <: StaticInjection}\n    return get_active_power_limits(d).max\nend\n\n\"\"\"\nReturn the max reactive power for a device as the max field in the named tuple returned by [`get_reactive_power_limits`](@ref).\n\"\"\"\nfunction get_max_reactive_power(d::T)::Float64 where {T <: StaticInjection}\n    if isnothing(get_reactive_power_limits(d))\n        return Inf\n    end\n    return get_reactive_power_limits(d).max\nend\n\n\"\"\"\nReturn the max reactive power for a [`RenewableDispatch`](@ref) generator calculated as the `rating` * `power_factor` if\nthe field `reactive_power_limits` is `nothing`\n\"\"\"\nfunction get_max_reactive_power(d::RenewableDispatch)\n    reactive_power_limits = get_reactive_power_limits(d)\n    if isnothing(reactive_power_limits)\n        return get_rating(d) * sin(acos(get_power_factor(d)))\n    end\n    return reactive_power_limits.max\nend\n\n\"\"\"\nGeneric fallback function for getting active power limits. Throws `ArgumentError` for devices\nthat don't implement this function.\n\"\"\"\nget_active_power_limits(::T) where {T <: Device} =\n    throw(ArgumentError(\"get_active_power_limits not implemented for $T\"))\n\"\"\"\nGeneric fallback function for getting reactive power limits. Throws `ArgumentError` for devices\nthat don't implement this function.\n\"\"\"\nget_reactive_power_limits(::T) where {T <: Device} =\n    throw(ArgumentError(\"get_reactive_power_limits not implemented for $T\"))\n\"\"\"\nGeneric fallback function for getting device rating. Throws `ArgumentError` for devices\nthat don't implement this function.\n\"\"\"\nget_rating(::T) where {T <: Device} =\n    throw(ArgumentError(\"get_rating not implemented for $T\"))\n\"\"\"\nGeneric fallback function for getting power factor. Throws `ArgumentError` for devices\nthat don't implement this function.\n\"\"\"\nget_power_factor(::T) where {T <: Device} =\n    throw(ArgumentError(\"get_power_factor not implemented for $T\"))\n\n\"\"\"\nCalculate the maximum active power for a [`StandardLoad`](@ref) or [`InterruptibleStandardLoad`](@ref)\n    by summing the maximum constant, impedance, and current components assuming a 1.0 voltage magnitude at the bus.\n\"\"\"\nfunction get_max_active_power(d::Union{InterruptibleStandardLoad, StandardLoad})\n    total_load = get_max_constant_active_power(d)\n    total_load += get_max_impedance_active_power(d)\n    total_load += get_max_current_active_power(d)\n    return total_load\nend\n\n\"\"\"\nGet the maximum storage capacity for HydroReservoir.\n\"\"\"\nfunction get_max_storage_level(reservoir::HydroReservoir)\n    return get_storage_level_limits(reservoir).max\nend\n\n\"\"\"\nGet the flow limits from source [`Area`](@ref) to destination [`Area`](@ref) for an [`AreaInterchange`](@ref).\n\"\"\"\nfunction get_from_to_flow_limit(a::AreaInterchange)\n    return get_flow_limits(a).from_to\nend\n\"\"\"\nGet the flow limits from destination [`Area`](@ref) to source [`Area`](@ref) for an [`AreaInterchange`](@ref).\n\"\"\"\nfunction get_to_from_flow_limit(a::AreaInterchange)\n    return get_flow_limits(a).to_from\nend\n\n\"\"\"\nGet the minimum active power flow limit for a [`TransmissionInterface`](@ref).\n\"\"\"\nfunction get_min_active_power_flow_limit(tx::TransmissionInterface)\n    return get_active_power_flow_limits(tx).min\nend\n\n\"\"\"\nGet the maximum active power flow limit for a [`TransmissionInterface`](@ref).\n\"\"\"\nfunction get_max_active_power_flow_limit(tx::TransmissionInterface)\n    return get_active_power_flow_limits(tx).max\nend\n\n\"\"\"\nCalculate the phase shift angle α for a [`TapTransformer`](@ref) or [`Transformer2W`](@ref) based on its winding group number.\nReturns the angle in radians, calculated as -(π/6) * `winding_group_number`.\nIf the `winding_group_number` is `WindingGroupNumber.UNDEFINED`, returns 0.0 and issues a warning.\n\"\"\"\nfunction get_α(t::Union{TapTransformer, Transformer2W})\n    if get_winding_group_number(t) == WindingGroupNumber.UNDEFINED\n        @debug \"winding group number for $(summary(t)) is undefined, assuming zero phase shift\"\n        return 0.0\n    else\n        return get_winding_group_number(t).value * -(π / 6)\n    end\nend\n\n\"\"\"\nCalculate the phase shift angle α for the primary winding of a [`Transformer3W`](@ref)\nbased on its primary winding group number. Returns the angle in radians, calculated\nas -(π/6) * `primary_group_number`. If `primary_group_number` is `WindingGroupNumber.UNDEFINED`, returns 0.0 and issues a warning.\n\"\"\"\nfunction get_α_primary(t::Transformer3W)\n    if get_primary_group_number(t) == WindingGroupNumber.UNDEFINED\n        @warn \"primary winding group number for $(summary(t)) is undefined, assuming zero phase shift\"\n        return 0.0\n    else\n        return get_primary_group_number(t).value * -(π / 6)\n    end\nend\n\"\"\"\nCalculate the phase shift angle α for the secondary winding of a [`Transformer3W`](@ref)\nbased on its secondary winding group number. Returns the angle in radians, calculated\nas -(π/6) * `secondary_group_number`. If `secondary_group_number` is `WindingGroupNumber.UNDEFINED`, returns 0.0 and issues a warning.\n\"\"\"\nfunction get_α_secondary(t::Transformer3W)\n    if get_secondary_group_number(t) == WindingGroupNumber.UNDEFINED\n        @warn \"secondary winding group number for $(summary(t)) is undefined, assuming zero phase shift\"\n        return 0.0\n    else\n        return get_secondary_group_number(t).value * -(π / 6)\n    end\nend\n\"\"\"\nCalculate the phase shift angle α for the tertiary winding of a [`Transformer3W`](@ref)\nbased on its tertiary winding group number. Returns the angle in radians, calculated\nas -(π/6) * `tertiary_group_number`. If `tertiary_group_number` is `WindingGroupNumber.UNDEFINED`, returns 0.0 and issues a warning.\n\"\"\"\nfunction get_α_tertiary(t::Transformer3W)\n    if get_tertiary_group_number(t) == WindingGroupNumber.UNDEFINED\n        @warn \"tertiary winding group number for $(summary(t)) is undefined, assuming zero phase shift\"\n        return 0.0\n    else\n        return get_tertiary_group_number(t).value * -(π / 6)\n    end\nend\n\nfunction supports_services(::AreaInterchange)\n    return true\nend\n"
  },
  {
    "path": "src/models/supplemental_constructors.jl",
    "content": "\"\"\"Accepts angle_limits as a Float64.\"\"\"\nfunction Line(\n    name,\n    available::Bool,\n    active_power_flow::Float64,\n    reactive_power_flow::Float64,\n    arc::Arc,\n    r,\n    x,\n    b,\n    rating,\n    angle_limits::Float64,\n)\n    return Line(\n        name,\n        available,\n        active_power_flow,\n        reactive_power_flow,\n        arc::Arc,\n        r,\n        x,\n        b,\n        rating,\n        (min = -angle_limits, max = angle_limits),\n    )\nend\n\n\"\"\"Allows construction with bus type specified as a string for legacy code.\"\"\"\nfunction ACBus(\n    number,\n    name,\n    available,\n    bustype::String,\n    angle,\n    voltage,\n    voltage_limits,\n    base_voltage,\n    area,\n    load_zone;\n    ext = Dict{String, Any}(),\n)\n    return ACBus(\n        number,\n        name,\n        available,\n        get_enum_value(ACBusTypes, bustype),\n        angle,\n        voltage,\n        voltage_limits,\n        base_voltage,\n        area,\n        load_zone,\n        ext,\n        InfrastructureSystemsInternal(),\n    )\nend\n\n\"\"\"Allows construction with bus type specified as a string for legacy code.\"\"\"\nfunction DiscreteControlledACBranch(\n    name,\n    available,\n    arc,\n    active_power_flow,\n    reactive_power_flow,\n    r,\n    x,\n    rating,\n    discrete_branch_type::String,\n    branch_status::String,\n    ext = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    return DiscreteControlledACBranch(\n        name,\n        available,\n        arc,\n        active_power_flow,\n        reactive_power_flow,\n        r,\n        x,\n        rating,\n        get_enum_value(DiscreteControlledBranchType, discrete_branch_type),\n        get_enum_value(DiscreteControlledBranchStatus, branch_status),\n        ext,\n        internal,\n    )\nend\n\n\"\"\"Allows construction of FACT Devices with control modes.\"\"\"\nfunction FACTSControlDevice(\n    name,\n    available,\n    bus,\n    control_mode::String,\n    voltage_setpoint,\n    max_shunt_current,\n    reactive_power_required,\n    services = Device[],\n    dynamic_injector = nothing,\n    ext = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    return FACTSControlDevice(\n        name,\n        available,\n        bus,\n        get_enum_value(FACTSOperationModes, control_mode),\n        voltage_setpoint,\n        max_shunt_current,\n        reactive_power_required,\n        services,\n        dynamic_injector,\n        ext,\n        internal,\n    )\nend\n\n\"\"\"Allows construction of a reserve from an iterator.\"\"\"\nfunction ConstantReserve(\n    name,\n    contributingdevices::IS.FlattenIteratorWrapper,\n    timeframe,\n    requirement,\n    time_series,\n    internal,\n)\n    return ConstantReserve(\n        name,\n        collect(contributingdevices),\n        timeframe,\n        requirement,\n        time_series,\n        internal,\n    )\nend\n\n\"\"\"Allows construction of a EnergyReservoirStorage without the specification of a cost.\"\"\"\nfunction EnergyReservoirStorage(\n    name::AbstractString,\n    available::Bool,\n    bus,\n    prime_mover_type,\n    storage_technology_type,\n    storage_capacity,\n    storage_level_limits,\n    initial_storage_capacity_level,\n    rating,\n    active_power,\n    input_active_power_limits,\n    output_active_power_limits,\n    efficiency,\n    reactive_power,\n    reactive_power_limits,\n    base_power,\n    ::Nothing,\n    services = Device[],\n    dynamic_injector = nothing,\n    ext = Dict{String, Any}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    EnergyReservoirStorage(\n        name,\n        available,\n        bus,\n        prime_mover_type,\n        storage_technology_type,\n        storage_capacity,\n        storage_level_limits,\n        initial_storage_capacity_level,\n        rating,\n        active_power,\n        input_active_power_limits,\n        output_active_power_limits,\n        efficiency,\n        reactive_power,\n        reactive_power_limits,\n        base_power,\n        StorageCost();\n        services = services,\n        dynamic_injector = dynamic_injector,\n        ext = ext,\n        internal = internal,\n    )\nend\n"
  },
  {
    "path": "src/models/supplemental_setters.jl",
    "content": "\"\"\"\nSet a single upstream turbine for a [`HydroReservoir`](@ref).\n\"\"\"\nfunction set_upstream_turbine!(reservoir::HydroReservoir, turbine::HydroUnit)\n    set_upstream_turbines!(reservoir, [turbine])\n    return\nend\n\n\"\"\"\nSet a single downstream turbine for a [`HydroReservoir`](@ref).\n\"\"\"\nfunction set_downstream_turbine!(reservoir::HydroReservoir, turbine::HydroUnit)\n    set_downstream_turbines!(reservoir, [turbine])\n    return\nend\n\nfunction set_head_to_volume_factor!(reservoir::HydroReservoir, val::Float64)\n    return set_head_to_volume_factor!(reservoir, LinearCurve(val))\nend\n"
  },
  {
    "path": "src/models/topological_elements.jl",
    "content": "\"\"\"\nAbstract type to represent the structure and interconnectedness of the system\n\"\"\"\nabstract type Topology <: Component end\n\n\"\"\"\nRepresents a geographical region of system components.\n\nAll subtypes must implement the method `get_aggregation_topology_accessor`.\n\"\"\"\nabstract type AggregationTopology <: Topology end\n\n\"\"\"\nAll PowerSystems [AggregationTopology](@ref) types support time series. This can be overridden for specific custom \naggregation topology types that do not support time series.\n\"\"\"\nsupports_time_series(::AggregationTopology) = true\n\n\"\"\"\nAbstract type to represent any type of Bus, AC or DC.\n\"\"\"\nabstract type Bus <: Topology end\n\n\"\"\"\nReturn the method to be called on a ACBus to get its AggregationTopology value for this type.\n\"\"\"\nfunction get_aggregation_topology_accessor(::Type{T}) where {T <: AggregationTopology}\n    error(\"get_aggregation_topology_accessor must be implemented for $T\")\n    return\nend\n\nfunction check_bus_params(\n    number,\n    name,\n    available,\n    bustype,\n    angle,\n    voltage,\n    voltage_limits,\n    base_voltage,\n    area,\n    load_zone,\n    ext,\n    internal,\n)\n    if !isnothing(bustype)\n        if bustype == ACBusTypes.SLACK\n            bustype = ACBusTypes.REF\n            @debug \"Changed bus type from SLACK to\" _group = IS.LOG_GROUP_SYSTEM bustype\n            #elseif bustype == BusTypes.ISOLATED\n            #    throw(DataFormatError(\"isolated buses are not supported; name=$name\"))\n        end\n    end\n\n    return number,\n    name,\n    available,\n    bustype,\n    angle,\n    voltage,\n    voltage_limits,\n    base_voltage,\n    area,\n    load_zone,\n    ext,\n    internal\nend\n"
  },
  {
    "path": "src/outages.jl",
    "content": "\"\"\"\nSupertype for outage contingencies representing planned or unplanned equipment outages.\n\nConcrete subtypes include [`GeometricDistributionForcedOutage`](@ref),\n[`PlannedOutage`](@ref), and [`FixedForcedOutage`](@ref).\n\"\"\"\nabstract type Outage <: Contingency end\n\nabstract type UnplannedOutage <: Outage end\n\n\"\"\"\nAll PowerSystems [Outage](@ref) types support time series. This can be overridden for custom \noutage types that do not support time series.\n\"\"\"\nsupports_time_series(::Outage) = true\n\n\"\"\"Get `internal`.\"\"\"\nget_internal(x::Outage) = x.internal\n\n\"\"\"\nAttribute that contains information regarding forced outages where the transition probabilities\nare modeled with geometric distributions. The outage probabilities and recovery probabilities can be modeled as time\nseries.\n\n# Arguments\n- `mean_time_to_recovery::Float64`: Time elapsed to recovery after a failure in Milliseconds.\n- `outage_transition_probability::Float64`: Characterizes the probability of failure (1 - p) in the geometric distribution.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct GeometricDistributionForcedOutage <: UnplannedOutage\n    mean_time_to_recovery::Float64\n    outage_transition_probability::Float64\n    internal::InfrastructureSystemsInternal\nend\n\n\"\"\"\n    GeometricDistributionForcedOutage(; mean_time_to_recovery, outage_transition_probability, internal)\n\nConstruct a [`GeometricDistributionForcedOutage`](@ref).\n\n# Arguments\n- `mean_time_to_recovery::Float64`: (default: `0.0`) Time elapsed to recovery after a failure in Milliseconds.\n- `outage_transition_probability::Float64`: (default: `0.0`) Characterizes the probability of failure (1 - p) in the geometric distribution.\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction GeometricDistributionForcedOutage(;\n    mean_time_to_recovery = 0.0,\n    outage_transition_probability = 0.0,\n    internal = InfrastructureSystemsInternal(),\n)\n    return GeometricDistributionForcedOutage(\n        mean_time_to_recovery,\n        outage_transition_probability,\n        internal,\n    )\nend\n\n\"\"\"Get [`GeometricDistributionForcedOutage`](@ref) `time_to_recovery`.\"\"\"\nget_mean_time_to_recovery(value::GeometricDistributionForcedOutage) =\n    value.mean_time_to_recovery\n\"\"\"Get [`GeometricDistributionForcedOutage`](@ref) `outage_transition_probability`.\"\"\"\nget_outage_transition_probability(value::GeometricDistributionForcedOutage) =\n    value.outage_transition_probability\n\n\"\"\"\nAttribute that contains information regarding planned outages.\n\n# Arguments\n- `outage_schedule::String`: String name of the time series used for the scheduled outages\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct PlannedOutage <: Outage\n    outage_schedule::String\n    internal::InfrastructureSystemsInternal\nend\n\n\"\"\"\n    PlannedOutage(; outage_schedule, internal)\n\nConstruct a [`PlannedOutage`](@ref).\n\n# Arguments\n- `outage_schedule::String`: String name of the time series used for the scheduled outages\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction PlannedOutage(;\n    outage_schedule,\n    internal = InfrastructureSystemsInternal(),\n)\n    return PlannedOutage(\n        outage_schedule,\n        internal,\n    )\nend\n\n\"\"\"Get [`PlannedOutage`](@ref) `outage_schedule`.\"\"\"\nget_outage_schedule(value::PlannedOutage) = value.outage_schedule\n\n\"\"\"\nAttribute that contains the representation of the status of the component forced outage.\nThe time series data for fixed outages can be obtained from the simulation of a stochastic process or historical information.\n\n# Arguments\n- `outage_status::Float64`: The forced outage status in the model. 1 represents outaged and 0 represents available.\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct FixedForcedOutage <: UnplannedOutage\n    outage_status::Float64\n    internal::InfrastructureSystemsInternal\nend\n\n\"\"\"\n    FixedForcedOutage(; outage_status, internal)\n\nConstruct a [`FixedForcedOutage`](@ref).\n\n# Arguments\n- `outage_status::Float64`: The forced outage status in the model. 1 represents outaged and 0 represents available.\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction FixedForcedOutage(;\n    outage_status,\n    internal = InfrastructureSystemsInternal(),\n)\n    return FixedForcedOutage(outage_status, internal)\nend\n\n\"\"\"Get [`FixedForcedOutage`](@ref) `outage_status`.\"\"\"\nget_outage_status(value::FixedForcedOutage) = value.outage_status\n"
  },
  {
    "path": "src/parsers/common.jl",
    "content": "const GENERATOR_MAPPING_FILE_PM =\n    joinpath(dirname(pathof(PowerSystems)), \"parsers\", \"generator_mapping_pm.yaml\")\n\nconst GENERATOR_MAPPING_FILE_CDM =\n    joinpath(dirname(pathof(PowerSystems)), \"parsers\", \"generator_mapping_cdm.yaml\")\n\nconst PSSE_DYR_MAPPING_FILE =\n    joinpath(dirname(pathof(PowerSystems)), \"parsers\", \"psse_dynamic_mapping.yaml\")\n\nconst STRING2FUEL =\n    Dict((normalize(string(x); casefold = true) => x) for x in instances(ThermalFuels))\nmerge!(\n    STRING2FUEL,\n    Dict(\n        \"ng\" => ThermalFuels.NATURAL_GAS,\n        \"nuc\" => ThermalFuels.NUCLEAR,\n        \"gas\" => ThermalFuels.NATURAL_GAS,\n        \"oil\" => ThermalFuels.DISTILLATE_FUEL_OIL,\n        \"dfo\" => ThermalFuels.DISTILLATE_FUEL_OIL,\n        \"sync_cond\" => ThermalFuels.OTHER,\n        \"geothermal\" => ThermalFuels.GEOTHERMAL,\n        \"ag_byproduct\" => ThermalFuels.AG_BYPRODUCT,\n    ),\n)\n\nconst STRING2PRIMEMOVER =\n    Dict((normalize(string(x); casefold = true) => x) for x in instances(PrimeMovers))\nmerge!(\n    STRING2PRIMEMOVER,\n    Dict(\n        \"w2\" => PrimeMovers.WT,\n        \"wind\" => PrimeMovers.WT,\n        \"pv\" => PrimeMovers.PVe,\n        \"solar\" => PrimeMovers.PVe,\n        \"rtpv\" => PrimeMovers.PVe,\n        \"nb\" => PrimeMovers.ST,\n        \"steam\" => PrimeMovers.ST,\n        \"hydro\" => PrimeMovers.HY,\n        \"ror\" => PrimeMovers.HY,\n        \"pump\" => PrimeMovers.PS,\n        \"pumped_hydro\" => PrimeMovers.PS,\n        \"nuclear\" => PrimeMovers.ST,\n        \"sync_cond\" => PrimeMovers.OT,\n        \"csp\" => PrimeMovers.CP,\n        \"un\" => PrimeMovers.OT,\n        \"storage\" => PrimeMovers.BA,\n        \"ice\" => PrimeMovers.IC,\n    ),\n)\n\n\"\"\"Return a dict where keys are a tuple of input parameters (fuel, unit_type) and values are\ngenerator types.\"\"\"\nfunction get_generator_mapping(filename::String)\n    genmap = open(filename) do file\n        YAML.load(file)\n    end\n\n    mappings = Dict{NamedTuple, DataType}()\n    for (gen_type, vals) in genmap\n        if gen_type == \"GenericBattery\"\n            @warn \"GenericBattery type is no longer supported. The new type is EnergyReservoirStorage\"\n            gen = EnergyReservoirStorage\n        else\n            gen = getfield(PowerSystems, Symbol(gen_type))\n        end\n        for val in vals\n            key = (fuel = val[\"fuel\"], unit_type = val[\"type\"])\n            if haskey(mappings, key)\n                error(\"duplicate generator mappings: $gen $(key.fuel) $(key.unit_type)\")\n            end\n            mappings[key] = gen\n        end\n    end\n\n    return mappings\nend\n\n\"\"\"Return the PowerSystems generator type for this fuel and unit_type.\"\"\"\nfunction get_generator_type(fuel, unit_type, mappings::Dict{NamedTuple, DataType})\n    fuel = isnothing(fuel) ? \"\" : uppercase(fuel)\n    unit_type = uppercase(unit_type)\n    generator = nothing\n\n    # Try to match the unit_type if it's defined. If it's nothing then just match on fuel.\n    for ut in (unit_type, nothing), fu in (fuel, nothing)\n        key = (fuel = fu, unit_type = ut)\n        if haskey(mappings, key)\n            generator = mappings[key]\n            break\n        end\n    end\n\n    if isnothing(generator)\n        @error \"No mapping for generator fuel=$fuel unit_type=$unit_type\"\n    end\n\n    return generator\nend\n\nfunction calculate_gen_rating(\n    active_power_limits::Union{MinMax, Nothing},\n    reactive_power_limits::Union{MinMax, Nothing},\n    base_conversion::Float64,\n)\n    reactive_power_max = isnothing(reactive_power_limits) ? 0.0 : reactive_power_limits.max\n    return calculate_gen_rating(\n        active_power_limits.max,\n        reactive_power_max,\n        base_conversion,\n    )\nend\n\nfunction calculate_gen_rating(\n    active_power_max::Float64,\n    reactive_power_max::Float64,\n    base_conversion::Float64,\n)\n    rating = sqrt(active_power_max^2 + reactive_power_max^2)\n    if rating == 0.0\n        @warn \"Rating calculation returned 0.0. Changing to 1.0 in the p.u. of the device.\"\n        return 1.0\n    end\n    return rating * base_conversion\nend\n\nfunction calculate_ramp_limit(\n    d::Dict{String, Any},\n    gen_name::Union{SubString{String}, String},\n)\n    if haskey(d, \"ramp_agc\")\n        return (up = d[\"ramp_agc\"], down = d[\"ramp_agc\"])\n    end\n    if haskey(d, \"ramp_10\")\n        return (up = d[\"ramp_10\"], down = d[\"ramp_10\"])\n    end\n    if haskey(d, \"ramp_30\")\n        return (up = d[\"ramp_30\"], down = d[\"ramp_30\"])\n    end\n    if abs(d[\"pmax\"]) > 0.0\n        @debug \"No ramp limits found for generator $(gen_name). Using pmax as ramp limit.\"\n        return (up = abs(d[\"pmax\"]), down = abs(d[\"pmax\"]))\n    end\n    @warn \"Not enough information to determine ramp limit for generator $(gen_name). Returning nothing\"\n    return nothing\nend\n\nfunction string_compare(str1, str2; casefold = true)\n    return normalize(str1; casefold = casefold) === normalize(str2; casefold = casefold)\nend\n\nfunction string_occursin(str1, str2; casefold = true)\n    return occursin(\n        normalize(str1; casefold = casefold),\n        normalize(srt2; casefold = casefold),\n    )\nend\n\nfunction convert_units!(\n    value::Float64,\n    unit_conversion::NamedTuple{(:From, :To), Tuple{String, String}},\n)\n    if string_compare(unit_conversion.From, \"degree\") &&\n       string_compare(unit_conversion.To, \"radian\")\n        value = deg2rad(value)\n    elseif string_compare(unit_conversion.From, \"radian\") &&\n           string_compare(unit_conversion.To, \"degree\")\n        value = rad2deg(value)\n    elseif string_compare(unit_conversion.From, \"TW\") &&\n           string_compare(unit_conversion.To, \"MW\")\n        value *= 1e6\n    elseif string_compare(unit_conversion.From, \"TWh\") &&\n           string_compare(unit_conversion.To, \"MWh\")\n        value *= 1e6\n    elseif string_compare(unit_conversion.From, \"GW\") &&\n           string_compare(unit_conversion.To, \"MW\")\n        value *= 1000\n    elseif string_compare(unit_conversion.From, \"GWh\") &&\n           string_compare(unit_conversion.To, \"MWh\")\n        value *= 1000\n    elseif string_compare(unit_conversion.From, \"kW\") &&\n           string_compare(unit_conversion.To, \"MW\")\n        value /= 1000\n    elseif string_compare(unit_conversion.From, \"kWh\") &&\n           string_compare(unit_conversion.To, \"MWh\")\n        value /= 1000\n    elseif string_compare(unit_conversion.From, \"hour\") &&\n           string_compare(unit_conversion.To, \"second\")\n        value *= 3600\n    elseif string_compare(unit_conversion.From, \"minute\") &&\n           string_compare(unit_conversion.To, \"second\")\n        value *= 60\n    elseif string_compare(unit_conversion.From, \"hour\") &&\n           string_compare(unit_conversion.To, \"minute\")\n        value *= 60\n    elseif string_compare(unit_conversion.From, \"minute\") &&\n           string_compare(unit_conversion.To, \"hour\")\n        value /= 60\n    elseif string_compare(unit_conversion.From, \"second\") &&\n           string_compare(unit_conversion.To, \"minute\")\n        value /= 60\n    elseif string_compare(unit_conversion.From, \"second\") &&\n           string_compare(unit_conversion.To, \"hour\")\n        value /= 3600\n    else\n        throw(\n            DataFormatError(\n                \"Unit conversion from $(unit_conversion.From) to $(unit_conversion.To) not supported\",\n            ),\n        )\n    end\n    return value\nend\n\nfunction convert_units!(\n    value::Int,\n    unit_conversion::NamedTuple{(:From, :To), Tuple{String, String}},\n)\n    return convert_units!(convert(Float64, value), unit_conversion)\nend\n\nfunction parse_enum_mapping(::Type{ThermalFuels}, fuel::AbstractString)\n    return STRING2FUEL[normalize(fuel; casefold = true)]\nend\n\nfunction parse_enum_mapping(::Type{ThermalFuels}, fuel::Symbol)\n    return parse_enum_mapping(ThermalFuels, string(fuel))\nend\n\nfunction parse_enum_mapping(::Type{PrimeMovers}, prime_mover::AbstractString)\n    return STRING2PRIMEMOVER[normalize(prime_mover; casefold = true)]\nend\n\nfunction parse_enum_mapping(::Type{PrimeMovers}, prime_mover::Symbol)\n    return parse_enum_mapping(PrimeMovers, string(prime_mover))\nend\n"
  },
  {
    "path": "src/parsers/enums.jl",
    "content": "\nIS.@scoped_enum(\n    InputCategory,\n    BRANCH = 1,\n    BUS = 2,\n    DC_BRANCH = 3,\n    GENERATOR = 4,\n    LOAD = 5,\n    RESERVE = 6,\n    SIMULATION_OBJECTS = 7,\n    STORAGE = 8,\n    FACTS = 9,\n    DCBRTYPE = 10,\n    DCBRSTATUS = 11,\n    TICT = 12,\n)\n\nconst ENUMS = (\n    AngleUnits,\n    ACBusTypes,\n    FACTSOperationModes,\n    DiscreteControlledBranchType,\n    DiscreteControlledBranchStatus,\n    WindingCategory,\n    ImpedanceCorrectionTransformerControlMode,\n    GeneratorCostModels,\n    InputCategory,\n    PrimeMovers,\n    StateTypes,\n    ReservoirDataType,\n    ReservoirLocation,\n    ThermalFuels,\n    UnitSystem,\n    LoadConformity,\n    WindingGroupNumber,\n    HydroTurbineType,\n    TransformerControlObjective,\n)\n\nconst ENUM_MAPPINGS = Dict()\n\nfor enum in ENUMS\n    ENUM_MAPPINGS[enum] = Dict()\n    for value in instances(enum)\n        ENUM_MAPPINGS[enum][normalize(string(value); casefold = true)] = value\n    end\nend\n\n\"\"\"Get the enum value for the string. Case insensitive.\"\"\"\nfunction get_enum_value(enum, value::AbstractString)\n    if !haskey(ENUM_MAPPINGS, enum)\n        throw(ArgumentError(\"enum=$enum is not valid\"))\n    end\n\n    val = normalize(value; casefold = true)\n    if !haskey(ENUM_MAPPINGS[enum], val)\n        throw(ArgumentError(\"enum=$enum does not have value=$val\"))\n    end\n\n    return ENUM_MAPPINGS[enum][val]\nend\n\nBase.convert(::Type{AngleUnits}, val::AbstractString) = get_enum_value(AngleUnits, val)\nBase.convert(::Type{ACBusTypes}, val::AbstractString) = get_enum_value(ACBusTypes, val)\nBase.convert(::Type{LoadConformity}, val::AbstractString) =\n    get_enum_value(LoadConformity, val)\nBase.convert(::Type{FACTSOperationModes}, val::AbstractString) =\n    get_enum_value(FACTSOperationModes, val)\nBase.convert(::Type{DiscreteControlledBranchType}, val::AbstractString) =\n    get_enum_value(DiscreteControlledBranchType, val)\nBase.convert(::Type{DiscreteControlledBranchStatus}, val::AbstractString) =\n    get_enum_value(DiscreteControlledBranchStatus, val)\nBase.convert(::Type{WindingCategory}, val::AbstractString) =\n    get_enum_value(WindingCategory, val)\nBase.convert(::Type{WindingGroupNumber}, val::AbstractString) =\n    get_enum_value(WindingGroupNumber, val)\nBase.convert(::Type{ImpedanceCorrectionTransformerControlMode}, val::AbstractString) =\n    get_enum_value(ImpedanceCorrectionTransformerControlMode, val)\nBase.convert(::Type{GeneratorCostModels}, val::AbstractString) =\n    get_enum_value(GeneratorCostModels, val)\nBase.convert(::Type{PrimeMovers}, val::AbstractString) = get_enum_value(PrimeMovers, val)\nBase.convert(::Type{StateTypes}, val::AbstractString) = get_enum_value(StateTypes, val)\nBase.convert(::Type{ThermalFuels}, val::AbstractString) = get_enum_value(ThermalFuels, val)\nBase.convert(::Type{TransformerControlObjective}, val::AbstractString) =\n    get_enum_value(TransformerControlObjective, val)\nBase.convert(::Type{ReservoirLocation}, val::AbstractString) =\n    get_enum_value(ReservoirLocation, val)\nBase.convert(::Type{HydroTurbineType}, val::AbstractString) =\n    get_enum_value(ReservoirLocation, val)\n"
  },
  {
    "path": "src/parsers/generator_mapping_cdm.yaml",
    "content": "# Parsing code ignores type=null.\n\nHydroTurbine:\n- {fuel: HYDRO, type: null}\n- {fuel: HYDRO, type: HYDRO}\n\nHydroDispatch:\n- {fuel: HYDRO, type: ROR}\n\nRenewableDispatch:\n- {fuel: SOLAR, type: PV}\n- {fuel: SOLAR, type: UN}\n- {fuel: WIND, type: WIND}\n- {fuel: WIND, type: null}\n- {fuel: SOLAR, type: CSP}  # TODO: may need a new struct\n\nRenewableNonDispatch:\n- {fuel: SOLAR, type: RTPV}\n\nThermalStandard:\n- {fuel: OIL, type: null}\n- {fuel: COAL, type: null}\n- {fuel: NG, type: null}\n- {fuel: GAS, type: null}\n- {fuel: NUCLEAR, type: null}\n- {fuel: NUC, type: null}\n- {fuel: OTHER, type: OT}\n\nSynchronousCondenser:\n- {fuel: SYNC_COND, type: SYNC_COND}\n\nEnergyReservoirStorage:\n- {fuel: STORAGE, type: null}\n"
  },
  {
    "path": "src/parsers/generator_mapping_pm.yaml",
    "content": "# Parsing code ignores type=null.\n\nHydroTurbine:\n- {fuel: HYDRO, type: null}\n- {fuel: HYDRO, type: HYDRO}\n\nHydroDispatch:\n- {fuel: HYDRO, type: ROR}\n\nRenewableDispatch:\n- {fuel: SOLAR, type: PV}\n- {fuel: SOLAR, type: UN}\n- {fuel: WIND, type: WIND}\n- {fuel: WIND, type: null}\n- {fuel: SOLAR, type: CSP}  # TODO: may need a new struct\n\nRenewableNonDispatch:\n- {fuel: SOLAR, type: RTPV}\n\nThermalStandard:\n- {fuel: OIL, type: null}\n- {fuel: COAL, type: null}\n- {fuel: NG, type: null}\n- {fuel: GAS, type: null}\n- {fuel: NUCLEAR, type: null}\n- {fuel: NUC, type: null}\n- {fuel: OTHER, type: OT}\n\nSynchronousCondenser:\n- {fuel: SYNC_COND, type: SYNC_COND}\n\nEnergyReservoirStorage:\n- {fuel: STORAGE, type: null}\n"
  },
  {
    "path": "src/parsers/im_io/LICENSE.md",
    "content": "Copyright (c) 2016, Los Alamos National Security, LLC\nAll rights reserved.\nCopyright 2016. Los Alamos National Security, LLC. This software was produced under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National Laboratory (LANL), which is operated by Los Alamos National Security, LLC for the U.S. Department of Energy. The U.S. Government has rights to use, reproduce, and distribute this software.  NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce derivative works, such modified software should be clearly marked, so as not to confuse it with the version available from LANL.\n\nAdditionally, redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n1.\tRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \n2.\tRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \n3.\tNeither the name of Los Alamos National Security, LLC, Los Alamos National Laboratory, LANL, the U.S. Government, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  \nTHIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "src/parsers/im_io/common.jl",
    "content": "\n\"turns top level arrays into dicts\"\nfunction arrays_to_dicts!(data::Dict{String, <:Any})\n    # update lookup structure\n    for (k, v) in data\n        if isa(v, Array) && length(v) > 0 && isa(v[1], Dict)\n            #println(\"updating $(k)\")\n            dict = Dict{Int, Any}()\n            for (i, item) in enumerate(v)\n                if haskey(item, \"index\")\n                    key = item[\"index\"]\n                else\n                    key = i\n                end\n\n                if !(haskey(dict, key))\n                    dict[key] = item\n                else\n                    @warn \"skipping component $(item[\"index\"]) from the $(k) table because a component with the same id already exists\"\n                end\n            end\n            data[k] = dict\n        end\n    end\nend\n\n\"takes a row from a matrix and assigns the values names and types\"\nfunction row_to_typed_dict(row_data, columns)\n    dict_data = Dict{String, Any}()\n    for (i, v) in enumerate(row_data)\n        if i <= length(columns)\n            name, typ = columns[i]\n            dict_data[name] = check_type(typ, v)\n        else\n            dict_data[\"col_$(i)\"] = v\n        end\n    end\n    return dict_data\nend\n\n\"takes a row from a matrix and assigns the values names\"\nfunction row_to_dict(row_data, columns)\n    dict_data = Dict{String, Any}()\n    for (i, v) in enumerate(row_data)\n        if i <= length(columns)\n            dict_data[columns[i]] = v\n        else\n            dict_data[\"col_$(i)\"] = v\n        end\n    end\n    return dict_data\nend\n\nrow_to_dict(row_data) = row_to_dict(row_data, [])\n"
  },
  {
    "path": "src/parsers/im_io/data.jl",
    "content": "\"recursively applies new_data to data, overwriting information\"\nfunction update_data!(data::Dict{String, <:Any}, new_data::Dict{String, <:Any})\n    if haskey(data, \"per_unit\") && haskey(new_data, \"per_unit\")\n        if data[\"per_unit\"] != new_data[\"per_unit\"]\n            error(\n                \"update_data requires datasets in the same units, try make_per_unit and make_mixed_units\",\n            )\n        end\n    else\n        @warn \"running update_data with data that does not include per_unit field, units may be incorrect\"\n    end\n    _update_data!(data, new_data)\n    return\nend\n\n\"recursive call of _update_data\"\nfunction _update_data!(data::Dict{String, <:Any}, new_data::Dict{String, <:Any})\n    for (key, new_v) in new_data\n        if haskey(data, key)\n            v = data[key]\n            if isa(v, Dict) && isa(new_v, Dict)\n                _update_data!(v, new_v)\n            else\n                data[key] = new_v\n            end\n        else\n            data[key] = new_v\n        end\n    end\n    return\nend\n\n\"checks if a given network data is a multinetwork\"\nismultinetwork(data::Dict{String, <:Any}) =\n    (haskey(data, \"multinetwork\") && data[\"multinetwork\"] == true)\n\n\"Transforms a single network into a multinetwork with several deepcopies of the original network\"\nfunction im_replicate(sn_data::Dict{String, <:Any}, count::Int, global_keys::Set{String})\n    @assert count > 0\n    if ismultinetwork(sn_data)\n        error(\"replicate can only be used on single networks\")\n    end\n\n    name = get(sn_data, \"name\", \"anonymous\")\n\n    mn_data = Dict{String, Any}(\"nw\" => Dict{String, Any}())\n\n    mn_data[\"multinetwork\"] = true\n\n    sn_data_tmp = deepcopy(sn_data)\n    for k in global_keys\n        if haskey(sn_data_tmp, k)\n            mn_data[k] = sn_data_tmp[k]\n        end\n\n        # note this is robust to cases where k is not present in sn_data_tmp\n        delete!(sn_data_tmp, k)\n    end\n\n    mn_data[\"name\"] = \"$(count) replicates of $(name)\"\n\n    for n in 1:count\n        mn_data[\"nw\"][\"$n\"] = deepcopy(sn_data_tmp)\n    end\n\n    return mn_data\nend\n\n#=\n\"Attempts to determine if the given data is a component dictionary\"\nfunction _iscomponentdict(data::Dict)\n    return all( typeof(comp) <: Dict for (i, comp) in data )\nend\n=#\n\n\"Makes a string bold in the terminal\"\nfunction _bold(s::String)\n    return \"\\033[1m$(s)\\033[0m\"\nend\n\n\"\"\"\nMakes a string grey in the terminal, does not seem to work well on Windows terminals\nmore info can be found at https://en.wikipedia.org/wiki/ANSI_escape_code\n\"\"\"\nfunction _grey(s::String)\n    return \"\\033[38;5;239m$(s)\\033[0m\"\nend\n\n\"converts any value to a string, summarizes arrays and dicts\"\nfunction _value2string(v, float_precision::Int)\n    if typeof(v) <: AbstractFloat\n        return _float2string(v, float_precision)\n    end\n    if typeof(v) <: Array\n        return \"[($(length(v)))]\"\n    end\n    if typeof(v) <: Dict\n        return \"{($(length(v)))}\"\n    end\n\n    return \"$(v)\"\nend\n\n\"\"\"\nconverts a float value into a string of fixed precision\n\nsprintf would do the job but this work around is needed because\nsprintf cannot take format strings during runtime\n\"\"\"\nfunction _float2string(v::AbstractFloat, float_precision::Int)\n    #str = \"$(round(v; digits=float_precision))\"\n    str = \"$(round(v; digits=float_precision))\"\n    lhs = length(split(str, '.')[1])\n    return rpad(str, lhs + 1 + float_precision, \"0\")\nend\n\n\"tests if two dicts are equal, up to floating point precision\"\nfunction compare_dict(d1, d2)\n    for (k1, v1) in d1\n        if !haskey(d2, k1)\n            #println(k1)\n            return false\n        end\n        v2 = d2[k1]\n\n        if isa(v1, Number)\n            if !_compare_numbers(v1, v2)\n                return false\n            end\n        elseif isa(v1, Array)\n            if length(v1) != length(v2)\n                return false\n            end\n            for i in 1:length(v1)\n                if isa(v1[i], Number)\n                    if !_compare_numbers(v1[i], v2[i])\n                        return false\n                    end\n                else\n                    if v1 != v2\n                        #println(v1, \" \", v2)\n                        return false\n                    end\n                end\n            end\n        elseif isa(v1, Dict)\n            if !compare_dict(v1, v2)\n                #println(v1, \" \", v2)\n                return false\n            end\n        else\n            #println(\"2\")\n            if !isapprox(v1, v2)\n                #println(v1, \" \", v2)\n                return false\n            end\n        end\n    end\n    return true\nend\n\n\"tests if two numbers are equal, up to floating point precision\"\nfunction _compare_numbers(v1, v2)\n    if isnan(v1)\n        #println(\"1.1\")\n        if !isnan(v2)\n            #println(v1, \" \", v2)\n            return false\n        end\n    else\n        #println(\"1.2\")\n        if !isapprox(v1, v2)\n            #println(v1, \" \", v2)\n            return false\n        end\n    end\n    return true\nend\n"
  },
  {
    "path": "src/parsers/im_io/matlab.jl",
    "content": "#########################################################################\n#                                                                       #\n# This file provides functions for interfacing with Matlab .m files     #\n#                                                                       #\n#########################################################################\n\n# this could benefit from a much more robust parser\n\nexport parse_matlab_file, parse_matlab_string\n\n\"\"\"\nParse a MATLAB `.m` file into a `Dict`.\n\"\"\"\nfunction parse_matlab_file(file_string::String; kwargs...)\n    data_string = read(open(file_string), String)\n    return parse_matlab_string(data_string; kwargs...)\nend\n\n\"\"\"\nParse a MATLAB data string into a `Dict`, extracting function definitions and matrix\nassignments.\n\"\"\"\nfunction parse_matlab_string(data_string::String; extended = false)\n    data_lines = split(data_string, '\\n')\n\n    matlab_dict = Dict{String, Any}()\n    struct_name = nothing\n    function_name = nothing\n    column_names = Dict{String, Any}()\n\n    last_index = length(data_lines)\n    index = 1\n    while index <= last_index\n        line = strip(data_lines[index])\n        line = \"$(line)\"\n\n        if length(line) <= 0 || strip(line)[1] == '%'\n            index = index + 1\n            continue\n        end\n\n        if occursin(\"function\", line)\n            func, value = _extract_matlab_assignment(line)\n            struct_name = strip(replace(func, \"function\" => \"\"))\n            function_name = value\n        elseif occursin(\"=\", line)\n            if struct_name !== nothing && !occursin(\"$(struct_name).\", line)\n                @warn \"assignments are expected to be made to \\\"$(struct_name)\\\" but given: $(line)\"\n            end\n\n            if occursin(\"[\", line)\n                matrix_dict = _parse_matlab_matrix(data_lines, index)\n                matlab_dict[matrix_dict[\"name\"]] = matrix_dict[\"data\"]\n                if haskey(matrix_dict, \"column_names\")\n                    column_names[matrix_dict[\"name\"]] = matrix_dict[\"column_names\"]\n                end\n                index = index + matrix_dict[\"line_count\"] - 1\n            elseif occursin(\"{\", line)\n                cell_dict = _parse_matlab_cells(data_lines, index)\n                matlab_dict[cell_dict[\"name\"]] = cell_dict[\"data\"]\n                if haskey(cell_dict, \"column_names\")\n                    column_names[cell_dict[\"name\"]] = cell_dict[\"column_names\"]\n                end\n                index = index + cell_dict[\"line_count\"] - 1\n            else\n                name, value = _extract_matlab_assignment(line)\n                value = _type_value(value)\n                matlab_dict[name] = value\n            end\n        else\n            @error \"Matlab parser skipping line number $(index) consisting of:\\n  $(line)\"\n        end\n\n        index += 1\n    end\n\n    if extended\n        return matlab_dict, function_name, column_names\n    else\n        return matlab_dict\n    end\nend\n\n\"breaks up matlab strings of the form 'name = value;'\"\nfunction _extract_matlab_assignment(string::AbstractString)\n    statement = split(string, ';')[1]\n    statement_parts = split(statement, '=')\n    @assert(length(statement_parts) == 2)\n    name = strip(statement_parts[1])\n    value = strip(statement_parts[2])\n    return name, value\nend\n\n\"Attempts to determine the type of a string extracted from a matlab file\"\nfunction _type_value(value_string::AbstractString)\n    value_string = strip(value_string)\n\n    if occursin(\"'\", value_string) # value is a string\n        value = strip(value_string, '\\'')\n    else\n        # if value is a float\n        if occursin(\".\", value_string) || occursin(\"e\", value_string)\n            value = check_type(Float64, value_string)\n        else # otherwise assume it is an int\n            value = check_type(Int, value_string)\n        end\n    end\n\n    return value\nend\n\n\"Attempts to determine the type of an array of strings extracted from a matlab file\"\nfunction _type_array(string_array::Vector{T}) where {T <: AbstractString}\n    value_string = [strip(value_string) for value_string in string_array]\n\n    return if any(occursin(\"'\", value_string) for value_string in string_array)\n        [strip(value_string, '\\'') for value_string in string_array]\n    elseif any(\n        occursin(\".\", value_string) ||\n        occursin(\"e\", value_string) ||\n        occursin(\"Inf\", value_string) ||\n        occursin(\"NaN\", value_string) for value_string in string_array\n    )\n        [check_type(Float64, value_string) for value_string in string_array]\n    else # otherwise assume it is an int\n        [check_type(Int, value_string) for value_string in string_array]\n    end\nend\n\n\"\"\n_parse_matlab_cells(lines, index) = _parse_matlab_data(lines, index, '{', '}')\n\n\"\"\n_parse_matlab_matrix(lines, index) = _parse_matlab_data(lines, index, '[', ']')\n\n\"\"\nfunction _parse_matlab_data(lines, index, start_char, end_char)\n    last_index = length(lines)\n    line_count = 0\n    columns = -1\n\n    @assert(occursin(\"=\", lines[index + line_count]))\n    matrix_assignment = split(lines[index + line_count], '%')[1]\n    matrix_assignment = strip(matrix_assignment)\n\n    @assert(occursin(\".\", matrix_assignment))\n    matrix_assignment_parts = split(matrix_assignment, '=')\n    matrix_name = strip(matrix_assignment_parts[1])\n\n    matrix_assignment_rhs = \"\"\n    if length(matrix_assignment_parts) > 1\n        matrix_assignment_rhs = strip(matrix_assignment_parts[2])\n    end\n\n    line_count = line_count + 1\n    matrix_body_lines = [matrix_assignment_rhs]\n    found_close_bracket = occursin(string(end_char), matrix_assignment_rhs)\n\n    while index + line_count < last_index && !found_close_bracket\n        line = strip(lines[index + line_count])\n\n        if length(line) == 0 || line[1] == '%'\n            line_count += 1\n            continue\n        end\n\n        line = strip(split(line, '%')[1])\n\n        if occursin(string(end_char), line)\n            found_close_bracket = true\n        end\n\n        push!(matrix_body_lines, line)\n\n        line_count = line_count + 1\n    end\n\n    #print(matrix_body_lines)\n    matrix_body_lines =\n        [_add_line_delimiter(line, start_char, end_char) for line in matrix_body_lines]\n    #print(matrix_body_lines)\n\n    matrix_body = join(matrix_body_lines, ' ')\n    matrix_body =\n        strip(replace(strip(strip(matrix_body), start_char), \"$(end_char);\" => \"\"))\n    matrix_body_rows = split(matrix_body, ';')\n    matrix_body_rows = matrix_body_rows[1:(length(matrix_body_rows) - 1)]\n\n    matrix = []\n    for row in matrix_body_rows\n        row_items = split_line(strip(row))\n        #println(row_items)\n        push!(matrix, row_items)\n        if columns < 0\n            columns = length(row_items)\n        elseif columns != length(row_items)\n            @error \"matrix parsing error, inconsistent number of items in each row\\n$(row)\"\n        end\n    end\n\n    rows = length(matrix)\n    typed_columns = [_type_array([matrix[r][c] for r in 1:rows]) for c in 1:columns]\n    for r in 1:rows\n        matrix[r] = [typed_columns[c][r] for c in 1:columns]\n    end\n\n    matrix_dict = Dict(\"name\" => matrix_name, \"data\" => matrix, \"line_count\" => line_count)\n\n    if index > 1 && occursin(\"%column_names%\", lines[index - 1])\n        column_names_string = lines[index - 1]\n        column_names_string = replace(column_names_string, \"%column_names%\" => \"\")\n        column_names = split(column_names_string)\n        if length(matrix[1]) != length(column_names)\n            @error \"column name parsing error, data rows $(length(matrix[1])), column names $(length(column_names)) \\n$(column_names)\"\n        end\n        for (c, column_name) in enumerate(column_names)\n            if column_name == \"index\"\n                @error \"column name parsing error, \\\"index\\\" is a reserved column name \\n$(column_names)\"\n\n                if !(typeof(typed_columns[c][1]) <: Int)\n                    @error \"the type of a column named \\\"index\\\" must be Int, but given $(typeof(typed_columns[c][1]))\"\n                end\n            end\n        end\n        matrix_dict[\"column_names\"] = column_names\n    end\n\n    return matrix_dict\nend\n\n\"\"\nfunction split_line(mp_line::AbstractString)\n    tokens = []\n    curr_token = \"\"\n    is_curr_token_quote = false\n\n    isquote(c) = (c == '\\'' || c == '\"')\n\n    function _push_curr_token()\n        if curr_pos <= length(mp_line)\n            curr_token *= mp_line[curr_pos]\n        end\n        curr_token = strip(curr_token)\n        if length(curr_token) > 0\n            push!(tokens, curr_token)\n        end\n        curr_token = \"\"\n        curr_pos += 1\n        is_curr_token_quote = false\n    end\n\n    function _push_curr_char()\n        curr_token *= mp_line[curr_pos]\n        curr_pos += 1\n    end\n\n    curr_pos = 1\n    while curr_pos <= length(mp_line)\n        if is_curr_token_quote\n            if mp_line[curr_pos] == curr_token[1]\n                if mp_line[curr_pos - 1] == '\\\\'\n                    # If we are inside a quote and we see slash-quote, we should\n                    # treat the quote character as a regular character.\n                    _push_curr_char()\n                elseif curr_pos < length(mp_line) && mp_line[curr_pos + 1] == curr_token[1]\n                    # If we are inside a quote, and we see two quotes in a row,\n                    # we should append one of the quotes to the current\n                    # token, then skip the other one.\n                    curr_token *= mp_line[curr_pos]\n                    curr_pos += 2\n                else\n                    # If we are inside a quote, and we see an unescaped quote char,\n                    # then the quote is ending. We should push the current token.\n                    _push_curr_token()\n                end\n            else\n                # If we are inside a quote and we see a non-quote character,\n                # we should append that character to the current token.\n                _push_curr_char()\n            end\n        else\n            if isspace(mp_line[curr_pos]) && !isspace(mp_line[curr_pos + 1])\n                # If we are not inside a quote and we see a transition from\n                # space to non-space character, then the current token is done.\n                _push_curr_token()\n            elseif isquote(mp_line[curr_pos])\n                # If we are not inside a quote and we see a quote character,\n                # then a new quote is starting. We should append the quote\n                # character to the current token and switch to quote mode.\n                curr_token = strip(curr_token * mp_line[curr_pos])\n                is_curr_token_quote = true\n                curr_pos += 1\n            else\n                # If we are not inside a quote and we see a regular character,\n                # we should append that character to the current token.\n                _push_curr_char()\n            end\n        end\n    end\n    _push_curr_token()\n    return tokens\nend\n\n\"\"\nfunction _add_line_delimiter(mp_line::AbstractString, start_char, end_char)\n    if strip(mp_line) == string(start_char)\n        return mp_line\n    end\n\n    if !occursin(\";\", mp_line) && !occursin(string(end_char), mp_line)\n        mp_line = \"$(mp_line);\"\n    end\n\n    if occursin(string(end_char), mp_line)\n        prefix = strip(split(mp_line, end_char)[1])\n        if length(prefix) > 0 && !occursin(\";\", prefix)\n            mp_line = replace(mp_line, end_char => \";$(end_char)\")\n        end\n    end\n\n    return mp_line\nend\n\n\"Checks if the given value is of a given type, if not tries to make it that type\"\nfunction check_type(typ, value)\n    if isa(value, typ)\n        return value\n    elseif isa(value, String) || isa(value, SubString)\n        try\n            value = parse(typ, value)\n            return value\n        catch e\n            @error \"parsing error, the matlab string \\\"$(value)\\\" can not be parsed to $(typ) data\"\n            rethrow(e)\n        end\n    else\n        try\n            value = typ(value)\n            return value\n        catch e\n            @error \"parsing error, the matlab value $(value) of type $(typeof(value)) can not be parsed to $(typ) data\"\n            rethrow(e)\n        end\n    end\nend\n"
  },
  {
    "path": "src/parsers/im_io.jl",
    "content": "include(\"im_io/matlab.jl\")\ninclude(\"im_io/common.jl\")\ninclude(\"im_io/data.jl\")\n"
  },
  {
    "path": "src/parsers/pm_io/LICENSE.md",
    "content": "Copyright (c) 2016, Los Alamos National Security, LLC\nAll rights reserved.\nCopyright 2016. Los Alamos National Security, LLC. This software was produced under U.S. Government contract DE-AC52-06NA25396 for Los Alamos National Laboratory (LANL), which is operated by Los Alamos National Security, LLC for the U.S. Department of Energy. The U.S. Government has rights to use, reproduce, and distribute this software.  NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce derivative works, such modified software should be clearly marked, so as not to confuse it with the version available from LANL.\n\nAdditionally, redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n1.\tRedistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. \n2.\tRedistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. \n3.\tNeither the name of Los Alamos National Security, LLC, Los Alamos National Laboratory, LANL, the U.S. Government, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.  \nTHIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL LOS ALAMOS NATIONAL SECURITY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "src/parsers/pm_io/common.jl",
    "content": "\"\"\"\n    parse_file(\n        file;\n        import_all = false,\n        validate = true,\n        correct_branch_rating = true,\n    )\n\nParses a Matpower .m `file` or PTI (PSS(R)E-v33) .raw `file` into a\nPowerModels data structure. All fields from PTI files will be imported if\n`import_all` is true (Default: false).\n\"\"\"\nfunction parse_file(\n    file::String;\n    import_all = false,\n    validate = true,\n    correct_branch_rating = true,\n)\n    pm_data = open(file) do io\n        pm_data = parse_file(\n            io;\n            import_all = import_all,\n            validate = validate,\n            correct_branch_rating = correct_branch_rating,\n            filetype = split(lowercase(file), '.')[end],\n        )\n    end\n    return pm_data\nend\n\n\"Parses the iostream from a file\"\nfunction parse_file(\n    io::IO;\n    import_all = false,\n    validate = true,\n    correct_branch_rating = true,\n    filetype = \"json\",\n)\n    if filetype == \"m\"\n        pm_data = parse_matpower(io; validate = validate)\n    elseif filetype == \"raw\"\n        pm_data = parse_psse(\n            io;\n            import_all = import_all,\n            validate = validate,\n            correct_branch_rating = correct_branch_rating,\n        )\n    elseif filetype == \"json\"\n        pm_data = parse_json(io; validate = validate)\n    else\n        @info(\"Unrecognized filetype\")\n    end\n\n    # TODO:  not sure if this relevant for all three file types, or only .m, JJS 3/7/19\n    move_genfuel_and_gentype!(pm_data)\n\n    return pm_data\nend\n\n\"\"\"\nRuns various data quality checks on a PowerModels data dictionary.\nApplies modifications in some cases.  Reports modified component ids.\n\"\"\"\nfunction correct_network_data!(data::Dict{String, <:Any}; correct_branch_rating = true)\n    mod_gen = Dict{Symbol, Set{Int}}()\n    mod_branch = Dict{Symbol, Set{Int}}()\n    mod_dcline = Dict{Symbol, Set{Int}}()\n\n    check_conductors(data)\n    check_connectivity(data)\n    check_status(data)\n    check_reference_bus(data)\n\n    make_per_unit!(data)\n\n    mod_branch[:xfer_fix] = correct_transformer_parameters!(data)\n    mod_branch[:vad_bounds] = correct_voltage_angle_differences!(data)\n    mod_branch[:mva_zero] = if (correct_branch_rating)\n        correct_thermal_limits!(data)\n    else\n        # Set rate_a as 0.0 for those branch dict entries witn no \"rate_a\" key\n        branches = [branch for branch in values(data[\"branch\"])]\n        if haskey(data, \"ne_branch\")\n            append!(branches, values(data[\"ne_branch\"]))\n        end\n\n        for branch in branches\n            if !haskey(branch, \"rate_a\")\n                if haskey(data, \"conductors\")\n                    error(\"Multiconductor Not Supported in PowerSystems\")\n                else\n                    branch[\"rate_a\"] = 0.0\n                end\n            end\n        end\n\n        Set{Int}()\n    end\n\n    #mod_branch[:ma_zero] = correct_current_limits!(data)\n    mod_branch[:orientation] = correct_branch_directions!(data)\n    check_branch_loops(data)\n\n    mod_dcline[:losses] = correct_dcline_limits!(data)\n\n    check_voltage_setpoints(data)\n\n    check_storage_parameters(data)\n    check_switch_parameters(data)\n\n    gen, dcline = correct_cost_functions!(data)\n    mod_gen[:cost_pwl] = gen\n    mod_dcline[:cost_pwl] = dcline\n\n    simplify_cost_terms!(data)\n\n    return Dict(\n        \"gen\" => mod_gen,\n        \"branch\" => mod_branch,\n        \"dcline\" => mod_dcline,\n    )\nend\n\nUNIT_SYSTEM_MAPPING = Dict(\n    \"SYSTEM_BASE\" => IS.UnitSystem.SYSTEM_BASE,\n    \"DEVICE_BASE\" => IS.UnitSystem.DEVICE_BASE,\n    \"NATURAL_UNITS\" => IS.UnitSystem.NATURAL_UNITS,\n    \"NA\" => nothing,\n)\n"
  },
  {
    "path": "src/parsers/pm_io/data.jl",
    "content": "# tools for working with a PowerModels data dict structure\n\n\"\"\nfunction calc_branch_t(branch::Dict{String, <:Any})\n    tap_ratio = branch[\"tap\"]\n    angle_shift = branch[\"shift\"]\n\n    tr = tap_ratio .* cos.(angle_shift)\n    ti = tap_ratio .* sin.(angle_shift)\n\n    return tr, ti\nend\n\n\"\"\nfunction calc_branch_y(branch::Dict{String, <:Any})\n    y = LinearAlgebra.pinv(branch[\"br_r\"] + im * branch[\"br_x\"])\n    g, b = real(y), imag(y)\n    return g, b\nend\n\n\"\"\nfunction calc_theta_delta_bounds(data::Dict{String, <:Any})\n    bus_count = length(data[\"bus\"])\n    branches = [branch for branch in values(data[\"branch\"])]\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    angle_min = Real[]\n    angle_max = Real[]\n\n    conductors = 1\n    if haskey(data, \"conductors\")\n        conductors = data[\"conductors\"]\n    end\n    conductor_ids = 1:conductors\n\n    for c in conductor_ids\n        angle_mins = [branch[\"angmin\"][c] for branch in branches]\n        angle_maxs = [branch[\"angmax\"][c] for branch in branches]\n\n        sort!(angle_mins)\n        sort!(angle_maxs; rev = true)\n\n        if length(angle_mins) > 1\n            # note that, this can occur when dclines are present\n            angle_count = min(bus_count - 1, length(branches))\n\n            angle_min_val = sum(angle_mins[1:angle_count])\n            angle_max_val = sum(angle_maxs[1:angle_count])\n        else\n            angle_min_val = angle_mins[1]\n            angle_max_val = angle_maxs[1]\n        end\n\n        push!(angle_min, angle_min_val)\n        push!(angle_max, angle_max_val)\n    end\n\n    if haskey(data, \"conductors\")\n        error(\"Multiconductor Not Supported in PowerSystems\")\n        #amin = MultiConductorVector(angle_min)\n        #amax = MultiConductorVector(angle_max)\n        #return amin, amax\n    else\n        return angle_min[1], angle_max[1]\n    end\nend\n\n\"\"\nfunction calc_max_cost_index(data::Dict{String, Any})\n    if ismultinetwork(data) # ismultinetwork is in im_io/data.jl\n        max_index = 0\n        for (i, nw_data) in data[\"nw\"]\n            nw_max_index = _calc_max_cost_index(nw_data)\n            max_index = max(max_index, nw_max_index)\n        end\n        return max_index\n    else\n        return _calc_max_cost_index(data)\n    end\nend\n\n\"\"\nfunction _calc_max_cost_index(data::Dict{String, <:Any})\n    max_index = 0\n\n    for (i, gen) in data[\"gen\"]\n        if haskey(gen, \"model\")\n            if gen[\"model\"] == 2\n                if haskey(gen, \"cost\")\n                    max_index = max(max_index, length(gen[\"cost\"]))\n                end\n            else\n                @info(\n                    \"skipping cost generator $(i) cost model in calc_cost_order, only model 2 is supported.\"\n                )\n            end\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if haskey(dcline, \"model\")\n            if dcline[\"model\"] == 2\n                if haskey(dcline, \"cost\")\n                    max_index = max(max_index, length(dcline[\"cost\"]))\n                end\n            else\n                @info(\n                    \"skipping cost dcline $(i) cost model in calc_cost_order, only model 2 is supported.\"\n                )\n            end\n        end\n    end\n\n    return max_index\nend\n\n\"maps component types to status parameters\"\nconst pm_component_status = Dict(\n    \"bus\" => \"bus_type\",\n    \"load\" => \"status\",\n    \"shunt\" => \"status\",\n    \"gen\" => \"gen_status\",\n    \"storage\" => \"status\",\n    \"switch\" => \"status\",\n    \"branch\" => \"br_status\",\n    \"dcline\" => \"br_status\",\n)\n\n\"maps component types to inactive status values\"\nconst pm_component_status_inactive = Dict(\n    \"bus\" => 4,\n    \"load\" => 0,\n    \"shunt\" => 0,\n    \"gen\" => 0,\n    \"storage\" => 0,\n    \"switch\" => 0,\n    \"branch\" => 0,\n    \"dcline\" => 0,\n)\n\nconst _pm_component_types_order = Dict(\n    \"bus\" => 1.0,\n    \"load\" => 2.0,\n    \"shunt\" => 3.0,\n    \"gen\" => 4.0,\n    \"storage\" => 5.0,\n    \"switch\" => 6.0,\n    \"branch\" => 7.0,\n    \"dcline\" => 8.0,\n)\n\nconst _pm_component_parameter_order = Dict(\n    \"bus_i\" => 1.0,\n    \"load_bus\" => 2.0,\n    \"shunt_bus\" => 3.0,\n    \"gen_bus\" => 4.0,\n    \"storage_bus\" => 5.0,\n    \"f_bus\" => 6.0,\n    \"t_bus\" => 7.0,\n    \"bus_name\" => 9.1,\n    \"base_kv\" => 9.2,\n    \"bus_type\" => 9.3,\n    \"vm\" => 10.0,\n    \"va\" => 11.0,\n    \"pd\" => 20.0,\n    \"qd\" => 21.0,\n    \"gs\" => 30.0,\n    \"bs\" => 31.0,\n    \"ps\" => 35.0,\n    \"qs\" => 36.0,\n    \"psw\" => 37.0,\n    \"qsw\" => 38.0,\n    \"pg\" => 40.0,\n    \"qg\" => 41.0,\n    \"vg\" => 42.0,\n    \"mbase\" => 43.0,\n    \"energy\" => 44.0,\n    \"br_r\" => 50.0,\n    \"br_x\" => 51.0,\n    \"g_fr\" => 52.0,\n    \"b_fr\" => 53.0,\n    \"g_to\" => 54.0,\n    \"b_to\" => 55.0,\n    \"tap\" => 56.0,\n    \"shift\" => 57.0,\n    \"vf\" => 58.1,\n    \"pf\" => 58.2,\n    \"qf\" => 58.3,\n    \"vt\" => 58.4,\n    \"pt\" => 58.5,\n    \"qt\" => 58.6,\n    \"loss0\" => 58.7,\n    \"loss1\" => 59.8,\n    \"vmin\" => 60.0,\n    \"vmax\" => 61.0,\n    \"pmin\" => 62.0,\n    \"pmax\" => 63.0,\n    \"qmin\" => 64.0,\n    \"qmax\" => 65.0,\n    \"rate_a\" => 66.0,\n    \"rate_b\" => 67.0,\n    \"rate_c\" => 68.0,\n    \"pminf\" => 69.0,\n    \"pmaxf\" => 70.0,\n    \"qminf\" => 71.0,\n    \"qmaxf\" => 72.0,\n    \"pmint\" => 73.0,\n    \"pmaxt\" => 74.0,\n    \"qmint\" => 75.0,\n    \"qmaxt\" => 76.0,\n    \"energy_rating\" => 77.01,\n    \"charge_rating\" => 77.02,\n    \"discharge_rating\" => 77.03,\n    \"charge_efficiency\" => 77.04,\n    \"discharge_efficiency\" => 77.05,\n    \"thermal_rating\" => 77.06,\n    \"qmin\" => 77.07,\n    \"qmax\" => 77.08,\n    \"qmin\" => 77.09,\n    \"qmax\" => 77.10,\n    \"r\" => 77.11,\n    \"x\" => 77.12,\n    \"p_loss\" => 77.13,\n    \"q_loss\" => 77.14,\n    \"status\" => 80.0,\n    \"gen_status\" => 81.0,\n    \"br_status\" => 82.0,\n    \"model\" => 90.0,\n    \"ncost\" => 91.0,\n    \"cost\" => 92.0,\n    \"startup\" => 93.0,\n    \"shutdown\" => 94.0,\n)\n\nconst _pm_component_status_parameters = Set([\"status\", \"gen_status\", \"br_status\"])\n\n#component_table(data::Dict{String,Any}, component::String, args...) = component_table(data, component, args...)\n\n#=\n\"recursively applies new_data to data, overwriting information\"\nfunction update_data!(data::Dict{String,<:Any}, new_data::Dict{String,<:Any})\n    if haskey(data, \"conductors\") && haskey(new_data, \"conductors\")\n        if data[\"conductors\"] != new_data[\"conductors\"]\n            error(\"update_data requires datasets with the same number of conductors\")\n        end\n    else\n        if (haskey(data, \"conductors\") && !haskey(new_data, \"conductors\")) || (!haskey(data, \"conductors\") && haskey(new_data, \"conductors\"))\n            @info(\"running update_data with missing onductors fields, conductors may be incorrect\")\n        end\n    end\n    update_data!(data, new_data)\nend\n=#\n\"\"\"\nTurns in given single network data in multinetwork data with a `count`\nreplicate of the given network.  Note that this function performs a deepcopy\nof the network data.  Significant multinetwork space savings can often be\nachieved by building application specific methods of building multinetwork\nwith minimal data replication.\n\"\"\"\nfunction replicate(\n    sn_data::Dict{String, <:Any},\n    count::Int;\n    global_keys::Set{String} = Set{String}(),\n)\n    pm_global_keys = Set([\"baseMVA\", \"per_unit\"])\n    return im_replicate(sn_data, count, union(global_keys, pm_global_keys))\nend\n\n\"\"\nfunction _apply_func!(data::Dict{String, <:Any}, key::String, func)\n    if haskey(data, key)\n        data[key] = func(data[key]) # multiconductor not supported in PowerSystems\n    end\nend\n\n\"Transforms network data into per-unit\"\nfunction make_per_unit!(data::Dict{String, <:Any})\n    if !haskey(data, \"per_unit\") || data[\"per_unit\"] == false\n        data[\"per_unit\"] = true\n        mva_base = data[\"baseMVA\"]\n        if ismultinetwork(data)\n            for (i, nw_data) in data[\"nw\"]\n                _make_per_unit!(nw_data, mva_base)\n            end\n        else\n            _make_per_unit!(data, mva_base)\n        end\n    end\nend\n\n\"\"\nfunction _make_per_unit!(data::Dict{String, <:Any}, mva_base::Real)\n    # to be consistent with matpower's opf.flow_lim= 'I' with current magnitude\n    # limit defined in MVA at 1 p.u. voltage\n    ka_base = mva_base\n\n    rescale = x -> x / mva_base\n    rescale_dual = x -> x * mva_base\n    rescale_ampere = x -> x / ka_base\n\n    if haskey(data, \"bus\")\n        for (i, bus) in data[\"bus\"]\n            _apply_func!(bus, \"va\", deg2rad)\n\n            _apply_func!(bus, \"lam_kcl_r\", rescale_dual)\n            _apply_func!(bus, \"lam_kcl_i\", rescale_dual)\n        end\n    end\n\n    if haskey(data, \"load\")\n        for (i, load) in data[\"load\"]\n            _apply_func!(load, \"pd\", rescale)\n            _apply_func!(load, \"qd\", rescale)\n            _apply_func!(load, \"pi\", rescale)\n            _apply_func!(load, \"qi\", rescale)\n            _apply_func!(load, \"py\", rescale)\n            _apply_func!(load, \"qy\", rescale)\n        end\n    end\n\n    if haskey(data, \"shunt\")\n        for (i, shunt) in data[\"shunt\"]\n            _apply_func!(shunt, \"gs\", rescale)\n            _apply_func!(shunt, \"bs\", rescale)\n        end\n    end\n\n    if haskey(data, \"switched_shunt\")\n        for (i, sw_shunt) in data[\"switched_shunt\"]\n            _apply_func!(sw_shunt, \"gs\", rescale)\n            _apply_func!(sw_shunt, \"bs\", rescale)\n            _apply_func!(sw_shunt, \"y_increment\", rescale)\n        end\n    end\n\n    if haskey(data, \"gen\")\n        for (i, gen) in data[\"gen\"]\n            _apply_func!(gen, \"pg\", rescale)\n            _apply_func!(gen, \"qg\", rescale)\n\n            _apply_func!(gen, \"pmax\", rescale)\n            _apply_func!(gen, \"pmin\", rescale)\n\n            _apply_func!(gen, \"qmax\", rescale)\n            _apply_func!(gen, \"qmin\", rescale)\n\n            _apply_func!(gen, \"ramp_agc\", rescale)\n            _apply_func!(gen, \"ramp_10\", rescale)\n            _apply_func!(gen, \"ramp_30\", rescale)\n            _apply_func!(gen, \"ramp_q\", rescale)\n\n            _rescale_cost_model!(gen, mva_base)\n        end\n    end\n\n    if haskey(data, \"storage\")\n        for (i, strg) in data[\"storage\"]\n            _apply_func!(strg, \"energy\", rescale)\n            _apply_func!(strg, \"energy_rating\", rescale)\n            _apply_func!(strg, \"charge_rating\", rescale)\n            _apply_func!(strg, \"discharge_rating\", rescale)\n            _apply_func!(strg, \"thermal_rating\", rescale)\n            _apply_func!(strg, \"current_rating\", rescale)\n            _apply_func!(strg, \"qmin\", rescale)\n            _apply_func!(strg, \"qmax\", rescale)\n            _apply_func!(strg, \"p_loss\", rescale)\n            _apply_func!(strg, \"q_loss\", rescale)\n        end\n    end\n\n    if haskey(data, \"switch\")\n        for (i, switch) in data[\"switch\"]\n            _apply_func!(switch, \"psw\", rescale)\n            _apply_func!(switch, \"qsw\", rescale)\n            _apply_func!(switch, \"thermal_rating\", rescale)\n            _apply_func!(switch, \"current_rating\", rescale)\n        end\n    end\n\n    branches = []\n    if haskey(data, \"branch\")\n        append!(branches, values(data[\"branch\"]))\n    end\n\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    for branch in branches\n        _apply_func!(branch, \"rate_a\", rescale)\n        _apply_func!(branch, \"rate_b\", rescale)\n        _apply_func!(branch, \"rate_c\", rescale)\n\n        _apply_func!(branch, \"c_rating_a\", rescale_ampere)\n        _apply_func!(branch, \"c_rating_b\", rescale_ampere)\n        _apply_func!(branch, \"c_rating_c\", rescale_ampere)\n\n        _apply_func!(branch, \"shift\", deg2rad)\n        _apply_func!(branch, \"angmax\", deg2rad)\n        _apply_func!(branch, \"angmin\", deg2rad)\n\n        _apply_func!(branch, \"pf\", rescale)\n        _apply_func!(branch, \"pt\", rescale)\n        _apply_func!(branch, \"qf\", rescale)\n        _apply_func!(branch, \"qt\", rescale)\n\n        _apply_func!(branch, \"mu_sm_fr\", rescale_dual)\n        _apply_func!(branch, \"mu_sm_to\", rescale_dual)\n\n        _apply_func!(branch, \"ta_max\", deg2rad)\n        _apply_func!(branch, \"ta_min\", deg2rad)\n    end\n\n    if haskey(data, \"dcline\")\n        for (i, dcline) in data[\"dcline\"]\n            _apply_func!(dcline, \"loss0\", rescale)\n            _apply_func!(dcline, \"pf\", rescale)\n            _apply_func!(dcline, \"pt\", rescale)\n            _apply_func!(dcline, \"qf\", rescale)\n            _apply_func!(dcline, \"qt\", rescale)\n            _apply_func!(dcline, \"pmaxt\", rescale)\n            _apply_func!(dcline, \"pmint\", rescale)\n            _apply_func!(dcline, \"pmaxf\", rescale)\n            _apply_func!(dcline, \"pminf\", rescale)\n            _apply_func!(dcline, \"qmaxt\", rescale)\n            _apply_func!(dcline, \"qmint\", rescale)\n            _apply_func!(dcline, \"qmaxf\", rescale)\n            _apply_func!(dcline, \"qminf\", rescale)\n\n            _rescale_cost_model!(dcline, mva_base)\n        end\n    end\nend\n\n\"Transforms network data into mixed-units (inverse of per-unit)\"\nfunction make_mixed_units!(data::Dict{String, <:Any})\n    if haskey(data, \"per_unit\") && data[\"per_unit\"] == true\n        data[\"per_unit\"] = false\n        mva_base = data[\"baseMVA\"]\n        if ismultinetwork(data)\n            for (i, nw_data) in data[\"nw\"]\n                _make_mixed_units!(nw_data, mva_base)\n            end\n        else\n            _make_mixed_units!(data, mva_base)\n        end\n    end\nend\n\n\"\"\nfunction _make_mixed_units!(data::Dict{String, <:Any})\n    mva_base = data[\"baseMVA\"]\n\n    # to be consistent with matpower's opf.flow_lim= 'I' with current magnitude\n    # limit defined in MVA at 1 p.u. voltage\n    ka_base = mva_base\n\n    rescale = x -> x * mva_base\n    rescale_dual = x -> x / mva_base\n    rescale_ampere = x -> x * ka_base\n\n    if haskey(data, \"bus\")\n        for (i, bus) in data[\"bus\"]\n            _apply_func!(bus, \"va\", rad2deg)\n\n            _apply_func!(bus, \"lam_kcl_r\", rescale_dual)\n            _apply_func!(bus, \"lam_kcl_i\", rescale_dual)\n        end\n    end\n\n    if haskey(data, \"load\")\n        for (i, load) in data[\"load\"]\n            _apply_func!(load, \"pd\", rescale)\n            _apply_func!(load, \"qd\", rescale)\n        end\n    end\n\n    if haskey(data, \"shunt\")\n        for (i, shunt) in data[\"shunt\"]\n            _apply_func!(shunt, \"gs\", rescale)\n            _apply_func!(shunt, \"bs\", rescale)\n        end\n    end\n\n    if haskey(data, \"gen\")\n        for (i, gen) in data[\"gen\"]\n            _apply_func!(gen, \"pg\", rescale)\n            _apply_func!(gen, \"qg\", rescale)\n\n            _apply_func!(gen, \"pmax\", rescale)\n            _apply_func!(gen, \"pmin\", rescale)\n\n            _apply_func!(gen, \"qmax\", rescale)\n            _apply_func!(gen, \"qmin\", rescale)\n\n            _apply_func!(gen, \"ramp_agc\", rescale)\n            _apply_func!(gen, \"ramp_10\", rescale)\n            _apply_func!(gen, \"ramp_30\", rescale)\n            _apply_func!(gen, \"ramp_q\", rescale)\n\n            _rescale_cost_model!(gen, 1.0 / mva_base)\n        end\n    end\n\n    if haskey(data, \"storage\")\n        for (i, strg) in data[\"storage\"]\n            _apply_func!(strg, \"energy\", rescale)\n            _apply_func!(strg, \"energy_rating\", rescale)\n            _apply_func!(strg, \"charge_rating\", rescale)\n            _apply_func!(strg, \"discharge_rating\", rescale)\n            _apply_func!(strg, \"thermal_rating\", rescale)\n            _apply_func!(strg, \"current_rating\", rescale)\n            _apply_func!(strg, \"qmin\", rescale)\n            _apply_func!(strg, \"qmax\", rescale)\n            _apply_func!(strg, \"p_loss\", rescale)\n            _apply_func!(strg, \"q_loss\", rescale)\n        end\n    end\n\n    if haskey(data, \"switch\")\n        for (i, switch) in data[\"switch\"]\n            _apply_func!(switch, \"psw\", rescale)\n            _apply_func!(switch, \"qsw\", rescale)\n            _apply_func!(switch, \"thermal_rating\", rescale)\n            _apply_func!(switch, \"current_rating\", rescale)\n        end\n    end\n\n    branches = []\n    if haskey(data, \"branch\")\n        append!(branches, values(data[\"branch\"]))\n    end\n\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    for branch in branches\n        _apply_func!(branch, \"rate_a\", rescale)\n        _apply_func!(branch, \"rate_b\", rescale)\n        _apply_func!(branch, \"rate_c\", rescale)\n\n        _apply_func!(branch, \"c_rating_a\", rescale_ampere)\n        _apply_func!(branch, \"c_rating_b\", rescale_ampere)\n        _apply_func!(branch, \"c_rating_c\", rescale_ampere)\n\n        _apply_func!(branch, \"shift\", rad2deg)\n        _apply_func!(branch, \"angmax\", rad2deg)\n        _apply_func!(branch, \"angmin\", rad2deg)\n\n        _apply_func!(branch, \"pf\", rescale)\n        _apply_func!(branch, \"pt\", rescale)\n        _apply_func!(branch, \"qf\", rescale)\n        _apply_func!(branch, \"qt\", rescale)\n\n        _apply_func!(branch, \"mu_sm_fr\", rescale_dual)\n        _apply_func!(branch, \"mu_sm_to\", rescale_dual)\n\n        _apply_func!(branch, \"ta\", rad2deg)\n    end\n\n    if haskey(data, \"dcline\")\n        for (i, dcline) in data[\"dcline\"]\n            _apply_func!(dcline, \"loss0\", rescale)\n            _apply_func!(dcline, \"pf\", rescale)\n            _apply_func!(dcline, \"pt\", rescale)\n            _apply_func!(dcline, \"qf\", rescale)\n            _apply_func!(dcline, \"qt\", rescale)\n            _apply_func!(dcline, \"pmaxt\", rescale)\n            _apply_func!(dcline, \"pmint\", rescale)\n            _apply_func!(dcline, \"pmaxf\", rescale)\n            _apply_func!(dcline, \"pminf\", rescale)\n            _apply_func!(dcline, \"qmaxt\", rescale)\n            _apply_func!(dcline, \"qmint\", rescale)\n            _apply_func!(dcline, \"qmaxf\", rescale)\n            _apply_func!(dcline, \"qminf\", rescale)\n\n            _rescale_cost_model!(dcline, 1.0 / mva_base)\n        end\n    end\nend\n\n\"\"\nfunction _rescale_cost_model!(comp::Dict{String, <:Any}, scale::Real)\n    if \"model\" in keys(comp) && \"cost\" in keys(comp)\n        if comp[\"model\"] == 1\n            for i in 1:2:length(comp[\"cost\"])\n                comp[\"cost\"][i] = comp[\"cost\"][i] / scale\n            end\n        elseif comp[\"model\"] == 2\n            degree = length(comp[\"cost\"])\n            for (i, item) in enumerate(comp[\"cost\"])\n                comp[\"cost\"][i] = item * (scale^(degree - i))\n            end\n        else\n            @info(\"Skipping cost model of type $(comp[\"model\"]) in per unit transformation\")\n        end\n    end\nend\n\n\"computes the generator cost from given network data\"\nfunction calc_gen_cost(data::Dict{String, <:Any})\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    @assert(!haskey(data, \"conductors\"))\n\n    if ismultinetwork(data)\n        nw_costs = Dict{String, Any}()\n        for (i, nw_data) in data[\"nw\"]\n            nw_costs[i] = _calc_gen_cost(nw_data)\n        end\n        return sum(nw_cost for (i, nw_cost) in nw_costs)\n    else\n        return _calc_gen_cost(data)\n    end\nend\n\nfunction _calc_gen_cost(data::Dict{String, <:Any})\n    cost = 0.0\n    for (i, gen) in data[\"gen\"]\n        if gen[\"gen_status\"] == 1\n            if haskey(gen, \"model\")\n                if gen[\"model\"] == 1\n                    cost += _calc_cost_pwl(gen, \"pg\")\n                elseif gen[\"model\"] == 2\n                    cost += _calc_cost_polynomial(gen, \"pg\")\n                else\n                    @info \"generator $(i) has an unknown cost model $(gen[\"model\"])\" maxlog =\n                        PS_MAX_LOG\n                end\n            else\n                @info \"generator $(i) does not have a cost model\" maxlog = PS_MAX_LOG\n            end\n        end\n    end\n    return cost\nend\n\n\"computes the dcline cost from given network data\"\nfunction calc_dcline_cost(data::Dict{String, <:Any})\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    @assert(!haskey(data, \"conductors\"))\n\n    if ismultinetwork(data)\n        nw_costs = Dict{String, Any}()\n        for (i, nw_data) in data[\"nw\"]\n            nw_costs[i] = _calc_dcline_cost(nw_data)\n        end\n        return sum(nw_cost for (i, nw_cost) in nw_costs)\n    else\n        return _calc_dcline_cost(data)\n    end\nend\n\nfunction _calc_dcline_cost(data::Dict{String, <:Any})\n    cost = 0.0\n    for (i, dcline) in data[\"dcline\"]\n        if dcline[\"br_status\"] == 1\n            if haskey(dcline, \"model\")\n                if dcline[\"model\"] == 1\n                    cost += _calc_cost_pwl(dcline, \"pf\")\n                elseif dcline[\"model\"] == 2\n                    cost += _calc_cost_polynomial(dcline, \"pf\")\n                else\n                    @info \"dcline $(i) has an unknown cost model $(dcline[\"model\"])\" maxlog =\n                        PS_MAX_LOG\n                end\n            else\n                @info \"dcline $(i) does not have a cost model\" maxlog = PS_MAX_LOG\n            end\n        end\n    end\n    return cost\nend\n\n\"\"\"\ncompute lines in m and b from from pwl cost models data is a list of components.\n\nCan be run on data or ref data structures\n\"\"\"\nfunction calc_cost_pwl_lines(comp_dict::Dict)\n    lines = Dict()\n    for (i, comp) in comp_dict\n        lines[i] = _calc_comp_lines(comp)\n    end\n    return lines\nend\n\n\"\"\"\ncompute lines in m and b from from pwl cost models\n\"\"\"\nfunction _calc_comp_lines(component::Dict{String, <:Any})\n    @assert component[\"model\"] == 1\n    points = component[\"cost\"]\n\n    line_data = []\n    for i in 3:2:length(points)\n        x1 = points[i - 2]\n        y1 = points[i - 1]\n        x2 = points[i - 0]\n        y2 = points[i + 1]\n\n        m = (y2 - y1) / (x2 - x1)\n        b = y1 - m * x1\n\n        push!(line_data, (slope = m, intercept = b))\n    end\n\n    for i in 2:length(line_data)\n        if line_data[i - 1].slope > line_data[i].slope\n            @info \"non-convex pwl function found in points $(component[\"cost\"])\\nlines: $(line_data)\" maxlog =\n                PS_MAX_LOG\n        end\n    end\n\n    return line_data\nend\n\nfunction _calc_cost_pwl(component::Dict{String, <:Any}, setpoint_id)\n    comp_lines = _calc_comp_lines(component)\n\n    setpoint = component[setpoint_id]\n    cost = -Inf\n    for line in comp_lines\n        cost = max(cost, line.slope * setpoint + line.intercept)\n    end\n\n    return cost\nend\n\nfunction _calc_cost_polynomial(component::Dict{String, <:Any}, setpoint_id)\n    cost_terms_rev = reverse(component[\"cost\"])\n\n    setpoint = component[setpoint_id]\n\n    if length(cost_terms_rev) == 0\n        cost = 0.0\n    elseif length(cost_terms_rev) == 1\n        cost = cost_terms_rev[1]\n    elseif length(cost_terms_rev) == 2\n        cost = cost_terms_rev[1] + cost_terms_rev[2] * setpoint\n    else\n        cost_terms_rev_high = cost_terms_rev[3:end]\n        cost =\n            cost_terms_rev[1] +\n            cost_terms_rev[2] * setpoint +\n            sum(v * setpoint^(d + 1) for (d, v) in enumerate(cost_terms_rev_high))\n    end\n\n    return cost\nend\n\n\"assumes a vaild ac solution is included in the data and computes the branch flow values\"\nfunction calc_branch_flow_ac(data::Dict{String, <:Any})\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    @assert(!haskey(data, \"conductors\"))\n\n    if ismultinetwork(data)\n        nws = Dict{String, Any}()\n        for (i, nw_data) in data[\"nw\"]\n            nws[i] = _calc_branch_flow_ac(nw_data)\n        end\n        return Dict{String, Any}(\n            \"nw\" => nws,\n            \"per_unit\" => data[\"per_unit\"],\n            \"baseMVA\" => data[\"baseMVA\"],\n        )\n    else\n        flows = _calc_branch_flow_ac(data)\n        flows[\"per_unit\"] = data[\"per_unit\"]\n        flows[\"baseMVA\"] = data[\"baseMVA\"]\n        return flows\n    end\nend\n\n\"helper function for calc_branch_flow_ac\"\nfunction _calc_branch_flow_ac(data::Dict{String, <:Any})\n    vm = Dict(bus[\"index\"] => bus[\"vm\"] for (i, bus) in data[\"bus\"])\n    va = Dict(bus[\"index\"] => bus[\"va\"] for (i, bus) in data[\"bus\"])\n\n    flows = Dict{String, Any}()\n    for (i, branch) in data[\"branch\"]\n        if branch[\"br_status\"] != 0\n            f_bus = branch[\"f_bus\"]\n            t_bus = branch[\"t_bus\"]\n\n            g, b = calc_branch_y(branch)\n            tr, ti = calc_branch_t(branch)\n            g_fr = branch[\"g_fr\"]\n            b_fr = branch[\"b_fr\"]\n            g_to = branch[\"g_to\"]\n            b_to = branch[\"b_to\"]\n\n            tm = branch[\"tap\"]\n\n            vm_fr = vm[f_bus]\n            vm_to = vm[t_bus]\n            va_fr = va[f_bus]\n            va_to = va[t_bus]\n\n            p_fr =\n                (g + g_fr) / tm^2 * vm_fr^2 +\n                (-g * tr + b * ti) / tm^2 * (vm_fr * vm_to * cos(va_fr - va_to)) +\n                (-b * tr - g * ti) / tm^2 * (vm_fr * vm_to * sin(va_fr - va_to))\n            q_fr =\n                -(b + b_fr) / tm^2 * vm_fr^2 -\n                (-b * tr - g * ti) / tm^2 * (vm_fr * vm_to * cos(va_fr - va_to)) +\n                (-g * tr + b * ti) / tm^2 * (vm_fr * vm_to * sin(va_fr - va_to))\n\n            p_to =\n                (g + g_to) * vm_to^2 +\n                (-g * tr - b * ti) / tm^2 * (vm_to * vm_fr * cos(va_to - va_fr)) +\n                (-b * tr + g * ti) / tm^2 * (vm_to * vm_fr * sin(va_to - va_fr))\n            q_to =\n                -(b + b_to) * vm_to^2 -\n                (-b * tr + g * ti) / tm^2 * (vm_to * vm_fr * cos(va_to - va_fr)) +\n                (-g * tr - b * ti) / tm^2 * (vm_to * vm_fr * sin(va_to - va_fr))\n        else\n            p_fr = NaN\n            q_fr = NaN\n\n            p_to = NaN\n            q_to = NaN\n        end\n\n        flows[i] = Dict(\"pf\" => p_fr, \"qf\" => q_fr, \"pt\" => p_to, \"qt\" => q_to)\n    end\n\n    return Dict{String, Any}(\"branch\" => flows)\nend\n\n\"assumes a vaild dc solution is included in the data and computes the branch flow values\"\nfunction calc_branch_flow_dc(data::Dict{String, <:Any})\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    @assert(!haskey(data, \"conductors\"))\n\n    if ismultinetwork(data)\n        nws = Dict{String, Any}()\n        for (i, nw_data) in data[\"nw\"]\n            nws[i] = _calc_branch_flow_dc(nw_data)\n        end\n        return Dict{String, Any}(\n            \"nw\" => nws,\n            \"per_unit\" => data[\"per_unit\"],\n            \"baseMVA\" => data[\"baseMVA\"],\n        )\n    else\n        flows = _calc_branch_flow_dc(data)\n        flows[\"per_unit\"] = data[\"per_unit\"]\n        flows[\"baseMVA\"] = data[\"baseMVA\"]\n        return flows\n    end\nend\n\n\"helper function for calc_branch_flow_dc\"\nfunction _calc_branch_flow_dc(data::Dict{String, <:Any})\n    vm = Dict(bus[\"index\"] => bus[\"vm\"] for (i, bus) in data[\"bus\"])\n    va = Dict(bus[\"index\"] => bus[\"va\"] for (i, bus) in data[\"bus\"])\n\n    flows = Dict{String, Any}()\n    for (i, branch) in data[\"branch\"]\n        if branch[\"br_status\"] != 0\n            f_bus = branch[\"f_bus\"]\n            t_bus = branch[\"t_bus\"]\n\n            g, b = calc_branch_y(branch)\n\n            p_fr = -b * (va[f_bus] - va[t_bus])\n        else\n            p_fr = NaN\n        end\n\n        flows[i] = Dict(\"pf\" => p_fr, \"qf\" => NaN, \"pt\" => -p_fr, \"qt\" => NaN)\n    end\n\n    return Dict{String, Any}(\"branch\" => flows)\nend\n\n\"assumes a vaild solution is included in the data and computes the power balance at each bus\"\nfunction calc_power_balance(data::Dict{String, <:Any})\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"]) # may not be strictly required\n    @assert(!haskey(data, \"conductors\"))\n\n    if ismultinetwork(data)\n        nws = Dict{String, Any}()\n        for (i, nw_data) in data[\"nw\"]\n            nws[i] = _calc_power_balance(nw_data)\n        end\n        return Dict{String, Any}(\n            \"nw\" => nws,\n            \"per_unit\" => data[\"per_unit\"],\n            \"baseMVA\" => data[\"baseMVA\"],\n        )\n    else\n        flows = _calc_power_balance(data)\n        flows[\"per_unit\"] = data[\"per_unit\"]\n        flows[\"baseMVA\"] = data[\"baseMVA\"]\n        return flows\n    end\nend\n\n\"helper function for calc_power_balance\"\nfunction _calc_power_balance(data::Dict{String, <:Any})\n    bus_values = Dict(bus[\"index\"] => Dict{String, Float64}() for (i, bus) in data[\"bus\"])\n    for (i, bus) in data[\"bus\"]\n        bvals = bus_values[bus[\"index\"]]\n        bvals[\"vm\"] = bus[\"vm\"]\n\n        bvals[\"pd\"] = 0.0\n        bvals[\"qd\"] = 0.0\n\n        bvals[\"gs\"] = 0.0\n        bvals[\"bs\"] = 0.0\n\n        bvals[\"ps\"] = 0.0\n        bvals[\"qs\"] = 0.0\n\n        bvals[\"pg\"] = 0.0\n        bvals[\"qg\"] = 0.0\n\n        bvals[\"p\"] = 0.0\n        bvals[\"q\"] = 0.0\n\n        bvals[\"psw\"] = 0.0\n        bvals[\"qsw\"] = 0.0\n\n        bvals[\"p_dc\"] = 0.0\n        bvals[\"q_dc\"] = 0.0\n    end\n\n    for (i, load) in data[\"load\"]\n        if load[\"status\"] != 0\n            bvals = bus_values[load[\"load_bus\"]]\n            bvals[\"pd\"] += load[\"pd\"]\n            bvals[\"qd\"] += load[\"qd\"]\n        end\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        if shunt[\"status\"] != 0\n            bvals = bus_values[shunt[\"shunt_bus\"]]\n            bvals[\"gs\"] += shunt[\"gs\"]\n            bvals[\"bs\"] += shunt[\"bs\"]\n        end\n    end\n\n    for (i, storage) in data[\"storage\"]\n        if storage[\"status\"] != 0\n            bvals = bus_values[storage[\"storage_bus\"]]\n            bvals[\"ps\"] += storage[\"ps\"]\n            bvals[\"qs\"] += storage[\"qs\"]\n        end\n    end\n\n    for (i, gen) in data[\"gen\"]\n        if gen[\"gen_status\"] != 0\n            bvals = bus_values[gen[\"gen_bus\"]]\n            bvals[\"pg\"] += gen[\"pg\"]\n            bvals[\"qg\"] += gen[\"qg\"]\n        end\n    end\n\n    for (i, switch) in data[\"switch\"]\n        if switch[\"status\"] != 0\n            bus_fr = switch[\"f_bus\"]\n            bvals_fr = bus_values[bus_fr]\n            bvals_fr[\"psw\"] += switch[\"psw\"]\n            bvals_fr[\"qsw\"] += switch[\"qsw\"]\n\n            bus_to = switch[\"t_bus\"]\n            bvals_to = bus_values[bus_to]\n            bvals_to[\"psw\"] -= switch[\"psw\"]\n            bvals_to[\"qsw\"] -= switch[\"qsw\"]\n        end\n    end\n\n    for (i, branch) in data[\"branch\"]\n        if branch[\"br_status\"] != 0\n            bus_fr = branch[\"f_bus\"]\n            bvals_fr = bus_values[bus_fr]\n            bvals_fr[\"p\"] += branch[\"pf\"]\n            bvals_fr[\"q\"] += branch[\"qf\"]\n\n            bus_to = branch[\"t_bus\"]\n            bvals_to = bus_values[bus_to]\n            bvals_to[\"p\"] += branch[\"pt\"]\n            bvals_to[\"q\"] += branch[\"qt\"]\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if dcline[\"br_status\"] != 0\n            bus_fr = dcline[\"f_bus\"]\n            bvals_fr = bus_values[bus_fr]\n            bvals_fr[\"p_dc\"] += dcline[\"pf\"]\n            bvals_fr[\"q_dc\"] += dcline[\"qf\"]\n\n            bus_to = dcline[\"t_bus\"]\n            bvals_to = bus_values[bus_to]\n            bvals_to[\"p_dc\"] += dcline[\"pt\"]\n            bvals_to[\"q_dc\"] += dcline[\"qt\"]\n        end\n    end\n\n    deltas = Dict{String, Any}()\n    for (i, bus) in data[\"bus\"]\n        if bus[\"bus_type\"] != 4\n            bvals = bus_values[bus[\"index\"]]\n            p_delta =\n                bvals[\"p\"] + bvals[\"p_dc\"] + bvals[\"psw\"] - bvals[\"pg\"] +\n                bvals[\"ps\"] +\n                bvals[\"pd\"] +\n                bvals[\"gs\"] * (bvals[\"vm\"]^2)\n            q_delta =\n                bvals[\"q\"] + bvals[\"q_dc\"] + bvals[\"qsw\"] - bvals[\"qg\"] +\n                bvals[\"qs\"] +\n                bvals[\"qd\"] - bvals[\"bs\"] * (bvals[\"vm\"]^2)\n        else\n            p_delta = NaN\n            q_delta = NaN\n        end\n\n        deltas[i] = Dict(\"p_delta\" => p_delta, \"q_delta\" => q_delta)\n    end\n\n    return Dict{String, Any}(\"bus\" => deltas)\nend\n\n\"\"\nfunction check_conductors(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        for (i, nw_data) in data[\"nw\"]\n            _check_conductors(nw_data)\n        end\n    else\n        _check_conductors(data)\n    end\nend\n\n\"\"\nfunction _check_conductors(data::Dict{String, <:Any})\n    if haskey(data, \"conductors\") && data[\"conductors\"] < 1\n        error(\"conductor values must be positive integers, given $(data[\"conductors\"])\")\n    end\nend\n\n\"checks that voltage angle differences are within 90 deg., if not tightens\"\nfunction correct_voltage_angle_differences!(data::Dict{String, <:Any}, default_pad = 1.0472)\n    if ismultinetwork(data)\n        error(\"check_voltage_angle_differences does not yet support multinetwork data\")\n    end\n\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    default_pad_deg = round(rad2deg(default_pad); digits = 2)\n\n    modified = Set{Int}()\n\n    for c in 1:get(data, \"conductors\", 1)\n        cnd_str = haskey(data, \"conductors\") ? \", conductor $(c)\" : \"\"\n        for (i, branch) in data[\"branch\"]\n            angmin = branch[\"angmin\"][c]\n            angmax = branch[\"angmax\"][c]\n\n            if angmin <= -pi / 2\n                @info \"this code only supports angmin values in -90 deg. to 90 deg., tightening the value on branch $i$(cnd_str) from $(rad2deg(angmin)) to -$(default_pad_deg) deg.\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    branch[\"angmin\"][c] = -default_pad\n                else\n                    branch[\"angmin\"] = -default_pad\n                end\n                push!(modified, branch[\"index\"])\n            end\n\n            if angmax >= pi / 2\n                @info \"this code only supports angmax values in -90 deg. to 90 deg., tightening the value on branch $i$(cnd_str) from $(rad2deg(angmax)) to $(default_pad_deg) deg.\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    branch[\"angmax\"][c] = default_pad\n                else\n                    branch[\"angmax\"] = default_pad\n                end\n                push!(modified, branch[\"index\"])\n            end\n\n            if angmin == 0.0 && angmax == 0.0\n                @info \"angmin and angmax values are 0, widening these values on branch $i$(cnd_str) to +/- $(default_pad_deg) deg.\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    branch[\"angmin\"][c] = -default_pad\n                    branch[\"angmax\"][c] = default_pad\n                else\n                    branch[\"angmin\"] = -default_pad\n                    branch[\"angmax\"] = default_pad\n                end\n                push!(modified, branch[\"index\"])\n            end\n        end\n    end\n\n    return modified\nend\n\n\"checks that each branch has a reasonable thermal rating-a, if not computes one\"\nfunction correct_thermal_limits!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"correct_thermal_limits! does not yet support multinetwork data\")\n    end\n\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    mva_base = data[\"baseMVA\"]\n\n    modified = Set{Int}()\n\n    branches = [branch for branch in values(data[\"branch\"])]\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    for branch in branches\n        if !haskey(branch, \"rate_a\")\n            if haskey(data, \"conductors\")\n                error(\"Multiconductor Not Supported in PowerSystems\")\n            else\n                branch[\"rate_a\"] = 0.0\n            end\n        end\n\n        for c in 1:get(data, \"conductors\", 1)\n            cnd_str = haskey(data, \"conductors\") ? \", conductor $(c)\" : \"\"\n            if branch[\"rate_a\"][c] <= 0.0\n                theta_max = max(abs(branch[\"angmin\"][c]), abs(branch[\"angmax\"][c]))\n\n                r = branch[\"br_r\"]\n                x = branch[\"br_x\"]\n                z = r + im * x\n                y = LinearAlgebra.pinv(z)\n                y_mag = abs.(y[c, c])\n\n                fr_vmax = data[\"bus\"][branch[\"f_bus\"]][\"vmax\"][c]\n                to_vmax = data[\"bus\"][branch[\"t_bus\"]][\"vmax\"][c]\n                m_vmax = max(fr_vmax, to_vmax)\n\n                c_max = sqrt(fr_vmax^2 + to_vmax^2 - 2 * fr_vmax * to_vmax * cos(theta_max))\n\n                new_rate = y_mag * m_vmax * c_max\n\n                if haskey(branch, \"c_rating_a\") && branch[\"c_rating_a\"][c] > 0.0\n                    new_rate = min(new_rate, branch[\"c_rating_a\"][c] * m_vmax)\n                end\n\n                @info \"this code only supports positive rate_a values, changing the value on branch $(branch[\"index\"])$(cnd_str) to $(round(mva_base*new_rate, digits=4))\" maxlog =\n                    PS_MAX_LOG\n\n                if haskey(data, \"conductors\")\n                    branch[\"rate_a\"][c] = new_rate\n                else\n                    branch[\"rate_a\"] = new_rate\n                end\n\n                push!(modified, branch[\"index\"])\n            end\n        end\n    end\n\n    return modified\nend\n\n\"checks that each branch has a reasonable current rating-a, if not computes one\"\nfunction correct_current_limits!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"correct_current_limits! does not yet support multinetwork data\")\n    end\n\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    mva_base = data[\"baseMVA\"]\n\n    modified = Set{Int}()\n\n    branches = [branch for branch in values(data[\"branch\"])]\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    for branch in branches\n        if !haskey(branch, \"c_rating_a\")\n            if haskey(data, \"conductors\")\n                error(\"Multiconductor Not Supported in PowerSystems\")\n            else\n                branch[\"c_rating_a\"] = 0.0\n            end\n        end\n\n        for c in 1:get(data, \"conductors\", 1)\n            cnd_str = haskey(data, \"conductors\") ? \", conductor $(c)\" : \"\"\n            if branch[\"c_rating_a\"][c] <= 0.0\n                theta_max = max(abs(branch[\"angmin\"][c]), abs(branch[\"angmax\"][c]))\n\n                r = branch[\"br_r\"]\n                x = branch[\"br_x\"]\n                z = r + im * x\n                y = LinearAlgebra.pinv(z)\n                y_mag = abs.(y[c, c])\n\n                fr_vmax = data[\"bus\"][string(branch[\"f_bus\"])][\"vmax\"][c]\n                to_vmax = data[\"bus\"][string(branch[\"t_bus\"])][\"vmax\"][c]\n                m_vmax = max(fr_vmax, to_vmax)\n\n                new_c_rating =\n                    y_mag *\n                    sqrt(fr_vmax^2 + to_vmax^2 - 2 * fr_vmax * to_vmax * cos(theta_max))\n\n                if haskey(branch, \"rate_a\") && branch[\"rate_a\"][c] > 0.0\n                    fr_vmin = data[\"bus\"][string(branch[\"f_bus\"])][\"vmin\"][c]\n                    to_vmin = data[\"bus\"][string(branch[\"t_bus\"])][\"vmin\"][c]\n                    vm_min = min(fr_vmin, to_vmin)\n\n                    new_c_rating = min(new_c_rating, branch[\"rate_a\"] / vm_min)\n                end\n\n                @info(\n                    \"this code only supports positive c_rating_a values, changing the value on branch $(branch[\"index\"])$(cnd_str) to $(mva_base*new_c_rating)\"\n                )\n                if haskey(data, \"conductors\")\n                    branch[\"c_rating_a\"][c] = new_c_rating\n                else\n                    branch[\"c_rating_a\"] = new_c_rating\n                end\n\n                push!(modified, branch[\"index\"])\n            end\n        end\n    end\n\n    return modified\nend\n\n\"checks that all parallel branches have the same orientation\"\nfunction correct_branch_directions!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"correct_branch_directions! does not yet support multinetwork data\")\n    end\n\n    modified = Set{Int}()\n\n    orientations = Set()\n    for (i, branch) in data[\"branch\"]\n        orientation = (branch[\"f_bus\"], branch[\"t_bus\"])\n        orientation_rev = (branch[\"t_bus\"], branch[\"f_bus\"])\n\n        if in(orientation_rev, orientations)\n            @info(\n                \"reversing the orientation of branch $(i) $(orientation) to be consistent with other parallel branches\"\n            )\n            branch_orginal = copy(branch)\n            branch[\"f_bus\"] = branch_orginal[\"t_bus\"]\n            branch[\"t_bus\"] = branch_orginal[\"f_bus\"]\n            branch[\"g_to\"] = branch_orginal[\"g_fr\"] .* branch_orginal[\"tap\"]' .^ 2\n            branch[\"b_to\"] = branch_orginal[\"b_fr\"] .* branch_orginal[\"tap\"]' .^ 2\n            branch[\"g_fr\"] = branch_orginal[\"g_to\"] ./ branch_orginal[\"tap\"]' .^ 2\n            branch[\"b_fr\"] = branch_orginal[\"b_to\"] ./ branch_orginal[\"tap\"]' .^ 2\n            branch[\"tap\"] = 1 ./ branch_orginal[\"tap\"]\n            branch[\"br_r\"] = branch_orginal[\"br_r\"] .* branch_orginal[\"tap\"]' .^ 2\n            branch[\"br_x\"] = branch_orginal[\"br_x\"] .* branch_orginal[\"tap\"]' .^ 2\n            branch[\"shift\"] = -branch_orginal[\"shift\"]\n            branch[\"angmin\"] = -branch_orginal[\"angmax\"]\n            branch[\"angmax\"] = -branch_orginal[\"angmin\"]\n\n            push!(modified, branch[\"index\"])\n        else\n            push!(orientations, orientation)\n        end\n    end\n\n    return modified\nend\n\n\"checks that all branches connect two distinct buses\"\nfunction check_branch_loops(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_branch_loops does not yet support multinetwork data\")\n    end\n\n    for (i, branch) in data[\"branch\"]\n        if branch[\"f_bus\"] == branch[\"t_bus\"]\n            throw(\n                DataFormatError(\n                    \"both sides of branch $(i) connect to bus $(branch[\"f_bus\"])\",\n                ),\n            )\n        end\n    end\nend\n\n\"checks that all buses are unique and other components link to valid buses\"\nfunction check_connectivity(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_connectivity does not yet support multinetwork data\")\n    end\n\n    bus_ids = Set(bus[\"index\"] for (i, bus) in data[\"bus\"])\n    @assert(length(bus_ids) == length(data[\"bus\"])) # if this is not true something very bad is going on\n\n    for (i, load) in data[\"load\"]\n        if !(load[\"load_bus\"] in bus_ids)\n            throw(DataFormatError(\"bus $(load[\"load_bus\"]) in load $(i) is not defined\"))\n        end\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        if !(shunt[\"shunt_bus\"] in bus_ids)\n            throw(DataFormatError(\"bus $(shunt[\"shunt_bus\"]) in shunt $(i) is not defined\"))\n        end\n    end\n\n    for (i, gen) in data[\"gen\"]\n        if !(gen[\"gen_bus\"] in bus_ids)\n            throw(DataFormatError(\"bus $(gen[\"gen_bus\"]) in generator $(i) is not defined\"))\n        end\n    end\n\n    for (i, strg) in data[\"storage\"]\n        if !(strg[\"storage_bus\"] in bus_ids)\n            throw(\n                DataFormatError(\n                    \"bus $(strg[\"storage_bus\"]) in storage unit $(i) is not defined\",\n                ),\n            )\n        end\n    end\n\n    if haskey(data, \"switch\")\n        for (i, switch) in data[\"switch\"]\n            if !(switch[\"f_bus\"] in bus_ids)\n                throw(\n                    DataFormatError(\n                        \"from bus $(branch[\"f_bus\"]) in switch $(i) is not defined\",\n                    ),\n                )\n            end\n\n            if !(switch[\"t_bus\"] in bus_ids)\n                throw(\n                    DataFormatError(\n                        \"to bus $(branch[\"t_bus\"]) in switch $(i) is not defined\",\n                    ),\n                )\n            end\n        end\n    end\n\n    for (i, branch) in data[\"branch\"]\n        if !(branch[\"f_bus\"] in bus_ids)\n            throw(\n                DataFormatError(\n                    \"from bus $(branch[\"f_bus\"]) in branch $(i) is not defined\",\n                ),\n            )\n        end\n\n        if !(branch[\"t_bus\"] in bus_ids)\n            throw(\n                DataFormatError(\"to bus $(branch[\"t_bus\"]) in branch $(i) is not defined\"),\n            )\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if !(dcline[\"f_bus\"] in bus_ids)\n            throw(\n                DataFormatError(\n                    \"from bus $(dcline[\"f_bus\"]) in dcline $(i) is not defined\",\n                ),\n            )\n        end\n\n        if !(dcline[\"t_bus\"] in bus_ids)\n            throw(\n                DataFormatError(\"to bus $(dcline[\"t_bus\"]) in dcline $(i) is not defined\"),\n            )\n        end\n    end\nend\n\n\"checks that active components are not connected to inactive buses, otherwise prints warnings\"\nfunction check_status(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_status does not yet support multinetwork data\")\n    end\n\n    active_bus_ids = Set(bus[\"index\"] for (i, bus) in data[\"bus\"] if bus[\"bus_type\"] != 4)\n\n    for (i, load) in data[\"load\"]\n        if load[\"status\"] != 0 && !(load[\"load_bus\"] in active_bus_ids)\n            @warn(\"active load $(i) is connected to inactive bus $(load[\"load_bus\"])\")\n        end\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        if shunt[\"status\"] != 0 && !(shunt[\"shunt_bus\"] in active_bus_ids)\n            @warn(\"active shunt $(i) is connected to inactive bus $(shunt[\"shunt_bus\"])\")\n        end\n    end\n\n    for (i, gen) in data[\"gen\"]\n        if gen[\"gen_status\"] != 0 && !(gen[\"gen_bus\"] in active_bus_ids)\n            @warn(\"active generator $(i) is connected to inactive bus $(gen[\"gen_bus\"])\")\n        end\n    end\n\n    for (i, strg) in data[\"storage\"]\n        if strg[\"status\"] != 0 && !(strg[\"storage_bus\"] in active_bus_ids)\n            @warn(\n                \"active storage unit $(i) is connected to inactive bus $(strg[\"storage_bus\"])\"\n            )\n        end\n    end\n\n    for (i, branch) in data[\"branch\"]\n        if branch[\"br_status\"] != 0 && !(branch[\"f_bus\"] in active_bus_ids)\n            @warn(\"active branch $(i) is connected to inactive bus $(branch[\"f_bus\"])\")\n        end\n\n        if branch[\"br_status\"] != 0 && !(branch[\"t_bus\"] in active_bus_ids)\n            @warn(\"active branch $(i) is connected to inactive bus $(branch[\"t_bus\"])\")\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if dcline[\"br_status\"] != 0 && !(dcline[\"f_bus\"] in active_bus_ids)\n            @warn(\"active dcline $(i) is connected to inactive bus $(dcline[\"f_bus\"])\")\n        end\n\n        if dcline[\"br_status\"] != 0 && !(dcline[\"t_bus\"] in active_bus_ids)\n            @warn(\"active dcline $(i) is connected to inactive bus $(dcline[\"t_bus\"])\")\n        end\n    end\nend\n\n\"checks that contains at least one refrence bus\"\nfunction check_reference_bus(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_reference_bus does not yet support multinetwork data\")\n    end\n\n    ref_buses = Dict{Int, Any}()\n    for (k, v) in data[\"bus\"]\n        if v[\"bus_type\"] == 3\n            ref_buses[k] = v\n        end\n    end\n\n    if length(ref_buses) == 0\n        if length(data[\"gen\"]) > 0\n            big_gen = _biggest_generator(data[\"gen\"])\n            gen_bus = big_gen[\"gen_bus\"]\n            ref_bus = data[\"bus\"][gen_bus]\n            ref_bus[\"bus_type\"] = 3\n            @warn(\n                \"no reference bus found, setting bus $(gen_bus) as reference based on generator $(big_gen[\"index\"])\"\n            )\n        else\n            (bus_item, state) = Base.iterate(values(data[\"bus\"]))\n            bus_item[\"bus_type\"] = 3\n            @warn(\n                \"no reference bus found, setting bus $(bus_item[\"index\"]) as reference\"\n            )\n        end\n    end\n    return\nend\n\n\"find the largest active generator in the network\"\nfunction _biggest_generator(gens)\n    biggest_gen = nothing\n    biggest_value = -Inf\n    for (k, gen) in gens\n        pmax = maximum(gen[\"pmax\"])\n        if pmax > biggest_value\n            biggest_gen = gen\n            biggest_value = pmax\n        end\n    end\n    @assert(biggest_gen !== nothing)\n    return biggest_gen\nend\n\n\"\"\"\nchecks that each branch has a reasonable transformer parameters\n\nthis is important because setting tap == 0.0 leads to NaN computations, which are hard to debug\n\"\"\"\nfunction correct_transformer_parameters!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_transformer_parameters does not yet support multinetwork data\")\n    end\n\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n\n    modified = Set{Int}()\n\n    for (i, branch) in data[\"branch\"]\n        if !haskey(branch, \"tap\")\n            @info \"branch found without tap value, setting a tap to 1.0\" maxlog = PS_MAX_LOG\n            if haskey(data, \"conductors\")\n                error(\"Multiconductor Not Supported in PowerSystems\")\n            else\n                branch[\"tap\"] = 1.0\n            end\n            push!(modified, branch[\"index\"])\n        else\n            for c in 1:get(data, \"conductors\", 1)\n                cnd_str = haskey(data, \"conductors\") ? \" on conductor $(c)\" : \"\"\n                if branch[\"tap\"][c] <= 0.0\n                    @info(\n                        \"branch found with non-positive tap value of $(branch[\"tap\"][c]), setting a tap to 1.0$(cnd_str)\"\n                    )\n                    if haskey(data, \"conductors\")\n                        branch[\"tap\"][c] = 1.0\n                    else\n                        branch[\"tap\"] = 1.0\n                    end\n                    push!(modified, branch[\"index\"])\n                end\n            end\n        end\n        if !haskey(branch, \"shift\")\n            @info(\"branch found without shift value, setting a shift to 0.0\")\n            if haskey(data, \"conductors\")\n                error(\"Multiconductor Not Supported in PowerSystems\")\n            else\n                branch[\"shift\"] = 0.0\n            end\n            push!(modified, branch[\"index\"])\n        end\n    end\n\n    return modified\nend\n\n\"\"\"\nchecks that each storage unit has a reasonable parameters\n\"\"\"\nfunction check_storage_parameters(data::Dict{String, Any})\n    if ismultinetwork(data)\n        error(\"check_storage_parameters does not yet support multinetwork data\")\n    end\n\n    for (i, strg) in data[\"storage\"]\n        if strg[\"energy\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive energy level $(strg[\"energy\"])\",\n                ),\n            )\n        end\n        if strg[\"energy_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive energy rating $(strg[\"energy_rating\"])\",\n                ),\n            )\n        end\n        if strg[\"charge_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive charge rating $(strg[\"energy_rating\"])\",\n                ),\n            )\n        end\n        if strg[\"discharge_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive discharge rating $(strg[\"energy_rating\"])\",\n                ),\n            )\n        end\n\n        if strg[\"r\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive resistance $(strg[\"r\"])\",\n                ),\n            )\n        end\n        if strg[\"x\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive reactance $(strg[\"x\"])\",\n                ),\n            )\n        end\n        if haskey(strg, \"thermal_rating\") && strg[\"thermal_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive thermal rating $(strg[\"thermal_rating\"])\",\n                ),\n            )\n        end\n        if haskey(strg, \"current_rating\") && strg[\"current_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive current rating $(strg[\"thermal_rating\"])\",\n                ),\n            )\n        end\n        if !isapprox(strg[\"x\"], 0.0; atol = 1e-6, rtol = 1e-6)\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-zero reactance $(strg[\"x\"]), which is currently ignored\",\n                ),\n            )\n        end\n\n        if strg[\"charge_efficiency\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive charge efficiency of $(strg[\"charge_efficiency\"])\",\n                ),\n            )\n        end\n        if strg[\"charge_efficiency\"] <= 0.0 || strg[\"charge_efficiency\"] > 1.0\n            @info \"storage unit $(strg[\"index\"]) charge efficiency of $(strg[\"charge_efficiency\"]) is out of the valid range (0.0. 1.0]\" maxlog =\n                PS_MAX_LOG\n        end\n        if strg[\"discharge_efficiency\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"storage unit $(strg[\"index\"]) has a non-positive discharge efficiency of $(strg[\"discharge_efficiency\"])\",\n                ),\n            )\n        end\n        if strg[\"discharge_efficiency\"] <= 0.0 || strg[\"discharge_efficiency\"] > 1.0\n            @info \"storage unit $(strg[\"index\"]) discharge efficiency of $(strg[\"discharge_efficiency\"]) is out of the valid range (0.0. 1.0]\" maxlog =\n                PS_MAX_LOG\n        end\n\n        if strg[\"p_loss\"] > 0.0 && strg[\"energy\"] <= 0.0\n            @info \"storage unit $(strg[\"index\"]) has positive active power losses but zero initial energy.  This can lead to model infeasiblity.\" maxlog =\n                PS_MAX_LOG\n        end\n        if strg[\"q_loss\"] > 0.0 && strg[\"energy\"] <= 0.0\n            @info \"storage unit $(strg[\"index\"]) has positive reactive power losses but zero initial energy.  This can lead to model infeasiblity.\" maxlog =\n                PS_MAX_LOG\n        end\n    end\nend\n\n\"\"\"\nchecks that each switch has a reasonable parameters\n\"\"\"\nfunction check_switch_parameters(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_switch_parameters does not yet support multinetwork data\")\n    end\n\n    for (i, switch) in data[\"switch\"]\n        if switch[\"state\"] <= 0.0 &&\n           (!isapprox(switch[\"psw\"], 0.0) || !isapprox(switch[\"qsw\"], 0.0))\n            @info \"switch $(switch[\"index\"]) is open with non-zero power values $(switch[\"psw\"]), $(switch[\"qsw\"])\" maxlog =\n                PS_MAX_LOG\n        end\n        if haskey(switch, \"thermal_rating\") && switch[\"thermal_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"switch $(switch[\"index\"]) has a non-positive thermal_rating $(switch[\"thermal_rating\"])\",\n                ),\n            )\n        end\n        if haskey(switch, \"current_rating\") && switch[\"current_rating\"] < 0.0\n            throw(\n                DataFormatError(\n                    \"switch $(switch[\"index\"]) has a non-positive current_rating $(switch[\"current_rating\"])\",\n                ),\n            )\n        end\n    end\nend\n\n\"checks that parameters for dc lines are reasonable\"\nfunction correct_dcline_limits!(data::Dict{String, Any})\n    if ismultinetwork(data)\n        error(\"check_dcline_limits does not yet support multinetwork data\")\n    end\n\n    @assert(\"per_unit\" in keys(data) && data[\"per_unit\"])\n    mva_base = data[\"baseMVA\"]\n\n    modified = Set{Int}()\n\n    for c in 1:get(data, \"conductors\", 1)\n        cnd_str = haskey(data, \"conductors\") ? \", conductor $(c)\" : \"\"\n        for (i, dcline) in data[\"dcline\"]\n            if dcline[\"loss0\"][c] < 0.0\n                new_rate = 0.0\n                @info \"this code only supports positive loss0 values, changing the value on dcline $(dcline[\"index\"])$(cnd_str) from $(mva_base*dcline[\"loss0\"][c]) to $(mva_base*new_rate)\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    dcline[\"loss0\"][c] = new_rate\n                else\n                    dcline[\"loss0\"] = new_rate\n                end\n                push!(modified, dcline[\"index\"])\n            end\n\n            if dcline[\"loss0\"][c] >=\n               dcline[\"pmaxf\"][c] * (1 - dcline[\"loss1\"][c]) + dcline[\"pmaxt\"][c]\n                new_rate = 0.0\n                @info \"this code only supports loss0 values which are consistent with the line flow bounds, changing the value on dcline $(dcline[\"index\"])$(cnd_str) from $(mva_base*dcline[\"loss0\"][c]) to $(mva_base*new_rate)\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    dcline[\"loss0\"][c] = new_rate\n                else\n                    dcline[\"loss0\"] = new_rate\n                end\n                push!(modified, dcline[\"index\"])\n            end\n\n            if dcline[\"loss1\"][c] < 0.0\n                new_rate = 0.0\n                @info \"this code only supports positive loss1 values, changing the value on dcline $(dcline[\"index\"])$(cnd_str) from $(dcline[\"loss1\"][c]) to $(new_rate)\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    dcline[\"loss1\"][c] = new_rate\n                else\n                    dcline[\"loss1\"] = new_rate\n                end\n                push!(modified, dcline[\"index\"])\n            end\n\n            if dcline[\"loss1\"][c] >= 1.0\n                new_rate = 0.0\n                @info \"this code only supports loss1 values < 1, changing the value on dcline $(dcline[\"index\"])$(cnd_str) from $(dcline[\"loss1\"][c]) to $(new_rate)\" maxlog =\n                    PS_MAX_LOG\n                if haskey(data, \"conductors\")\n                    dcline[\"loss1\"][c] = new_rate\n                else\n                    dcline[\"loss1\"] = new_rate\n                end\n                push!(modified, dcline[\"index\"])\n            end\n\n            if dcline[\"pmint\"][c] < 0.0 && dcline[\"loss1\"][c] > 0.0\n                #new_rate = 0.0\n                @info \"the dc line model is not meant to be used bi-directionally when loss1 > 0, be careful interpreting the results as the dc line losses can now be negative. change loss1 to 0 to avoid this warning\" maxlog =\n                    PS_MAX_LOG\n                #dcline[\"loss0\"] = new_rate\n            end\n        end\n    end\n\n    return modified\nend\n\n\"throws warnings if generator and dc line voltage setpoints are not consistent with the bus voltage setpoint\"\nfunction check_voltage_setpoints(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_voltage_setpoints does not yet support multinetwork data\")\n    end\n\n    for c in 1:get(data, \"conductors\", 1)\n        cnd_str = haskey(data, \"conductors\") ? \"conductor $(c) \" : \"\"\n        for (i, gen) in data[\"gen\"]\n            bus_id = gen[\"gen_bus\"]\n            bus = data[\"bus\"][bus_id]\n            if gen[\"vg\"][c] != bus[\"vm\"][c]\n                @info \"the $(cnd_str)voltage setpoint on generator $(i) does not match the value at bus $(bus_id)\" maxlog =\n                    PS_MAX_LOG\n            end\n        end\n\n        for (i, dcline) in data[\"dcline\"]\n            bus_fr_id = dcline[\"f_bus\"]\n            bus_to_id = dcline[\"t_bus\"]\n\n            bus_fr = data[\"bus\"][bus_fr_id]\n            bus_to = data[\"bus\"][bus_to_id]\n\n            if dcline[\"vf\"][c] != bus_fr[\"vm\"][c]\n                @info(\n                    \"the $(cnd_str)from bus voltage setpoint on dc line $(i) does not match the value at bus $(bus_fr_id)\"\n                )\n            end\n\n            if dcline[\"vt\"][c] != bus_to[\"vm\"][c]\n                @info(\n                    \"the $(cnd_str)to bus voltage setpoint on dc line $(i) does not match the value at bus $(bus_to_id)\"\n                )\n            end\n        end\n    end\nend\n\n\"throws warnings if cost functions are malformed\"\nfunction correct_cost_functions!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        error(\"check_cost_functions does not yet support multinetwork data\")\n    end\n\n    modified_gen = Set{Int}()\n    for (i, gen) in data[\"gen\"]\n        if _correct_cost_function!(i, gen, \"generator\")\n            push!(modified_gen, gen[\"index\"])\n        end\n    end\n\n    modified_dcline = Set{Int}()\n    for (i, dcline) in data[\"dcline\"]\n        if _correct_cost_function!(i, dcline, \"dcline\")\n            push!(modified_dcline, dcline[\"index\"])\n        end\n    end\n\n    return (modified_gen, modified_dcline)\nend\n\n\"\"\nfunction _correct_cost_function!(id, comp, type_name)\n    modified = false\n\n    if \"model\" in keys(comp) && \"cost\" in keys(comp)\n        if comp[\"model\"] == 1\n            if length(comp[\"cost\"]) != 2 * comp[\"ncost\"]\n                error(\n                    \"ncost of $(comp[\"ncost\"]) not consistent with $(length(comp[\"cost\"])) cost values on $(type_name) $(id)\",\n                )\n            end\n            if length(comp[\"cost\"]) < 4\n                error(\n                    \"cost includes $(comp[\"ncost\"]) points, but at least two points are required on $(type_name) $(id)\",\n                )\n            end\n\n            modified = _remove_pwl_cost_duplicates!(id, comp, type_name)\n\n            for i in 3:2:length(comp[\"cost\"])\n                if comp[\"cost\"][i - 2] >= comp[\"cost\"][i]\n                    error(\"non-increasing x values in pwl cost model on $(type_name) $(id)\")\n                end\n            end\n            if \"pmin\" in keys(comp) && \"pmax\" in keys(comp)\n                pmin = sum(comp[\"pmin\"]) # sum supports multi-conductor case\n                pmax = sum(comp[\"pmax\"])\n                for i in 3:2:length(comp[\"cost\"])\n                    if comp[\"cost\"][i] < pmin || comp[\"cost\"][i] > pmax\n                        @info(\n                            \"pwl x value $(comp[\"cost\"][i]) is outside the bounds $(pmin)-$(pmax) on $(type_name) $(id)\"\n                        )\n                    end\n                end\n            end\n            modified |= _simplify_pwl_cost!(id, comp, type_name)\n        elseif comp[\"model\"] == 2\n            if length(comp[\"cost\"]) != comp[\"ncost\"]\n                error(\n                    \"ncost of $(comp[\"ncost\"]) not consistent with $(length(comp[\"cost\"])) cost values on $(type_name) $(id)\",\n                )\n            end\n        else\n            @info \"Unknown cost model of type $(comp[\"model\"]) on $(type_name) $(id)\" maxlog =\n                PS_MAX_LOG\n        end\n    end\n\n    return modified\nend\n\n\"checks that each point in the a pwl function is unique, simplifies the function if duplicates appear\"\nfunction _remove_pwl_cost_duplicates!(id, comp, type_name, tolerance = 1e-2)\n    @assert comp[\"model\"] == 1\n\n    unique_costs = Float64[comp[\"cost\"][1], comp[\"cost\"][2]]\n    for i in 3:2:length(comp[\"cost\"])\n        x1 = unique_costs[end - 1]\n        y1 = unique_costs[end]\n        x2 = comp[\"cost\"][i + 0]\n        y2 = comp[\"cost\"][i + 1]\n        if !(isapprox(x1, x2) && isapprox(y1, y2))\n            push!(unique_costs, x2)\n            push!(unique_costs, y2)\n        end\n    end\n\n    # in the event that all of the given points are the same\n    # this code ensures that at least two of the points remain\n    if length(unique_costs) <= 2\n        push!(unique_costs, comp[\"cost\"][end - 1])\n        push!(unique_costs, comp[\"cost\"][end])\n    end\n\n    if length(unique_costs) < length(comp[\"cost\"])\n        @info \"removing duplicate points from pwl cost on $(type_name) $(id), $(comp[\"cost\"]) -> $(unique_costs)\" maxlog =\n            PS_MAX_LOG\n        comp[\"cost\"] = unique_costs\n        comp[\"ncost\"] = length(unique_costs) / 2\n        return true\n    end\n\n    return false\nend\n\n\"checks the slope of each segment in a pwl function, simplifies the function if the slope changes is below a tolerance\"\nfunction _simplify_pwl_cost!(id, comp, type_name, tolerance = 1e-2)\n    @assert comp[\"model\"] == 1\n\n    slopes = Float64[]\n    smpl_cost = Float64[]\n    prev_slope = nothing\n\n    x2, y2 = 0.0, 0.0\n\n    for i in 3:2:length(comp[\"cost\"])\n        x1 = comp[\"cost\"][i - 2]\n        y1 = comp[\"cost\"][i - 1]\n        x2 = comp[\"cost\"][i - 0]\n        y2 = comp[\"cost\"][i + 1]\n\n        m = (y2 - y1) / (x2 - x1)\n\n        if prev_slope === nothing || (abs(prev_slope - m) > tolerance)\n            push!(smpl_cost, x1)\n            push!(smpl_cost, y1)\n            prev_slope = m\n        end\n\n        push!(slopes, m)\n    end\n\n    push!(smpl_cost, x2)\n    push!(smpl_cost, y2)\n\n    if length(smpl_cost) < length(comp[\"cost\"])\n        @info \"simplifying pwl cost on $(type_name) $(id), $(comp[\"cost\"]) -> $(smpl_cost)\" maxlog =\n            PS_MAX_LOG\n        comp[\"cost\"] = smpl_cost\n        comp[\"ncost\"] = length(smpl_cost) / 2\n        return true\n    end\n    return false\nend\n\n\"trims zeros from higher order cost terms\"\nfunction simplify_cost_terms!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        networks = data[\"nw\"]\n    else\n        networks = [(\"0\", data)]\n    end\n\n    modified_gen = Set{Int}()\n    modified_dcline = Set{Int}()\n\n    for (i, network) in networks\n        if haskey(network, \"gen\")\n            for (i, gen) in network[\"gen\"]\n                if haskey(gen, \"model\") && gen[\"model\"] == 2\n                    ncost = length(gen[\"cost\"])\n                    for j in 1:ncost\n                        if gen[\"cost\"][1] == 0.0\n                            gen[\"cost\"] = gen[\"cost\"][2:end]\n                        else\n                            break\n                        end\n                    end\n                    if length(gen[\"cost\"]) != ncost\n                        gen[\"ncost\"] = length(gen[\"cost\"])\n                        @info \"removing $(ncost - gen[\"ncost\"]) cost terms from generator $(i): $(gen[\"cost\"])\" maxlog =\n                            PS_MAX_LOG\n                        push!(modified_gen, gen[\"index\"])\n                    end\n                end\n            end\n        end\n\n        if haskey(network, \"dcline\")\n            for (i, dcline) in network[\"dcline\"]\n                if haskey(dcline, \"model\") && dcline[\"model\"] == 2\n                    ncost = length(dcline[\"cost\"])\n                    for j in 1:ncost\n                        if dcline[\"cost\"][1] == 0.0\n                            dcline[\"cost\"] = dcline[\"cost\"][2:end]\n                        else\n                            break\n                        end\n                    end\n                    if length(dcline[\"cost\"]) != ncost\n                        dcline[\"ncost\"] = length(dcline[\"cost\"])\n                        @info \"removing $(ncost - dcline[\"ncost\"]) cost terms from dcline $(i): $(dcline[\"cost\"])\" maxlog =\n                            PS_MAX_LOG\n                        push!(modified_dcline, dcline[\"index\"])\n                    end\n                end\n            end\n        end\n    end\n\n    return (modified_gen, modified_dcline)\nend\n\n\"ensures all polynomial costs functions have the same number of terms\"\nfunction standardize_cost_terms!(data::Dict{String, <:Any}; order = -1)\n    comp_max_order = 1\n\n    if ismultinetwork(data)\n        networks = data[\"nw\"]\n    else\n        networks = [(\"0\", data)]\n    end\n\n    for (i, network) in networks\n        if haskey(network, \"gen\")\n            for (i, gen) in network[\"gen\"]\n                if haskey(gen, \"model\") && gen[\"model\"] == 2\n                    max_nonzero_index = 1\n                    for i in 1:length(gen[\"cost\"])\n                        max_nonzero_index = i\n                        if gen[\"cost\"][i] != 0.0\n                            break\n                        end\n                    end\n\n                    max_oder = length(gen[\"cost\"]) - max_nonzero_index + 1\n\n                    comp_max_order = max(comp_max_order, max_oder)\n                end\n            end\n        end\n\n        if haskey(network, \"dcline\")\n            for (i, dcline) in network[\"dcline\"]\n                if haskey(dcline, \"model\") && dcline[\"model\"] == 2\n                    max_nonzero_index = 1\n                    for i in 1:length(dcline[\"cost\"])\n                        max_nonzero_index = i\n                        if dcline[\"cost\"][i] != 0.0\n                            break\n                        end\n                    end\n\n                    max_oder = length(dcline[\"cost\"]) - max_nonzero_index + 1\n\n                    comp_max_order = max(comp_max_order, max_oder)\n                end\n            end\n        end\n    end\n\n    if comp_max_order <= order + 1\n        comp_max_order = order + 1\n    else\n        if order != -1 # if not the default\n            @info(\n                \"a standard cost order of $(order) was requested but the given data requires an order of at least $(comp_max_order-1)\"\n            )\n        end\n    end\n\n    for (i, network) in networks\n        if haskey(network, \"gen\")\n            _standardize_cost_terms!(network[\"gen\"], comp_max_order, \"generator\")\n        end\n        if haskey(network, \"dcline\")\n            _standardize_cost_terms!(network[\"dcline\"], comp_max_order, \"dcline\")\n        end\n    end\nend\n\n\"ensures all polynomial costs functions have at exactly comp_order terms\"\nfunction _standardize_cost_terms!(\n    components::Dict{String, <:Any},\n    comp_order::Int,\n    cost_comp_name::String,\n)\n    modified = Set{Int}()\n    for (i, comp) in components\n        if haskey(comp, \"model\") && comp[\"model\"] == 2 && length(comp[\"cost\"]) != comp_order\n            std_cost = [0.0 for i in 1:comp_order]\n            current_cost = reverse(comp[\"cost\"])\n            #println(\"gen cost: $(comp[\"cost\"])\")\n            for i in 1:min(comp_order, length(current_cost))\n                std_cost[i] = current_cost[i]\n            end\n            comp[\"cost\"] = reverse(std_cost)\n            comp[\"ncost\"] = comp_order\n            #println(\"std gen cost: $(comp[\"cost\"])\")\n\n            @info \"Updated $(cost_comp_name) $(comp[\"index\"]) cost function with order $(length(current_cost)) to a function of order $(comp_order): $(comp[\"cost\"])\" maxlog =\n                PS_MAX_LOG\n            push!(modified, comp[\"index\"])\n        end\n    end\n    return modified\nend\n\n\"\"\"\nfinds active network buses and branches that are not necessary for the\ncomputation and sets their status to off.\n\nWorks on a PowerModels data dict, so that a it can be used without a GenericPowerModel object\n\nWarning: this implementation has quadratic complexity, in the worst case\n\"\"\"\nfunction propagate_topology_status!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        for (i, nw_data) in data[\"nw\"]\n            _propagate_topology_status!(nw_data)\n        end\n    else\n        _propagate_topology_status!(data)\n    end\nend\n\n\"\"\nfunction _propagate_topology_status!(data::Dict{String, <:Any})\n    buses = Dict(bus[\"bus_i\"] => bus for (i, bus) in data[\"bus\"])\n\n    for (i, load) in data[\"load\"]\n        if load[\"status\"] != 0 && all(load[\"pd\"] .== 0.0) && all(load[\"qd\"] .== 0.0)\n            @info(\"deactivating load $(load[\"index\"]) due to zero pd and qd\")\n            load[\"status\"] = 0\n        end\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        if shunt[\"status\"] != 0 && all(shunt[\"gs\"] .== 0.0) && all(shunt[\"bs\"] .== 0.0)\n            @info(\"deactivating shunt $(shunt[\"index\"]) due to zero gs and bs\")\n            shunt[\"status\"] = 0\n        end\n    end\n\n    # compute what active components are incident to each bus\n    incident_load = bus_load_lookup(data[\"load\"], data[\"bus\"])\n    incident_active_load = Dict()\n    for (i, load_list) in incident_load\n        incident_active_load[i] = [load for load in load_list if load[\"status\"] != 0]\n    end\n\n    incident_shunt = bus_shunt_lookup(data[\"shunt\"], data[\"bus\"])\n    incident_active_shunt = Dict()\n    for (i, shunt_list) in incident_shunt\n        incident_active_shunt[i] = [shunt for shunt in shunt_list if shunt[\"status\"] != 0]\n    end\n\n    incident_gen = bus_gen_lookup(data[\"gen\"], data[\"bus\"])\n    incident_active_gen = Dict()\n    for (i, gen_list) in incident_gen\n        incident_active_gen[i] = [gen for gen in gen_list if gen[\"gen_status\"] != 0]\n    end\n\n    incident_strg = bus_storage_lookup(data[\"storage\"], data[\"bus\"])\n    incident_active_strg = Dict()\n    for (i, strg_list) in incident_strg\n        incident_active_strg[i] = [strg for strg in strg_list if strg[\"status\"] != 0]\n    end\n\n    incident_branch = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, branch) in data[\"branch\"]\n        push!(incident_branch[branch[\"f_bus\"]], branch)\n        push!(incident_branch[branch[\"t_bus\"]], branch)\n    end\n\n    incident_dcline = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, dcline) in data[\"dcline\"]\n        push!(incident_dcline[dcline[\"f_bus\"]], dcline)\n        push!(incident_dcline[dcline[\"t_bus\"]], dcline)\n    end\n\n    incident_switch = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, switch) in data[\"switch\"]\n        push!(incident_switch[switch[\"f_bus\"]], switch)\n        push!(incident_switch[switch[\"t_bus\"]], switch)\n    end\n\n    revised = false\n\n    for (i, branch) in data[\"branch\"]\n        if branch[\"br_status\"] != 0\n            f_bus = buses[branch[\"f_bus\"]]\n            t_bus = buses[branch[\"t_bus\"]]\n\n            if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                @info \"deactivating branch $(i):($(branch[\"f_bus\"]),$(branch[\"t_bus\"])) due to connecting bus status\" maxlog =\n                    PS_MAX_LOG\n                branch[\"br_status\"] = 0\n                revised = true\n            end\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if dcline[\"br_status\"] != 0\n            f_bus = buses[dcline[\"f_bus\"]]\n            t_bus = buses[dcline[\"t_bus\"]]\n\n            if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                @info \"deactivating dcline $(i):($(dcline[\"f_bus\"]),$(dcline[\"t_bus\"])) due to connecting bus status\" maxlog =\n                    PS_MAX_LOG\n                dcline[\"br_status\"] = 0\n                revised = true\n            end\n        end\n    end\n\n    for (i, switch) in data[\"switch\"]\n        if switch[\"status\"] != 0\n            f_bus = buses[switch[\"f_bus\"]]\n            t_bus = buses[switch[\"t_bus\"]]\n\n            if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                @info \"deactivating switch $(i):($(switch[\"f_bus\"]),$(switch[\"t_bus\"])) due to connecting bus status\" maxlog =\n                    PS_MAX_LOG\n                switch[\"status\"] = 0\n                revised = true\n            end\n        end\n    end\n\n    for (i, bus) in buses\n        if bus[\"bus_type\"] == 4\n            for load in incident_active_load[i]\n                if load[\"status\"] != 0\n                    @info \"deactivating load $(load[\"index\"]) due to inactive bus $(i)\" maxlog =\n                        PS_MAX_LOG\n                    load[\"status\"] = 0\n                    revised = true\n                end\n            end\n\n            for shunt in incident_active_shunt[i]\n                if shunt[\"status\"] != 0\n                    @info \"deactivating shunt $(shunt[\"index\"]) due to inactive bus $(i)\" maxlog =\n                        PS_MAX_LOG\n                    shunt[\"status\"] = 0\n                    revised = true\n                end\n            end\n\n            for gen in incident_active_gen[i]\n                if gen[\"gen_status\"] != 0\n                    @info \"deactivating generator $(gen[\"index\"]) due to inactive bus $(i)\" maxlog =\n                        PS_MAX_LOG\n                    gen[\"gen_status\"] = 0\n                    revised = true\n                end\n            end\n\n            for strg in incident_active_strg[i]\n                if strg[\"status\"] != 0\n                    @info \"deactivating storage $(strg[\"index\"]) due to inactive bus $(i)\" maxlog =\n                        PS_MAX_LOG\n                    strg[\"status\"] = 0\n                    revised = true\n                end\n            end\n        end\n    end\n\n    return revised\nend\n\n\"\"\"\nremoves buses with single branch connections and without any other attached\ncomponents.  Also removes connected components without suffuceint generation\nor loads.\n\nalso deactivates 0 valued loads and shunts.\n\"\"\"\nfunction deactivate_isolated_components!(data::Dict{String, <:Any})\n    revised = false\n    pm_data = get_pm_data(data)\n\n    if _IM.ismultinetwork(pm_data)\n        for (i, pm_nw_data) in pm_data[\"nw\"]\n            revised |= _deactivate_isolated_components!(pm_nw_data)\n        end\n    else\n        revised = _deactivate_isolated_components!(pm_data)\n    end\n\n    return revised\nend\n\n\"\"\nfunction _deactivate_isolated_components!(data::Dict{String, <:Any})\n    buses = Dict(bus[\"bus_i\"] => bus for (i, bus) in data[\"bus\"])\n\n    revised = false\n\n    for (i, load) in data[\"load\"]\n        if load[\"status\"] != 0 && all(load[\"pd\"] .== 0.0) && all(load[\"qd\"] .== 0.0)\n            @info \"deactivating load $(load[\"index\"]) due to zero pd and qd\" maxlog =\n                PS_MAX_LOG\n            load[\"status\"] = 0\n            revised = true\n        end\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        if shunt[\"status\"] != 0 && all(shunt[\"gs\"] .== 0.0) && all(shunt[\"bs\"] .== 0.0)\n            @info \"deactivating shunt $(shunt[\"index\"]) due to zero gs and bs\" maxlog =\n                PS_MAX_LOG\n            shunt[\"status\"] = 0\n            revised = true\n        end\n    end\n\n    # compute what active components are incident to each bus\n    incident_load = bus_load_lookup(data[\"load\"], data[\"bus\"])\n    incident_active_load = Dict()\n    for (i, load_list) in incident_load\n        incident_active_load[i] = [load for load in load_list if load[\"status\"] != 0]\n    end\n\n    incident_shunt = bus_shunt_lookup(data[\"shunt\"], data[\"bus\"])\n    incident_active_shunt = Dict()\n    for (i, shunt_list) in incident_shunt\n        incident_active_shunt[i] = [shunt for shunt in shunt_list if shunt[\"status\"] != 0]\n    end\n\n    incident_gen = bus_gen_lookup(data[\"gen\"], data[\"bus\"])\n    incident_active_gen = Dict()\n    for (i, gen_list) in incident_gen\n        incident_active_gen[i] = [gen for gen in gen_list if gen[\"gen_status\"] != 0]\n    end\n\n    incident_strg = bus_storage_lookup(data[\"storage\"], data[\"bus\"])\n    incident_active_strg = Dict()\n    for (i, strg_list) in incident_strg\n        incident_active_strg[i] = [strg for strg in strg_list if strg[\"status\"] != 0]\n    end\n\n    incident_branch = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, branch) in data[\"branch\"]\n        push!(incident_branch[branch[\"f_bus\"]], branch)\n        push!(incident_branch[branch[\"t_bus\"]], branch)\n    end\n\n    incident_dcline = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, dcline) in data[\"dcline\"]\n        push!(incident_dcline[dcline[\"f_bus\"]], dcline)\n        push!(incident_dcline[dcline[\"t_bus\"]], dcline)\n    end\n\n    incident_switch = Dict(bus[\"bus_i\"] => [] for (i, bus) in data[\"bus\"])\n    for (i, switch) in data[\"switch\"]\n        push!(incident_switch[switch[\"f_bus\"]], switch)\n        push!(incident_switch[switch[\"t_bus\"]], switch)\n    end\n\n    changed = true\n    while changed\n        changed = false\n\n        for (i, bus) in buses\n            if bus[\"bus_type\"] != 4\n                incident_active_edge = 0\n                if length(incident_branch[i]) +\n                   length(incident_dcline[i]) +\n                   length(incident_switch[i]) > 0\n                    incident_branch_count =\n                        sum([0; [branch[\"br_status\"] for branch in incident_branch[i]]])\n                    incident_dcline_count =\n                        sum([0; [dcline[\"br_status\"] for dcline in incident_dcline[i]]])\n                    incident_switch_count =\n                        sum([0; [switch[\"status\"] for switch in incident_switch[i]]])\n                    incident_active_edge =\n                        incident_branch_count +\n                        incident_dcline_count +\n                        incident_switch_count\n                end\n\n                if incident_active_edge == 1 &&\n                   length(incident_active_gen[i]) == 0 &&\n                   length(incident_active_load[i]) == 0 &&\n                   length(incident_active_shunt[i]) == 0 &&\n                   length(incident_active_strg[i]) == 0\n                    @info \"deactivating bus $(i) due to dangling bus without generation, load, or storage\" maxlog =\n                        PS_MAX_LOG\n                    bus[\"bus_type\"] = 4\n                    revised = true\n                    changed = true\n                end\n            end\n        end\n\n        if changed\n            for (i, branch) in data[\"branch\"]\n                if branch[\"br_status\"] != 0\n                    f_bus = buses[branch[\"f_bus\"]]\n                    t_bus = buses[branch[\"t_bus\"]]\n\n                    if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                        @info \"deactivating branch $(i):($(branch[\"f_bus\"]),$(branch[\"t_bus\"])) due to connecting bus status\" maxlog =\n                            PS_MAX_LOG\n                        branch[\"br_status\"] = 0\n                    end\n                end\n            end\n\n            for (i, dcline) in data[\"dcline\"]\n                if dcline[\"br_status\"] != 0\n                    f_bus = buses[dcline[\"f_bus\"]]\n                    t_bus = buses[dcline[\"t_bus\"]]\n\n                    if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                        @info \"deactivating dcline $(i):($(dcline[\"f_bus\"]),$(dcline[\"t_bus\"])) due to connecting bus status\" maxlog =\n                            PS_MAX_LOG\n                        dcline[\"br_status\"] = 0\n                    end\n                end\n            end\n\n            for (i, switch) in data[\"switch\"]\n                if switch[\"status\"] != 0\n                    f_bus = buses[switch[\"f_bus\"]]\n                    t_bus = buses[switch[\"t_bus\"]]\n\n                    if f_bus[\"bus_type\"] == 4 || t_bus[\"bus_type\"] == 4\n                        @info \"deactivating switch $(i):($(switch[\"f_bus\"]),$(switch[\"t_bus\"])) due to connecting bus status\" maxlog =\n                            PS_MAX_LOG\n                        switch[\"status\"] = 0\n                    end\n                end\n            end\n        end\n    end\n\n    ccs = calc_connected_components(data)\n\n    for cc in ccs\n        cc_active_loads = [0]\n        cc_active_shunts = [0]\n        cc_active_gens = [0]\n        cc_active_strg = [0]\n\n        for i in cc\n            cc_active_loads = push!(cc_active_loads, length(incident_active_load[i]))\n            cc_active_shunts = push!(cc_active_shunts, length(incident_active_shunt[i]))\n            cc_active_gens = push!(cc_active_gens, length(incident_active_gen[i]))\n        end\n\n        active_load_count = sum(cc_active_loads)\n        active_shunt_count = sum(cc_active_shunts)\n        active_gen_count = sum(cc_active_gens)\n\n        if (active_load_count == 0 && active_shunt_count == 0 && active_strg_count == 0) ||\n           active_gen_count == 0\n            @info \"deactivating connected component $(cc) due to isolation without generation and load\" maxlog =\n                PS_MAX_LOG\n            for i in cc\n                buses[i][\"bus_type\"] = 4\n            end\n            revised = true\n        end\n    end\n\n    return revised\nend\n\n\"\"\"\nattempts to deactive components that are not needed in the network by repeated\ncalls to `propagate_topology_status!` and `deactivate_isolated_components!`\n\nwarning: this implementation has quadratic complexity, in the worst case\n\"\"\"\nfunction simplify_network!(data::Dict{String, <:Any})\n    revised = true\n    iteration = 0\n\n    while revised\n        iteration += 1\n        revised = false\n        revised |= propagate_topology_status!(data)\n        revised |= deactivate_isolated_components!(data)\n    end\n\n    @info \"network simplification fixpoint reached in $(iteration) rounds\" maxlog =\n        PS_MAX_LOG\n    return revised\nend\n\n\"\"\"\ndetermines the largest connected component of the network and turns everything else off\n\"\"\"\nfunction select_largest_component(data::Dict{String, Any})\n    if ismultinetwork(data)\n        for (i, nw_data) in data[\"nw\"]\n            _select_largest_component(nw_data)\n        end\n    else\n        _select_largest_component(data)\n    end\nend\n\n\"\"\nfunction _select_largest_component!(data::Dict{String, <:Any})\n    ccs = calc_connected_components(data)\n    @info \"found $(length(ccs)) components\" maxlog = PS_MAX_LOG\n\n    if length(ccs) > 1\n        ccs_order = sort(collect(ccs); by = length)\n        largest_cc = ccs_order[end]\n\n        @info \"largest component has $(length(largest_cc)) buses\" maxlog = PS_MAX_LOG\n\n        for (i, bus) in data[\"bus\"]\n            if bus[\"bus_type\"] != 4 && !(bus[\"index\"] in largest_cc)\n                bus[\"bus_type\"] = 4\n                @info \"deactivating bus $(i) due to small connected component\" maxlog =\n                    PS_MAX_LOG\n            end\n        end\n\n        correct_reference_buses!(data)\n    end\nend\n\n\"\"\"\nchecks that each connected components has a reference bus, if not, adds one\n\"\"\"\nfunction check_reference_buses(data::Dict{String, Any})\n    if ismultinetwork(data)\n        for (i, nw_data) in data[\"nw\"]\n            _correct_reference_buses!(nw_data)\n        end\n    else\n        _correct_reference_buses!(data)\n    end\nend\n\n\"\"\nfunction _correct_reference_buses!(data::Dict{String, <:Any})\n    bus_lookup = Dict(bus[\"bus_i\"] => bus for (i, bus) in data[\"bus\"])\n    bus_gen = bus_gen_lookup(data[\"gen\"], data[\"bus\"])\n\n    ccs = calc_connected_components(data)\n    ccs_order = sort(collect(ccs); by = length)\n\n    bus_to_cc = Dict()\n    for (i, cc) in enumerate(ccs_order)\n        for bus_i in cc\n            bus_to_cc[bus_i] = i\n        end\n    end\n\n    cc_gens = Dict(i => Dict() for (i, cc) in enumerate(ccs_order))\n    for (i, gen) in data[\"gen\"]\n        bus_id = gen[\"gen_bus\"]\n        if haskey(bus_to_cc, bus_id)\n            cc_id = bus_to_cc[bus_id]\n            cc_gens[cc_id][i] = gen\n        end\n    end\n\n    for (i, cc) in enumerate(ccs_order)\n        correct_component_refrence_bus!(cc, bus_lookup, cc_gens[i])\n    end\nend\n\n\"\"\"\nchecks that a connected component has a reference bus, if not, tries to add one\n\"\"\"\nfunction correct_component_refrence_bus!(component_bus_ids, bus_lookup, component_gens)\n    refrence_buses = Set()\n    for bus_id in component_bus_ids\n        bus = bus_lookup[bus_id]\n        if bus[\"bus_type\"] == 3\n            push!(refrence_buses, bus_id)\n        end\n    end\n\n    if length(refrence_buses) == 0\n        @info(\"no reference bus found in connected component $(component_bus_ids)\")\n        component_gens_active =\n            Dict(k => v for (k, v) in component_gens if v[\"gen_status\"] != 0)\n\n        if length(component_gens_active) > 0\n            big_gen = _biggest_generator(component_gens_active)\n            gen_bus = bus_lookup[big_gen[\"gen_bus\"]]\n            gen_bus[\"bus_type\"] = 3\n            @info(\n                \"setting bus $(gen_bus[\"index\"]) as reference bus in connected component $(component_bus_ids), based on generator $(big_gen[\"index\"])\"\n            )\n        else\n            @info(\n                \"no generators found in connected component $(component_bus_ids), try running propagate_topology_status\"\n            )\n        end\n    end\nend\n\n\"builds a lookup list of what generators are connected to a given bus\"\nfunction bus_gen_lookup(gen_data::Dict{String, <:Any}, bus_data::Dict{String, <:Any})\n    bus_gen = Dict(bus[\"bus_i\"] => [] for (i, bus) in bus_data)\n    for (i, gen) in gen_data\n        push!(bus_gen[gen[\"gen_bus\"]], gen)\n    end\n    return bus_gen\nend\n\n\"builds a lookup list of what loads are connected to a given bus\"\nfunction bus_load_lookup(load_data::Dict{String, <:Any}, bus_data::Dict{String, <:Any})\n    bus_load = Dict(bus[\"bus_i\"] => [] for (i, bus) in bus_data)\n    for (i, load) in load_data\n        push!(bus_load[load[\"load_bus\"]], load)\n    end\n    return bus_load\nend\n\n\"builds a lookup list of what shunts are connected to a given bus\"\nfunction bus_shunt_lookup(shunt_data::Dict{String, <:Any}, bus_data::Dict{String, <:Any})\n    bus_shunt = Dict(bus[\"bus_i\"] => [] for (i, bus) in bus_data)\n    for (i, shunt) in shunt_data\n        push!(bus_shunt[shunt[\"shunt_bus\"]], shunt)\n    end\n    return bus_shunt\nend\n\n\"builds a lookup list of what storage is connected to a given bus\"\nfunction bus_storage_lookup(\n    storage_data::Dict{String, <:Any},\n    bus_data::Dict{String, <:Any},\n)\n    bus_storage = Dict(bus[\"bus_i\"] => [] for (i, bus) in bus_data)\n    for (i, storage) in storage_data\n        push!(bus_storage[storage[\"storage_bus\"]], storage)\n    end\n    return bus_storage\nend\n\n\"\"\"\ncomputes the connected components of the network graph\nreturns a set of sets of bus ids, each set is a connected component\n\"\"\"\nfunction calc_connected_components(\n    pm_data::Dict{String, <:Any};\n    edges = [\"branch\", \"dcline\", \"switch\"],\n)\n    if ismultinetwork(pm_data)\n        error(\"connected_components does not yet support multinetwork data\")\n    end\n\n    active_bus = Dict(x for x in pm_data[\"bus\"] if x.second[\"bus_type\"] != 4)\n    active_bus_ids = Set{Int64}([bus[\"bus_i\"] for (i, bus) in active_bus])\n\n    neighbors = Dict(i => Int[] for i in active_bus_ids)\n    for comp_type in edges\n        status_key = get(pm_component_status, comp_type, \"status\")\n        status_inactive = get(pm_component_status_inactive, comp_type, 0)\n        for edge in values(get(pm_data, comp_type, Dict()))\n            if get(edge, status_key, 1) != status_inactive &&\n               edge[\"f_bus\"] in active_bus_ids &&\n               edge[\"t_bus\"] in active_bus_ids\n                push!(neighbors[edge[\"f_bus\"]], edge[\"t_bus\"])\n                push!(neighbors[edge[\"t_bus\"]], edge[\"f_bus\"])\n            end\n        end\n    end\n\n    component_lookup = Dict(i => Set{Int}([i]) for i in active_bus_ids)\n    touched = Set{Int64}()\n\n    for i in active_bus_ids\n        if !(i in touched)\n            _cc_dfs(i, neighbors, component_lookup, touched)\n        end\n    end\n\n    ccs = (Set(values(component_lookup)))\n\n    return ccs\nend\n\n\"\"\"\nDFS on a graph\n\"\"\"\nfunction _cc_dfs(i, neighbors, component_lookup, touched)\n    push!(touched, i)\n    for j in neighbors[i]\n        if !(j in touched)\n            for k in component_lookup[j]\n                push!(component_lookup[i], k)\n            end\n            for k in component_lookup[j]\n                component_lookup[k] = component_lookup[i]\n            end\n            _cc_dfs(j, neighbors, component_lookup, touched)\n        end\n    end\nend\n\n\"\"\"\ngiven a network data dict and a mapping of current-bus-ids to new-bus-ids\nmodifies the data dict to reflect the proposed new bus ids.\n\"\"\"\nfunction update_bus_ids!(\n    data::Dict{String, <:Any},\n    bus_id_map::Dict{Int, Int};\n    injective = true,\n)\n    data_it = ismultiinfrastructure(data) ? data[\"it\"][pm_it_name] : data\n\n    if _IM.ismultinetwork(data_it) && apply_to_subnetworks\n        for (nw, nw_data) in data_it[\"nw\"]\n            _update_bus_ids!(nw_data, bus_id_map; injective = injective)\n        end\n    else\n        _update_bus_ids!(data_it, bus_id_map; injective = injective)\n    end\nend\n\nfunction _update_bus_ids!(\n    data::Dict{String, <:Any},\n    bus_id_map::Dict{Int, Int};\n    injective = true,\n)\n    # verify bus id map is injective\n    if injective\n        new_bus_ids = Set{Int}()\n        for (i, bus) in data[\"bus\"]\n            new_id = get(bus_id_map, bus[\"index\"], bus[\"index\"])\n            if !(new_id in new_bus_ids)\n                push!(new_bus_ids, new_id)\n            else\n                throw(\n                    error(\n                        \"bus id mapping given to update_bus_ids has an id clash on new bus id $(new_id)\",\n                    ),\n                )\n            end\n        end\n    end\n\n    # start renumbering process\n    renumbered_bus_dict = Dict{String, Any}()\n\n    for (i, bus) in data[\"bus\"]\n        new_id = get(bus_id_map, bus[\"index\"], bus[\"index\"])\n        bus[\"index\"] = new_id\n        bus[\"bus_i\"] = new_id\n        renumbered_bus_dict[\"$new_id\"] = bus\n    end\n\n    data[\"bus\"] = renumbered_bus_dict\n\n    # update bus numbering in dependent components\n    for (i, load) in data[\"load\"]\n        load[\"load_bus\"] = get(bus_id_map, load[\"load_bus\"], load[\"load_bus\"])\n    end\n\n    for (i, shunt) in data[\"shunt\"]\n        shunt[\"shunt_bus\"] = get(bus_id_map, shunt[\"shunt_bus\"], shunt[\"shunt_bus\"])\n    end\n\n    for (i, gen) in data[\"gen\"]\n        gen[\"gen_bus\"] = get(bus_id_map, gen[\"gen_bus\"], gen[\"gen_bus\"])\n    end\n\n    for (i, strg) in data[\"storage\"]\n        strg[\"storage_bus\"] = get(bus_id_map, strg[\"storage_bus\"], strg[\"storage_bus\"])\n    end\n\n    for (i, switch) in data[\"switch\"]\n        switch[\"f_bus\"] = get(bus_id_map, switch[\"f_bus\"], switch[\"f_bus\"])\n        switch[\"t_bus\"] = get(bus_id_map, switch[\"t_bus\"], switch[\"t_bus\"])\n    end\n\n    branches = []\n    if haskey(data, \"branch\")\n        append!(branches, values(data[\"branch\"]))\n    end\n\n    if haskey(data, \"ne_branch\")\n        append!(branches, values(data[\"ne_branch\"]))\n    end\n\n    for branch in branches\n        branch[\"f_bus\"] = get(bus_id_map, branch[\"f_bus\"], branch[\"f_bus\"])\n        branch[\"t_bus\"] = get(bus_id_map, branch[\"t_bus\"], branch[\"t_bus\"])\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        dcline[\"f_bus\"] = get(bus_id_map, dcline[\"f_bus\"], dcline[\"f_bus\"])\n        dcline[\"t_bus\"] = get(bus_id_map, dcline[\"t_bus\"], dcline[\"t_bus\"])\n    end\nend\n\n\"\"\"\ngiven a network data dict merges buses that are connected by closed switches\nconverting the dataset into a pure bus-branch model.\n\"\"\"\nfunction resolve_swithces!(data::Dict{String, <:Any})\n    if ismultinetwork(data)\n        for (i, nw_data) in data[\"nw\"]\n            _resolve_swithces!(nw_data, mva_base)\n        end\n    else\n        _resolve_swithces!(data, mva_base)\n    end\nend\n\n\"\"\nfunction _resolve_swithces!(data::Dict{String, <:Any})\n    if length(data[\"switch\"]) <= 0\n        return\n    end\n\n    bus_sets = Dict{Int, Set{Int}}()\n\n    switch_status_key = pm_component_status[\"switch\"]\n    switch_status_value = pm_component_status_inactive[\"switch\"]\n\n    for (i, switch) in data[\"switch\"]\n        if switch[switch_status_key] != switch_status_value && switch[\"state\"] == 1\n            if !haskey(bus_sets, switch[\"f_bus\"])\n                bus_sets[switch[\"f_bus\"]] = Set{Int}([switch[\"f_bus\"]])\n            end\n            if !haskey(bus_sets, switch[\"t_bus\"])\n                bus_sets[switch[\"t_bus\"]] = Set{Int}([switch[\"t_bus\"]])\n            end\n\n            merged_set =\n                Set{Int}([bus_sets[switch[\"f_bus\"]]..., bus_sets[switch[\"t_bus\"]]...])\n            bus_sets[switch[\"f_bus\"]] = merged_set\n            bus_sets[switch[\"t_bus\"]] = merged_set\n        end\n    end\n\n    bus_id_map = Dict{Int, Int}()\n    for bus_set in Set(values(bus_sets))\n        bus_min = minimum(bus_set)\n        @info \"merged buses $(join(bus_set, \",\")) in to bus $(bus_min) based on switch status\" maxlog =\n            PS_MAX_LOG\n        for i in bus_set\n            if i != bus_min\n                bus_id_map[i] = bus_min\n            end\n        end\n    end\n\n    update_bus_ids!(data, bus_id_map; injective = false)\n\n    for (i, branch) in data[\"branch\"]\n        if branch[\"f_bus\"] == branch[\"t_bus\"]\n            @warn \"switch removal resulted in both sides of branch $(i) connect to bus $(branch[\"f_bus\"]), deactivating branch\"\n            branch[pm_component_status[\"branch\"]] = pm_component_status_inactive[\"branch\"]\n        end\n    end\n\n    for (i, dcline) in data[\"dcline\"]\n        if dcline[\"f_bus\"] == dcline[\"t_bus\"]\n            @warn \"switch removal resulted in both sides of dcline $(i) connect to bus $(branch[\"f_bus\"]), deactivating dcline\"\n            branch[pm_component_status[\"dcline\"]] = pm_component_status_inactive[\"dcline\"]\n        end\n    end\n\n    @info \"removed $(length(data[\"switch\"])) switch components\"\n    data[\"switch\"] = Dict{String, Any}()\n    return\nend\n\n\"\"\"\nMove gentype and genfuel fields to be subfields of gen\n\"\"\"\nfunction move_genfuel_and_gentype!(data::Dict{String, Any}) # added by PSY\n    ngen = length(data[\"gen\"])\n\n    toplevkeys = (\"genfuel\", \"gentype\")\n    sublevkeys = (\"fuel\", \"type\")\n    for i in range(1; stop = length(toplevkeys))\n        if haskey(data, toplevkeys[i])\n            # check that lengths of category and generators match\n            if length(data[toplevkeys[i]]) != ngen\n                str = toplevkeys[i]\n                throw(\n                    DataFormatError(\n                        \"length of $str does not equal the number of generators\",\n                    ),\n                )\n            end\n            for (key, val) in data[toplevkeys[i]]\n                data[\"gen\"][key][sublevkeys[i]] = val[\"col_1\"]\n            end\n            delete!(data, toplevkeys[i])\n        end\n    end\nend\n"
  },
  {
    "path": "src/parsers/pm_io/matpower.jl",
    "content": "#########################################################################\n#                                                                       #\n# This file provides functions for interfacing with Matpower data files #\n#                                                                       #\n#########################################################################\n\nconst MP_FIX_VOLTAGE_BUSES = [2, 3]\n\n\"Parses the matpwer data from either a filename or an IO object\"\nfunction parse_matpower(io::IO; validate = true)::Dict\n    mp_data = _parse_matpower_string(read(io, String))\n    pm_data = _matpower_to_powermodels!(mp_data)\n    if validate\n        correct_network_data!(pm_data)\n    end\n    return pm_data\nend\n\nfunction parse_matpower(file::String; kwargs...)::Dict\n    mp_data = open(file) do io\n        parse_matpower(io; kwargs...)\n    end\n    return mp_data\nend\n\n### Data and functions specific to Matpower format ###\n\nconst _mp_data_names = [\n    \"mpc.version\",\n    \"mpc.baseMVA\",\n    \"mpc.bus\",\n    \"mpc.gen\",\n    \"mpc.branch\",\n    \"mpc.dcline\",\n    \"mpc.gencost\",\n    \"mpc.dclinecost\",\n    \"mpc.bus_name\",\n    \"mpc.storage\",\n    \"mpc.switch\",\n]\n\nconst _mp_bus_columns = [\n    (\"bus_i\", Int),\n    (\"bus_type\", Int),\n    (\"pd\", Float64),\n    (\"qd\", Float64),\n    (\"gs\", Float64),\n    (\"bs\", Float64),\n    (\"area\", Int),\n    (\"vm\", Float64),\n    (\"va\", Float64),\n    (\"base_kv\", Float64),\n    (\"zone\", Int),\n    (\"vmax\", Float64),\n    (\"vmin\", Float64),\n    (\"lam_p\", Float64),\n    (\"lam_q\", Float64),\n    (\"mu_vmax\", Float64),\n    (\"mu_vmin\", Float64),\n]\n\nconst _mp_bus_name_columns = [(\"name\", Union{String, SubString{String}})]\n\nconst _mp_gen_columns = [\n    (\"gen_bus\", Int),\n    (\"pg\", Float64),\n    (\"qg\", Float64),\n    (\"qmax\", Float64),\n    (\"qmin\", Float64),\n    (\"vg\", Float64),\n    (\"mbase\", Float64),\n    (\"gen_status\", Int),\n    (\"pmax\", Float64),\n    (\"pmin\", Float64),\n    (\"pc1\", Float64),\n    (\"pc2\", Float64),\n    (\"qc1min\", Float64),\n    (\"qc1max\", Float64),\n    (\"qc2min\", Float64),\n    (\"qc2max\", Float64),\n    (\"ramp_agc\", Float64),\n    (\"ramp_10\", Float64),\n    (\"ramp_30\", Float64),\n    (\"ramp_q\", Float64),\n    (\"apf\", Float64),\n    (\"mu_pmax\", Float64),\n    (\"mu_pmin\", Float64),\n    (\"mu_qmax\", Float64),\n    (\"mu_qmin\", Float64),\n]\n\nconst _mp_branch_columns = [\n    (\"f_bus\", Int),\n    (\"t_bus\", Int),\n    (\"br_r\", Float64),\n    (\"br_x\", Float64),\n    (\"br_b\", Float64),\n    (\"rate_a\", Float64),\n    (\"rate_b\", Float64),\n    (\"rate_c\", Float64),\n    (\"tap\", Float64),\n    (\"shift\", Float64),\n    (\"br_status\", Int),\n    (\"angmin\", Float64),\n    (\"angmax\", Float64),\n    (\"pf\", Float64),\n    (\"qf\", Float64),\n    (\"pt\", Float64),\n    (\"qt\", Float64),\n    (\"mu_sf\", Float64),\n    (\"mu_st\", Float64),\n    (\"mu_angmin\", Float64),\n    (\"mu_angmax\", Float64),\n]\n\nconst _mp_dcline_columns = [\n    (\"f_bus\", Int),\n    (\"t_bus\", Int),\n    (\"br_status\", Int),\n    (\"pf\", Float64),\n    (\"pt\", Float64),\n    (\"qf\", Float64),\n    (\"qt\", Float64),\n    (\"vf\", Float64),\n    (\"vt\", Float64),\n    (\"pmin\", Float64),\n    (\"pmax\", Float64),\n    (\"qminf\", Float64),\n    (\"qmaxf\", Float64),\n    (\"qmint\", Float64),\n    (\"qmaxt\", Float64),\n    (\"loss0\", Float64),\n    (\"loss1\", Float64),\n    (\"mu_pmin\", Float64),\n    (\"mu_pmax\", Float64),\n    (\"mu_qminf\", Float64),\n    (\"mu_qmaxf\", Float64),\n    (\"mu_qmint\", Float64),\n    (\"mu_qmaxt\", Float64),\n]\n\nconst _mp_storage_columns = [\n    (\"storage_bus\", Int),\n    (\"ps\", Float64),\n    (\"qs\", Float64),\n    (\"energy\", Float64),\n    (\"energy_rating\", Float64),\n    (\"charge_rating\", Float64),\n    (\"discharge_rating\", Float64),\n    (\"charge_efficiency\", Float64),\n    (\"discharge_efficiency\", Float64),\n    (\"thermal_rating\", Float64),\n    (\"qmin\", Float64),\n    (\"qmax\", Float64),\n    (\"r\", Float64),\n    (\"x\", Float64),\n    (\"p_loss\", Float64),\n    (\"q_loss\", Float64),\n    (\"status\", Int),\n]\n\nconst _mp_switch_columns = [\n    (\"f_bus\", Int),\n    (\"t_bus\", Int),\n    (\"psw\", Float64),\n    (\"qsw\", Float64),\n    (\"state\", Int),\n    (\"thermal_rating\", Float64),\n    (\"status\", Int),\n]\n\n\"\"\nfunction _parse_matpower_string(data_string::String)\n    matlab_data, func_name, colnames = parse_matlab_string(data_string; extended = true)\n\n    case = Dict{String, Any}()\n\n    if func_name !== nothing\n        case[\"name\"] = func_name\n    else\n        @info(\n            string(\n                \"no case name found in matpower file.  The file seems to be missing \\\"function mpc = ...\\\"\",\n            )\n        )\n        case[\"name\"] = \"no_name_found\"\n    end\n\n    case[\"source_type\"] = \"matpower\"\n    if haskey(matlab_data, \"mpc.version\")\n        case[\"source_version\"] = matlab_data[\"mpc.version\"]\n    else\n        @info(\n            string(\n                \"no case version found in matpower file.  The file seems to be missing \\\"mpc.version = ...\\\"\",\n            )\n        )\n        case[\"source_version\"] = \"0.0.0+\"\n    end\n\n    if haskey(matlab_data, \"mpc.baseMVA\")\n        case[\"baseMVA\"] = Float64(matlab_data[\"mpc.baseMVA\"])\n    else\n        @info(\n            string(\n                \"no baseMVA found in matpower file.  The file seems to be missing \\\"mpc.baseMVA = ...\\\"\",\n            )\n        )\n        case[\"baseMVA\"] = 1.0\n    end\n\n    if haskey(matlab_data, \"mpc.bus\")\n        buses = []\n        pv_bus_lookup = Dict{Int, Any}()\n        for bus_row in matlab_data[\"mpc.bus\"]\n            bus_data = row_to_typed_dict(bus_row, _mp_bus_columns)\n            bus_data[\"index\"] = check_type(Int, bus_row[1])\n            bus_data[\"source_id\"] = [\"bus\", bus_data[\"index\"]]\n            push!(buses, bus_data)\n            if bus_data[\"bus_type\"] ∈ MP_FIX_VOLTAGE_BUSES\n                pv_bus_lookup[bus_data[\"index\"]] = bus_data\n            end\n        end\n        case[\"bus\"] = buses\n    else\n        error(\n            string(\n                \"no bus table found in matpower file.  The file seems to be missing \\\"mpc.bus = [...];\\\"\",\n            ),\n        )\n    end\n\n    if haskey(matlab_data, \"mpc.gen\")\n        gens = []\n        corrected_pv_bus_vm = Dict{Int, Float64}()\n        for (i, gen_row) in enumerate(matlab_data[\"mpc.gen\"])\n            gen_data = row_to_typed_dict(gen_row, _mp_gen_columns)\n            bus_data = get(pv_bus_lookup, gen_data[\"gen_bus\"], nothing)\n            if bus_data !== nothing\n                if bus_data[\"bus_type\"] ∈ MP_FIX_VOLTAGE_BUSES &&\n                   bus_data[\"vm\"] != gen_data[\"vg\"]\n                    @info \"Correcting vm in bus $(gen_data[\"gen_bus\"]) to $(gen_data[\"vg\"]) to match generator set-point\"\n                    if gen_data[\"gen_bus\"] ∈ keys(corrected_pv_bus_vm)\n                        if corrected_pv_bus_vm[gen_data[\"gen_bus\"]] != gen_data[\"vg\"]\n                            @error(\n                                \"Generator voltage set-points for bus $(gen_data[\"gen_bus\"]) are inconsistent. This can lead to unexpected results\"\n                            )\n                        end\n                    else\n                        bus_data[\"vm\"] = gen_data[\"vg\"]\n                        corrected_pv_bus_vm[gen_data[\"gen_bus\"]] = gen_data[\"vg\"]\n                    end\n                end\n            end\n            gen_data[\"index\"] = i\n            gen_data[\"source_id\"] = [\"gen\", i]\n            push!(gens, gen_data)\n        end\n        case[\"gen\"] = gens\n    else\n        error(\n            string(\n                \"no gen table found in matpower file.  The file seems to be missing \\\"mpc.gen = [...];\\\"\",\n            ),\n        )\n    end\n\n    if haskey(matlab_data, \"mpc.branch\")\n        branches = []\n        for (i, branch_row) in enumerate(matlab_data[\"mpc.branch\"])\n            branch_data = row_to_typed_dict(branch_row, _mp_branch_columns)\n            branch_data[\"index\"] = i\n            branch_data[\"source_id\"] = [\"branch\", i]\n            push!(branches, branch_data)\n        end\n        case[\"branch\"] = branches\n    else\n        error(\n            string(\n                \"no branch table found in matpower file.  The file seems to be missing \\\"mpc.branch = [...];\\\"\",\n            ),\n        )\n    end\n\n    if haskey(matlab_data, \"mpc.dcline\")\n        dclines = []\n        for (i, dcline_row) in enumerate(matlab_data[\"mpc.dcline\"])\n            dcline_data = row_to_typed_dict(dcline_row, _mp_dcline_columns)\n            dcline_data[\"index\"] = i\n            dcline_data[\"source_id\"] = [\"dcline\", i]\n            push!(dclines, dcline_data)\n        end\n        case[\"dcline\"] = dclines\n    end\n\n    if haskey(matlab_data, \"mpc.storage\")\n        storage = []\n        for (i, storage_row) in enumerate(matlab_data[\"mpc.storage\"])\n            storage_data = row_to_typed_dict(storage_row, _mp_storage_columns)\n            storage_data[\"index\"] = i\n            storage_data[\"source_id\"] = [\"storage\", i]\n            push!(storage, storage_data)\n        end\n        case[\"storage\"] = storage\n    end\n\n    if haskey(matlab_data, \"mpc.switch\")\n        switch = []\n        for (i, switch_row) in enumerate(matlab_data[\"mpc.switch\"])\n            switch_data = row_to_typed_dict(switch_row, _mp_switch_columns)\n            switch_data[\"index\"] = i\n            switch_data[\"source_id\"] = [\"switch\", i]\n            push!(switch, switch_data)\n        end\n        case[\"switch\"] = switch\n    end\n\n    if haskey(matlab_data, \"mpc.bus_name\")\n        bus_names = []\n        for (i, bus_name_row) in enumerate(matlab_data[\"mpc.bus_name\"])\n            bus_name_data = row_to_typed_dict(bus_name_row, _mp_bus_name_columns)\n            bus_name_data[\"index\"] = i\n            bus_name_data[\"source_id\"] = [\"bus_name\", i]\n            push!(bus_names, bus_name_data)\n        end\n        case[\"bus_name\"] = bus_names\n\n        if length(case[\"bus_name\"]) != length(case[\"bus\"])\n            error(\n                \"incorrect Matpower file, the number of bus names ($(length(case[\"bus_name\"]))) is inconsistent with the number of buses ($(length(case[\"bus\"]))).\\n\",\n            )\n        end\n    end\n\n    if haskey(matlab_data, \"mpc.gencost\")\n        gencost = []\n        for (i, gencost_row) in enumerate(matlab_data[\"mpc.gencost\"])\n            gencost_data = _mp_cost_data(gencost_row)\n            gencost_data[\"index\"] = i\n            gencost_data[\"source_id\"] = [\"gencost\", i]\n            push!(gencost, gencost_data)\n        end\n        case[\"gencost\"] = gencost\n\n        if length(case[\"gencost\"]) != length(case[\"gen\"]) &&\n           length(case[\"gencost\"]) != 2 * length(case[\"gen\"])\n            error(\n                \"incorrect Matpower file, the number of generator cost functions ($(length(case[\"gencost\"]))) is inconsistent with the number of generators ($(length(case[\"gen\"]))).\\n\",\n            )\n        end\n    end\n\n    if haskey(matlab_data, \"mpc.dclinecost\")\n        dclinecosts = []\n        for (i, dclinecost_row) in enumerate(matlab_data[\"mpc.dclinecost\"])\n            dclinecost_data = _mp_cost_data(dclinecost_row)\n            dclinecost_data[\"index\"] = i\n            dclinecost_data[\"source_id\"] = [\"dclinecost\", i]\n            push!(dclinecosts, dclinecost_data)\n        end\n        case[\"dclinecost\"] = dclinecosts\n\n        if length(case[\"dclinecost\"]) != length(case[\"dcline\"])\n            error(\n                \"incorrect Matpower file, the number of dcline cost functions ($(length(case[\"dclinecost\"]))) is inconsistent with the number of dclines ($(length(case[\"dcline\"]))).\\n\",\n            )\n        end\n    end\n\n    for k in keys(matlab_data)\n        if !in(k, _mp_data_names) && startswith(k, \"mpc.\")\n            case_name = k[5:length(k)]\n            value = matlab_data[k]\n            if isa(value, Array)\n                column_names = []\n                if haskey(colnames, k)\n                    column_names = colnames[k]\n                end\n                tbl = []\n                for (i, row) in enumerate(matlab_data[k])\n                    row_data = row_to_dict(row, column_names)\n                    row_data[\"index\"] = i\n                    row_data[\"source_id\"] = [case_name, i]\n                    push!(tbl, row_data)\n                end\n                case[case_name] = tbl\n                @info(\n                    \"extending matpower format with data: $(case_name) $(length(tbl))x$(length(tbl[1])-1)\"\n                )\n            else\n                case[case_name] = value\n                @info(\"extending matpower format with constant data: $(case_name)\")\n            end\n        end\n    end\n\n    return case\nend\n\n\"\"\nfunction _mp_cost_data(cost_row)\n    ncost = check_type(Int, cost_row[4])\n    model = check_type(Int, cost_row[1])\n    if model == 1\n        nr_parameters = ncost * 2\n    elseif model == 2\n        nr_parameters = ncost\n    end\n\n    cost_data = Dict(\n        \"model\" => model,\n        \"startup\" => check_type(Float64, cost_row[2]),\n        \"shutdown\" => check_type(Float64, cost_row[3]),\n        \"ncost\" => ncost,\n        \"cost\" => [check_type(Float64, x) for x in cost_row[5:(5 + nr_parameters - 1)]],\n    )\n\n    #=\n    # skip this literal interpretation, as its hard to invert\n    cost_values = [check_type(Float64, x) for x in cost_row[5:length(cost_row)]]\n    if cost_data[\"model\"] == 1:\n        if length(cost_values)%2 != 0\n            error(\"incorrect matpower file, odd number of pwl cost function values\")\n        end\n        for i in 0:(length(cost_values)/2-1)\n            p_idx = 1+2*i\n            f_idx = 2+2*i\n            cost_data[\"p_$(i)\"] = cost_values[p_idx]\n            cost_data[\"f_$(i)\"] = cost_values[f_idx]\n        end\n    else:\n        for (i,v) in enumerate(cost_values)\n            cost_data[\"c_$(length(cost_values)+1-i)\"] = v\n        end\n    =#\n    return cost_data\nend\n\n### Data and functions specific to PowerModels format ###\n\n\"\"\"\nConverts a Matpower dict into a PowerModels dict\n\"\"\"\nfunction _matpower_to_powermodels!(mp_data::Dict{String, <:Any})\n    pm_data = mp_data\n\n    # required default values\n    if !haskey(pm_data, \"dcline\")\n        pm_data[\"dcline\"] = []\n    end\n    if !haskey(pm_data, \"gencost\")\n        pm_data[\"gencost\"] = []\n    end\n    if !haskey(pm_data, \"dclinecost\")\n        pm_data[\"dclinecost\"] = []\n    end\n    if !haskey(pm_data, \"storage\")\n        pm_data[\"storage\"] = []\n    end\n    if !haskey(pm_data, \"switch\")\n        pm_data[\"switch\"] = []\n    end\n\n    # Add conformity key to bus data if not present\n    missing_conformity_loads = [\n        bus for bus in pm_data[\"bus\"]\n        if (bus[\"pd\"] != 0.0 || bus[\"qd\"] != 0.0) && !haskey(bus, \"conformity\")\n    ]\n    for bus in missing_conformity_loads\n        bus[\"conformity\"] = 1\n    end\n    missing_conformity_count = length(missing_conformity_loads)\n    if missing_conformity_count > 0\n        @info \"No conformity field found for $missing_conformity_count load(s). Setting to default value of 1 (Conforming Load).\"\n    end\n\n    # translate component models\n    _mp2pm_branch!(pm_data)\n    _mp2pm_dcline!(pm_data)\n\n    # translate cost models\n    _add_dcline_costs!(pm_data)\n\n    # merge data tables\n    _merge_bus_name_data!(pm_data)\n    _merge_cost_data!(pm_data)\n    _merge_generic_data!(pm_data)\n\n    # split loads and shunts from buses\n    _split_loads_shunts!(pm_data)\n\n    # use once available\n    arrays_to_dicts!(pm_data)\n\n    base_voltages = Dict{Int64, Float64}(\n        bus_ind => bus_data[\"base_kv\"] for (bus_ind, bus_data) in pm_data[\"bus\"]\n    )\n    for transf in values(pm_data[\"branch\"])\n        if transf[\"transformer\"] == true && !haskey(transf, \"base_voltage_from\")\n            transf[\"base_voltage_from\"] = base_voltages[transf[\"f_bus\"]]\n            transf[\"base_voltage_to\"] = base_voltages[transf[\"t_bus\"]]\n        end\n    end\n\n    for optional in [\"dcline\", \"load\", \"shunt\", \"storage\", \"switch\"]\n        if length(pm_data[optional]) == 0\n            pm_data[optional] = Dict{String, Any}()\n        end\n    end\n\n    return pm_data\nend\n\n\"\"\"\n    _split_loads_shunts!(data)\n\nSeperates Loads and Shunts in `data` under separate \"load\" and \"shunt\" keys in the\nPowerModels data format. Includes references to originating bus via \"load_bus\"\nand \"shunt_bus\" keys, respectively.\n\"\"\"\nfunction _split_loads_shunts!(data::Dict{String, Any})\n    data[\"load\"] = []\n    data[\"shunt\"] = []\n\n    load_num = 1\n    shunt_num = 1\n    for (i, bus) in enumerate(data[\"bus\"])\n        if bus[\"pd\"] != 0.0 || bus[\"qd\"] != 0.0\n            append!(\n                data[\"load\"],\n                [\n                    Dict{String, Any}(\n                        \"pd\" => bus[\"pd\"],\n                        \"qd\" => bus[\"qd\"],\n                        \"load_bus\" => bus[\"bus_i\"],\n                        \"status\" => convert(Int8, bus[\"bus_type\"] != 4),\n                        \"conformity\" => get(bus, \"conformity\", 1),\n                        \"index\" => load_num,\n                        \"source_id\" => [\"bus\", bus[\"bus_i\"]],\n                    ),\n                ],\n            )\n            load_num += 1\n        end\n\n        if bus[\"gs\"] != 0.0 || bus[\"bs\"] != 0.0\n            append!(\n                data[\"shunt\"],\n                [\n                    Dict{String, Any}(\n                        \"gs\" => bus[\"gs\"],\n                        \"bs\" => bus[\"bs\"],\n                        \"shunt_bus\" => bus[\"bus_i\"],\n                        \"status\" => convert(Int8, bus[\"bus_type\"] != 4),\n                        \"index\" => shunt_num,\n                        \"source_id\" => [\"bus\", bus[\"bus_i\"]],\n                    ),\n                ],\n            )\n            shunt_num += 1\n        end\n\n        for key in [\"pd\", \"qd\", \"gs\", \"bs\"]\n            delete!(bus, key)\n        end\n    end\nend\n\n\"sets all branch transformer taps to 1.0, to simplify branch models\"\nfunction _mp2pm_branch!(data::Dict{String, Any})\n    branches = [branch for branch in data[\"branch\"]]\n    if haskey(data, \"ne_branch\")\n        append!(branches, data[\"ne_branch\"])\n    end\n    for branch in branches\n        if branch[\"tap\"] == 0.0\n            branch[\"transformer\"] = false\n            branch[\"tap\"] = 1.0\n            # Evenly split the susceptance between the `from` and `to` ends\n            branch[\"b_fr\"] = branch[\"br_b\"] / 2.0\n            branch[\"b_to\"] = branch[\"br_b\"] / 2.0\n        else\n            branch[\"transformer\"] = true\n            if branch[\"br_b\"] != 0.0\n                @warn \"Reflecting transformer shunts to primary; the ybus matrix will differ from matpower\" maxlog =\n                    5\n                branch[\"b_fr\"] = (branch[\"br_b\"] / branch[\"tap\"]^2)\n            else\n                branch[\"b_fr\"] = 0.0\n            end\n            branch[\"b_to\"] = 0.0\n        end\n        branch[\"g_fr\"] = 0.0\n        branch[\"g_to\"] = 0.0\n\n        branch[\"base_power\"] = data[\"baseMVA\"]\n\n        delete!(branch, \"br_b\")\n\n        if branch[\"rate_a\"] == 0.0\n            delete!(branch, \"rate_a\")\n        end\n        if branch[\"rate_b\"] == 0.0\n            delete!(branch, \"rate_b\")\n        end\n        if branch[\"rate_c\"] == 0.0\n            delete!(branch, \"rate_c\")\n        end\n    end\nend\n\n\"adds pmin and pmax values at to and from buses\"\nfunction _mp2pm_dcline!(data::Dict{String, Any})\n    for dcline in data[\"dcline\"]\n        pmin = dcline[\"pmin\"]\n        pmax = dcline[\"pmax\"]\n        loss0 = dcline[\"loss0\"]\n        loss1 = dcline[\"loss1\"]\n\n        delete!(dcline, \"pmin\")\n        delete!(dcline, \"pmax\")\n\n        if pmin >= 0 && pmax >= 0\n            pminf = pmin\n            pmaxf = pmax\n            pmint = loss0 - pmaxf * (1 - loss1)\n            pmaxt = loss0 - pminf * (1 - loss1)\n        end\n        if pmin >= 0 && pmax < 0\n            pminf = pmin\n            pmint = pmax\n            pmaxf = (-pmint + loss0) / (1 - loss1)\n            pmaxt = loss0 - pminf * (1 - loss1)\n        end\n        if pmin < 0 && pmax >= 0\n            pmaxt = -pmin\n            pmaxf = pmax\n            pminf = (-pmaxt + loss0) / (1 - loss1)\n            pmint = loss0 - pmaxf * (1 - loss1)\n        end\n        if pmin < 0 && pmax < 0\n            pmaxt = -pmin\n            pmint = pmax\n            pmaxf = (-pmint + loss0) / (1 - loss1)\n            pminf = (-pmaxt + loss0) / (1 - loss1)\n        end\n\n        dcline[\"pmaxt\"] = pmaxt\n        dcline[\"pmint\"] = pmint\n        dcline[\"pmaxf\"] = pmaxf\n        dcline[\"pminf\"] = pminf\n\n        # preserve the old pmin and pmax values\n        dcline[\"mp_pmin\"] = pmin\n        dcline[\"mp_pmax\"] = pmax\n\n        dcline[\"pt\"] = -dcline[\"pt\"] # matpower has opposite convention\n        dcline[\"qf\"] = -dcline[\"qf\"] # matpower has opposite convention\n        dcline[\"qt\"] = -dcline[\"qt\"] # matpower has opposite convention\n    end\nend\n\n\"adds dcline costs, if gen costs exist\"\nfunction _add_dcline_costs!(data::Dict{String, Any})\n    if length(data[\"gencost\"]) > 0 &&\n       length(data[\"dclinecost\"]) <= 0 &&\n       length(data[\"dcline\"]) > 0\n        @info(\"added zero cost function data for dclines\")\n        model = data[\"gencost\"][1][\"model\"]\n        if model == 1\n            for (i, dcline) in enumerate(data[\"dcline\"])\n                dclinecost = Dict(\n                    \"index\" => i,\n                    \"model\" => 1,\n                    \"startup\" => 0.0,\n                    \"shutdown\" => 0.0,\n                    \"ncost\" => 2,\n                    \"cost\" => [dcline[\"pminf\"], 0.0, dcline[\"pmaxf\"], 0.0],\n                )\n                push!(data[\"dclinecost\"], dclinecost)\n            end\n        else\n            for (i, dcline) in enumerate(data[\"dcline\"])\n                dclinecost = Dict(\n                    \"index\" => i,\n                    \"model\" => 2,\n                    \"startup\" => 0.0,\n                    \"shutdown\" => 0.0,\n                    \"ncost\" => 3,\n                    \"cost\" => [0.0, 0.0, 0.0],\n                )\n                push!(data[\"dclinecost\"], dclinecost)\n            end\n        end\n    end\nend\n\n\"merges generator cost functions into generator data, if costs exist\"\nfunction _merge_cost_data!(data::Dict{String, Any})\n    if haskey(data, \"gencost\")\n        gen = data[\"gen\"]\n        gencost = data[\"gencost\"]\n\n        if length(gen) != length(gencost)\n            if length(gencost) > length(gen)\n                @warn(\n                    \"The last $(length(gencost) - length(gen)) generator cost records will be ignored due to too few generator records.\",\n                )\n                gencost = gencost[1:length(gen)]\n            else\n                @warn(\n                    \"The number of generators ($(length(gen))) does not match the number of generator cost records ($(length(gencost))).\",\n                )\n            end\n        end\n\n        for (i, gc) in enumerate(gencost)\n            g = gen[i]\n            @assert(g[\"index\"] == gc[\"index\"])\n            delete!(gc, \"index\")\n            delete!(gc, \"source_id\")\n\n            _check_keys(g, keys(gc))\n            merge!(g, gc)\n        end\n\n        delete!(data, \"gencost\")\n    end\n\n    if haskey(data, \"dclinecost\")\n        dcline = data[\"dcline\"]\n        dclinecost = data[\"dclinecost\"]\n\n        if length(dcline) != length(dclinecost)\n            @warn(\n                \"The number of dclines ($(length(dcline))) does not match the number of dcline cost records ($(length(dclinecost))).\",\n            )\n        end\n\n        for (i, dclc) in enumerate(dclinecost)\n            dcl = dcline[i]\n            @assert(dcl[\"index\"] == dclc[\"index\"])\n            delete!(dclc, \"index\")\n            delete!(dclc, \"source_id\")\n\n            _check_keys(dcl, keys(dclc))\n            merge!(dcl, dclc)\n        end\n        delete!(data, \"dclinecost\")\n    end\nend\n\n\"merges bus name data into buses, if names exist\"\nfunction _merge_bus_name_data!(data::Dict{String, Any})\n    if haskey(data, \"bus_name\")\n        # can assume same length is same as bus\n        # this is validated during matpower parsing\n        for (i, bus_name) in enumerate(data[\"bus_name\"])\n            bus = data[\"bus\"][i]\n            delete!(bus_name, \"index\")\n            delete!(bus_name, \"source_id\")\n\n            _check_keys(bus, keys(bus_name))\n            merge!(bus, bus_name)\n        end\n        delete!(data, \"bus_name\")\n    end\nend\n\n\"merges Matpower tables based on the table extension syntax\"\nfunction _merge_generic_data!(data::Dict{String, Any})\n    mp_matrix_names = [name[5:length(name)] for name in _mp_data_names]\n\n    key_to_delete = []\n    for (k, v) in data\n        if isa(v, Array)\n            for mp_name in mp_matrix_names\n                if startswith(k, \"$(mp_name)_\")\n                    mp_matrix = data[mp_name]\n                    push!(key_to_delete, k)\n\n                    if length(mp_matrix) != length(v)\n                        error(\n                            \"failed to extend the matpower matrix \\\"$(mp_name)\\\" with the matrix \\\"$(k)\\\" because they do not have the same number of rows, $(length(mp_matrix)) and $(length(v)) respectively.\",\n                        )\n                    end\n\n                    @info(\n                        \"extending matpower format by appending matrix \\\"$(k)\\\" in to \\\"$(mp_name)\\\"\"\n                    )\n\n                    for (i, row) in enumerate(mp_matrix)\n                        merge_row = v[i]\n                        #@assert(row[\"index\"] == merge_row[\"index\"]) # note this does not hold for the bus table\n                        delete!(merge_row, \"index\")\n                        delete!(merge_row, \"source_id\")\n                        for key in keys(merge_row)\n                            if haskey(row, key)\n                                error(\n                                    \"failed to extend the matpower matrix \\\"$(mp_name)\\\" with the matrix \\\"$(k)\\\" because they both share \\\"$(key)\\\" as a column name.\",\n                                )\n                            end\n                            row[key] = merge_row[key]\n                        end\n                    end\n\n                    break # out of mp_matrix_names loop\n                end\n            end\n        end\n    end\n\n    for key in key_to_delete\n        delete!(data, key)\n    end\nend\n\n\"\"\nfunction _check_keys(data, keys)\n    for key in keys\n        if haskey(data, key)\n            error(\"attempting to overwrite value of $(key) in PowerModels data,\\n$(data)\")\n        end\n    end\nend\n"
  },
  {
    "path": "src/parsers/pm_io/psse.jl",
    "content": "# Parse PSS(R)E data from PTI file into PowerModels data format\n\"\"\"\n    _init_bus!(bus, id)\n\nInitializes a `bus` of id `id` with default values given in the PSS(R)E\nspecification.\n\"\"\"\nfunction _init_bus!(bus::Dict{String, Any}, id::Int)\n    bus[\"bus_i\"] = id\n    bus[\"bus_type\"] = 1\n    bus[\"area\"] = 1\n    bus[\"vm\"] = 1.0\n    bus[\"va\"] = 0.0\n    bus[\"base_kv\"] = 1.0\n    bus[\"zone\"] = 1\n    bus[\"name\"] = \"            \"\n    bus[\"vmax\"] = 1.1\n    bus[\"vmin\"] = 0.9\n    bus[\"index\"] = id\n    return\nend\n\nfunction _find_bus_value(bus_i::Int, field::String, pm_bus_data::Array)\n    for bus in pm_bus_data\n        if bus[\"index\"] == bus_i\n            return bus[field]\n        end\n    end\n    @info(\"Could not find bus $bus_i, returning 0 for field $field\")\n    return 0\nend\n\nfunction _find_bus_value(bus_i::Int, field::String, pm_bus_data::Dict)\n    if !haskey(pm_bus_data, bus_i)\n        @info(\"Could not find bus $bus_i, returning 0 for field $field\")\n        return 0\n    else\n        return pm_bus_data[bus_i][field]\n    end\nend\n\n\"\"\"\n    _get_bus_value(bus_i, field, pm_data)\n\nReturns the value of `field` of `bus_i` from the PowerModels data. Requires\n\"bus\" Dict to already be populated.\n\"\"\"\nfunction _get_bus_value(bus_i::Int, field::String, pm_data::Dict{String, Any})\n    return _find_bus_value(bus_i, field, pm_data[\"bus\"])\nend\n\n\"\"\"\n    _find_max_bus_id(pm_data)\n\nReturns the maximum bus id in `pm_data`\n\"\"\"\nfunction _find_max_bus_id(pm_data::Dict)::Int\n    max_id = 0\n    for bus in values(pm_data[\"bus\"])\n        if bus[\"index\"] > max_id && !endswith(bus[\"name\"], \"starbus\")\n            max_id = bus[\"index\"]\n        end\n    end\n\n    return max_id\nend\n\n\"\"\"\n    create_starbus(pm_data, transformer)\n\nCreates a starbus from a given three-winding `transformer`. \"source_id\" is given\nby `[\"bus_i\", \"name\", \"I\", \"J\", \"K\", \"CKT\"]` where \"bus_i\" and \"name\" are the\nmodified names for the starbus, and \"I\", \"J\", \"K\" and \"CKT\" come from the\noriginating transformer, in the PSS(R)E transformer specification.\n\"\"\"\nfunction _create_starbus_from_transformer(\n    pm_data::Dict,\n    transformer::Dict,\n    starbus_id::Int,\n)::Dict\n    starbus = Dict{String, Any}()\n\n    _init_bus!(starbus, starbus_id)\n\n    starbus[\"name\"] = \"starbus_$(transformer[\"I\"])_$(transformer[\"J\"])_$(transformer[\"K\"])_$(strip(transformer[\"CKT\"]))\"\n\n    bus_type = 1\n    starbus[\"vm\"] = transformer[\"VMSTAR\"]\n    starbus[\"va\"] = transformer[\"ANSTAR\"]\n    starbus[\"bus_type\"] = bus_type\n    if transformer[\"STAT\"] != 0\n        starbus[\"bus_status\"] = true\n    else\n        starbus[\"bus_status\"] = false\n    end\n    starbus[\"area\"] = _get_bus_value(transformer[\"I\"], \"area\", pm_data)\n    starbus[\"zone\"] = _get_bus_value(transformer[\"I\"], \"zone\", pm_data)\n    starbus[\"hidden\"] = true\n    starbus[\"source_id\"] = push!(\n        [\"transformer\", starbus[\"bus_i\"], starbus[\"name\"]],\n        transformer[\"I\"],\n        transformer[\"J\"],\n        transformer[\"K\"],\n        transformer[\"CKT\"],\n    )\n\n    return starbus\nend\n\n\"Imports remaining top level component lists from `data_in` into `data_out`, excluding keys in `exclude`\"\nfunction _import_remaining_comps!(data_out::Dict, data_in::Dict; exclude = [])\n    for (comp_class, v) in data_in\n        if !(comp_class in exclude)\n            comps_out = Dict{String, Any}()\n\n            if isa(v, Array)\n                for (n, item) in enumerate(v)\n                    if isa(item, Dict)\n                        comp_out = Dict{String, Any}()\n                        _import_remaining_keys!(comp_out, item)\n                        if !(\"index\" in keys(item))\n                            comp_out[\"index\"] = n\n                        end\n                        comps_out[\"$(n)\"] = comp_out\n                    else\n                        @error(\"psse data parsing error, please post an issue\")\n                    end\n                end\n            elseif isa(v, Dict)\n                comps_out = Dict{String, Any}()\n                _import_remaining_keys!(comps_out, v)\n            else\n                @error(\"psse data parsing error, please post an issue\")\n            end\n\n            data_out[lowercase(comp_class)] = comps_out\n        end\n    end\nend\n\n\"Imports remaining keys from a source component into detestation component, excluding keys in `exclude`\"\nfunction _import_remaining_keys!(comp_dest::Dict, comp_src::Dict; exclude = [])\n    for (k, v) in comp_src\n        if !(k in exclude)\n            key = lowercase(k)\n            if !haskey(comp_dest, key)\n                comp_dest[key] = v\n            else\n                if key != \"index\"\n                    @warn(\"duplicate key $(key), please post an issue\")\n                end\n            end\n        end\n    end\nend\n\n\"\"\"\n    _psse2pm_branch!(pm_data, pti_data)\n\nParses PSS(R)E-style Branch data into a PowerModels-style Dict. \"source_id\" is\ngiven by `[\"I\", \"J\", \"CKT\"]` in PSS(R)E Branch specification.\n\"\"\"\nfunction _psse2pm_branch!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Branch data into a PowerModels Dict...\"\n    pm_data[\"branch\"] = []\n    if haskey(pti_data, \"BRANCH\")\n        for branch in pti_data[\"BRANCH\"]\n            if !haskey(branch, \"I\") || !haskey(branch, \"J\")\n                @error \"Bus Data Incomplete for $(branch). Skipping branch creation\"\n                continue\n            end\n            if first(branch[\"CKT\"]) != '@' && first(branch[\"CKT\"]) != '*'\n                sub_data = Dict{String, Any}()\n                sub_data[\"f_bus\"] = pop!(branch, \"I\")\n                sub_data[\"t_bus\"] = pop!(branch, \"J\")\n                bus_from = pm_data[\"bus\"][sub_data[\"f_bus\"]]\n                sub_data[\"base_voltage_from\"] = bus_from[\"base_kv\"]\n                bus_to = pm_data[\"bus\"][sub_data[\"t_bus\"]]\n                sub_data[\"base_voltage_to\"] = bus_to[\"base_kv\"]\n                if pm_data[\"has_isolated_type_buses\"]\n                    if !(bus_from[\"bus_type\"] == 4 || bus_to[\"bus_type\"] == 4)\n                        push!(pm_data[\"connected_buses\"], sub_data[\"f_bus\"])\n                        push!(pm_data[\"connected_buses\"], sub_data[\"t_bus\"])\n                    end\n                end\n                sub_data[\"br_r\"] = pop!(branch, \"R\")\n                sub_data[\"br_x\"] = pop!(branch, \"X\")\n                sub_data[\"g_fr\"] = pop!(branch, \"GI\")\n                # Evenly split the susceptance between the `from` and `to` ends\n                sub_data[\"b_fr\"] = (branch[\"B\"] / 2) + pop!(branch, \"BI\")\n                sub_data[\"g_to\"] = pop!(branch, \"GJ\")\n                sub_data[\"b_to\"] = (branch[\"B\"] / 2) + pop!(branch, \"BJ\")\n\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"LEN\" => pop!(branch, \"LEN\"),\n                )\n\n                if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                    sub_data[\"rate_a\"] = pop!(branch, \"RATEA\")\n                    sub_data[\"rate_b\"] = pop!(branch, \"RATEB\")\n                    sub_data[\"rate_c\"] = pop!(branch, \"RATEC\")\n                elseif pm_data[\"source_version\"] == \"35\"\n                    sub_data[\"rate_a\"] = pop!(branch, \"RATE1\")\n                    sub_data[\"rate_b\"] = pop!(branch, \"RATE2\")\n                    sub_data[\"rate_c\"] = pop!(branch, \"RATE3\")\n\n                    for i in 4:12\n                        rate_key = \"RATE$i\"\n                        if haskey(branch, rate_key)\n                            sub_data[\"ext\"][rate_key] = pop!(branch, rate_key)\n                        end\n                    end\n                else\n                    error(\n                        \"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\",\n                    )\n                end\n\n                sub_data[\"tap\"] = 1.0\n                sub_data[\"shift\"] = 0.0\n                sub_data[\"br_status\"] = pop!(branch, \"ST\")\n                sub_data[\"angmin\"] = 0.0\n                sub_data[\"angmax\"] = 0.0\n                sub_data[\"transformer\"] = false\n\n                sub_data[\"source_id\"] =\n                    [\"branch\", sub_data[\"f_bus\"], sub_data[\"t_bus\"], pop!(branch, \"CKT\")]\n                sub_data[\"index\"] = length(pm_data[\"branch\"]) + 1\n\n                if import_all\n                    _import_remaining_keys!(sub_data, branch; exclude = [\"B\", \"BI\", \"BJ\"])\n                end\n\n                if sub_data[\"rate_a\"] == 0.0\n                    delete!(sub_data, \"rate_a\")\n                end\n                if sub_data[\"rate_b\"] == 0.0\n                    delete!(sub_data, \"rate_b\")\n                end\n                if sub_data[\"rate_c\"] == 0.0\n                    delete!(sub_data, \"rate_c\")\n                end\n                branch_isolated_bus_modifications!(pm_data, sub_data)\n                push!(pm_data[\"branch\"], sub_data)\n            else\n                from_bus = branch[\"I\"]\n                to_bus = branch[\"J\"]\n                ckt = branch[\"CKT\"]\n                @info \"Branch $from_bus -> $to_bus with CKT=$ckt will be parsed as DiscreteControlledACBranch\"\n            end\n        end\n    end\n    return\nend\n\nfunction branch_isolated_bus_modifications!(pm_data::Dict, branch_data::Dict)\n    bus_data = pm_data[\"bus\"]\n    from_bus_no = branch_data[\"f_bus\"]\n    to_bus_no = branch_data[\"t_bus\"]\n    from_bus = bus_data[from_bus_no]\n    to_bus = bus_data[to_bus_no]\n\n    status_field = haskey(branch_data, \"br_status\") ? \"br_status\" : \"state\"\n    if (from_bus[\"bus_type\"] == 4 || to_bus[\"bus_type\"] == 4) &&\n       branch_data[status_field] == 1\n        @warn \"Branch connected between buses $(from_bus_no) -> $(to_bus_no) is connected to an isolated bus. Setting branch status to 0.\"\n        branch_data[status_field] = 0\n    end\n    if from_bus[\"bus_type\"] == 4\n        push!(pm_data[\"candidate_isolated_to_pq_buses\"], from_bus_no)\n    end\n    if to_bus[\"bus_type\"] == 4\n        push!(pm_data[\"candidate_isolated_to_pq_buses\"], to_bus_no)\n    end\n    return\nend\n\nfunction transformer3W_isolated_bus_modifications!(pm_data::Dict, branch_data::Dict)\n    bus_data = pm_data[\"bus\"]\n    primary_bus_number = branch_data[\"bus_primary\"]\n    secondary_bus_number = branch_data[\"bus_secondary\"]\n    tertiary_bus_number = branch_data[\"bus_tertiary\"]\n    primary_bus = bus_data[primary_bus_number]\n    secondary_bus = bus_data[secondary_bus_number]\n    tertiary_bus = bus_data[tertiary_bus_number]\n    if branch_data[\"available\"] == 1\n        if primary_bus[\"bus_type\"] == 4\n            branch_data[\"available_primary\"] = 0\n            @warn \"Three winding transformer primary bus $(primary_bus_number) is isolated. Setting primary winding status to 0.\"\n        end\n        if secondary_bus[\"bus_type\"] == 4\n            branch_data[\"available_secondary\"] = 0\n            @warn \"Three winding transformer secondary bus $(secondary_bus_number) is isolated. Setting secondary winding status to 0.\"\n        end\n        if tertiary_bus[\"bus_type\"] == 4\n            branch_data[\"available_tertiary\"] = 0\n            @warn \"Three winding transformer tertiary bus $(tertiary_bus_number) is isolated. Setting tertiary winding status to 0.\"\n        end\n        if (\n            branch_data[\"available_primary\"] == 0 &&\n            branch_data[\"available_secondary\"] == 0 &&\n            branch_data[\"available_tertiary\"] == 0\n        )\n            branch_data[\"available\"] = 0\n            @warn \"All three windings are unavailable. Setting overall transformer availability to 0\"\n        end\n    end\n    if primary_bus[\"bus_type\"] == 4\n        push!(pm_data[\"candidate_isolated_to_pq_buses\"], primary_bus_number)\n    end\n    if secondary_bus[\"bus_type\"] == 4\n        push!(pm_data[\"candidate_isolated_to_pq_buses\"], secondary_bus_number)\n    end\n    if tertiary_bus[\"bus_type\"] == 4\n        push!(pm_data[\"candidate_isolated_to_pq_buses\"], tertiary_bus_number)\n    end\n    return\nend\n\n\"\"\"\n    _is_synch_condenser(sub_data, pm_data)\n\nReturns `true` if the generator described by `sub_data` and `pm_data` meets the criteria for a synchronous condenser.\n\"\"\"\nfunction _is_synch_condenser(sub_data::Dict{String, Any}, pm_data::Dict{String, Any})\n    is_zero_pg = sub_data[\"pg\"] == 0.0\n    has_q_limits = (sub_data[\"qmax\"] != 0.0 || sub_data[\"qmin\"] != 0.0)\n    has_zero_p_limits = (sub_data[\"pmax\"] == 0.0 && sub_data[\"pmin\"] == 0.0)\n    zero_control_mode = sub_data[\"m_control_mode\"] == 0\n    is_pv_bus = pm_data[\"bus\"][sub_data[\"gen_bus\"]][\"bus_type\"] == 2\n\n    if is_zero_pg && has_q_limits && has_zero_p_limits && zero_control_mode\n        if !is_pv_bus\n            @warn \"Generator $(sub_data[\"gen_bus\"]) is likely a synchronous condenser but not connected to a PV bus.\"\n        end\n        return true\n    end\n    return false\nend\n\nfunction _determine_injector_status(\n    sub_data::Dict{String, Any},\n    pm_data::Dict{String, Any},\n    gen_bus::Int,\n    status_key::String,\n    bus_conversion_list::String,\n)\n    # Special case for FACTS:  MODE = 0 -> Unavailable, MODE = 1 -> Normal mode, MODE = 2 -> Link bypassed\n    if status_key == \"MODE\"\n        device_status = pop!(sub_data, status_key) != 0 ? true : false\n    else\n        device_status = pop!(sub_data, status_key) == 1 ? true : false\n    end\n    # If device is off keep it off.\n    if !device_status\n        return false\n    end\n    # If device is on check the topology and status of the bus it is connected to.\n    if pm_data[\"bus\"][gen_bus][\"bus_type\"] == 4\n        gen_bus_connected = gen_bus ∈ pm_data[\"connected_buses\"]\n        if gen_bus_connected && device_status\n            @warn \"Device connected to bus $(gen_bus) is marked as available, but the bus is set isolated and not topologically isolated. Setting device status to 1 and the bus added to candidate for conversion.\"\n            push!(pm_data[bus_conversion_list], gen_bus)\n            pm_data[\"bus\"][gen_bus][\"bus_status\"] = true\n            return true\n        elseif !gen_bus_connected && device_status\n            @warn \"Device connected to bus $(gen_bus) is marked as available, but the bus is set isolated. Setting device status to 0.\"\n            pm_data[\"bus\"][gen_bus][\"bus_status\"] = false\n            return false\n        else\n            error(\"Unrecognized generator and bus status combination.\")\n        end\n    else\n        sub_data[\"gen_status\"] = true\n        return true\n    end\nend\n\n\"\"\"\n    _psse2pm_generator!(pm_data, pti_data)\n\nParses PSS(R)E-style Generator data in a PowerModels-style Dict. \"source_id\" is\ngiven by `[\"I\", \"ID\"]` in PSS(R)E Generator specification.\n\"\"\"\nfunction _psse2pm_generator!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Generator data into a PowerModels Dict...\"\n    if haskey(pti_data, \"GENERATOR\")\n        pm_data[\"gen\"] = Vector{Dict{String, Any}}(undef, length(pti_data[\"GENERATOR\"]))\n        for (ix, gen) in enumerate(pti_data[\"GENERATOR\"])\n            sub_data = Dict{String, Any}()\n            sub_data[\"gen_bus\"] = pop!(gen, \"I\")\n            sub_data[\"gen_status\"] =\n                _determine_injector_status(\n                    gen,\n                    pm_data,\n                    sub_data[\"gen_bus\"],\n                    \"STAT\",\n                    \"candidate_isolated_to_pv_buses\",\n                )\n            sub_data[\"pg\"] = pop!(gen, \"PG\")\n            sub_data[\"qg\"] = pop!(gen, \"QG\")\n            sub_data[\"vg\"] = pop!(gen, \"VS\")\n            sub_data[\"mbase\"] = pop!(gen, \"MBASE\")\n            sub_data[\"pmin\"] = pop!(gen, \"PB\")\n            sub_data[\"pmax\"] = pop!(gen, \"PT\")\n            sub_data[\"qmin\"] = pop!(gen, \"QB\")\n            sub_data[\"qmax\"] = pop!(gen, \"QT\")\n            sub_data[\"rt_source\"] = pop!(gen, \"RT\")\n            sub_data[\"xt_source\"] = pop!(gen, \"XT\")\n            sub_data[\"r_source\"] = pop!(gen, \"ZR\")\n            sub_data[\"x_source\"] = pop!(gen, \"ZX\")\n            sub_data[\"m_control_mode\"] = pop!(gen, \"WMOD\")\n\n            if _is_synch_condenser(sub_data, pm_data)\n                sub_data[\"fuel\"] = \"SYNC_COND\"\n                sub_data[\"type\"] = \"SYNC_COND\"\n            end\n\n            if pm_data[\"source_version\"] == \"35\"\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"NREG\" => pop!(gen, \"NREG\"),\n                    \"BASLOD\" => pop!(gen, \"BASLOD\"),\n                )\n            elseif pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"IREG\" => pop!(gen, \"IREG\"),\n                    \"WPF\" => pop!(gen, \"WPF\"),\n                    \"WMOD\" => sub_data[\"m_control_mode\"],\n                    \"GTAP\" => pop!(gen, \"GTAP\"),\n                    \"RMPCT\" => pop!(gen, \"RMPCT\"),\n                )\n            else\n                error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n            end\n\n            # Default Cost functions\n            sub_data[\"model\"] = 2\n            sub_data[\"startup\"] = 0.0\n            sub_data[\"shutdown\"] = 0.0\n            sub_data[\"ncost\"] = 2\n            sub_data[\"cost\"] = [1.0, 0.0]\n\n            sub_data[\"source_id\"] =\n                [\"generator\", string(sub_data[\"gen_bus\"]), pop!(gen, \"ID\")]\n            sub_data[\"index\"] = ix\n\n            if import_all\n                _import_remaining_keys!(sub_data, gen)\n            end\n\n            pm_data[\"gen\"][ix] = sub_data\n        end\n    else\n        pm_data[\"gen\"] = Vector{Dict{String, Any}}()\n    end\nend\n\nfunction _psse2pm_area_interchange!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E AreaInterchange data into a PowerModels Dict...\"\n    pm_data[\"area_interchange\"] = []\n\n    if haskey(pti_data, \"AREA INTERCHANGE\")\n        for area_int in pti_data[\"AREA INTERCHANGE\"]\n            sub_data = Dict{String, Any}()\n            sub_data[\"area_name\"] = pop!(area_int, \"ARNAME\")\n            sub_data[\"area_number\"] = pop!(area_int, \"I\")\n            sub_data[\"bus_number\"] = pop!(area_int, \"ISW\")\n            sub_data[\"net_interchange\"] = pop!(area_int, \"PDES\")\n            sub_data[\"tol_interchange\"] = pop!(area_int, \"PTOL\")\n            sub_data[\"index\"] = length(pm_data[\"area_interchange\"]) + 1\n            if import_all\n                _import_remaining_keys!(sub_data, area_int)\n            end\n\n            push!(pm_data[\"area_interchange\"], sub_data)\n        end\n    end\nend\n\nfunction _psse2pm_interarea_transfer!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E InterAreaTransfer data into a PowerModels Dict...\"\n    pm_data[\"interarea_transfer\"] = []\n\n    if haskey(pti_data, \"INTER-AREA TRANSFER\")\n        for interarea in pti_data[\"INTER-AREA TRANSFER\"]\n            sub_data = Dict{String, Any}()\n            sub_data[\"area_from\"] = pop!(interarea, \"ARFROM\")\n            sub_data[\"area_to\"] = pop!(interarea, \"ARTO\")\n            sub_data[\"transfer_id\"] = pop!(interarea, \"TRID\")\n            sub_data[\"power_transfer\"] = pop!(interarea, \"PTRAN\")\n\n            sub_data[\"index\"] = length(pm_data[\"interarea_transfer\"]) + 1\n            if import_all\n                _import_remaining_keys!(sub_data, interarea)\n            end\n\n            push!(pm_data[\"interarea_transfer\"], sub_data)\n        end\n    end\nend\n\nfunction _psse2pm_zone!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Zone data into a PowerModels Dict...\"\n    pm_data[\"zone\"] = []\n\n    if haskey(pti_data, \"ZONE\")\n        for zone in pti_data[\"ZONE\"]\n            sub_data = Dict{String, Any}()\n            sub_data[\"zone_number\"] = pop!(zone, \"I\")\n            sub_data[\"zone_name\"] = pop!(zone, \"ZONAME\")\n            sub_data[\"index\"] = length(pm_data[\"zone\"]) + 1\n            if import_all\n                _import_remaining_keys!(sub_data, zone)\n            end\n\n            push!(pm_data[\"zone\"], sub_data)\n        end\n    end\nend\n\n\"\"\"\n    _psse2pm_bus!(pm_data, pti_data)\n\nParses PSS(R)E-style Bus data into a PowerModels-style Dict. \"source_id\" is given\nby [\"I\", \"NAME\"] in PSS(R)E Bus specification.\n\"\"\"\nfunction _psse2pm_bus!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Bus data into a PowerModels Dict...\"\n    pm_data[\"has_isolated_type_buses\"] = false\n    pm_data[\"bus\"] = Dict{Int, Any}()\n    if haskey(pti_data, \"BUS\")\n        for bus in pti_data[\"BUS\"]\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"bus_i\"] = bus[\"I\"]\n            sub_data[\"bus_type\"] = pop!(bus, \"IDE\")\n            if sub_data[\"bus_type\"] == 4\n                @warn \"The PSS(R)E data contains buses designated as isolated. The parser will check if the buses are connected or topologically isolated.\"\n                pm_data[\"has_isolated_type_buses\"] = true\n                sub_data[\"bus_status\"] = false\n                pm_data[\"connected_buses\"] = Set{Int}()\n                pm_data[\"candidate_isolated_to_pq_buses\"] = Set{Int}()\n                pm_data[\"candidate_isolated_to_pv_buses\"] = Set{Int}()\n            else\n                sub_data[\"bus_status\"] = true\n            end\n            sub_data[\"area\"] = pop!(bus, \"AREA\")\n            sub_data[\"vm\"] = pop!(bus, \"VM\")\n            sub_data[\"va\"] = pop!(bus, \"VA\")\n            sub_data[\"base_kv\"] = pop!(bus, \"BASKV\")\n            sub_data[\"zone\"] = pop!(bus, \"ZONE\")\n            sub_data[\"name\"] = pop!(bus, \"NAME\")\n            sub_data[\"vmax\"] = pop!(bus, \"NVHI\")\n            sub_data[\"vmin\"] = pop!(bus, \"NVLO\")\n            sub_data[\"hidden\"] = false\n\n            sub_data[\"source_id\"] = [\"bus\", \"$(bus[\"I\"])\"]\n            sub_data[\"index\"] = pop!(bus, \"I\")\n\n            if import_all\n                _import_remaining_keys!(sub_data, bus)\n            end\n\n            if haskey(pm_data[\"bus\"], sub_data[\"bus_i\"])\n                error(\"Repeated $(sub_data[\"bus_i\"])\")\n            end\n            pm_data[\"bus\"][sub_data[\"bus_i\"]] = sub_data\n        end\n    end\n    return\nend\n\n\"\"\"\n    _psse2pm_load!(pm_data, pti_data)\n\nParses PSS(R)E-style Load data into a PowerModels-style Dict. \"source_id\" is given\nby `[\"I\", \"ID\"]` in the PSS(R)E Load specification.\n\"\"\"\nfunction _psse2pm_load!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Load data into a PowerModels Dict...\"\n    pm_data[\"load\"] = []\n    if haskey(pti_data, \"LOAD\")\n        for load in pti_data[\"LOAD\"]\n            sub_data = Dict{String, Any}()\n            sub_data[\"load_bus\"] = pop!(load, \"I\")\n            sub_data[\"pd\"] = pop!(load, \"PL\")\n            sub_data[\"qd\"] = pop!(load, \"QL\")\n            sub_data[\"pi\"] = pop!(load, \"IP\")\n            sub_data[\"qi\"] = pop!(load, \"IQ\")\n            sub_data[\"py\"] = pop!(load, \"YP\")\n            # Reactive power component of constant Y load.\n            # Positive for an inductive load (consumes Q)\n            # Negative for a capacitive load (injects Q)\n            sub_data[\"qy\"] = -pop!(load, \"YQ\")\n            sub_data[\"conformity\"] = pop!(load, \"SCALE\")\n            sub_data[\"source_id\"] = [\"load\", sub_data[\"load_bus\"], pop!(load, \"ID\")]\n            sub_data[\"interruptible\"] = pop!(load, \"INTRPT\")\n            sub_data[\"ext\"] = Dict{String, Any}()\n\n            if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                sub_data[\"ext\"][\"LOADTYPE\"] = \"\"\n            elseif pm_data[\"source_version\"] == \"35\"\n                sub_data[\"ext\"][\"LOADTYPE\"] = pop!(load, \"LOADTYPE\", \"\")\n            else\n                error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n            end\n\n            sub_data[\"status\"] =\n                _determine_injector_status(\n                    load,\n                    pm_data,\n                    sub_data[\"load_bus\"],\n                    \"STATUS\",\n                    \"candidate_isolated_to_pq_buses\",\n                )\n            sub_data[\"index\"] = length(pm_data[\"load\"]) + 1\n            if import_all\n                _import_remaining_keys!(sub_data, load)\n            end\n            push!(pm_data[\"load\"], sub_data)\n        end\n    end\nend\n\n\"\"\"\n    _psse2pm_shunt!(pm_data, pti_data)\n\nParses PSS(R)E-style Fixed and Switched Shunt data into a PowerModels-style\nDict. \"source_id\" is given by `[\"I\", \"ID\"]` for Fixed Shunts, and `[\"I\", \"SWREM\"]`\nfor Switched Shunts, as given by the PSS(R)E Fixed and Switched Shunts\nspecifications.\n\"\"\"\nfunction _psse2pm_shunt!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Fixed & Switched Shunt data into a PowerModels Dict...\"\n\n    pm_data[\"shunt\"] = []\n    if haskey(pti_data, \"FIXED SHUNT\")\n        for shunt in pti_data[\"FIXED SHUNT\"]\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"shunt_bus\"] = pop!(shunt, \"I\")\n            sub_data[\"gs\"] = pop!(shunt, \"GL\")\n            sub_data[\"bs\"] = pop!(shunt, \"BL\")\n            sub_data[\"status\"] = _determine_injector_status(\n                shunt,\n                pm_data,\n                sub_data[\"shunt_bus\"],\n                \"STATUS\",\n                \"candidate_isolated_to_pq_buses\",\n            )\n\n            sub_data[\"source_id\"] =\n                [\"fixed shunt\", sub_data[\"shunt_bus\"], pop!(shunt, \"ID\")]\n            sub_data[\"index\"] = length(pm_data[\"shunt\"]) + 1\n\n            if import_all\n                _import_remaining_keys!(sub_data, shunt)\n            end\n            push!(pm_data[\"shunt\"], sub_data)\n        end\n    end\n\n    pm_data[\"switched_shunt\"] = []\n    if haskey(pti_data, \"SWITCHED SHUNT\")\n        for switched_shunt in pti_data[\"SWITCHED SHUNT\"]\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"shunt_bus\"] = pop!(switched_shunt, \"I\")\n            sub_data[\"gs\"] = 0.0\n            sub_data[\"bs\"] = pop!(switched_shunt, \"BINIT\")\n            sub_data[\"status\"] = _determine_injector_status(\n                switched_shunt,\n                pm_data,\n                sub_data[\"shunt_bus\"],\n                \"STAT\",\n                \"candidate_isolated_to_pq_buses\",\n            )\n            sub_data[\"admittance_limits\"] =\n                (pop!(switched_shunt, \"VSWLO\"), pop!(switched_shunt, \"VSWHI\"))\n\n            step_numbers = Dict(\n                k => v for\n                (k, v) in switched_shunt if startswith(k, \"N\") && isdigit(last(k))\n            )\n            step_numbers_sorted =\n                sort(collect(keys(step_numbers)); by = x -> parse(Int, x[2:end]))\n            sub_data[\"step_number\"] = [step_numbers[k] for k in step_numbers_sorted]\n            sub_data[\"step_number\"] = sub_data[\"step_number\"][sub_data[\"step_number\"] .!= 0]\n\n            sub_data[\"ext\"] = Dict{String, Any}(\n                \"MODSW\" => switched_shunt[\"MODSW\"],\n                \"ADJM\" => switched_shunt[\"ADJM\"],\n                \"RMPCT\" => switched_shunt[\"RMPCT\"],\n                \"RMIDNT\" => switched_shunt[\"RMIDNT\"],\n            )\n\n            y_increment = Dict(\n                k => v for\n                (k, v) in switched_shunt if startswith(k, \"B\") && isdigit(last(k))\n            )\n            y_increment_sorted =\n                sort(collect(keys(y_increment)); by = x -> parse(Int, x[2:end]))\n            sub_data[\"y_increment\"] = [y_increment[k] for k in y_increment_sorted]im\n            sub_data[\"y_increment\"] = sub_data[\"y_increment\"][sub_data[\"y_increment\"] .!= 0]\n\n            if pm_data[\"source_version\"] == \"35\"\n                sub_data[\"sw_id\"] = pop!(switched_shunt, \"ID\")\n\n                initial_ss_status = Dict(\n                    k => v for\n                    (k, v) in switched_shunt if startswith(k, \"S\") && isdigit(last(k))\n                )\n                initial_ss_status_sorted =\n                    sort(collect(keys(initial_ss_status)); by = x -> parse(Int, x[2:end]))\n                sub_data[\"initial_status\"] =\n                    [initial_ss_status[k] for k in initial_ss_status_sorted]\n                sub_data[\"initial_status\"] =\n                    sub_data[\"initial_status\"][1:length(sub_data[\"step_number\"])]\n\n                sub_data[\"ext\"][\"NREG\"] = pop!(switched_shunt, \"NREG\")\n            elseif pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                sub_data[\"ext\"][\"SWREM\"] = switched_shunt[\"SWREM\"]\n                sub_data[\"initial_status\"] = ones(Int, length(sub_data[\"y_increment\"]))\n            else\n                error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n            end\n\n            sub_data[\"index\"] = length(pm_data[\"switched_shunt\"]) + 1\n            sub_data[\"source_id\"] =\n                [\"switched shunt\", sub_data[\"shunt_bus\"], sub_data[\"index\"]]\n\n            if import_all\n                _import_remaining_keys!(sub_data, switched_shunt)\n            end\n            push!(pm_data[\"switched_shunt\"], sub_data)\n        end\n    end\nend\n\nfunction apply_tap_correction!(\n    windv_value::Float64,\n    transformer::Dict{String, Any},\n    cod_key::String,\n    rmi_key::String,\n    rma_key::String,\n    ntp_key::String,\n    cw_value::Int64,\n    winding_name::String,\n)\n    if abs(transformer[cod_key]) ∈ [1, 2] && cw_value ∈ [1, 2, 3]\n        tap_positions = collect(\n            range(\n                transformer[rmi_key],\n                transformer[rma_key];\n                length = Int(transformer[ntp_key]),\n            ),\n        )\n        closest_tap_ix = argmin(abs.(tap_positions .- windv_value))\n        if !isapprox(\n            windv_value,\n            tap_positions[closest_tap_ix];\n            atol = PARSER_TAP_RATIO_CORRECTION_TOL,\n        )\n            @warn \"Transformer $winding_name winding tap setting is not on a step; $windv_value set to $(tap_positions[closest_tap_ix])\"\n            return tap_positions[closest_tap_ix]\n        end\n    end\n    return windv_value\nend\n\n# Base Power has a different key in sub_data depending on the number of windings\nfunction _transformer_mag_pu_conversion(\n    transformer::Dict,\n    sub_data::Dict,\n    base_power::Float64,\n)\n    if isapprox(transformer[\"MAG1\"], ZERO_IMPEDANCE_REACTANCE_THRESHOLD) &&\n       isapprox(transformer[\"MAG2\"], ZERO_IMPEDANCE_REACTANCE_THRESHOLD)\n        @warn \"Transformer $(sub_data[\"f_bus\"]) -> $(sub_data[\"t_bus\"]) has zero MAG1 and MAG2 values.\"\n        return 0.0, 0.0\n    else\n        G_pu = 1e-6 * transformer[\"MAG1\"] / base_power\n        mag_diff = transformer[\"MAG2\"]^2 - G_pu^2\n        @assert mag_diff >= -ZERO_IMPEDANCE_REACTANCE_THRESHOLD\n        B_pu = sqrt(max(0.0, mag_diff))\n        return G_pu, B_pu\n    end\nend\n\n\"\"\"\n    _psse2pm_transformer!(pm_data, pti_data)\n\nParses PSS(R)E-style Transformer data into a PowerModels-style Dict. \"source_id\"\nis given by `[\"I\", \"J\", \"K\", \"CKT\", \"winding\"]`, where \"winding\" is 0 if\ntransformer is two-winding, and 1, 2, or 3 for three-winding, and the remaining\nkeys are defined in the PSS(R)E Transformer specification.\n\"\"\"\nfunction _psse2pm_transformer!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Transformer data into a PowerModels Dict...\"\n    if !haskey(pm_data, \"branch\")\n        pm_data[\"branch\"] = []\n    end\n\n    if haskey(pti_data, \"TRANSFORMER\")\n        starbus_id = 10^ceil(Int, log10(abs(_find_max_bus_id(pm_data)))) + 1\n        for transformer in pti_data[\"TRANSFORMER\"]\n            if !(transformer[\"CZ\"] in [1, 2, 3])\n                @warn(\n                    \"transformer CZ value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CZ\"]), should be 1, 2 or 3\",\n                )\n                transformer[\"CZ\"] = 1\n            end\n\n            if !(transformer[\"CW\"] in [1, 2, 3])\n                @warn(\n                    \"transformer CW value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CW\"]), should be 1, 2 or 3\",\n                )\n                transformer[\"CW\"] = 1\n            end\n\n            if !(transformer[\"CM\"] in [1, 2])\n                @warn(\n                    \"transformer CM value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CM\"]), should be 1 or 2\",\n                )\n                transformer[\"CM\"] = 1\n            end\n\n            if transformer[\"K\"] == 0  # Two-winding Transformers\n                sub_data = Dict{String, Any}()\n\n                sub_data[\"f_bus\"] = transformer[\"I\"]\n                sub_data[\"t_bus\"] = transformer[\"J\"]\n                if pm_data[\"has_isolated_type_buses\"]\n                    bus_from = pm_data[\"bus\"][sub_data[\"f_bus\"]]\n                    bus_to = pm_data[\"bus\"][sub_data[\"t_bus\"]]\n                    if !(bus_from[\"bus_type\"] == 4 || bus_to[\"bus_type\"] == 4)\n                        push!(pm_data[\"connected_buses\"], sub_data[\"f_bus\"])\n                        push!(pm_data[\"connected_buses\"], sub_data[\"t_bus\"])\n                    end\n                end\n\n                # Store base_power\n                if transformer[\"SBASE1-2\"] < 0.0\n                    throw(\n                        IS.InvalidValue(\n                            \"Transformer $(sub_data[\"f_bus\"]) -> $(sub_data[\"t_bus\"]) has non-positive base power SBASE1-2: $(transformer[\"SBASE1-2\"])\",\n                        ),\n                    )\n                end\n                if iszero(transformer[\"SBASE1-2\"])\n                    sub_data[\"base_power\"] = pm_data[\"baseMVA\"]\n                else\n                    sub_data[\"base_power\"] = transformer[\"SBASE1-2\"]\n                end\n                if iszero(transformer[\"NOMV1\"])\n                    sub_data[\"base_voltage_from\"] =\n                        _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                else\n                    sub_data[\"base_voltage_from\"] = transformer[\"NOMV1\"]\n                end\n                if iszero(transformer[\"NOMV2\"])\n                    sub_data[\"base_voltage_to\"] =\n                        _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                else\n                    sub_data[\"base_voltage_to\"] = transformer[\"NOMV2\"]\n                end\n\n                # Unit Transformations\n                # Data must be stored in the DEVICE_BASE\n                # Z_base_device = (V_device)^2 / S_device, Z_base_sys = (V_device)^2 / S_sys\n                # Z_ohms = Z_pu_sys * Z_base_sys, Z_pu_device = Z_ohms / Z_device = Z_pu_sys * S_device / S_sys\n                mva_ratio = sub_data[\"base_power\"] / pm_data[\"baseMVA\"]\n                Z_base_device = sub_data[\"base_voltage_from\"]^2 / sub_data[\"base_power\"]\n                Z_base_sys = sub_data[\"base_voltage_from\"]^2 / pm_data[\"baseMVA\"]\n                #_get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)^2 /\n                #pm_data[\"baseMVA\"]\n                if transformer[\"CZ\"] == 2  # \"for resistance and reactance in pu on system MVA base and winding voltage base\"\n                    # Compute br_r and br_x in pu of device base\n                    br_r, br_x = transformer[\"R1-2\"], transformer[\"X1-2\"]\n                else  # NOT \"for resistance and reactance in pu on system MVA base and winding voltage base\"\n                    if transformer[\"CZ\"] == 3  # \"for transformer load loss in watts and impedance magnitude in pu on a specified MVA base and winding voltage base.\"\n                        br_r = 1e-6 * transformer[\"R1-2\"] / sub_data[\"base_power\"] # device pu\n                        br_x = sqrt(transformer[\"X1-2\"]^2 - br_r^2) # device pu\n                    else # \"CZ\" = 1 in system base pu\n                        @assert transformer[\"CZ\"] == 1\n                        br_r, br_x = transformer[\"R1-2\"], transformer[\"X1-2\"] # sys pu\n                        if iszero(Z_base_device) # NOMV1 = 0.0: use the power ratios\n                            br_r = transformer[\"R1-2\"] * mva_ratio\n                            br_x = transformer[\"X1-2\"] * mva_ratio\n                        else # NOMV1 could potentially be different than the bus_voltage, use impedance ratios\n                            br_r = (transformer[\"R1-2\"] * Z_base_sys) / Z_base_device\n                            br_x = (transformer[\"X1-2\"] * Z_base_sys) / Z_base_device\n                        end\n                    end\n                end\n\n                # Zeq scaling for tap2 (see eq (4.21b) in PROGRAM APPLICATION GUIDE 1 in PSSE installation folder)\n                # Unit Transformations\n                if transformer[\"CW\"] == 1  # \"for off-nominal turns ratio in pu of winding bus base voltage\"\n                    br_r *= transformer[\"WINDV2\"]^2\n                    br_x *= transformer[\"WINDV2\"]^2\n                    # NOT \"for off-nominal turns ratio in pu of winding bus base voltage\"\n                elseif transformer[\"CW\"] == 2 # \"for winding voltage in kV\"\n                    br_r *=\n                        (\n                            transformer[\"WINDV2\"] /\n                            _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                        )^2\n                    br_x *=\n                        (\n                            transformer[\"WINDV2\"] /\n                            _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                        )^2\n                elseif transformer[\"CW\"] == 3  # \"for off-nominal turns ratio in pu of nominal winding voltage, NOMV1, NOMV2 and NOMV3.\"\n                    #The nominal (rated) Winding 2 voltage base in kV, or zero to indicate\n                    # that nominal Winding 2 voltage is assumed to be identical to the base\n                    # voltage of bus J. NOMV2 is used in converting tap ratio data between values\n                    # in per unit of nominal Winding 2 voltage and values in per unit of Winding 2\n                    #bus base voltage when CW is 3. NOMV2 = 0.0 by default.\n                    if iszero(transformer[\"NOMV2\"])\n                        nominal_voltage_ratio = 1.0\n                    else\n                        nominal_voltage_ratio =\n                            transformer[\"NOMV2\"] /\n                            _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                    end\n\n                    br_r *= (transformer[\"WINDV2\"] * (nominal_voltage_ratio))^2\n                    br_x *= (transformer[\"WINDV2\"] * (nominal_voltage_ratio))^2\n                else\n                    error(\"invalid transformer $(transformer[\"CW\"])\")\n                end\n\n                if transformer[\"X1-2\"] < 0.0 && br_x < 0.0\n                    @warn \"Transformer $(sub_data[\"f_bus\"]) -> $(sub_data[\"t_bus\"]) has negative impedance values X1-2: $(transformer[\"X1-2\"]), br_x: $(br_x)\"\n                end\n\n                sub_data[\"br_r\"] = br_r\n                sub_data[\"br_x\"] = br_x\n\n                if transformer[\"CM\"] == 1\n                    # Transform admittance to device per unit\n                    mva_ratio_12 = sub_data[\"base_power\"] / pm_data[\"baseMVA\"]\n                    sub_data[\"g_fr\"] = transformer[\"MAG1\"] / mva_ratio_12\n                    sub_data[\"b_fr\"] = transformer[\"MAG2\"] / mva_ratio_12\n                else # CM=2: MAG1 are no load loss in Watts and MAG2 is the exciting current in pu, in device base.\n                    @assert transformer[\"CM\"] == 2\n                    G_pu, B_pu = _transformer_mag_pu_conversion(\n                        transformer,\n                        sub_data,\n                        sub_data[\"base_power\"],\n                    )\n                    sub_data[\"g_fr\"] = G_pu\n                    sub_data[\"b_fr\"] = B_pu\n                end\n                sub_data[\"g_to\"] = 0.0\n                sub_data[\"b_to\"] = 0.0\n\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"psse_name\" => transformer[\"NAME\"],\n                    \"CW\" => transformer[\"CW\"],\n                    \"CZ\" => transformer[\"CZ\"],\n                    \"CM\" => transformer[\"CM\"],\n                    \"COD1\" => transformer[\"COD1\"],\n                    \"CONT1\" => transformer[\"CONT1\"],\n                    \"NOMV1\" => transformer[\"NOMV1\"],\n                    \"NOMV2\" => transformer[\"NOMV2\"],\n                    \"WINDV1\" => transformer[\"WINDV1\"],\n                    \"WINDV2\" => transformer[\"WINDV2\"],\n                    \"SBASE1-2\" => transformer[\"SBASE1-2\"],\n                    \"RMI1\" => transformer[\"RMI1\"],\n                    \"RMA1\" => transformer[\"RMA1\"],\n                    \"NTP1\" => transformer[\"NTP1\"],\n                    \"R1-2\" => transformer[\"R1-2\"],\n                    \"X1-2\" => transformer[\"X1-2\"],\n                    \"MAG1\" => transformer[\"MAG1\"],\n                    \"MAG2\" => transformer[\"MAG2\"],\n                )\n\n                if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                    sub_data[\"rate_a\"] = pop!(transformer, \"RATA1\")\n                    sub_data[\"rate_b\"] = pop!(transformer, \"RATB1\")\n                    sub_data[\"rate_c\"] = pop!(transformer, \"RATC1\")\n                elseif pm_data[\"source_version\"] == \"35\"\n                    sub_data[\"rate_a\"] = pop!(transformer, \"RATE11\")\n                    sub_data[\"rate_b\"] = pop!(transformer, \"RATE12\")\n                    sub_data[\"rate_c\"] = pop!(transformer, \"RATE13\")\n\n                    for i in 4:12\n                        rate_key = \"RATE1$i\"\n                        if haskey(transformer, rate_key)\n                            sub_data[\"ext\"][rate_key] = pop!(transformer, rate_key)\n                        end\n                    end\n                else\n                    error(\n                        \"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\",\n                    )\n                end\n\n                if sub_data[\"rate_a\"] == 0.0\n                    delete!(sub_data, \"rate_a\")\n                end\n                if sub_data[\"rate_b\"] == 0.0\n                    delete!(sub_data, \"rate_b\")\n                end\n                if sub_data[\"rate_c\"] == 0.0\n                    delete!(sub_data, \"rate_c\")\n                end\n\n                if import_all\n                    sub_data[\"windv1\"] = transformer[\"WINDV1\"]\n                    sub_data[\"windv2\"] = transformer[\"WINDV2\"]\n                    sub_data[\"nomv1\"] = transformer[\"NOMV1\"]\n                    sub_data[\"nomv2\"] = transformer[\"NOMV2\"]\n                end\n\n                windv1 = pop!(transformer, \"WINDV1\")\n                windv1 = apply_tap_correction!(\n                    windv1,\n                    transformer,\n                    \"COD1\",\n                    \"RMI1\",\n                    \"RMA1\",\n                    \"NTP1\",\n                    transformer[\"CW\"],\n                    \"primary\",\n                )\n                sub_data[\"tap\"] = windv1 / pop!(transformer, \"WINDV2\")\n                sub_data[\"shift\"] = pop!(transformer, \"ANG1\")\n\n                if transformer[\"CW\"] != 1  # NOT \"for off-nominal turns ratio in pu of winding bus base voltage\"\n                    sub_data[\"tap\"] *=\n                        _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data) /\n                        _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                    if transformer[\"CW\"] == 3  # \"for off-nominal turns ratio in pu of nominal winding voltage, NOMV1, NOMV2 and NOMV3.\"\n                        if iszero(transformer[\"NOMV1\"])\n                            winding1_nominal_voltage =\n                                _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                        else\n                            winding1_nominal_voltage = transformer[\"NOMV1\"]\n                        end\n\n                        if iszero(transformer[\"NOMV2\"])\n                            winding2_nominal_voltage =\n                                _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                        else\n                            winding2_nominal_voltage = transformer[\"NOMV2\"]\n                        end\n\n                        sub_data[\"tap\"] *=\n                            winding1_nominal_voltage / winding2_nominal_voltage\n                    end\n                end\n\n                if import_all\n                    sub_data[\"cw\"] = transformer[\"CW\"]\n                end\n\n                if transformer[\"STAT\"] == 0 || transformer[\"STAT\"] == 2\n                    sub_data[\"br_status\"] = 0\n                else\n                    sub_data[\"br_status\"] = 1\n                end\n\n                sub_data[\"angmin\"] = 0.0\n                sub_data[\"angmax\"] = 0.0\n\n                sub_data[\"source_id\"] = [\n                    \"transformer\",\n                    pop!(transformer, \"I\"),\n                    pop!(transformer, \"J\"),\n                    pop!(transformer, \"K\"),\n                    pop!(transformer, \"CKT\"),\n                    0,\n                ]\n\n                sub_data[\"transformer\"] = true\n                sub_data[\"correction_table\"] = transformer[\"TAB1\"]\n\n                sub_data[\"index\"] = length(pm_data[\"branch\"]) + 1\n                sub_data[\"COD1\"] = transformer[\"COD1\"]\n                if import_all\n                    _import_remaining_keys!(\n                        sub_data,\n                        transformer;\n                        exclude = [\n                            \"I\",\n                            \"J\",\n                            \"K\",\n                            \"CZ\",\n                            \"CW\",\n                            \"R1-2\",\n                            \"R2-3\",\n                            \"R3-1\",\n                            \"X1-2\",\n                            \"X2-3\",\n                            \"X3-1\",\n                            \"SBASE1-2\",\n                            \"SBASE2-3\",\n                            \"SBASE3-1\",\n                            \"MAG1\",\n                            \"MAG2\",\n                            \"STAT\",\n                            \"NOMV1\",\n                            \"NOMV2\",\n                        ],\n                    )\n                end\n                branch_isolated_bus_modifications!(pm_data, sub_data)\n                push!(pm_data[\"branch\"], sub_data)\n            else  # Three-winding Transformers\n                # Create 3w-transformer key\n                if !haskey(pm_data, \"3w_transformer\")\n                    pm_data[\"3w_transformer\"] = []\n                end\n\n                bus_id1, bus_id2, bus_id3 =\n                    transformer[\"I\"], transformer[\"J\"], transformer[\"K\"]\n                # Creates a starbus (or \"dummy\" bus) to which each winding of the transformer will connect\n                starbus = _create_starbus_from_transformer(pm_data, transformer, starbus_id)\n                pm_data[\"bus\"][starbus_id] = starbus\n                if pm_data[\"has_isolated_type_buses\"]\n                    bus_primary = pm_data[\"bus\"][bus_id1]\n                    bus_secondary = pm_data[\"bus\"][bus_id2]\n                    bus_tertiary = pm_data[\"bus\"][bus_id3]\n                    push!(pm_data[\"connected_buses\"], starbus_id)   # Starbus should never be converted to isolated\n                    # If one bus winding is isolated, the other two buses should still be considered connected:\n                    !(bus_primary[\"bus_type\"] == 4) &&\n                        push!(pm_data[\"connected_buses\"], bus_id1)\n                    !(bus_secondary[\"bus_type\"] == 4) &&\n                        push!(pm_data[\"connected_buses\"], bus_id2)\n                    !(bus_tertiary[\"bus_type\"] == 4) &&\n                        push!(pm_data[\"connected_buses\"], bus_id3)\n                end\n                # Add parameters to the 3w-transformer key\n                sub_data = Dict{String, Any}()\n                bases = [\n                    transformer[\"SBASE1-2\"],\n                    transformer[\"SBASE2-3\"],\n                    transformer[\"SBASE3-1\"],\n                ]\n                base_names = [\n                    \"base_power_12\",\n                    \"base_power_23\",\n                    \"base_power_13\",\n                ]\n\n                for (ix, base) in enumerate(bases)\n                    if base < 0.0\n                        throw(\n                            IS.InvalidValue(\n                                \"Transformer $(transformer[I]) -> $(transformer[\"J\"]) -> $(transformer[\"K\"]) has negative base power $base\",\n                            ),\n                        )\n                    end\n                    if iszero(base)\n                        sub_data[base_names[ix]] = pm_data[\"baseMVA\"]\n                    else\n                        sub_data[base_names[ix]] = base\n                    end\n                end\n\n                if iszero(transformer[\"NOMV1\"])\n                    sub_data[\"base_voltage_primary\"] =\n                        _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                else\n                    sub_data[\"base_voltage_primary\"] = transformer[\"NOMV1\"]\n                end\n                if iszero(transformer[\"NOMV2\"])\n                    sub_data[\"base_voltage_secondary\"] =\n                        _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                else\n                    sub_data[\"base_voltage_secondary\"] = transformer[\"NOMV2\"]\n                end\n                if iszero(transformer[\"NOMV3\"])\n                    sub_data[\"base_voltage_tertiary\"] =\n                        _get_bus_value(transformer[\"K\"], \"base_kv\", pm_data)\n                else\n                    sub_data[\"base_voltage_tertiary\"] = transformer[\"NOMV3\"]\n                end\n\n                mva_ratio_12 = sub_data[\"base_power_12\"] / pm_data[\"baseMVA\"]\n                mva_ratio_23 = sub_data[\"base_power_23\"] / pm_data[\"baseMVA\"]\n                mva_ratio_31 = sub_data[\"base_power_13\"] / pm_data[\"baseMVA\"]\n                Z_base_device_1 = transformer[\"NOMV1\"]^2 / sub_data[\"base_power_12\"]\n                Z_base_device_2 = transformer[\"NOMV2\"]^2 / sub_data[\"base_power_23\"]\n                Z_base_device_3 = transformer[\"NOMV3\"]^2 / sub_data[\"base_power_13\"]\n                Z_base_sys_1 = (sub_data[\"base_voltage_primary\"])^2 / pm_data[\"baseMVA\"]\n                Z_base_sys_2 =\n                    (sub_data[\"base_voltage_secondary\"])^2 / pm_data[\"baseMVA\"]\n                Z_base_sys_3 =\n                    (sub_data[\"base_voltage_tertiary\"])^2 / pm_data[\"baseMVA\"]\n                # Create 3 branches from a three winding transformer (one for each winding, which will each connect to the starbus)\n                br_r12, br_r23, br_r31 =\n                    transformer[\"R1-2\"], transformer[\"R2-3\"], transformer[\"R3-1\"]\n                br_x12, br_x23, br_x31 =\n                    transformer[\"X1-2\"], transformer[\"X2-3\"], transformer[\"X3-1\"]\n\n                # Unit Transformations\n                if transformer[\"CZ\"] == 3  # \"for transformer load loss in watts and impedance magnitude in pu on a specified MVA base and winding voltage base.\"\n                    # In device base\n                    br_r12 *= 1e-6 / sub_data[\"base_power_12\"]\n                    br_r23 *= 1e-6 / sub_data[\"base_power_23\"]\n                    br_r31 *= 1e-6 / sub_data[\"base_power_13\"]\n\n                    br_x12 = sqrt(br_x12^2 - br_r12^2)\n                    br_x23 = sqrt(br_x23^2 - br_r23^2)\n                    br_x31 = sqrt(br_x31^2 - br_r31^2)\n                    # Unit Transformations\n                elseif transformer[\"CZ\"] == 1  # \"for resistance and reactance in pu on system MVA base (transform to device base)\"\n                    if iszero(Z_base_device_1) # NOMV1 = 0.0: use the power ratios\n                        br_r12 *= mva_ratio_12\n                        br_x12 *= mva_ratio_12\n                    else # NOMV1 could potentially be different than the bus_voltage, use impedance ratios\n                        br_r12 *= Z_base_sys_1 / Z_base_device_1\n                        br_x12 *= Z_base_sys_1 / Z_base_device_1\n                    end\n                    if iszero(Z_base_device_2) # NOMV2 = 0.0: use the power ratios\n                        br_r23 *= mva_ratio_23\n                        br_x23 *= mva_ratio_23\n                    else # NOMV2 could potentially be different than the bus_voltage, use impedance ratios\n                        br_r23 *= Z_base_sys_2 / Z_base_device_2\n                        br_x23 *= Z_base_sys_2 / Z_base_device_2\n                    end\n                    if iszero(Z_base_device_3) # NOMV3 = 0.0: use the power ratios\n                        br_r31 *= mva_ratio_31\n                        br_x31 *= mva_ratio_31\n                    else # NOMV3 could potentially be different than the bus_voltage, use impedance ratios\n                        br_r31 *= Z_base_sys_3 / Z_base_device_3\n                        br_x31 *= Z_base_sys_3 / Z_base_device_3\n                    end\n                end\n\n                # Compute primary,secondary, tertiary impedances in system base, then convert to base power of appropriate winding\n                if iszero(Z_base_device_1)\n                    br_r12_sysbase = br_r12 / mva_ratio_12\n                    br_x12_sysbase = br_x12 / mva_ratio_12\n                else\n                    br_r12_sysbase = br_r12 * (Z_base_device_1 / Z_base_sys_1)\n                    br_x12_sysbase = br_x12 * (Z_base_device_1 / Z_base_sys_1)\n                end\n                if iszero(Z_base_device_2)\n                    br_r23_sysbase = br_r23 / mva_ratio_23\n                    br_x23_sysbase = br_x23 / mva_ratio_23\n                else\n                    br_r23_sysbase = br_r23 * (Z_base_device_2 / Z_base_sys_2)\n                    br_x23_sysbase = br_x23 * (Z_base_device_2 / Z_base_sys_2)\n                end\n                if iszero(Z_base_device_3)\n                    br_r31_sysbase = br_r31 / mva_ratio_31\n                    br_x31_sysbase = br_x31 / mva_ratio_31\n                else\n                    br_r31_sysbase = br_r31 * (Z_base_device_3 / Z_base_sys_3)\n                    br_x31_sysbase = br_x31 * (Z_base_device_3 / Z_base_sys_3)\n                end\n                # See \"Power System Stability and Control\", ISBN: 0-07-035958-X, Eq. 6.72\n                Zr_p = 1 / 2 * (br_r12_sysbase - br_r23_sysbase + br_r31_sysbase)\n                Zr_s = 1 / 2 * (br_r23_sysbase - br_r31_sysbase + br_r12_sysbase)\n                Zr_t = 1 / 2 * (br_r31_sysbase - br_r12_sysbase + br_r23_sysbase)\n                Zx_p = 1 / 2 * (br_x12_sysbase - br_x23_sysbase + br_x31_sysbase)\n                Zx_s = 1 / 2 * (br_x23_sysbase - br_x31_sysbase + br_x12_sysbase)\n                Zx_t = 1 / 2 * (br_x31_sysbase - br_x12_sysbase + br_x23_sysbase)\n\n                # See PSSE Manual (Section 1.15.1 \"Three-Winding Transformer Notes\" of Data Formats file)\n                zero_names = []\n                if isapprox(Zx_p, 0.0; atol = eps(Float32))\n                    push!(zero_names, \"primary\")\n                    Zx_p = ZERO_IMPEDANCE_REACTANCE_THRESHOLD\n                end\n                if isapprox(Zx_s, 0.0; atol = eps(Float32))\n                    push!(zero_names, \"secondary\")\n                    Zx_s = ZERO_IMPEDANCE_REACTANCE_THRESHOLD\n                end\n                if isapprox(Zx_t, 0.0; atol = eps(Float32))\n                    push!(zero_names, \"tertiary\")\n                    Zx_t = ZERO_IMPEDANCE_REACTANCE_THRESHOLD\n                end\n                if !isempty(zero_names)\n                    @info \"Zero impedance reactance detected in 3W Transformer $(transformer[\"NAME\"]) for winding(s): $(join(zero_names, \", \")). Setting to threshold value $(ZERO_IMPEDANCE_REACTANCE_THRESHOLD).\"\n                end\n\n                if iszero(Z_base_device_1)\n                    Zr_p *= mva_ratio_12\n                    Zx_p *= mva_ratio_12\n                else\n                    Zr_p *= Z_base_sys_1 / Z_base_device_1\n                    Zx_p *= Z_base_sys_1 / Z_base_device_1\n                end\n                if iszero(Z_base_device_2)\n                    Zr_s *= mva_ratio_23\n                    Zx_s *= mva_ratio_23\n                else\n                    Zr_s *= Z_base_sys_2 / Z_base_device_2\n                    Zx_s *= Z_base_sys_2 / Z_base_device_2\n                end\n                if iszero(Z_base_device_3)\n                    Zr_t *= mva_ratio_31\n                    Zx_t *= mva_ratio_31\n                else\n                    Zr_t *= Z_base_sys_3 / Z_base_device_3\n                    Zx_t *= Z_base_sys_3 / Z_base_device_3\n                end\n\n                sub_data[\"name\"] = transformer[\"NAME\"]\n                sub_data[\"bus_primary\"] = bus_id1\n                sub_data[\"bus_secondary\"] = bus_id2\n                sub_data[\"bus_tertiary\"] = bus_id3\n\n                sub_data[\"available\"] = false\n                if transformer[\"STAT\"] != 0\n                    sub_data[\"available\"] = true\n                end\n\n                sub_data[\"available_primary\"] = true\n                sub_data[\"available_secondary\"] = true\n                sub_data[\"available_tertiary\"] = true\n\n                if transformer[\"STAT\"] == 2\n                    sub_data[\"available_secondary\"] = false\n                end\n\n                if transformer[\"STAT\"] == 3\n                    sub_data[\"available_tertiary\"] = false\n                end\n\n                if transformer[\"STAT\"] == 4\n                    sub_data[\"available_primary\"] = false\n                end\n\n                if transformer[\"STAT\"] == 0\n                    sub_data[\"available_primary\"] = false\n                    sub_data[\"available_secondary\"] = false\n                    sub_data[\"available_tertiary\"] = false\n                end\n\n                sub_data[\"star_bus\"] = starbus_id\n\n                sub_data[\"active_power_flow_primary\"] = 0.0\n                sub_data[\"reactive_power_flow_primary\"] = 0.0\n                sub_data[\"active_power_flow_secondary\"] = 0.0\n                sub_data[\"reactive_power_flow_secondary\"] = 0.0\n                sub_data[\"active_power_flow_tertiary\"] = 0.0\n                sub_data[\"reactive_power_flow_tertiary\"] = 0.0\n\n                sub_data[\"r_primary\"] = Zr_p\n                sub_data[\"x_primary\"] = Zx_p\n                sub_data[\"r_secondary\"] = Zr_s\n                sub_data[\"x_secondary\"] = Zx_s\n                sub_data[\"r_tertiary\"] = Zr_t\n                sub_data[\"x_tertiary\"] = Zx_t\n\n                if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                    sub_data[\"rating_primary\"] =\n                        min(\n                            transformer[\"RATA1\"],\n                            transformer[\"RATB1\"],\n                            transformer[\"RATC1\"],\n                        )\n                    sub_data[\"rating_secondary\"] =\n                        min(\n                            transformer[\"RATA2\"],\n                            transformer[\"RATB2\"],\n                            transformer[\"RATC2\"],\n                        )\n                    sub_data[\"rating_tertiary\"] =\n                        min(\n                            transformer[\"RATA3\"],\n                            transformer[\"RATB3\"],\n                            transformer[\"RATC3\"],\n                        )\n                    sub_data[\"rating\"] = min(\n                        sub_data[\"rating_primary\"],\n                        sub_data[\"rating_secondary\"],\n                        sub_data[\"rating_tertiary\"],\n                    )\n                elseif pm_data[\"source_version\"] == \"35\"\n                    sub_data[\"rating_primary\"] =\n                        min(\n                            transformer[\"RATE11\"],\n                            transformer[\"RATE12\"],\n                            transformer[\"RATE13\"],\n                        )\n                    sub_data[\"rating_secondary\"] =\n                        min(\n                            transformer[\"RATE21\"],\n                            transformer[\"RATE22\"],\n                            transformer[\"RATE23\"],\n                        )\n                    sub_data[\"rating_tertiary\"] =\n                        min(\n                            transformer[\"RATE31\"],\n                            transformer[\"RATE32\"],\n                            transformer[\"RATE33\"],\n                        )\n                    sub_data[\"rating\"] = min(\n                        sub_data[\"rating_primary\"],\n                        sub_data[\"rating_secondary\"],\n                        sub_data[\"rating_tertiary\"],\n                    )\n                else\n                    error(\n                        \"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\",\n                    )\n                end\n\n                sub_data[\"r_12\"] = br_r12\n                sub_data[\"x_12\"] = br_x12\n                sub_data[\"r_23\"] = br_r23\n                sub_data[\"x_23\"] = br_x23\n                sub_data[\"r_13\"] = br_r31\n                sub_data[\"x_13\"] = br_x31\n                if transformer[\"CM\"] == 1\n                    # Transform admittance to device per unit\n                    mva_ratio_12 = sub_data[\"base_power_12\"] / pm_data[\"baseMVA\"]\n                    sub_data[\"g\"] = transformer[\"MAG1\"] / mva_ratio_12\n                    sub_data[\"b\"] = transformer[\"MAG2\"] / mva_ratio_12\n                else # CM=2: MAG1 are no load loss in Watts and MAG2 is the exciting current in pu, in device base.\n                    @assert transformer[\"CM\"] == 2\n                    G_pu, B_pu = _transformer_mag_pu_conversion(\n                        transformer,\n                        sub_data,\n                        sub_data[\"base_power_12\"],\n                    )\n                    sub_data[\"g\"] = G_pu\n                    sub_data[\"b\"] = B_pu\n                end\n                # If CM = 1 & MAG2 != 0 -> MAG2 < 0\n                # If CM = 2 & MAG2 != 0 -> MAG2 > 0\n\n                sub_data[\"primary_correction_table\"] = transformer[\"TAB1\"]\n                sub_data[\"secondary_correction_table\"] = transformer[\"TAB2\"]\n                sub_data[\"tertiary_correction_table\"] = transformer[\"TAB3\"]\n\n                sub_data[\"primary_phase_shift_angle\"] = transformer[\"ANG1\"] * pi / 180.0\n                sub_data[\"secondary_phase_shift_angle\"] = transformer[\"ANG2\"] * pi / 180.0\n                sub_data[\"tertiary_phase_shift_angle\"] = transformer[\"ANG3\"] * pi / 180.0\n\n                windv1 = transformer[\"WINDV1\"]\n                windv2 = transformer[\"WINDV2\"]\n                windv3 = transformer[\"WINDV3\"]\n\n                windv1 = apply_tap_correction!(\n                    windv1,\n                    transformer,\n                    \"COD1\",\n                    \"RMI1\",\n                    \"RMA1\",\n                    \"NTP1\",\n                    transformer[\"CW\"],\n                    \"primary\",\n                )\n                windv2 = apply_tap_correction!(\n                    windv2,\n                    transformer,\n                    \"COD2\",\n                    \"RMI2\",\n                    \"RMA2\",\n                    \"NTP2\",\n                    transformer[\"CW\"],\n                    \"secondary\",\n                )\n                windv3 = apply_tap_correction!(\n                    windv3,\n                    transformer,\n                    \"COD3\",\n                    \"RMI3\",\n                    \"RMA3\",\n                    \"NTP3\",\n                    transformer[\"CW\"],\n                    \"tertiary\",\n                )\n\n                if transformer[\"CW\"] == 1\n                    sub_data[\"primary_turns_ratio\"] = windv1\n                    sub_data[\"secondary_turns_ratio\"] = windv2\n                    sub_data[\"tertiary_turns_ratio\"] = windv3\n                elseif transformer[\"CW\"] == 2\n                    sub_data[\"primary_turns_ratio\"] =\n                        windv1 / _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                    sub_data[\"secondary_turns_ratio\"] =\n                        windv2 / _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                    sub_data[\"tertiary_turns_ratio\"] =\n                        windv3 / _get_bus_value(transformer[\"K\"], \"base_kv\", pm_data)\n                else\n                    @assert transformer[\"CW\"] == 3\n                    sub_data[\"primary_turns_ratio\"] =\n                        windv1 * (\n                            sub_data[\"base_voltage_primary\"] /\n                            _get_bus_value(transformer[\"I\"], \"base_kv\", pm_data)\n                        )\n                    sub_data[\"secondary_turns_ratio\"] =\n                        windv2 * (\n                            sub_data[\"base_voltage_secondary\"] /\n                            _get_bus_value(transformer[\"J\"], \"base_kv\", pm_data)\n                        )\n                    sub_data[\"tertiary_turns_ratio\"] =\n                        windv3 * (\n                            sub_data[\"base_voltage_tertiary\"] /\n                            _get_bus_value(transformer[\"K\"], \"base_kv\", pm_data)\n                        )\n                end\n                sub_data[\"circuit\"] = strip(transformer[\"CKT\"])\n                sub_data[\"COD1\"] = transformer[\"COD1\"]\n                sub_data[\"COD2\"] = transformer[\"COD2\"]\n                sub_data[\"COD3\"] = transformer[\"COD3\"]\n\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"psse_name\" => transformer[\"NAME\"],\n                    \"CW\" => transformer[\"CW\"],\n                    \"CZ\" => transformer[\"CZ\"],\n                    \"CM\" => transformer[\"CM\"],\n                    \"MAG1\" => transformer[\"MAG1\"],\n                    \"MAG2\" => transformer[\"MAG2\"],\n                    \"VMSTAR\" => transformer[\"VMSTAR\"],\n                    \"ANSTAR\" => transformer[\"ANSTAR\"],\n                )\n\n                for prefix in TRANSFORMER3W_PARAMETER_NAMES\n                    for i in 1:length(WINDING_NAMES)\n                        key = \"$prefix$i\"\n                        if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                            sub_data[\"ext\"][key] = transformer[key]\n                        else\n                            continue\n                        end\n                    end\n                end\n\n                for suffix in [\"1-2\", \"2-3\", \"3-1\"]\n                    sub_data[\"ext\"][\"R$suffix\"] = transformer[\"R$suffix\"]\n                    sub_data[\"ext\"][\"X$suffix\"] = transformer[\"X$suffix\"]\n                end\n\n                sub_data[\"index\"] = length(pm_data[\"3w_transformer\"]) + 1\n\n                if import_all\n                    _import_remaining_keys!(\n                        sub_data,\n                        transformer;\n                        exclude = [\n                            \"NAME\",\n                            \"STAT\",\n                            \"MAG1\",\n                            \"MAG2\",\n                            \"WINDV1\",\n                            \"WINDV2\",\n                            \"WINDV3\",\n                        ],\n                    )\n                end\n                transformer3W_isolated_bus_modifications!(pm_data, sub_data)\n                push!(pm_data[\"3w_transformer\"], sub_data)\n\n                starbus_id += 1 # after adding the 1st 3WT, increase the counter\n            end\n        end\n    end\n    return\nend\n\n\"\"\"\n    _psse2pm_dcline!(pm_data, pti_data)\n\nParses PSS(R)E-style Two-Terminal and VSC DC Lines data into a PowerModels\ncompatible Dict structure by first converting them to a simple DC Line Model.\nFor Two-Terminal DC lines, \"source_id\" is given by `[\"IPR\", \"IPI\", \"NAME\"]` in the\nPSS(R)E Two-Terminal DC specification. For Voltage Source Converters, \"source_id\"\nis given by `[\"IBUS1\", \"IBUS2\", \"NAME\"]`, where \"IBUS1\" is \"IBUS\" of the first\nconverter bus, and \"IBUS2\" is the \"IBUS\" of the second converter bus, in the\nPSS(R)E Voltage Source Converter specification.\n\"\"\"\nfunction _psse2pm_dcline!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Two-Terminal and VSC DC line data into a PowerModels Dict...\"\n    pm_data[\"dcline\"] = []\n    pm_data[\"vscline\"] = []\n    baseMVA = pm_data[\"baseMVA\"]\n\n    if haskey(pti_data, \"TWO-TERMINAL DC\")\n        for dcline in pti_data[\"TWO-TERMINAL DC\"]\n            sub_data = Dict{String, Any}()\n\n            # Unit conversions?\n            power_demand =\n                if dcline[\"MDC\"] == 1\n                    abs(dcline[\"SETVL\"])\n                elseif dcline[\"MDC\"] == 2\n                    abs(dcline[\"SETVL\"] * dcline[\"VSCHD\"] / 1000) # Amp * V\n                else\n                    0\n                end\n\n            sub_data[\"transfer_setpoint\"] = dcline[\"SETVL\"]\n\n            sub_data[\"name\"] = strip(dcline[\"NAME\"], ['\"', '\\''])\n            sub_data[\"f_bus\"] = dcline[\"IPR\"]\n            sub_data[\"t_bus\"] = dcline[\"IPI\"]\n            if pm_data[\"has_isolated_type_buses\"]\n                push!(pm_data[\"connected_buses\"], sub_data[\"f_bus\"])\n                push!(pm_data[\"connected_buses\"], sub_data[\"t_bus\"])\n            end\n\n            if dcline[\"MDC\"] == 1\n                sub_data[\"power_mode\"] = true\n            else\n                sub_data[\"power_mode\"] = false\n            end\n            sub_data[\"available\"] = dcline[\"MDC\"] == 0 ? false : true\n            sub_data[\"br_status\"] = sub_data[\"available\"]\n\n            sub_data[\"scheduled_dc_voltage\"] = dcline[\"VSCHD\"]\n            rectifier_base_voltage = dcline[\"EBASR\"]\n            if rectifier_base_voltage == 0\n                throw(\n                    ArgumentError(\n                        \"DC line $(sub_data[\"name\"]): Rectifier base voltage EBASER cannot be 0\",\n                    ),\n                )\n            end\n            ZbaseR = rectifier_base_voltage^2 / baseMVA\n            sub_data[\"rectifier_bridges\"] = dcline[\"NBR\"]\n            sub_data[\"rectifier_rc\"] = dcline[\"RCR\"] / ZbaseR\n            sub_data[\"rectifier_xc\"] = dcline[\"XCR\"] / ZbaseR\n            sub_data[\"rectifier_base_voltage\"] = rectifier_base_voltage\n\n            inverter_base_voltage = dcline[\"EBASI\"]\n            if inverter_base_voltage == 0\n                throw(\n                    ArgumentError(\n                        \"DC line $(sub_data[\"name\"]): Inverter base voltage EBASI cannot be 0\",\n                    ),\n                )\n            end\n            ZbaseI = inverter_base_voltage^2 / baseMVA\n            sub_data[\"inverter_bridges\"] = dcline[\"NBI\"]\n            sub_data[\"inverter_rc\"] = dcline[\"RCI\"] / ZbaseI\n            sub_data[\"inverter_xc\"] = dcline[\"XCI\"] / ZbaseI\n            sub_data[\"inverter_base_voltage\"] = inverter_base_voltage\n\n            sub_data[\"switch_mode_voltage\"] = dcline[\"VCMOD\"]\n            sub_data[\"compounding_resistance\"] = dcline[\"RCOMP\"]\n            sub_data[\"min_compounding_voltage\"] = dcline[\"DCVMIN\"]\n\n            sub_data[\"rectifier_transformer_ratio\"] = dcline[\"TRR\"]\n            sub_data[\"rectifier_tap_setting\"] = dcline[\"TAPR\"]\n            sub_data[\"rectifier_tap_limits\"] = (min = dcline[\"TMNR\"], max = dcline[\"TMXR\"])\n            sub_data[\"rectifier_tap_step\"] = dcline[\"STPR\"]\n\n            sub_data[\"inverter_transformer_ratio\"] = dcline[\"TRI\"]\n            sub_data[\"inverter_tap_setting\"] = dcline[\"TAPI\"]\n            sub_data[\"inverter_tap_limits\"] = (min = dcline[\"TMNI\"], max = dcline[\"TMXI\"])\n            sub_data[\"inverter_tap_step\"] = dcline[\"STPI\"]\n\n            sub_data[\"loss0\"] = 0.0\n            sub_data[\"loss1\"] = 0.0\n\n            sub_data[\"pf\"] = power_demand\n            sub_data[\"active_power_flow\"] = sub_data[\"pf\"]\n            sub_data[\"pt\"] = power_demand\n            sub_data[\"qf\"] = 0.0\n            sub_data[\"qt\"] = 0.0\n            sub_data[\"vf\"] = _get_bus_value(pop!(dcline, \"IPR\"), \"vm\", pm_data)\n            sub_data[\"vt\"] = _get_bus_value(pop!(dcline, \"IPI\"), \"vm\", pm_data)\n\n            sub_data[\"pminf\"] = 0.0\n            sub_data[\"pmaxf\"] = dcline[\"SETVL\"] > 0 ? power_demand : -power_demand\n            sub_data[\"pmint\"] = pop!(dcline, \"SETVL\") > 0 ? -power_demand : power_demand\n            sub_data[\"pmaxt\"] = 0.0\n\n            anmn = []\n            for key in [\"ANMNR\", \"ANMNI\"]\n                if abs(dcline[key]) <= 90.0\n                    push!(anmn, dcline[key])\n                else\n                    push!(anmn, 0)\n                    @info(\"$key outside reasonable limits, setting to 0 degress\")\n                end\n            end\n            sub_data[\"rectifier_delay_angle_limits\"] =\n                (min = deg2rad(anmn[1]), max = deg2rad(dcline[\"ANMXR\"]))\n            sub_data[\"inverter_extinction_angle_limits\"] =\n                (min = deg2rad(anmn[2]), max = deg2rad(dcline[\"ANMXI\"]))\n\n            sub_data[\"rectifier_delay_angle\"] = deg2rad(anmn[1])\n            sub_data[\"inverter_extinction_angle\"] = deg2rad(anmn[2])\n\n            sub_data[\"qmaxf\"] = 0.0\n            sub_data[\"qmaxt\"] = 0.0\n            sub_data[\"qminf\"] =\n                -max(abs(sub_data[\"pminf\"]), abs(sub_data[\"pmaxf\"])) * cosd(anmn[1])\n            sub_data[\"qmint\"] =\n                -max(abs(sub_data[\"pmint\"]), abs(sub_data[\"pmaxt\"])) * cosd(anmn[2])\n\n            sub_data[\"active_power_limits_from\"] =\n                (min = sub_data[\"pminf\"], max = sub_data[\"pmaxf\"])\n            sub_data[\"active_power_limits_to\"] =\n                (min = sub_data[\"pmint\"], max = sub_data[\"pmaxt\"])\n            sub_data[\"reactive_power_limits_from\"] =\n                (min = sub_data[\"qminf\"], max = sub_data[\"qmaxf\"])\n            sub_data[\"reactive_power_limits_to\"] =\n                (min = sub_data[\"qmint\"], max = sub_data[\"qmaxt\"])\n\n            sub_data[\"rectifier_capacitor_reactance\"] = dcline[\"XCAPR\"] / ZbaseR\n            sub_data[\"inverter_capacitor_reactance\"] = dcline[\"XCAPI\"] / ZbaseI\n            sub_data[\"r\"] = dcline[\"RDC\"] / ZbaseR\n\n            if pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"psse_name\" => dcline[\"NAME\"],\n                )\n            elseif pm_data[\"source_version\"] == \"35\"\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"NDR\" => dcline[\"NDR\"],\n                    \"NDI\" => dcline[\"NDI\"],\n                )\n            else\n                error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n            end\n\n            sub_data[\"source_id\"] = [\n                \"two-terminal dc\",\n                sub_data[\"f_bus\"],\n                sub_data[\"t_bus\"],\n                pop!(dcline, \"NAME\"),\n            ]\n            sub_data[\"index\"] = length(pm_data[\"dcline\"]) + 1\n\n            if import_all\n                _import_remaining_keys!(sub_data, dcline)\n            end\n            branch_isolated_bus_modifications!(pm_data, sub_data)\n            push!(pm_data[\"dcline\"], sub_data)\n        end\n    end\n\n    if haskey(pti_data, \"VOLTAGE SOURCE CONVERTER\")\n        for dcline in pti_data[\"VOLTAGE SOURCE CONVERTER\"]\n            # Converter buses : is the distinction between ac and dc side meaningful?\n            from_bus, to_bus = dcline[\"CONVERTER BUSES\"]\n\n            # PowerWorld conversion from PTI to matpower seems to create two\n            # artificial generators from a VSC, but it is not clear to me how\n            # the value of \"pg\" is determined and adds shunt to the DC-side bus.\n            sub_data = Dict{String, Any}()\n            sub_data[\"name\"] = strip(dcline[\"NAME\"], ['\"', '\\''])\n\n            # VSC intended to be one or bi-directional?\n            sub_data[\"f_bus\"] = from_bus[\"IBUS\"]\n            sub_data[\"t_bus\"] = to_bus[\"IBUS\"]\n            if pm_data[\"has_isolated_type_buses\"]\n                push!(pm_data[\"connected_buses\"], sub_data[\"f_bus\"])\n                push!(pm_data[\"connected_buses\"], sub_data[\"t_bus\"])\n            end\n            sub_data[\"br_status\"] =\n                if dcline[\"MDC\"] == 0 ||\n                   from_bus[\"TYPE\"] == 0 ||\n                   to_bus[\"TYPE\"] == 0\n                    0\n                else\n                    1\n                end\n            sub_data[\"available\"] = sub_data[\"br_status\"] == 0 ? false : true\n\n            sub_data[\"dc_voltage_control_from\"] = from_bus[\"TYPE\"] == 1 ? true : false\n            sub_data[\"dc_voltage_control_to\"] = to_bus[\"TYPE\"] == 1 ? true : false\n            sub_data[\"ac_voltage_control_from\"] = from_bus[\"MODE\"] == 1 ? true : false\n            sub_data[\"ac_voltage_control_to\"] = to_bus[\"MODE\"] == 1 ? true : false\n\n            sub_data[\"dc_setpoint_from\"] = from_bus[\"DCSET\"]\n            sub_data[\"dc_setpoint_to\"] = to_bus[\"DCSET\"]\n            sub_data[\"ac_setpoint_from\"] = from_bus[\"ACSET\"]\n            sub_data[\"ac_setpoint_to\"] = to_bus[\"ACSET\"]\n\n            # ALOSS, MINLOSS in kW, and BLOSS in kW/A. Divide by a 1000 to transform into MW, and divide by baseMVA to normalize to per-unit.\n            sub_data[\"converter_loss_from\"] = LinearCurve(\n                from_bus[\"BLOSS\"] / (1000.0 * baseMVA),\n                (from_bus[\"ALOSS\"] + from_bus[\"MINLOSS\"]) / (1000.0 * baseMVA),\n            )\n            sub_data[\"converter_loss_to\"] = LinearCurve(\n                to_bus[\"BLOSS\"] / (1000.0 * baseMVA),\n                (to_bus[\"ALOSS\"] + to_bus[\"MINLOSS\"]) / (1000.0 * baseMVA),\n            )\n\n            sub_data[\"pf\"] = 0.0\n            sub_data[\"pt\"] = 0.0\n\n            sub_data[\"qf\"] = 0.0\n            sub_data[\"qt\"] = 0.0\n\n            sub_data[\"qminf\"] = from_bus[\"MINQ\"] / baseMVA\n            sub_data[\"qmaxf\"] = from_bus[\"MAXQ\"] / baseMVA\n            sub_data[\"qmint\"] = to_bus[\"MINQ\"] / baseMVA\n            sub_data[\"qmaxt\"] = to_bus[\"MAXQ\"] / baseMVA\n\n            PTI_INF = 9999.0\n\n            sub_data[\"rating_from\"] =\n                from_bus[\"SMAX\"] == 0.0 ? PTI_INF : from_bus[\"SMAX\"] / baseMVA\n            sub_data[\"rating_to\"] =\n                to_bus[\"SMAX\"] == 0.0 ? PTI_INF : to_bus[\"SMAX\"] / baseMVA\n            sub_data[\"rating\"] = min(sub_data[\"rating_from\"], sub_data[\"rating_to\"])\n            sub_data[\"max_dc_current_from\"] =\n                from_bus[\"IMAX\"] == 0.0 ? PTI_INF : from_bus[\"IMAX\"]\n            sub_data[\"max_dc_current_to\"] = to_bus[\"IMAX\"] == 0.0 ? PTI_INF : to_bus[\"IMAX\"]\n            sub_data[\"power_factor_weighting_fraction_from\"] = from_bus[\"PWF\"]\n            sub_data[\"power_factor_weighting_fraction_to\"] = to_bus[\"PWF\"]\n            qmax_from = max(abs(sub_data[\"qminf\"]), abs(sub_data[\"qmaxf\"]))\n            qmax_to = max(abs(sub_data[\"qmint\"]), abs(sub_data[\"qmaxt\"]))\n            sub_data[\"pmaxf\"] = sqrt(sub_data[\"rating_from\"]^2 - qmax_from^2)\n            sub_data[\"pmaxt\"] = sqrt(sub_data[\"rating_to\"]^2 - qmax_to^2)\n            sub_data[\"pminf\"] = -sub_data[\"pmaxf\"]\n            sub_data[\"pmint\"] = -sub_data[\"pmaxt\"]\n\n            if sub_data[\"dc_voltage_control_from\"] && !sub_data[\"dc_voltage_control_to\"]\n                base_voltage = sub_data[\"dc_setpoint_from\"]\n                flow_setpoint = sub_data[\"dc_setpoint_to\"]\n            elseif !sub_data[\"dc_voltage_control_from\"] && sub_data[\"dc_voltage_control_to\"]\n                base_voltage = sub_data[\"dc_setpoint_to\"]\n                flow_setpoint = -sub_data[\"dc_setpoint_from\"]\n            else\n                error(\n                    \"At least one converter in converter $(sub_data[\"name\"]) must set a voltage control.\",\n                )\n            end\n            Zbase = base_voltage^2 / baseMVA\n            sub_data[\"r\"] = dcline[\"RDC\"] / Zbase\n            sub_data[\"pf\"] = flow_setpoint / baseMVA\n            sub_data[\"if\"] = 1000.0 * (flow_setpoint / base_voltage)\n\n            sub_data[\"ext\"] = Dict{String, Any}(\n                \"REMOT_FROM\" => from_bus[\"REMOT\"],\n                \"REMOT_TO\" => to_bus[\"REMOT\"],\n                \"RMPCT_FROM\" => from_bus[\"RMPCT\"],\n                \"RMPCT_TO\" => to_bus[\"RMPCT\"],\n                \"ALOSS_FROM\" => from_bus[\"ALOSS\"],\n                \"ALOSS_TO\" => to_bus[\"ALOSS\"],\n                \"MINLOSS_FROM\" => from_bus[\"MINLOSS\"],\n                \"MINLOSS_TO\" => to_bus[\"MINLOSS\"],\n                \"TYPE_FROM\" => from_bus[\"TYPE\"],\n                \"TYPE_TO\" => to_bus[\"TYPE\"],\n                \"MODE_FROM\" => from_bus[\"MODE\"],\n                \"MODE_TO\" => to_bus[\"MODE\"],\n                \"RDC\" => dcline[\"RDC\"],\n            )\n\n            sub_data[\"source_id\"] =\n                [\"vsc dc\", sub_data[\"f_bus\"], sub_data[\"t_bus\"], dcline[\"NAME\"]]\n            sub_data[\"index\"] = length(pm_data[\"vscline\"]) + 1\n\n            if import_all\n                _import_remaining_keys!(sub_data, dcline)\n\n                for cb in sub_data[\"converter buses\"]\n                    for (k, v) in cb\n                        cb[lowercase(k)] = v\n                        delete!(cb, k)\n                    end\n                end\n            end\n            branch_isolated_bus_modifications!(pm_data, sub_data)\n            push!(pm_data[\"vscline\"], sub_data)\n        end\n    end\nend\n\nfunction _psse2pm_facts!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E FACTs devices data into a PowerModels Dict...\"\n    pm_data[\"facts\"] = []\n\n    if haskey(pti_data, \"FACTS CONTROL DEVICE\")\n        for facts in pti_data[\"FACTS CONTROL DEVICE\"]\n            @info(\n                \"\"\"FACTs are supported via a simplification approach for terminal_bus = 0 (STATCOM operation)\"\"\"\n            )\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"name\"] = strip(facts[\"NAME\"], ['\"', '\\''])\n            sub_data[\"control_mode\"] = facts[\"MODE\"]\n\n            sub_data[\"bus\"] = facts[\"I\"]  # Sending end bus number\n            sub_data[\"tbus\"] = facts[\"J\"] # Terminal end bus number\n            sub_data[\"available\"] = _determine_injector_status(\n                facts,\n                pm_data,\n                sub_data[\"bus\"],\n                \"MODE\",\n                \"candidate_isolated_to_pq_buses\",\n            )\n\n            sub_data[\"voltage_setpoint\"] = facts[\"VSET\"]\n            sub_data[\"max_shunt_current\"] = facts[\"SHMX\"]\n\n            # % of MVAr required to hold voltage at sending bus\n            if facts[\"RMPCT\"] < 0\n                @warn \"% MVAr required must me positive.\"\n            end\n\n            sub_data[\"reactive_power_required\"] = facts[\"RMPCT\"]\n            sub_data[\"ext\"] = Dict{String, Any}()\n\n            if pm_data[\"source_version\"] == \"35\"\n                sub_data[\"ext\"][\"NREG\"] = facts[\"NREG\"]\n                sub_data[\"ext\"][\"MNAME\"] = facts[\"MNAME\"]\n            elseif pm_data[\"source_version\"] ∈ (\"32\", \"33\")\n                sub_data[\"ext\"] = Dict{String, Any}(\n                    \"J\" => facts[\"J\"],\n                )\n            else\n                error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n            end\n\n            sub_data[\"source_id\"] =\n                [\"facts\", sub_data[\"bus\"], sub_data[\"name\"]]\n            sub_data[\"index\"] = length(pm_data[\"facts\"]) + 1\n\n            if import_all\n                _import_remaining_keys!(sub_data, facts)\n            end\n            push!(pm_data[\"facts\"], sub_data)\n        end\n    end\n    return\nend\n\nfunction _build_switch_breaker_sub_data(\n    pm_data::Dict,\n    dict_object::Dict,\n    device_type::String,\n    discrete_device_type::Int,\n    index::Int,\n)\n    sub_data = Dict{String, Any}()\n\n    sub_data[\"f_bus\"] = pop!(dict_object, \"I\")\n    sub_data[\"t_bus\"] = pop!(dict_object, \"J\")\n    if pm_data[\"has_isolated_type_buses\"]\n        push!(pm_data[\"connected_buses\"], sub_data[\"f_bus\"])\n        push!(pm_data[\"connected_buses\"], sub_data[\"t_bus\"])\n    end\n\n    sub_data[\"x\"] = pop!(dict_object, \"X\")\n    sub_data[\"active_power_flow\"] = 0.0\n    sub_data[\"reactive_power_flow\"] = 0.0\n    sub_data[\"psw\"] = sub_data[\"active_power_flow\"]\n    sub_data[\"qsw\"] = sub_data[\"reactive_power_flow\"]\n    sub_data[\"discrete_branch_type\"] = discrete_device_type\n    sub_data[\"ext\"] = Dict{String, Any}()\n\n    if haskey(dict_object, \"STAT\")\n        sub_data[\"state\"] = pop!(dict_object, \"STAT\")\n    elseif haskey(dict_object, \"ST\")\n        sub_data[\"state\"] = pop!(dict_object, \"ST\")\n    else\n        @warn \"No STAT or ST field found in the data for switch/breaker. Assuming it is off.\"\n        sub_data[\"state\"] = 0.0\n    end\n\n    if pm_data[\"source_version\"] == (\"35\")\n        sub_data[\"r\"] = 0.0\n        sub_data[\"rating\"] = pop!(dict_object, \"RATE1\")\n        for i in 2:12\n            rate_key = \"RATE$i\"\n            if haskey(dict_object, rate_key)\n                sub_data[\"ext\"][rate_key] = pop!(dict_object, rate_key)\n            end\n        end\n    else\n        sub_data[\"r\"] = pop!(dict_object, \"R\")\n        sub_data[\"rating\"] = pop!(dict_object, \"RATEA\")\n    end\n\n    sub_data[\"source_id\"] =\n        [device_type, sub_data[\"f_bus\"], sub_data[\"t_bus\"], dict_object[\"CKT\"]]\n    sub_data[\"index\"] = index\n\n    return sub_data\nend\n\nfunction _psse2pm_switch_breaker!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Switches & Breakers data into a PowerModels Dict...\"\n    pm_data[\"breaker\"] = []\n    pm_data[\"switch\"] = []\n    mapping = Dict('@' => (\"breaker\", 1), '*' => (\"switch\", 0))\n    # PSS(R)E v35 STYPE values:\n    # 1 - Generic connector, 2 - Circuit breaker, 3 - Disconnect switch.\n    # Generic connectors are stored in the \"switch\" list and distinguished via\n    # discrete_branch_type = OTHER (2).\n    mapping_v35 = Dict(\n        1 => (\"switch\", 2),\n        2 => (\"breaker\", 1),\n        3 => (\"switch\", 0),\n    )\n\n    # Always check for legacy entries in PSSe 35 for switches and breakers set as @ or *\n    if haskey(pti_data, \"SWITCHES_AS_BRANCHES\")\n        for branch in pti_data[\"SWITCHES_AS_BRANCHES\"]\n            branch_init = first(branch[\"CKT\"])\n\n            # Check if character is in the mapping\n            if haskey(mapping, branch_init)\n                branch_type, discrete_branch_type = mapping[branch_init]\n\n                sub_data = _build_switch_breaker_sub_data(\n                    pm_data,\n                    branch,\n                    branch_type,\n                    discrete_branch_type,\n                    length(pm_data[branch_type]) + 1,\n                )\n\n                if import_all\n                    _import_remaining_keys!(sub_data, branch)\n                end\n                branch_isolated_bus_modifications!(pm_data, sub_data)\n                push!(pm_data[branch_type], sub_data)\n            end\n        end\n    end\n\n    if haskey(pti_data, \"SWITCHING DEVICE\")\n        if pm_data[\"source_version\"] == \"35\"\n            for switching_device in pti_data[\"SWITCHING DEVICE\"]\n                stype = get(switching_device, \"STYPE\", nothing)\n                type_mapping = get(mapping_v35, stype, nothing)\n\n                if isnothing(type_mapping)\n                    @warn \"Unsupported SWITCHING DEVICE STYPE=$(stype). Skipping entry.\"\n                    continue\n                end\n\n                device_type, discrete_branch_type = type_mapping\n\n                sub_data = _build_switch_breaker_sub_data(\n                    pm_data,\n                    switching_device,\n                    device_type,\n                    discrete_branch_type,\n                    length(pm_data[device_type]) + 1,\n                )\n\n                if import_all\n                    _import_remaining_keys!(sub_data, switching_device)\n                end\n\n                branch_isolated_bus_modifications!(pm_data, sub_data)\n                push!(pm_data[device_type], sub_data)\n            end\n        else\n            error(\"Unsupported PSS(R)E source version: $(pm_data[\"source_version\"])\")\n        end\n    end\n    return\nend\n\nfunction _psse2pm_multisection_line!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Adding PSS(R)E Multi-section Lines data into the branches PowerModels Dict...\"\n    branch_lookup = Dict{Tuple{Int, Int}, Int}()\n    if haskey(pm_data, \"branch\")\n        for branch in pm_data[\"branch\"]\n            branch_lookup[(branch[\"f_bus\"], branch[\"t_bus\"])] = branch[\"index\"]\n        end\n    end\n    if haskey(pti_data, \"MULTI-SECTION LINE\")\n        for multisec_line in pti_data[\"MULTI-SECTION LINE\"]\n            filter!(x -> x.second != \"\", multisec_line)\n            f_bus = multisec_line[\"I\"]\n            t_bus = multisec_line[\"J\"]\n            id = filter(isdigit, multisec_line[\"ID\"])\n            # Sort by dummy bus index\n            dummy_buses = sort([\n                (k, v) for (k, v) in multisec_line if startswith(k, \"DUM\") && v != \"\"\n            ])\n            dummy_bus_numbers = [x[2] for x in dummy_buses]\n            all_buses = [f_bus; dummy_bus_numbers; t_bus]\n            for ix in 1:(length(all_buses) - 1)\n                branch_index = nothing\n                if haskey(branch_lookup, (all_buses[ix], all_buses[ix + 1]))\n                    branch_index = branch_lookup[(all_buses[ix], all_buses[ix + 1])]\n                elseif haskey(branch_lookup, (all_buses[ix + 1], all_buses[ix]))\n                    branch_index = branch_lookup[(all_buses[ix + 1], all_buses[ix])]\n                else\n                    @warn \"Branch between buses $(all_buses[ix]) and $(all_buses[ix + 1]) not found in branch data. Skipping segment.\"\n                    continue\n                end\n                # Proceed if a valid branch is found\n                if branch_index !== nothing\n                    ext = get(pm_data[\"branch\"][branch_index], \"ext\", Dict{String, Any}())\n                    ext[\"from_multisection\"] = true\n                    ext[\"multisection_psse_entry\"] = multisec_line\n                    pm_data[\"branch\"][branch_index][\"ext\"] = ext\n                end\n            end\n        end\n    end\n    return\nend\n\nfunction sort_values_by_key_prefix(imp_correction::Dict{String, <:Any}, prefix::String)\n    sorted_values = [\n        last(pair) for pair in sort(\n            [\n                (parse(Int, k[2:end]), v) for\n                (k, v) in imp_correction if startswith(k, prefix)\n            ];\n            by = first,\n        )\n    ]\n\n    first_non_zero_index = findfirst(x -> x != 0.0, reverse(sorted_values))\n    sorted_values = sorted_values[1:(length(sorted_values) - first_non_zero_index + 1)]\n\n    return sorted_values\nend\n\nfunction sort_values_by_key_prefix_v35(imp_correction::Dict{String, <:Any}, prefix::String)\n    # For v35, we need to handle \"Re(F1)\", \"Im(F1)\" format\n    sorted_values = [\n        last(pair) for pair in sort(\n            [\n                (parse(Int, match(r\"\\d+\", k).match), v) for\n                (k, v) in imp_correction if startswith(k, prefix) && contains(k, r\"\\d+\")\n            ];\n            by = first,\n        )\n    ]\n\n    # Remove trailing zeros in IC data that indicate end of entry (0.00000,0.00000,0.00000)\n    # Acoording to PSSE DataFormat Section 1.18. TIC Tables\n    # Check if the last entry is all zeros across (T, Re(F), Im(F))\n    while !isempty(sorted_values)\n        last_index = length(sorted_values)\n        keys_to_check = [\"T$last_index\", \"Re(F$last_index)\", \"Im(F$last_index)\"]\n\n        if all(k -> haskey(imp_correction, k) && imp_correction[k] == 0.0, keys_to_check)\n            pop!(sorted_values)\n        else\n            break\n        end\n    end\n\n    return sorted_values\nend\n\nfunction _psse2pm_impedance_correction!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @info \"Parsing PSS(R)E Transformer Impedance Correction Tables data into a PowerModels Dict...\"\n\n    pm_data[\"impedance_correction\"] = []\n\n    if haskey(pti_data, \"IMPEDANCE CORRECTION\")\n        for imp_correction in pti_data[\"IMPEDANCE CORRECTION\"]\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"table_number\"] = imp_correction[\"I\"]\n\n            is_v35 =\n                any(k -> contains(k, \"Re(F\") || contains(k, \"Im(F\"), keys(imp_correction))\n\n            if is_v35\n                sub_data[\"scaling_factor\"] =\n                    sort_values_by_key_prefix_v35(imp_correction, \"Re(F\")\n                sub_data[\"scaling_factor_imag\"] =\n                    sort_values_by_key_prefix_v35(imp_correction, \"Im(F\")\n                sub_data[\"tap_or_angle\"] =\n                    sort_values_by_key_prefix_v35(imp_correction, \"T\")\n            else\n                sub_data[\"scaling_factor\"] = sort_values_by_key_prefix(imp_correction, \"F\")\n                sub_data[\"tap_or_angle\"] = sort_values_by_key_prefix(imp_correction, \"T\")\n            end\n\n            sub_data[\"index\"] = length(pm_data[\"impedance_correction\"]) + 1\n\n            if import_all\n                _import_remaining_keys!(sub_data, imp_correction)\n            end\n\n            push!(pm_data[\"impedance_correction\"], sub_data)\n        end\n    end\n    return\nend\n\nfunction _psse2pm_substation_data!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @warn \"Parsing PSS(R)E Substation data into a PowerModels Dict...\"\n    pm_data[\"substation_data\"] = []\n\n    if haskey(pti_data, \"SUBSTATION DATA\")\n        for substation_data in pti_data[\"SUBSTATION DATA\"]\n            sub_data = Dict{String, Any}()\n\n            sub_data[\"name\"] = substation_data[\"NAME\"]\n            sub_data[\"substation_is\"] = substation_data[\"IS\"]\n\n            sub_data[\"latitude\"] = substation_data[\"LATITUDE\"]\n            sub_data[\"longitude\"] = substation_data[\"LONGITUDE\"]\n            sub_data[\"nodes\"] = substation_data[\"NODES\"]\n\n            if import_all\n                _import_remaining_keys!(sub_data, substation_data)\n            end\n\n            sub_data[\"index\"] = length(pm_data[\"substation_data\"]) + 1\n            push!(pm_data[\"substation_data\"], sub_data)\n        end\n    end\nend\n\nfunction _psse2pm_storage!(pm_data::Dict, pti_data::Dict, import_all::Bool)\n    @warn \"This PSS(R)E parser currently doesn't support Storage data parsing...\"\n    pm_data[\"storage\"] = []\n    return\nend\n\n\"\"\"\n    _pti_to_powermodels!(pti_data)\n\nConverts PSS(R)E-style data parsed from a PTI raw file, passed by `pti_data`\ninto a format suitable for use internally in PowerModels. Imports all remaining\ndata from the PTI file if `import_all` is true (Default: false).\n\"\"\"\nfunction _pti_to_powermodels!(\n    pti_data::Dict;\n    import_all = false,\n    validate = true,\n    correct_branch_rating = true,\n)::Dict\n    pm_data = Dict{String, Any}()\n\n    rev = pop!(pti_data[\"CASE IDENTIFICATION\"][1], \"REV\")\n\n    pm_data[\"per_unit\"] = false\n    pm_data[\"source_type\"] = \"pti\"\n    pm_data[\"source_version\"] = \"$rev\"\n    pm_data[\"baseMVA\"] = pop!(pti_data[\"CASE IDENTIFICATION\"][1], \"SBASE\")\n    pm_data[\"name\"] = pop!(pti_data[\"CASE IDENTIFICATION\"][1], \"NAME\")\n\n    if import_all\n        _import_remaining_keys!(pm_data, pti_data[\"CASE IDENTIFICATION\"][1])\n    end\n\n    _psse2pm_interarea_transfer!(pm_data, pti_data, import_all)\n    _psse2pm_area_interchange!(pm_data, pti_data, import_all)\n    _psse2pm_zone!(pm_data, pti_data, import_all)\n    # Order matters here. Buses need to parsed first\n    _psse2pm_bus!(pm_data, pti_data, import_all)\n    # Branches need to be parsed after buses to find topologically connected buses\n    _psse2pm_branch!(pm_data, pti_data, import_all)\n    _psse2pm_switch_breaker!(pm_data, pti_data, import_all)\n    _psse2pm_multisection_line!(pm_data, pti_data, import_all)\n    _psse2pm_transformer!(pm_data, pti_data, import_all)\n    # Injectors need to be parsed after branches and transformers to find topologically connected buses\n    _psse2pm_load!(pm_data, pti_data, import_all)\n    _psse2pm_shunt!(pm_data, pti_data, import_all)\n    _psse2pm_generator!(pm_data, pti_data, import_all)\n    _psse2pm_facts!(pm_data, pti_data, import_all)\n\n    _psse2pm_dcline!(pm_data, pti_data, import_all)\n    _psse2pm_impedance_correction!(pm_data, pti_data, import_all)\n    _psse2pm_substation_data!(pm_data, pti_data, import_all)\n    _psse2pm_storage!(pm_data, pti_data, import_all)\n\n    if pm_data[\"has_isolated_type_buses\"]\n        bus_numbers = Set(v[\"bus_i\"] for (_, v) in pm_data[\"bus\"])\n        topologically_isolated_buses = setdiff(bus_numbers, pm_data[\"connected_buses\"])\n        convert_to_pq =\n            setdiff(\n                pm_data[\"candidate_isolated_to_pq_buses\"],\n                pm_data[\"candidate_isolated_to_pv_buses\"],\n            )\n        convert_to_pv = pm_data[\"candidate_isolated_to_pv_buses\"]\n\n        for b in setdiff!(convert_to_pq, topologically_isolated_buses)\n            pm_data[\"bus\"][b][\"bus_type\"] = 1\n        end\n        for b in setdiff!(convert_to_pv, topologically_isolated_buses)\n            pm_data[\"bus\"][b][\"bus_type\"] = 2\n        end\n\n        if !isempty(topologically_isolated_buses)\n            for b in topologically_isolated_buses\n                if pm_data[\"bus\"][b][\"bus_type\"] == 4\n                    continue\n                else\n                    b_number = pm_data[\"bus\"][b][\"bus_i\"]\n                    b_type = pm_data[\"bus\"][b][\"bus_type\"]\n                    if b_type == 3\n                        error(\n                            \"PSEE reference bus $(b_number) that is topologically isolated from the system. Indicates an error in the data.\",\n                        )\n                    end\n                    @error \"PSEE data file contains a topologically isolated bus $(b_number) that is disconnected from the system and set to bus_type = $(b_type) instead of 4. Likely indicates an error in the data.\"\n                    pm_data[\"bus\"][b][\"bus_type\"] = 4\n                    pm_data[\"bus\"][b][\"bus_status\"] = false\n                end\n            end\n        end\n    end\n\n    if import_all\n        _import_remaining_comps!(\n            pm_data,\n            pti_data;\n            exclude = [\n                \"CASE IDENTIFICATION\",\n                \"BUS\",\n                \"LOAD\",\n                \"FIXED SHUNT\",\n                \"SWITCHED SHUNT\",\n                \"GENERATOR\",\n                \"BRANCH\",\n                \"TRANSFORMER\",\n                \"TWO-TERMINAL DC\",\n                \"VOLTAGE SOURCE CONVERTER\",\n            ],\n        )\n    end\n\n    # update lookup structure\n    for (k, v) in pm_data\n        if isa(v, Array)\n            dict = Dict{String, Any}()\n            for item in v\n                @assert(\"index\" in keys(item))\n                dict[string(item[\"index\"])] = item\n            end\n            pm_data[k] = dict\n        end\n    end\n\n    if validate\n        correct_network_data!(pm_data; correct_branch_rating = correct_branch_rating)\n    end\n\n    return pm_data\nend\n\n\"\"\"\n    parse_psse(filename::String; kwargs...)::Dict\n\nParses directly from file\n\"\"\"\nfunction parse_psse(filename::String; kwargs...)::Dict\n    pm_data = open(filename) do f\n        parse_psse(f; kwargs...)\n    end\n\n    return pm_data\nend\n\n\"\"\"\n    function parse_psse(io::IO; kwargs...)::Dict\n\nParses directly from iostream\n\"\"\"\nfunction parse_psse(io::IO; kwargs...)::Dict\n    @info(\n        \"The PSS(R)E parser currently supports buses, loads, shunts, generators, branches, switches, breakers, IC tables, transformers, facts, and dc lines\",\n    )\n    pti_data = parse_pti(io)\n    pm = _pti_to_powermodels!(pti_data; kwargs...)\n    return pm\nend\n"
  },
  {
    "path": "src/parsers/pm_io/pti.jl",
    "content": "#####################################################################\n#                                                                   #\n# This file provides functions for interfacing with pti .raw files  #\n#                                                                   #\n#####################################################################\n\n\"\"\"\nA list of data file sections in the order that they appear in a PTI v33/v35 file\n\"\"\"\nconst _pti_sections = [\n    \"CASE IDENTIFICATION\",\n    \"BUS\",\n    \"LOAD\",\n    \"FIXED SHUNT\",\n    \"GENERATOR\",\n    \"BRANCH\",\n    \"TRANSFORMER\",\n    \"AREA INTERCHANGE\",\n    \"TWO-TERMINAL DC\",\n    \"VOLTAGE SOURCE CONVERTER\",\n    \"IMPEDANCE CORRECTION\",\n    \"MULTI-TERMINAL DC\",\n    \"MULTI-SECTION LINE\",\n    \"ZONE\",\n    \"INTER-AREA TRANSFER\",\n    \"OWNER\",\n    \"FACTS CONTROL DEVICE\",\n    \"SWITCHED SHUNT\",\n    \"GNE DEVICE\",\n    \"INDUCTION MACHINE\",\n]\n\nconst _pti_sections_v35 = vcat(\n    _pti_sections[1:6],\n    [\"SWITCHING DEVICE\"],\n    _pti_sections[7:end],\n    \"SUBSTATION DATA\",\n)\n\nconst _transaction_dtypes = [\n    (\"IC\", Int64),\n    (\"SBASE\", Float64),\n    (\"REV\", Int64),\n    (\"XFRRAT\", Float64),\n    (\"NXFRAT\", Float64),\n    (\"BASFRQ\", Float64),\n]\n\nconst _transaction_dtypes_v35 = _transaction_dtypes\n\nconst _system_wide_dtypes_v35 = [\n    (\"THRSHZ\", Float64),\n    (\"PQBRAK\", Float64),\n    (\"BLOWUP\", Float64),\n    (\"MAXISOLLVLS\", Int64),\n    (\"CAMAXREPTSLN\", Int64),\n    (\"CHKDUPCNTLBL\", Int64),\n    (\"ITMX\", Int64),\n    (\"ACCP\", Float64),\n    (\"ACCQ\", Float64),\n    (\"ACCM\", Float64),\n    (\"TOL\", Float64),\n    (\"ITMXN\", Int64),\n    (\"ACCN\", Float64),\n    (\"TOLN\", Float64),\n    (\"VCTOLQ\", Float64),\n    (\"VCTOLV\", Float64),\n    (\"DVLIM\", Float64),\n    (\"NDVFCT\", Float64),\n    (\"ADJTHR\", Float64),\n    (\"ACCTAP\", Float64),\n    (\"TAPLIM\", Float64),\n    (\"SWVBND\", Float64),\n    (\"MXTPSS\", Int64),\n    (\"MXSWIM\", Int64),\n    (\"ITMXTY\", Int64),\n    (\"ACCTY\", Float64),\n    (\"TOLTY\", Float64),\n    (\"METHOD\", String),\n    (\"ACTAPS\", Int64),\n    (\"AREAIN\", Int64),\n    (\"PHSHFT\", Int64),\n    (\"DCTAPS\", Int64),\n    (\"SWSHNT\", Int64),\n    (\"FLATST\", Int64),\n    (\"VARLIM\", Int64),\n    (\"NONDIV\", Int64),\n    (\"IRATE\", Int64),\n    (\"NAME\", String),\n    (\"DESC\", String),\n]\n\nconst _system_wide_data_sections_v35 = Dict{String, Vector{String}}(\n    \"GENERAL\" =>\n        [\"THRSHZ\", \"PQBRAK\", \"BLOWUP\", \"MAXISOLLVLS\", \"CAMAXREPTSLN\", \"CHKDUPCNTLBL\"],\n    \"GAUSS\" => [\"ITMX\", \"ACCP\", \"ACCQ\", \"ACCM\", \"TOL\"],\n    \"NEWTON\" => [\"ITMXN\", \"ACCN\", \"TOLN\", \"VCTOLQ\", \"VCTOLV\", \"DVLIM\", \"NDVFCT\"],\n    \"ADJUST\" => [\"ADJTHR\", \"ACCTAP\", \"TAPLIM\", \"SWVBND\", \"MXTPSS\", \"MXSWIM\"],\n    \"TYSL\" => [\"ITMXTY\", \"ACCTY\", \"TOLTY\"],\n    \"SOLVER\" => [\n        \"METHOD\",\n        \"ACTAPS\",\n        \"AREAIN\",\n        \"PHSHFT\",\n        \"DCTAPS\",\n        \"SWSHNT\",\n        \"FLATST\",\n        \"VARLIM\",\n        \"NONDIV\",\n    ],\n    \"RATING\" => [\"IRATE\", \"NAME\", \"DESC\"],\n)\n\nconst _bus_dtypes = [\n    (\"I\", Int64),\n    (\"NAME\", String),\n    (\"BASKV\", Float64),\n    (\"IDE\", Int64),\n    (\"AREA\", Int64),\n    (\"ZONE\", Int64),\n    (\"OWNER\", Int64),\n    (\"VM\", Float64),\n    (\"VA\", Float64),\n    (\"NVHI\", Float64),\n    (\"NVLO\", Float64),\n    (\"EVHI\", Float64),\n    (\"EVLO\", Float64),\n]\n\nconst _bus_dtypes_v35 = _bus_dtypes\n\nconst _load_dtypes = [\n    (\"I\", Int64),\n    (\"ID\", String),\n    (\"STATUS\", Int64),\n    (\"AREA\", Int64),\n    (\"ZONE\", Int64),\n    (\"PL\", Float64),\n    (\"QL\", Float64),\n    (\"IP\", Float64),\n    (\"IQ\", Float64),\n    (\"YP\", Float64),\n    (\"YQ\", Float64),\n    (\"OWNER\", Int64),\n    (\"SCALE\", Int64),\n    (\"INTRPT\", Int64),\n]\n\nconst _load_dtypes_v35 = vcat(\n    _load_dtypes[1:14],\n    [\n        (\"DGENP\", Float64),\n        (\"DGENQ\", Float64),\n        (\"DGENM\", Float64),\n        (\"LOADTYPE\", String),\n    ],\n)\n\nconst _fixed_shunt_dtypes = [\n    (\"I\", Int64),\n    (\"ID\", String),\n    (\"STATUS\", Int64),\n    (\"GL\", Float64),\n    (\"BL\", Float64),\n]\n\nconst _fixed_shunt_dtypes_v35 = _fixed_shunt_dtypes\n\nconst _generator_dtypes = [\n    (\"I\", Int64),\n    (\"ID\", String),\n    (\"PG\", Float64),\n    (\"QG\", Float64),\n    (\"QT\", Float64),\n    (\"QB\", Float64),\n    (\"VS\", Float64),\n    (\"IREG\", Int64),\n    (\"MBASE\", Float64),\n    (\"ZR\", Float64),\n    (\"ZX\", Float64),\n    (\"RT\", Float64),\n    (\"XT\", Float64),\n    (\"GTAP\", Float64),\n    (\"STAT\", Int64),\n    (\"RMPCT\", Float64),\n    (\"PT\", Float64),\n    (\"PB\", Float64),\n    (\"O1\", Int64),\n    (\"F1\", Float64),\n    (\"O2\", Int64),\n    (\"F2\", Float64),\n    (\"O3\", Int64),\n    (\"F3\", Float64),\n    (\"O4\", Int64),\n    (\"F4\", Float64),\n    (\"WMOD\", Int64),\n    (\"WPF\", Float64),\n]\n\nconst _generator_dtypes_v35 = vcat(\n    _generator_dtypes[1:8],\n    [(\"NREG\", Int64)],\n    _generator_dtypes[9:18],\n    [(\"BASLOD\", Int64)],\n    _generator_dtypes[19:end],\n)\n\nconst _branch_dtypes = [\n    (\"I\", Int64),\n    (\"J\", Int64),\n    (\"CKT\", String),\n    (\"R\", Float64),\n    (\"X\", Float64),\n    (\"B\", Float64),\n    (\"RATEA\", Float64),\n    (\"RATEB\", Float64),\n    (\"RATEC\", Float64),\n    (\"GI\", Float64),\n    (\"BI\", Float64),\n    (\"GJ\", Float64),\n    (\"BJ\", Float64),\n    (\"ST\", Int64),\n    (\"MET\", Int64),\n    (\"LEN\", Float64),\n    (\"O1\", Int64),\n    (\"F1\", Float64),\n    (\"O2\", Int64),\n    (\"F2\", Float64),\n    (\"O3\", Int64),\n    (\"F3\", Float64),\n    (\"O4\", Int64),\n    (\"F4\", Float64),\n]\n\nconst _branch_dtypes_v35 = vcat(\n    _branch_dtypes[1:6],\n    [\n        (\"NAME\", String),\n        (\"RATE1\", Float64),\n        (\"RATE2\", Float64),\n        (\"RATE3\", Float64),\n        (\"RATE4\", Float64),\n        (\"RATE5\", Float64),\n        (\"RATE6\", Float64),\n        (\"RATE7\", Float64),\n        (\"RATE8\", Float64),\n        (\"RATE9\", Float64),\n        (\"RATE10\", Float64),\n        (\"RATE11\", Float64),\n        (\"RATE12\", Float64),\n    ],\n    _branch_dtypes[10:end],\n)\n\nconst _switching_dtypes_v35 = [\n    (\"I\", Int64),\n    (\"J\", Int64),\n    (\"CKT\", String),\n    (\"X\", Float64),\n    (\"RATE1\", Float64),\n    (\"RATE2\", Float64),\n    (\"RATE3\", Float64),\n    (\"RATE4\", Float64),\n    (\"RATE5\", Float64),\n    (\"RATE6\", Float64),\n    (\"RATE7\", Float64),\n    (\"RATE8\", Float64),\n    (\"RATE9\", Float64),\n    (\"RATE10\", Float64),\n    (\"RATE11\", Float64),\n    (\"RATE12\", Float64),\n    (\"STAT\", Int64),\n    (\"NSTAT\", Int64),\n    (\"MET\", Int64),\n    (\"STYPE\", Int64),\n    (\"NAME\", String),\n]\n\nconst _transformer_dtypes = [\n    (\"I\", Int64),\n    (\"J\", Int64),\n    (\"K\", Int64),\n    (\"CKT\", String),\n    (\"CW\", Int64),\n    (\"CZ\", Int64),\n    (\"CM\", Int64),\n    (\"MAG1\", Float64),\n    (\"MAG2\", Float64),\n    (\"NMETR\", Int64),\n    (\"NAME\", String),\n    (\"STAT\", Int64),\n    (\"O1\", Int64),\n    (\"F1\", Float64),\n    (\"O2\", Int64),\n    (\"F2\", Float64),\n    (\"O3\", Int64),\n    (\"F3\", Float64),\n    (\"O4\", Int64),\n    (\"F4\", Float64),\n    (\"VECGRP\", String),\n]\n\nconst _transformer_dtypes_v35 = _transformer_dtypes\n\nconst _transformer_3_1_dtypes = [\n    (\"R1-2\", Float64),\n    (\"X1-2\", Float64),\n    (\"SBASE1-2\", Float64),\n    (\"R2-3\", Float64),\n    (\"X2-3\", Float64),\n    (\"SBASE2-3\", Float64),\n    (\"R3-1\", Float64),\n    (\"X3-1\", Float64),\n    (\"SBASE3-1\", Float64),\n    (\"VMSTAR\", Float64),\n    (\"ANSTAR\", Float64),\n]\n\nconst _transformer_3_1_dtypes_v35 = _transformer_3_1_dtypes\n\nconst _transformer_3_2_dtypes = [\n    (\"WINDV1\", Float64),\n    (\"NOMV1\", Float64),\n    (\"ANG1\", Float64),\n    (\"RATA1\", Float64),\n    (\"RATB1\", Float64),\n    (\"RATC1\", Float64),\n    (\"COD1\", Int64),\n    (\"CONT1\", Int64),\n    (\"RMA1\", Float64),\n    (\"RMI1\", Float64),\n    (\"VMA1\", Float64),\n    (\"VMI1\", Float64),\n    (\"NTP1\", Float64),\n    (\"TAB1\", Int64),\n    (\"CR1\", Float64),\n    (\"CX1\", Float64),\n    (\"CNXA1\", Float64),\n]\n\nconst _transformer_3_2_dtypes_v35 = vcat(\n    _transformer_3_2_dtypes[1:3],\n    [\n        (\"RATE11\", Float64),\n        (\"RATE12\", Float64),\n        (\"RATE13\", Float64),\n        (\"RATE14\", Float64),\n        (\"RATE15\", Float64),\n        (\"RATE16\", Float64),\n        (\"RATE17\", Float64),\n        (\"RATE18\", Float64),\n        (\"RATE19\", Float64),\n        (\"RATE110\", Float64),\n        (\"RATE111\", Float64),\n        (\"RATE112\", Float64),\n    ],\n    _transformer_3_2_dtypes[7:8],\n    [(\"NOD1\", Int64)],\n    _transformer_3_2_dtypes[9:end],\n)\n\nconst _transformer_3_3_dtypes = [\n    (\"WINDV2\", Float64),\n    (\"NOMV2\", Float64),\n    (\"ANG2\", Float64),\n    (\"RATA2\", Float64),\n    (\"RATB2\", Float64),\n    (\"RATC2\", Float64),\n    (\"COD2\", Int64),\n    (\"CONT2\", Int64),\n    (\"RMA2\", Float64),\n    (\"RMI2\", Float64),\n    (\"VMA2\", Float64),\n    (\"VMI2\", Float64),\n    (\"NTP2\", Float64),\n    (\"TAB2\", Int64),\n    (\"CR2\", Float64),\n    (\"CX2\", Float64),\n    (\"CNXA2\", Float64),\n]\n\nconst _transformer_3_3_dtypes_v35 = vcat(\n    _transformer_3_3_dtypes[1:3],\n    [\n        (\"RATE21\", Float64),\n        (\"RATE22\", Float64),\n        (\"RATE23\", Float64),\n        (\"RATE24\", Float64),\n        (\"RATE25\", Float64),\n        (\"RATE26\", Float64),\n        (\"RATE27\", Float64),\n        (\"RATE28\", Float64),\n        (\"RATE29\", Float64),\n        (\"RATE210\", Float64),\n        (\"RATE211\", Float64),\n        (\"RATE212\", Float64),\n    ],\n    _transformer_3_3_dtypes[7:8],\n    [(\"NOD2\", Int64)],\n    _transformer_3_3_dtypes[9:end],\n)\n\nconst _transformer_3_4_dtypes = [\n    (\"WINDV3\", Float64),\n    (\"NOMV3\", Float64),\n    (\"ANG3\", Float64),\n    (\"RATA3\", Float64),\n    (\"RATB3\", Float64),\n    (\"RATC3\", Float64),\n    (\"COD3\", Int64),\n    (\"CONT3\", Int64),\n    (\"RMA3\", Float64),\n    (\"RMI3\", Float64),\n    (\"VMA3\", Float64),\n    (\"VMI3\", Float64),\n    (\"NTP3\", Float64),\n    (\"TAB3\", Int64),\n    (\"CR3\", Float64),\n    (\"CX3\", Float64),\n    (\"CNXA3\", Float64),\n]\n\nconst _transformer_3_4_dtypes_v35 = vcat(\n    _transformer_3_4_dtypes[1:3],\n    [\n        (\"RATE31\", Float64),\n        (\"RATE32\", Float64),\n        (\"RATE33\", Float64),\n        (\"RATE34\", Float64),\n        (\"RATE35\", Float64),\n        (\"RATE36\", Float64),\n        (\"RATE37\", Float64),\n        (\"RATE38\", Float64),\n        (\"RATE39\", Float64),\n        (\"RATE310\", Float64),\n        (\"RATE311\", Float64),\n        (\"RATE312\", Float64),\n    ],\n    _transformer_3_4_dtypes[7:8],\n    [(\"NOD3\", Int64)],\n    _transformer_3_4_dtypes[9:end],\n)\n\nconst _transformer_2_1_dtypes =\n    [(\"R1-2\", Float64), (\"X1-2\", Float64), (\"SBASE1-2\", Float64)]\n\nconst _transformer_2_1_dtypes_v35 = _transformer_2_1_dtypes\n\nconst _transformer_2_2_dtypes = [\n    (\"WINDV1\", Float64),\n    (\"NOMV1\", Float64),\n    (\"ANG1\", Float64),\n    (\"RATA1\", Float64),\n    (\"RATB1\", Float64),\n    (\"RATC1\", Float64),\n    (\"COD1\", Int64),\n    (\"CONT1\", Int64),\n    (\"RMA1\", Float64),\n    (\"RMI1\", Float64),\n    (\"VMA1\", Float64),\n    (\"VMI1\", Float64),\n    (\"NTP1\", Float64),\n    (\"TAB1\", Int64),\n    (\"CR1\", Float64),\n    (\"CX1\", Float64),\n    (\"CNXA1\", Float64),\n]\n\nconst _transformer_2_2_dtypes_v35 = vcat(\n    _transformer_2_2_dtypes[1:3],\n    [\n        (\"RATE11\", Float64),\n        (\"RATE12\", Float64),\n        (\"RATE13\", Float64),\n        (\"RATE14\", Float64),\n        (\"RATE15\", Float64),\n        (\"RATE16\", Float64),\n        (\"RATE17\", Float64),\n        (\"RATE18\", Float64),\n        (\"RATE19\", Float64),\n        (\"RATE110\", Float64),\n        (\"RATE111\", Float64),\n        (\"RATE112\", Float64),\n    ],\n    _transformer_2_2_dtypes[7:8],\n    [(\"NOD1\", Int64)],\n    _transformer_2_2_dtypes[9:end],\n)\n\nconst _transformer_2_3_dtypes = [(\"WINDV2\", Float64), (\"NOMV2\", Float64)]\n\nconst _transformer_2_3_dtypes_v35 = _transformer_2_3_dtypes\n\nconst _area_interchange_dtypes =\n    [(\"I\", Int64), (\"ISW\", Int64), (\"PDES\", Float64), (\"PTOL\", Float64), (\"ARNAME\", String)]\n\nconst _area_interchange_dtypes_v35 = _area_interchange_dtypes\n\nconst _two_terminal_line_dtypes = [\n    (\"NAME\", String),\n    (\"MDC\", Int64),\n    (\"RDC\", Float64),\n    (\"SETVL\", Float64),\n    (\"VSCHD\", Float64),\n    (\"VCMOD\", Float64),\n    (\"RCOMP\", Float64),\n    (\"DELTI\", Float64),\n    (\"METER\", String),\n    (\"DCVMIN\", Float64),\n    (\"CCCITMX\", Int64),\n    (\"CCCACC\", Float64),\n    (\"IPR\", Int64),\n    (\"NBR\", Int64),\n    (\"ANMXR\", Float64),\n    (\"ANMNR\", Float64),\n    (\"RCR\", Float64),\n    (\"XCR\", Float64),\n    (\"EBASR\", Float64),\n    (\"TRR\", Float64),\n    (\"TAPR\", Float64),\n    (\"TMXR\", Float64),\n    (\"TMNR\", Float64),\n    (\"STPR\", Float64),\n    (\"ICR\", Int64),\n    (\"IFR\", Int64),\n    (\"ITR\", Int64),\n    (\"IDR\", String),\n    (\"XCAPR\", Float64),\n    (\"IPI\", Int64),\n    (\"NBI\", Int64),\n    (\"ANMXI\", Float64),\n    (\"ANMNI\", Float64),\n    (\"RCI\", Float64),\n    (\"XCI\", Float64),\n    (\"EBASI\", Float64),\n    (\"TRI\", Float64),\n    (\"TAPI\", Float64),\n    (\"TMXI\", Float64),\n    (\"TMNI\", Float64),\n    (\"STPI\", Float64),\n    (\"ICI\", Int64),\n    (\"IFI\", Int64),\n    (\"ITI\", Int64),\n    (\"IDI\", String),\n    (\"XCAPI\", Float64),\n]\n\nconst _two_terminal_line_dtypes_v35 = vcat(\n    _two_terminal_line_dtypes[1:25],\n    [(\"NDR\", Int64)],\n    _two_terminal_line_dtypes[26:42],\n    [(\"NDI\", Int64)],\n    _two_terminal_line_dtypes[43:end],\n)\n\nconst _vsc_line_dtypes = [\n    (\"NAME\", String),\n    (\"MDC\", Int64),\n    (\"RDC\", Float64),\n    (\"O1\", Int64),\n    (\"F1\", Float64),\n    (\"O2\", Int64),\n    (\"F2\", Float64),\n    (\"O3\", Int64),\n    (\"F3\", Float64),\n    (\"O4\", Int64),\n    (\"F4\", Float64),\n]\n\nconst _vsc_line_dtypes_35 = _vsc_line_dtypes\n\nconst _vsc_subline_dtypes = [\n    (\"IBUS\", Int64),\n    (\"TYPE\", Int64),\n    (\"MODE\", Int64),\n    (\"DCSET\", Float64),\n    (\"ACSET\", Float64),\n    (\"ALOSS\", Float64),\n    (\"BLOSS\", Float64),\n    (\"MINLOSS\", Float64),\n    (\"SMAX\", Float64),\n    (\"IMAX\", Float64),\n    (\"PWF\", Float64),\n    (\"MAXQ\", Float64),\n    (\"MINQ\", Float64),\n    (\"REMOT\", Int64),\n    (\"RMPCT\", Float64),\n]\n\nconst _vsc_subline_dtypes_v35 = _vsc_subline_dtypes\n\nconst _impedance_correction_dtypes = [\n    (\"I\", Int64),\n    (\"T1\", Float64),\n    (\"F1\", Float64),\n    (\"T2\", Float64),\n    (\"F2\", Float64),\n    (\"T3\", Float64),\n    (\"F3\", Float64),\n    (\"T4\", Float64),\n    (\"F4\", Float64),\n    (\"T5\", Float64),\n    (\"F5\", Float64),\n    (\"T6\", Float64),\n    (\"F6\", Float64),\n    (\"T7\", Float64),\n    (\"F7\", Float64),\n    (\"T8\", Float64),\n    (\"F8\", Float64),\n    (\"T9\", Float64),\n    (\"F9\", Float64),\n    (\"T10\", Float64),\n    (\"F10\", Float64),\n    (\"T11\", Float64),\n    (\"F11\", Float64),\n]\n\nconst _impedance_correction_dtypes_v35 = [\n    (\"I\", Int64),\n    (\"T1\", Float64), (\"Re(F1)\", Float64), (\"Im(F1)\", Float64),\n    (\"T2\", Float64), (\"Re(F2)\", Float64), (\"Im(F2)\", Float64),\n    (\"T3\", Float64), (\"Re(F3)\", Float64), (\"Im(F3)\", Float64),\n    (\"T4\", Float64), (\"Re(F4)\", Float64), (\"Im(F4)\", Float64),\n    (\"T5\", Float64), (\"Re(F5)\", Float64), (\"Im(F5)\", Float64),\n    (\"T6\", Float64), (\"Re(F6)\", Float64), (\"Im(F6)\", Float64),\n    (\"T7\", Float64), (\"Re(F7)\", Float64), (\"Im(F7)\", Float64),\n    (\"T8\", Float64), (\"Re(F8)\", Float64), (\"Im(F8)\", Float64),\n    (\"T9\", Float64), (\"Re(F9)\", Float64), (\"Im(F9)\", Float64),\n    (\"T10\", Float64), (\"Re(F10)\", Float64), (\"Im(F10)\", Float64),\n    (\"T11\", Float64), (\"Re(F11)\", Float64), (\"Im(F11)\", Float64),\n    (\"T12\", Float64), (\"Re(F12)\", Float64), (\"Im(F12)\", Float64),\n]\n\nconst _multi_term_main_dtypes = [\n    (\"NAME\", String),\n    (\"NCONV\", Int64),\n    (\"NDCBS\", Int64),\n    (\"NDCLN\", Int64),\n    (\"MDC\", Int64),\n    (\"VCONV\", Int64),\n    (\"VCMOD\", Float64),\n    (\"VCONVN\", Float64),\n]\n\nconst _multi_term_main_dtypes_v35 = _multi_term_main_dtypes\n\nconst _multi_term_nconv_dtypes = [\n    (\"IB\", Int64),\n    (\"N\", Int64),\n    (\"ANGMX\", Float64),\n    (\"ANGMN\", Float64),\n    (\"RC\", Float64),\n    (\"XC\", Float64),\n    (\"EBAS\", Float64),\n    (\"TR\", Float64),\n    (\"TAP\", Float64),\n    (\"TPMX\", Float64),\n    (\"TPMN\", Float64),\n    (\"TSTP\", Float64),\n    (\"SETVL\", Float64),\n    (\"DCPF\", Float64),\n    (\"MARG\", Float64),\n    (\"CNVCOD\", Int64),\n]\n\nconst _multi_term_nconv_dtypes_v35 = _multi_term_nconv_dtypes\n\nconst _multi_term_ndcbs_dtypes = [\n    (\"IDC\", Int64),\n    (\"IB\", Int64),\n    (\"AREA\", Int64),\n    (\"ZONE\", Int64),\n    (\"DCNAME\", String),\n    (\"IDC2\", Int64),\n    (\"RGRND\", Float64),\n    (\"OWNER\", Int64),\n]\n\nconst _multi_term_ndcbs_dtypes_v35 = _multi_term_ndcbs_dtypes\n\nconst _multi_term_ndcln_dtypes = [\n    (\"IDC\", Int64),\n    (\"JDC\", Int64),\n    (\"DCCKT\", String),\n    (\"MET\", Int64),\n    (\"RDC\", Float64),\n    (\"LDC\", Float64),\n]\n\nconst _multi_term_ndcln_dtypes_v35 = _multi_term_ndcln_dtypes\n\nconst _multi_section_dtypes = [\n    (\"I\", Int64),\n    (\"J\", Int64),\n    (\"ID\", String),\n    (\"MET\", Int64),\n    (\"DUM1\", Int64),\n    (\"DUM2\", Int64),\n    (\"DUM3\", Int64),\n    (\"DUM4\", Int64),\n    (\"DUM5\", Int64),\n    (\"DUM6\", Int64),\n    (\"DUM7\", Int64),\n    (\"DUM8\", Int64),\n    (\"DUM9\", Int64),\n]\n\nconst _multi_section_dtypes_v35 = _multi_section_dtypes\n\nconst _zone_dtypes = [(\"I\", Int64), (\"ZONAME\", String)]\n\nconst _zone_dtypes_v35 = _zone_dtypes\n\nconst _interarea_dtypes =\n    [(\"ARFROM\", Int64), (\"ARTO\", Int64), (\"TRID\", String), (\"PTRAN\", Float64)]\n\nconst _interarea_dtypes_v35 = _interarea_dtypes\n\nconst _owner_dtypes = [(\"I\", Int64), (\"OWNAME\", String)]\n\nconst _owner_dtypes_v35 = _owner_dtypes\n\nconst _FACTS_dtypes = [\n    (\"NAME\", String),\n    (\"I\", Int64),\n    (\"J\", Int64),\n    (\"MODE\", Int64),\n    (\"PDES\", Float64),\n    (\"QDES\", Float64),\n    (\"VSET\", Float64),\n    (\"SHMX\", Float64),\n    (\"TRMX\", Float64),\n    (\"VTMN\", Float64),\n    (\"VTMX\", Float64),\n    (\"VSMX\", Float64),\n    (\"IMX\", Float64),\n    (\"LINX\", Float64),\n    (\"RMPCT\", Float64),\n    (\"OWNER\", Int64),\n    (\"SET1\", Float64),\n    (\"SET2\", Float64),\n    (\"VSREF\", Int64),\n    (\"REMOT\", Int64),\n    (\"MNAME\", String),\n]\n\nconst _FACTS_dtypes_v35 = vcat(\n    _FACTS_dtypes[1:19],\n    [\n        (\"FCREG\", Int64),\n        (\"NREG\", Int64),\n        (\"MNAME\", String),\n    ],\n)\n\nconst _switched_shunt_dtypes = [\n    (\"I\", Int64),\n    (\"MODSW\", Int64),\n    (\"ADJM\", Int64),\n    (\"STAT\", Int64),\n    (\"VSWHI\", Float64),\n    (\"VSWLO\", Float64),\n    (\"SWREM\", Int64),\n    (\"RMPCT\", Float64),\n    (\"RMIDNT\", String),\n    (\"BINIT\", Float64),\n    (\"N1\", Int64),\n    (\"B1\", Float64),\n    (\"N2\", Int64),\n    (\"B2\", Float64),\n    (\"N3\", Int64),\n    (\"B3\", Float64),\n    (\"N4\", Int64),\n    (\"B4\", Float64),\n    (\"N5\", Int64),\n    (\"B5\", Float64),\n    (\"N6\", Int64),\n    (\"B6\", Float64),\n    (\"N7\", Int64),\n    (\"B7\", Float64),\n    (\"N8\", Int64),\n    (\"B8\", Float64),\n]\n\nconst _switched_shunt_dtypes_v35 = vcat(\n    _switched_shunt_dtypes[1],\n    [(\"ID\", String)],\n    _switched_shunt_dtypes[2:7],\n    [\n        (\"NREG\", Int64),\n        (\"RMPCT\", Float64),\n        (\"RMIDNT\", String),\n        (\"BINIT\", Float64),\n        (\"S1\", Int64), (\"N1\", Int64), (\"B1\", Float64),\n        (\"S2\", Int64), (\"N2\", Int64), (\"B2\", Float64),\n        (\"S3\", Int64), (\"N3\", Int64), (\"B3\", Float64),\n        (\"S4\", Int64), (\"N4\", Int64), (\"B4\", Float64),\n        (\"S5\", Int64), (\"N5\", Int64), (\"B5\", Float64),\n        (\"S6\", Int64), (\"N6\", Int64), (\"B6\", Float64),\n        (\"S7\", Int64), (\"N7\", Int64), (\"B7\", Float64),\n        (\"S8\", Int64), (\"N8\", Int64), (\"B8\", Float64),\n    ],\n)\n\n# TODO: Account for multiple lines in GNE Device entries\nconst _gne_device_dtypes = [\n    (\"NAME\", String),\n    (\"MODEL\", String),\n    (\"NTERM\", Int64),\n    (\"BUSi\", Int64),\n    (\"NREAL\", Int64),\n    (\"NINTG\", Int64),\n    (\"NCHAR\", Int64),\n    (\"STATUS\", Int64),\n    (\"OWNER\", Int64),\n    (\"NMETR\", Int64),\n    (\"REALi\", Float64),\n    (\"INTGi\", Int64),\n    (\"CHARi\", String),\n]\n\nconst _gne_device_dtypes_v35 = _gne_device_dtypes\n\nconst _induction_machine_dtypes = [\n    (\"I\", Int64),\n    (\"ID\", String),\n    (\"STAT\", Int64),\n    (\"SCODE\", Int64),\n    (\"DCODE\", Int64),\n    (\"AREA\", Int64),\n    (\"ZONE\", Int64),\n    (\"OWNER\", Int64),\n    (\"TCODE\", Int64),\n    (\"BCODE\", Int64),\n    (\"MBASE\", Float64),\n    (\"RATEKV\", Float64),\n    (\"PCODE\", Int64),\n    (\"PSET\", Float64),\n    (\"H\", Float64),\n    (\"A\", Float64),\n    (\"B\", Float64),\n    (\"D\", Float64),\n    (\"E\", Float64),\n    (\"RA\", Float64),\n    (\"XA\", Float64),\n    (\"XM\", Float64),\n    (\"R1\", Float64),\n    (\"X1\", Float64),\n    (\"R2\", Float64),\n    (\"X2\", Float64),\n    (\"X3\", Float64),\n    (\"E1\", Float64),\n    (\"SE1\", Float64),\n    (\"E2\", Float64),\n    (\"SE2\", Float64),\n    (\"IA1\", Float64),\n    (\"IA2\", Float64),\n    (\"XAMULT\", Float64),\n]\n\nconst _induction_machine_dtypes_v35 = _induction_machine_dtypes\n\nconst _substation_dtypes_v35 = [\n    (\"IS\", Int64),\n    (\"NAME\", String),\n    (\"LATITUDE\", Float64),\n    (\"LONGITUDE\", Float64),\n    (\"SGR\", Float64),\n]\n\n\"\"\"\nlookup array of data types for PTI file sections given by\n`field_name`, as enumerated by PSS/E Program Operation Manual.\n\"\"\"\nconst _pti_dtypes = Dict{String, Array}(\n    \"BUS\" => _bus_dtypes,\n    \"LOAD\" => _load_dtypes,\n    \"FIXED SHUNT\" => _fixed_shunt_dtypes,\n    \"GENERATOR\" => _generator_dtypes,\n    \"BRANCH\" => _branch_dtypes,\n    \"TRANSFORMER\" => _transformer_dtypes,\n    \"TRANSFORMER TWO-WINDING LINE 1\" => _transformer_2_1_dtypes,\n    \"TRANSFORMER TWO-WINDING LINE 2\" => _transformer_2_2_dtypes,\n    \"TRANSFORMER TWO-WINDING LINE 3\" => _transformer_2_3_dtypes,\n    \"TRANSFORMER THREE-WINDING LINE 1\" => _transformer_3_1_dtypes,\n    \"TRANSFORMER THREE-WINDING LINE 2\" => _transformer_3_2_dtypes,\n    \"TRANSFORMER THREE-WINDING LINE 3\" => _transformer_3_3_dtypes,\n    \"TRANSFORMER THREE-WINDING LINE 4\" => _transformer_3_4_dtypes,\n    \"AREA INTERCHANGE\" => _area_interchange_dtypes,\n    \"TWO-TERMINAL DC\" => _two_terminal_line_dtypes,\n    \"VOLTAGE SOURCE CONVERTER\" => _vsc_line_dtypes,\n    \"VOLTAGE SOURCE CONVERTER SUBLINES\" => _vsc_subline_dtypes,\n    \"IMPEDANCE CORRECTION\" => _impedance_correction_dtypes,\n    \"MULTI-TERMINAL DC\" => _multi_term_main_dtypes,\n    \"MULTI-TERMINAL DC NCONV\" => _multi_term_nconv_dtypes,\n    \"MULTI-TERMINAL DC NDCBS\" => _multi_term_ndcbs_dtypes,\n    \"MULTI-TERMINAL DC NDCLN\" => _multi_term_ndcln_dtypes,\n    \"MULTI-SECTION LINE\" => _multi_section_dtypes,\n    \"ZONE\" => _zone_dtypes,\n    \"INTER-AREA TRANSFER\" => _interarea_dtypes,\n    \"OWNER\" => _owner_dtypes,\n    \"FACTS CONTROL DEVICE\" => _FACTS_dtypes,\n    \"SWITCHED SHUNT\" => _switched_shunt_dtypes,\n    \"CASE IDENTIFICATION\" => _transaction_dtypes,\n    \"GNE DEVICE\" => _gne_device_dtypes,\n    \"INDUCTION MACHINE\" => _induction_machine_dtypes,\n)\n\nconst _pti_dtypes_v35 = Dict{String, Array}(\n    \"BUS\" => _bus_dtypes_v35,\n    \"LOAD\" => _load_dtypes_v35,\n    \"FIXED SHUNT\" => _fixed_shunt_dtypes_v35,\n    \"GENERATOR\" => _generator_dtypes_v35,\n    \"BRANCH\" => _branch_dtypes_v35,\n    \"SWITCHING DEVICE\" => _switching_dtypes_v35,\n    \"TRANSFORMER\" => _transformer_dtypes_v35,\n    \"TRANSFORMER TWO-WINDING LINE 1\" => _transformer_2_1_dtypes_v35,\n    \"TRANSFORMER TWO-WINDING LINE 2\" => _transformer_2_2_dtypes_v35,\n    \"TRANSFORMER TWO-WINDING LINE 3\" => _transformer_2_3_dtypes_v35,\n    \"TRANSFORMER THREE-WINDING LINE 1\" => _transformer_3_1_dtypes_v35,\n    \"TRANSFORMER THREE-WINDING LINE 2\" => _transformer_3_2_dtypes_v35,\n    \"TRANSFORMER THREE-WINDING LINE 3\" => _transformer_3_3_dtypes_v35,\n    \"TRANSFORMER THREE-WINDING LINE 4\" => _transformer_3_4_dtypes_v35,\n    \"AREA INTERCHANGE\" => _area_interchange_dtypes_v35,\n    \"TWO-TERMINAL DC\" => _two_terminal_line_dtypes_v35,\n    \"VOLTAGE SOURCE CONVERTER\" => _vsc_line_dtypes_35,\n    \"VOLTAGE SOURCE CONVERTER SUBLINES\" => _vsc_subline_dtypes_v35,\n    \"IMPEDANCE CORRECTION\" => _impedance_correction_dtypes_v35,\n    \"MULTI-TERMINAL DC\" => _multi_term_main_dtypes_v35,\n    \"MULTI-TERMINAL DC NCONV\" => _multi_term_nconv_dtypes_v35,\n    \"MULTI-TERMINAL DC NDCBS\" => _multi_term_ndcbs_dtypes_v35,\n    \"MULTI-TERMINAL DC NDCLN\" => _multi_term_ndcln_dtypes_v35,\n    \"MULTI-SECTION LINE\" => _multi_section_dtypes_v35,\n    \"ZONE\" => _zone_dtypes_v35,\n    \"INTER-AREA TRANSFER\" => _interarea_dtypes_v35,\n    \"OWNER\" => _owner_dtypes_v35,\n    \"FACTS CONTROL DEVICE\" => _FACTS_dtypes_v35,\n    \"SWITCHED SHUNT\" => _switched_shunt_dtypes_v35,\n    \"CASE IDENTIFICATION\" => _transaction_dtypes_v35,\n    \"GNE DEVICE\" => _gne_device_dtypes_v35,\n    \"INDUCTION MACHINE\" => _induction_machine_dtypes_v35,\n    \"SUBSTATION DATA\" => _substation_dtypes_v35,\n)\n\nconst _default_case_identification = Dict(\n    \"IC\" => 0,\n    \"SBASE\" => 100.0,\n    \"REV\" => 33,\n    \"XFRRAT\" => 0,\n    \"NXFRAT\" => 0,\n    \"BASFRQ\" => 60,\n)\n\nconst _default_case_identification_v35 = Dict(\n    \"IC\" => 0,\n    \"SBASE\" => 100.0,\n    \"REV\" => 35,\n    \"XFRRAT\" => 0,\n    \"NXFRAT\" => 0,\n    \"BASFRQ\" => 60,\n)\n\nconst _default_bus = Dict(\n    \"BASKV\" => 0.0,\n    \"IDE\" => 1,\n    \"AREA\" => 1,\n    \"ZONE\" => 1,\n    \"OWNER\" => 1,\n    \"VM\" => 1.0,\n    \"VA\" => 0.0,\n    \"NVHI\" => 1.1,\n    \"NVLO\" => 0.9,\n    \"EVHI\" => 1.1,\n    \"EVLO\" => 0.9,\n    \"NAME\" => \"            \",\n)\n\nconst _default_bus_v35 = _default_bus\n\nconst _default_load = Dict(\n    \"ID\" => \"1\",\n    \"STATUS\" => 1,\n    \"PL\" => 0.0,\n    \"QL\" => 0.0,\n    \"IP\" => 0.0,\n    \"IQ\" => 0.0,\n    \"YP\" => 0.0,\n    \"YQ\" => 0.0,\n    \"SCALE\" => 1,\n    \"INTRPT\" => 0,\n    \"AREA\" => nothing,\n    \"ZONE\" => nothing,\n    \"OWNER\" => nothing,\n)\n\nconst _default_load_v35 = merge(\n    _default_load,\n    Dict(\n        \"DGENP\" => 0.0,\n        \"DGENQ\" => 0.0,\n        \"DGENM\" => 0.0,\n        \"LOADTYPE\" => nothing,\n    ),\n)\n\nconst _default_fixed_shunt = Dict(\"ID\" => \"1\", \"STATUS\" => 1, \"GL\" => 0.0, \"BL\" => 0.0)\n\nconst _default_fixed_shunt_v35 = _default_fixed_shunt\n\nconst _default_generator = Dict(\n    \"ID\" => \"1\",\n    \"PG\" => 0.0,\n    \"QG\" => 0.0,\n    \"QT\" => 9999.0,\n    \"QB\" => -9999.0,\n    \"VS\" => 1.0,\n    \"IREG\" => 0,\n    \"MBASE\" => nothing,\n    \"ZR\" => 0.0,\n    \"ZX\" => 1.0,\n    \"RT\" => 0.0,\n    \"XT\" => 0.0,\n    \"GTAP\" => 1.0,\n    \"STAT\" => 1,\n    \"RMPCT\" => 100.0,\n    \"PT\" => 9999.0,\n    \"PB\" => -9999.0,\n    \"O1\" => nothing,\n    \"O2\" => 0,\n    \"O3\" => 0,\n    \"O4\" => 0,\n    \"F1\" => 1.0,\n    \"F2\" => 1.0,\n    \"F3\" => 1.0,\n    \"F4\" => 1.0,\n    \"WMOD\" => 0,\n    \"WPF\" => 1.0,\n)\n\nconst _default_generator_v35 = merge(_default_generator, Dict(\n    \"NREG\" => 0,\n    \"BASLOD\" => 0,\n))\n\nconst _default_branch = Dict(\n    \"CKT\" => \"1\",\n    \"B\" => 0.0,\n    \"RATEA\" => 0.0,\n    \"RATEB\" => 0.0,\n    \"RATEC\" => 0.0,\n    \"GI\" => 0.0,\n    \"BI\" => 0.0,\n    \"GJ\" => 0.0,\n    \"BJ\" => 0.0,\n    \"ST\" => 1,\n    \"MET\" => 1,\n    \"LEN\" => 0.0,\n    \"O1\" => nothing,\n    \"O2\" => 0,\n    \"O3\" => 0,\n    \"O4\" => 0,\n    \"F1\" => 1.0,\n    \"F2\" => 1.0,\n    \"F3\" => 1.0,\n    \"F4\" => 1.0,\n)\n\nconst _default_branch_v35 = merge(\n    _default_branch,\n    Dict(\n        \"RATE1\" => 0.0,\n        \"RATE2\" => 0.0,\n        \"RATE3\" => 0.0,\n        \"RATE4\" => 0.0,\n        \"RATE5\" => 0.0,\n        \"RATE6\" => 0.0,\n        \"RATE7\" => 0.0,\n        \"RATE8\" => 0.0,\n        \"RATE9\" => 0.0,\n        \"RATE10\" => 0.0,\n        \"RATE11\" => 0.0,\n        \"RATE12\" => 0.0,\n    ),\n)\n\nconst _default_switching_device_v35 = Dict(\n    \"CKT\" => \"1\",\n    \"RATE1\" => 0.0,\n    \"RATE2\" => 0.0,\n    \"RATE3\" => 0.0,\n    \"RATE4\" => 0.0,\n    \"RATE5\" => 0.0,\n    \"RATE6\" => 0.0,\n    \"RATE7\" => 0.0,\n    \"RATE8\" => 0.0,\n    \"RATE9\" => 0.0,\n    \"RATE10\" => 0.0,\n    \"RATE11\" => 0.0,\n    \"RATE12\" => 0.0,\n    \"STAT\" => 1,\n    \"NSTAT\" => 1,\n    \"MET\" => 0.0,\n    \"STYPE\" => 0.0,\n    \"NAME\" => \"\",\n)\n\nconst _default_transformer = Dict(\n    \"K\" => 0,\n    \"CKT\" => \"1\",\n    \"CW\" => 1,\n    \"CZ\" => 1,\n    \"CM\" => 1,\n    \"MAG1\" => 0.0,\n    \"MAG2\" => 0.0,\n    \"NMETR\" => 2,\n    \"NAME\" => \"            \",\n    \"STAT\" => 1,\n    \"O1\" => nothing,\n    \"O2\" => 0,\n    \"O3\" => 0,\n    \"O4\" => 0,\n    \"F1\" => 1.0,\n    \"F2\" => 1.0,\n    \"F3\" => 1.0,\n    \"F4\" => 1.0,\n    \"VECGRP\" => \"            \",\n    \"R1-2\" => 0.0,\n    \"SBASE1-2\" => nothing,\n    \"R2-3\" => 0.0,\n    \"SBASE2-3\" => nothing,\n    \"R3-1\" => 0.0,\n    \"SBASE3-1\" => nothing,\n    \"VMSTAR\" => 1.0,\n    \"ANSTAR\" => 0.0,\n    \"WINDV1\" => nothing,\n    \"NOMV1\" => 0.0,\n    \"ANG1\" => 0.0,\n    \"RATA1\" => 0.0,\n    \"RATB1\" => 0.0,\n    \"RATC1\" => 0.0,\n    \"COD1\" => 0,\n    \"CONT1\" => 0,\n    \"RMA1\" => 1.1,\n    \"RMI1\" => 0.9,\n    \"VMA1\" => 1.1,\n    \"VMI1\" => 0.9,\n    \"NTP1\" => 33,\n    \"TAB1\" => 0,\n    \"CR1\" => 0.0,\n    \"CX1\" => 0.0,\n    \"CNXA1\" => 0.0,\n    \"WINDV2\" => nothing,\n    \"NOMV2\" => 0.0,\n    \"ANG2\" => 0.0,\n    \"RATA2\" => 0.0,\n    \"RATB2\" => 0.0,\n    \"RATC2\" => 0.0,\n    \"COD2\" => 0,\n    \"CONT2\" => 0,\n    \"RMA2\" => 1.1,\n    \"RMI2\" => 0.9,\n    \"VMA2\" => 1.1,\n    \"VMI2\" => 0.9,\n    \"NTP2\" => 33,\n    \"TAB2\" => 0,\n    \"CR2\" => 0.0,\n    \"CX2\" => 0.0,\n    \"CNXA2\" => 0.0,\n    \"WINDV3\" => nothing,\n    \"NOMV3\" => 0.0,\n    \"ANG3\" => 0.0,\n    \"RATA3\" => 0.0,\n    \"RATB3\" => 0.0,\n    \"RATC3\" => 0.0,\n    \"COD3\" => 0,\n    \"CONT3\" => 0,\n    \"RMA3\" => 1.1,\n    \"RMI3\" => 0.9,\n    \"VMA3\" => 1.1,\n    \"VMI3\" => 0.9,\n    \"NTP3\" => 33,\n    \"TAB3\" => 0,\n    \"CR3\" => 0.0,\n    \"CX3\" => 0.0,\n    \"CNXA3\" => 0.0,\n)\n\nconst _default_transformer_v35 = merge(\n    _default_transformer,\n    Dict(\n        \"NOD1\" => 0,\n        \"NOD2\" => 0,\n        \"NOD3\" => 0,\n    ),\n)\n\nconst _default_area_interchange =\n    Dict(\"ISW\" => 0, \"PDES\" => 0.0, \"PTOL\" => 10.0, \"ARNAME\" => \"            \")\n\nconst _default_area_interchange_v35 = _default_area_interchange\n\nconst _default_two_terminal_dc = Dict(\n    \"MDC\" => 0,\n    \"VCMOD\" => 0.0,\n    \"RCOMP\" => 0.0,\n    \"DELTI\" => 0.0,\n    \"METER\" => \"I\",\n    \"DCVMIN\" => 0.0,\n    \"CCCITMX\" => 20,\n    \"CCCACC\" => 1.0,\n    \"TRR\" => 1.0,\n    \"TAPR\" => 1.0,\n    \"TMXR\" => 1.5,\n    \"TMNR\" => 0.51,\n    \"STPR\" => 0.00625,\n    \"ICR\" => 0,\n    \"IFR\" => 0,\n    \"ITR\" => 0,\n    \"IDR\" => \"1\",\n    \"XCAPR\" => 0.0,\n    \"TRI\" => 1.0,\n    \"TAPI\" => 1.0,\n    \"TMXI\" => 1.5,\n    \"TMNI\" => 0.51,\n    \"STPI\" => 0.00625,\n    \"ICI\" => 0,\n    \"IFI\" => 0,\n    \"ITI\" => 0,\n    \"IDI\" => \"1\",\n    \"XCAPI\" => 0.0,\n)\n\nconst _default_two_terminal_dc_v35 = merge(_default_two_terminal_dc, Dict(\n    \"NDR\" => 0,\n    \"NDI\" => 0,\n))\n\nconst _default_vsc_dc = Dict(\n    \"MDC\" => 1,\n    \"O1\" => nothing,\n    \"O2\" => 0,\n    \"O3\" => 0,\n    \"O4\" => 0,\n    \"F1\" => 1.0,\n    \"F2\" => 1.0,\n    \"F3\" => 1.0,\n    \"F4\" => 1.0,\n    \"CONVERTER BUSES\" => Dict(\n        \"MODE\" => 1,\n        \"ACSET\" => 1.0,\n        \"ALOSS\" => 1.0,\n        \"BLOSS\" => 0.0,\n        \"MINLOSS\" => 0.0,\n        \"SMAX\" => 0.0,\n        \"IMAX\" => 0.0,\n        \"PWF\" => 1.0,\n        \"MAXQ\" => 9999.0,\n        \"MINQ\" => -9999.0,\n        \"REMOT\" => 0,\n        \"RMPCT\" => 100.0,\n    ),\n)\n\nconst _default_vsc_dc_v35 = _default_vsc_dc\n\nconst _default_impedance_correction = Dict(\n    \"T1\" => 0.0,\n    \"T2\" => 0.0,\n    \"T3\" => 0.0,\n    \"T4\" => 0.0,\n    \"T5\" => 0.0,\n    \"T6\" => 0.0,\n    \"T7\" => 0.0,\n    \"T8\" => 0.0,\n    \"T9\" => 0.0,\n    \"T10\" => 0.0,\n    \"T11\" => 0.0,\n    \"F1\" => 0.0,\n    \"F2\" => 0.0,\n    \"F3\" => 0.0,\n    \"F4\" => 0.0,\n    \"F5\" => 0.0,\n    \"F6\" => 0.0,\n    \"F7\" => 0.0,\n    \"F8\" => 0.0,\n    \"F9\" => 0.0,\n    \"F10\" => 0.0,\n    \"F11\" => 0.0,\n)\n\nconst _default_impedance_correction_v35 = Dict(\n    \"T1\" => 0.0, \"Re(F1)\" => 0.0, \"Im(F1)\" => 0.0,\n    \"T2\" => 0.0, \"Re(F2)\" => 0.0, \"Im(F2)\" => 0.0,\n    \"T3\" => 0.0, \"Re(F3)\" => 0.0, \"Im(F3)\" => 0.0,\n    \"T4\" => 0.0, \"Re(F4)\" => 0.0, \"Im(F4)\" => 0.0,\n    \"T5\" => 0.0, \"Re(F5)\" => 0.0, \"Im(F5)\" => 0.0,\n    \"T6\" => 0.0, \"Re(F6)\" => 0.0, \"Im(F6)\" => 0.0,\n    \"T7\" => 0.0, \"Re(F7)\" => 0.0, \"Im(F7)\" => 0.0,\n    \"T8\" => 0.0, \"Re(F8)\" => 0.0, \"Im(F8)\" => 0.0,\n    \"T9\" => 0.0, \"Re(F9)\" => 0.0, \"Im(F9)\" => 0.0,\n    \"T10\" => 0.0, \"Re(F10)\" => 0.0, \"Im(F10)\" => 0.0,\n    \"T11\" => 0.0, \"Re(F11)\" => 0.0, \"Im(F11)\" => 0.0,\n    \"T12\" => 0.0, \"Re(F12)\" => 0.0, \"Im(F12)\" => 0.0,\n)\n\nconst _default_multi_term_dc = Dict(\n    \"MDC\" => 0,\n    \"VCMOD\" => 0.0,\n    \"VCONVN\" => 0,\n    \"CONV\" => Dict(\n        \"TR\" => 1.0,\n        \"TAP\" => 1.0,\n        \"TPMX\" => 1.5,\n        \"TPMN\" => 0.51,\n        \"TSTP\" => 0.00625,\n        \"DCPF\" => 1,\n        \"MARG\" => 0.0,\n        \"CNVCOD\" => 1,\n    ),\n    \"DCBS\" => Dict(\n        \"IB\" => 0.0,\n        \"AREA\" => 1,\n        \"ZONE\" => 1,\n        \"DCNAME\" => \"            \",\n        \"IDC2\" => 0,\n        \"RGRND\" => 0.0,\n        \"OWNER\" => 1,\n    ),\n    \"DCLN\" => Dict(\"DCCKT\" => 1, \"MET\" => 1, \"LDC\" => 0.0),\n)\n\nconst _default_multi_term_dc_v35 = _default_multi_term_dc\n\nconst _default_multi_section = Dict(\"ID\" => \"&1\", \"MET\" => 1)\n\nconst _default_multi_section_v35 = _default_multi_section\n\nconst _default_zone = Dict(\"ZONAME\" => \"            \")\n\nconst _default_zone_v35 = _default_zone\n\nconst _default_interarea = Dict(\"TRID\" => 1, \"PTRAN\" => 0.0)\n\nconst _default_interarea_v35 = _default_interarea\n\nconst _default_owner = Dict(\"OWNAME\" => \"            \")\n\nconst _default_owner_v35 = _default_owner\n\nconst _default_facts = Dict(\n    \"J\" => 0,\n    \"MODE\" => 1,\n    \"PDES\" => 0.0,\n    \"QDES\" => 0.0,\n    \"VSET\" => 1.0,\n    \"SHMX\" => 9999.0,\n    \"TRMX\" => 9999.0,\n    \"VTMN\" => 0.9,\n    \"VTMX\" => 1.1,\n    \"VSMX\" => 1.0,\n    \"IMX\" => 0.0,\n    \"LINX\" => 0.05,\n    \"RMPCT\" => 100.0,\n    \"OWNER\" => 1,\n    \"SET1\" => 0.0,\n    \"SET2\" => 0.0,\n    \"VSREF\" => 0,\n    \"REMOT\" => 0,\n    \"MNAME\" => \"\",\n)\n\nconst _default_facts_v35 = merge(\n    Dict(k => v for (k, v) in pairs(_default_facts) if k != \"REMOT\"),\n    Dict(\n        \"FCREG\" => 0,  # Replaces REMOT in v35\n        \"NREG\" => 0,\n    ),\n)\n\nconst _default_switched_shunt = Dict(\n    \"MODSW\" => 1,\n    \"ADJM\" => 0,\n    \"STAT\" => 1,\n    \"VSWHI\" => 1.0,\n    \"VSWLO\" => 1.0,\n    \"SWREM\" => 0,\n    \"RMPCT\" => 100.0,\n    \"RMIDNT\" => \"\",\n    \"BINIT\" => 0.0,\n    \"S1\" => 1, \"N1\" => 0, \"B1\" => 0.0,\n    \"S2\" => 1, \"N2\" => 0, \"B2\" => 0.0,\n    \"S3\" => 1, \"N3\" => 0, \"B3\" => 0.0,\n    \"S4\" => 1, \"N4\" => 0, \"B4\" => 0.0,\n    \"S5\" => 1, \"N5\" => 0, \"B5\" => 0.0,\n    \"S6\" => 1, \"N6\" => 0, \"B6\" => 0.0,\n    \"S7\" => 1, \"N7\" => 0, \"B7\" => 0.0,\n    \"S8\" => 1, \"N8\" => 0, \"B8\" => 0.0,\n)\n\nconst _default_switched_shunt_v35 = merge(\n    Dict(k => v for (k, v) in pairs(_default_switched_shunt) if k != \"SWREM\"),\n    Dict(\n        \"SWREG\" => 0,\n        \"ID\" => \"1\",\n        \"NAME\" => \"\",\n    ),\n)\n\nconst _default_gne_device = Dict(\n    \"NTERM\" => 1,\n    \"NREAL\" => 0,\n    \"NINTG\" => 0,\n    \"NCHAR\" => 0,\n    \"STATUS\" => 1,\n    \"OWNER\" => nothing,\n    \"NMETR\" => nothing,\n    \"REAL\" => 0,\n    \"INTG\" => nothing,\n    \"CHAR\" => \"1\",\n)\n\nconst _default_gne_device_v35 = _default_gne_device\n\nconst _default_induction_machine = Dict(\n    \"ID\" => 1,\n    \"STAT\" => 1,\n    \"SCODE\" => 1,\n    \"DCODE\" => 2,\n    \"AREA\" => nothing,\n    \"ZONE\" => nothing,\n    \"OWNER\" => nothing,\n    \"TCODE\" => 1,\n    \"BCODE\" => 1,\n    \"MBASE\" => nothing,\n    \"RATEKV\" => 0.0,\n    \"PCODE\" => 1,\n    \"H\" => 1.0,\n    \"A\" => 1.0,\n    \"B\" => 1.0,\n    \"D\" => 1.0,\n    \"E\" => 1.0,\n    \"RA\" => 0.0,\n    \"XA\" => 0.0,\n    \"XM\" => 2.5,\n    \"R1\" => 999.0,\n    \"X1\" => 999.0,\n    \"R2\" => 999.0,\n    \"X2\" => 999.0,\n    \"X3\" => 0.0,\n    \"E1\" => 1.0,\n    \"SE1\" => 0.0,\n    \"E2\" => 1.2,\n    \"SE2\" => 0.0,\n    \"IA1\" => 0.0,\n    \"IA2\" => 0.0,\n    \"XAMULT\" => 1,\n)\n\nconst _default_induction_machine_v35 = _default_induction_machine\n\nconst _default_substation_data_v35 = Dict(\n    \"NAME\" => \"\",\n    \"LATI\" => 0.0,\n    \"LONG\" => 0.0,\n    \"SGR\" => 0.1,\n)\n\nconst _pti_defaults = Dict(\n    \"BUS\" => _default_bus,\n    \"LOAD\" => _default_load,\n    \"FIXED SHUNT\" => _default_fixed_shunt,\n    \"GENERATOR\" => _default_generator,\n    \"BRANCH\" => _default_branch,\n    \"TRANSFORMER\" => _default_transformer,\n    \"AREA INTERCHANGE\" => _default_area_interchange,\n    \"TWO-TERMINAL DC\" => _default_two_terminal_dc,\n    \"VOLTAGE SOURCE CONVERTER\" => _default_vsc_dc,\n    \"IMPEDANCE CORRECTION\" => _default_impedance_correction,\n    \"MULTI-TERMINAL DC\" => _default_multi_term_dc,\n    \"MULTI-SECTION LINE\" => _default_multi_section,\n    \"ZONE\" => _default_zone,\n    \"INTER-AREA TRANSFER\" => _default_interarea,\n    \"OWNER\" => _default_owner,\n    \"FACTS CONTROL DEVICE\" => _default_facts,\n    \"SWITCHED SHUNT\" => _default_switched_shunt,\n    \"CASE IDENTIFICATION\" => _default_case_identification,\n    \"GNE DEVICE\" => _default_gne_device,\n    \"INDUCTION MACHINE\" => _default_induction_machine,\n)\n\nconst _pti_defaults_v35 = Dict(\n    \"BUS\" => _default_bus,\n    \"LOAD\" => _default_load,\n    \"FIXED SHUNT\" => _default_fixed_shunt,\n    \"GENERATOR\" => _default_generator,\n    \"BRANCH\" => _default_branch,\n    \"SWITCHING DEVICE\" => _default_switching_device_v35,\n    \"TRANSFORMER\" => _default_transformer,\n    \"AREA INTERCHANGE\" => _default_area_interchange,\n    \"TWO-TERMINAL DC\" => _default_two_terminal_dc,\n    \"VOLTAGE SOURCE CONVERTER\" => _default_vsc_dc,\n    \"IMPEDANCE CORRECTION\" => _default_impedance_correction,\n    \"MULTI-TERMINAL DC\" => _default_multi_term_dc,\n    \"MULTI-SECTION LINE\" => _default_multi_section,\n    \"ZONE\" => _default_zone,\n    \"INTER-AREA TRANSFER\" => _default_interarea,\n    \"OWNER\" => _default_owner,\n    \"FACTS CONTROL DEVICE\" => _default_facts,\n    \"SWITCHED SHUNT\" => _default_switched_shunt,\n    \"CASE IDENTIFICATION\" => _default_case_identification,\n    \"GNE DEVICE\" => _default_gne_device,\n    \"INDUCTION MACHINE\" => _default_induction_machine,\n    \"SUBSTATION DATA\" => _default_substation_data_v35,\n)\n\nfunction _correct_nothing_values!(data::Dict)\n    if !haskey(data, \"BUS\")\n        return\n    end\n\n    sbase = data[\"CASE IDENTIFICATION\"][1][\"SBASE\"]\n    bus_lookup = Dict(bus[\"I\"] => bus for bus in data[\"BUS\"])\n\n    if haskey(data, \"LOAD\")\n        for load in data[\"LOAD\"]\n            load_bus = bus_lookup[load[\"I\"]]\n            if load[\"AREA\"] === nothing\n                load[\"AREA\"] = load_bus[\"AREA\"]\n            end\n            if load[\"ZONE\"] === nothing\n                load[\"ZONE\"] = load_bus[\"ZONE\"]\n            end\n            if load[\"OWNER\"] === nothing\n                load[\"OWNER\"] = load_bus[\"OWNER\"]\n            end\n        end\n    end\n\n    if haskey(data, \"GENERATOR\")\n        for gen in data[\"GENERATOR\"]\n            gen_bus = bus_lookup[gen[\"I\"]]\n            if haskey(gen, \"OWNER\") && gen[\"OWNER\"] === nothing\n                gen[\"OWNER\"] = gen_bus[\"OWNER\"]\n            end\n            if gen[\"MBASE\"] === nothing\n                gen[\"MBASE\"] = sbase\n            end\n        end\n    end\n\n    if haskey(data, \"BRANCH\")\n        for branch in data[\"BRANCH\"]\n            branch_bus = bus_lookup[branch[\"I\"]]\n            if haskey(branch, \"OWNER\") && branch[\"OWNER\"] === nothing\n                branch[\"OWNER\"] = branch_bus[\"OWNER\"]\n            end\n        end\n    end\n\n    if haskey(data, \"TRANSFORMER\")\n        for transformer in data[\"TRANSFORMER\"]\n            transformer_bus = bus_lookup[transformer[\"I\"]]\n            for base_id in [\"SBASE1-2\", \"SBASE2-3\", \"SBASE3-1\"]\n                if haskey(transformer, base_id) && transformer[base_id] === nothing\n                    transformer[base_id] = sbase\n                end\n            end\n            for winding_id in [\"WINDV1\", \"WINDV2\", \"WINDV3\"]\n                if haskey(transformer, winding_id) && transformer[winding_id] === nothing\n                    if transformer[\"CW\"] == 2\n                        transformer[winding_id] = transformer_bus[\"BASKV\"]\n                    else\n                        transformer[winding_id] = 1.0\n                    end\n                end\n            end\n        end\n    end\n\n    #=\n    # TODO update this default value\n    if haskey(data, \"VOLTAGE SOURCE CONVERTER\")\n        for mdc in data[\"VOLTAGE SOURCE CONVERTER\"]\n            mdc[\"O1\"] = Expr(:call, :_get_component_property, data[\"BUS\"], \"OWNER\", \"I\", get(get(component, \"CONVERTER BUSES\", [Dict()])[1], \"IBUS\", 0))\n        end\n    end\n    =#\n\n    if haskey(data, \"GNE DEVICE\")\n        for gne in data[\"GNE DEVICE\"]\n            gne_bus = bus_lookup[gne[\"I\"]]\n            if haskey(gne, \"OWNER\") && gne[\"OWNER\"] === nothing\n                gne[\"OWNER\"] = gne_bus[\"OWNER\"]\n            end\n            if haskey(gne, \"NMETR\") && gne[\"NMETR\"] === nothing\n                gne[\"NMETR\"] = gne_bus[\"NTERM\"]\n            end\n        end\n    end\n\n    if haskey(data, \"INDUCTION MACHINE\")\n        for indm in data[\"INDUCTION MACHINE\"]\n            indm_bus = bus_lookup[indm[\"I\"]]\n            if indm[\"AREA\"] === nothing\n                indm[\"AREA\"] = indm_bus[\"AREA\"]\n            end\n            if indm[\"ZONE\"] === nothing\n                indm[\"ZONE\"] = indm_bus[\"ZONE\"]\n            end\n            if indm[\"OWNER\"] === nothing\n                indm[\"OWNER\"] = indm_bus[\"OWNER\"]\n            end\n            if indm[\"MBASE\"] === nothing\n                indm[\"MBASE\"] = sbase\n            end\n        end\n    end\nend\n\n\"\"\"\nThis is an experimental method for parsing elements and setting defaults at the same time.\nIt is not currently working but would reduce memory allocations if implemented correctly.\n\"\"\"\nfunction _parse_elements(\n    elements::Array,\n    dtypes::Array,\n    defaults::Dict,\n    section::AbstractString,\n)\n    data = Dict{String, Any}()\n\n    if length(elements) > length(dtypes)\n        @warn(\n            \"ignoring $(length(elements) - length(dtypes)) extra values in section $section, only $(length(dtypes)) items are defined\"\n        )\n        elements = elements[1:length(dtypes)]\n    end\n\n    for (i, element) in enumerate(elements)\n        field, dtype = dtypes[i]\n\n        element = strip(element)\n\n        if dtype == String\n            if startswith(element, \"'\") && endswith(element, \"'\")\n                data[field] = element[2:(end - 1)]\n            else\n                data[field] = element\n            end\n        else\n            if length(element) <= 0\n                # this will be set to a default in the cleanup phase\n                data[field] = nothing\n            else\n                try\n                    data[field] = parse(dtype, element)\n                catch message\n                    if isa(message, Meta.ParseError)\n                        data[field] = element\n                    else\n                        @error(\n                            \"value '$element' for $field in section $section is not of type $dtype.\"\n                        )\n                    end\n                end\n            end\n        end\n    end\n\n    if length(elements) < length(dtypes)\n        for (field, dtype) in dtypes[length(elements):end]\n            data[field] = defaults[field]\n            #=\n            if length(missing_fields) > 0\n                for field in missing_fields\n                    data[field] = \"\"\n                end\n                missing_str = join(missing_fields, \", \")\n                if !(section == \"SWITCHED SHUNT\" && startswith(missing_str, \"N\")) &&\n                    !(section == \"MULTI-SECTION LINE\" && startswith(missing_str, \"DUM\")) &&\n                    !(section == \"IMPEDANCE CORRECTION\" && startswith(missing_str, \"T\"))\n                    @warn(\"The following fields in $section are missing: $missing_str\")\n                end\n            end\n            =#\n        end\n    end\n\n    return data\nend\n\n\"\"\"\n    _parse_line_element!(data, elements, section)\n\nInternal function. Parses a single \"line\" of data elements from a PTI file, as\ngiven by `elements` which is an array of the line, typically split at `,`.\nElements are parsed into data types given by `section` and saved into `data::Dict`.\n\"\"\"\nfunction _parse_line_element!(\n    data::Dict,\n    elements::Array,\n    section::AbstractString,\n    dtypes::Dict{String, Array},\n)\n    missing_fields = []\n    for (i, (field, dtype)) in enumerate(dtypes[section])\n        if i > length(elements)\n            @debug \"Have run out of elements in $section at $field\" _group =\n                IS.LOG_GROUP_PARSING\n            push!(missing_fields, field)\n            continue\n        else\n            element = strip(elements[i])\n        end\n\n        try\n            if dtype != String && element != \"\"\n                data[field] = parse(dtype, element)\n            else\n                if dtype == String && startswith(element, \"'\") && endswith(element, \"'\")\n                    data[field] = chop(element[nextind(element, 1):end])\n                else\n                    data[field] = element\n                end\n            end\n        catch message\n            if isa(message, Meta.ParseError)\n                data[field] = element\n            else\n                error(\n                    \"value '$element' for $field in section $section is not of type $dtype.\",\n                )\n            end\n        end\n    end\n\n    if length(missing_fields) > 0\n        for field in missing_fields\n            data[field] = \"\"\n        end\n        missing_str = join(missing_fields, \", \")\n        if !(section == \"SWITCHED SHUNT\" && startswith(missing_str, \"N\")) &&\n           !(section == \"MULTI-SECTION LINE\" && startswith(missing_str, \"DUM\")) &&\n           !(section == \"IMPEDANCE CORRECTION\" && startswith(missing_str, \"T\"))\n            @debug \"The following fields in $section are missing: $missing_str\"\n        end\n    end\nend\n\nconst _comment_split = r\"(?!\\B[\\'][^\\']*)[\\/](?![^\\']*[\\']\\B)\"\nconst _split_string = r\",(?=(?:[^']*'[^']*')*[^']*$)\"\n\n\"\"\"\n    _get_line_elements(line)\n\nInternal function. Uses regular expressions to extract all separate data\nelements from a line of a PTI file and populate them into an `Array{String}`.\nComments, typically indicated at the end of a line with a `'/'` character,\nare also extracted separately, and `Array{Array{String}, String}` is returned.\n\"\"\"\nfunction _get_line_elements(line::AbstractString)\n    if count(i -> (i == \"'\"), line) % 2 == 1\n        throw(\n            DataFormatError(\n                \"There are an uneven number of single-quotes in \\\"{line}\\\", the line cannot be parsed.\",\n            ),\n        )\n    end\n\n    line_comment = split(line, _comment_split; limit = 2)\n    line = strip(line_comment[1])\n    comment = length(line_comment) > 1 ? strip(line_comment[2]) : \"\"\n\n    elements = split(line, _split_string)\n\n    return (elements, comment)\nend\n\n\"\"\"\nProcess substation data with elements and parse associated nodes\n\"\"\"\nfunction parse_substation_nodes!(\n    section_data::Dict{String, Any},\n    data_lines::Vector{String},\n    start_line_index::Int,\n)::Int\n    \"\"\"Parse nodes for a substation and return the updated line index\"\"\"\n    section_data[\"NODES\"] = []\n    temp_line_index = start_line_index + 1\n\n    # Look for \"BEGIN SUBSTATION NODE DATA\" comment\n    while temp_line_index <= length(data_lines)\n        temp_line = data_lines[temp_line_index]\n        if contains(temp_line, \"BEGIN SUBSTATION NODE DATA\")\n            temp_line_index += 1\n            break\n        end\n        temp_line_index += 1\n    end\n\n    # Parse node data until we hit the end marker\n    while temp_line_index <= length(data_lines)\n        temp_line = data_lines[temp_line_index]\n\n        if startswith(temp_line, \"0 /\") && (\n            contains(temp_line, \"END OF SUBSTATION NODE DATA\") ||\n            contains(temp_line, \"SUBSTATION TERMINAL DATA\")\n        )\n            return temp_line_index\n        end\n\n        if contains(temp_line, \"BEGIN SUBSTATION DATA BLOCK\")\n            return temp_line_index - 1\n        end\n\n        if !startswith(temp_line, \"@!\") && !isempty(strip(temp_line))\n            (check_elements, check_comment) = _get_line_elements(temp_line)\n            if length(check_elements) == 5 &&\n               tryparse(Int, strip(check_elements[1])) !== nothing &&\n               occursin('\\'', check_elements[2]) &&\n               tryparse(Float64, strip(check_elements[3])) !== nothing &&\n               tryparse(Float64, strip(check_elements[4])) !== nothing &&\n               tryparse(Float64, strip(check_elements[5])) !== nothing\n                return temp_line_index - 1\n            end\n        end\n\n        if startswith(temp_line, \"@!\")\n            temp_line_index += 1\n            continue\n        end\n\n        if !isempty(strip(temp_line))\n            (node_elements, node_comment) = _get_line_elements(temp_line)\n\n            if length(node_elements) >= 4\n                if length(node_elements) >= 3 &&\n                   length(strip(node_elements[3])) == 3 &&\n                   startswith(strip(node_elements[3]), \"'\") &&\n                   endswith(strip(node_elements[3]), \"'\")\n                    return temp_line_index - 1\n                end\n            end\n\n            if length(node_elements) >= 4 && length(node_elements) <= 6\n                node_data = Dict{String, Any}()\n                node_data[\"NI\"] = parse(Int, strip(node_elements[1]))\n\n                name_string = strip(node_elements[2])\n                if startswith(name_string, \"'\") && endswith(name_string, \"'\")\n                    name_string = name_string[2:(end - 1)]  # Remove quotes\n                end\n                node_data[\"NAME\"] = strip(name_string)\n\n                i_value = strip(node_elements[3])\n                if startswith(i_value, \"'\") && endswith(i_value, \"'\")\n                    i_value = i_value[2:(end - 1)]  # Remove quotes\n                end\n                node_data[\"I\"] = parse(Int, strip(i_value))\n\n                node_data[\"STATUS\"] = parse(Int, strip(node_elements[4]))\n                if length(node_elements) >= 5 && !isempty(strip(node_elements[5]))\n                    node_data[\"VM\"] = parse(Float64, strip(node_elements[5]))\n                end\n                if length(node_elements) >= 6 && !isempty(strip(node_elements[6]))\n                    node_data[\"VA\"] = parse(Float64, strip(node_elements[6]))\n                end\n                push!(section_data[\"NODES\"], node_data)\n            elseif length(node_elements) > 6\n                return temp_line_index - 1\n            end\n        end\n        temp_line_index += 1\n    end\n\n    return temp_line_index\nend\n\n\"\"\"\nProcess substation data with elements and parse associated nodes\n\"\"\"\nfunction process_substation_data!(\n    section_data,\n    elements,\n    section,\n    current_dtypes,\n    data_lines,\n    line_index,\n    pti_data,\n)\n    try\n        _parse_line_element!(section_data, elements, section, current_dtypes)\n\n        if haskey(section_data, \"NAME\")\n            section_data[\"NAME\"] = strip(section_data[\"NAME\"])\n        end\n\n        # Parse nodes for this substation\n        updated_line_index = parse_substation_nodes!(section_data, data_lines, line_index)\n\n        if haskey(pti_data, section)\n            push!(pti_data[section], section_data)\n        else\n            pti_data[section] = [section_data]\n        end\n\n        return updated_line_index\n    catch message\n        error(\"Parsing failed at line $line_index: $(sprint(showerror, message))\")\n    end\nend\n\n\"\"\"\n    _parse_pti_data(data_string, sections)\n\nInternal function. Parse a PTI raw file into a `Dict`, given the\n`data_string` of the file and a list of the `sections` in the PTI\nfile (typically given by default by `get_pti_sections()`.\n\"\"\"\nfunction _parse_pti_data(data_io::IO)\n    sections = deepcopy(_pti_sections)\n    sections_v35 = deepcopy(_pti_sections_v35)\n    data_lines = readlines(data_io)\n    skip_lines = 0\n    skip_sublines = 0\n    subsection = \"\"\n    is_v35 = false\n\n    pti_data = Dict{String, Array{Dict}}()\n\n    section = popfirst!(sections)\n    section_v35 = popfirst!(sections_v35)\n    section_data = Dict{String, Any}()\n\n    if any(startswith.(data_lines, \"@!\"))\n        is_v35 = true\n    end\n\n    header_line_start = is_v35 ? 2 : 1 # Start in second line due to @!\n    # Dynamically handle the start of BUS DATA section\n    # In v35 files, BUS DATA starts in different lines due to the fields GENERAL,GAUSS,NEWTON,ADJUST,TYSL,SOLVER,RATING\n    # This fields are optional in the file and when not found, the start of the reading vary a lot\n    bus_data_start = if is_v35\n        found_start = 25  # Default of most files\n        for i in 3:min(35, length(data_lines))\n            line = strip(data_lines[i])\n\n            # Skip comments and system-wide data\n            if startswith(\n                line,\n                r\"@!|GENERAL,|GAUSS,|NEWTON,|ADJUST,|TYSL,|SOLVER,|RATING,\",\n            ) || isempty(line)\n                continue\n            end\n\n            # Look for section marker of BUS DATA\n            if contains(line, \"END OF SYSTEM-WIDE DATA\") ||\n               (\n                tryparse(Int, split(line, ',')[1] |> strip) !== nothing &&\n                contains(line, \"'\")\n            )\n                found_start = if contains(line, \"END OF SYSTEM-WIDE DATA\")\n                    (i + (startswith(strip(data_lines[i + 1]), \"@!\") ? 2 : 1))\n                else\n                    i\n                end\n                break\n            end\n        end\n        # New updated start section\n        found_start\n    else\n        4 # Start for all v33 files\n    end\n\n    current_dtypes = is_v35 ? _pti_dtypes_v35 : _pti_dtypes\n\n    line_index = 1\n    while line_index <= length(data_lines)\n        line = data_lines[line_index]\n\n        if startswith(line, \"@!\")\n            line_index += 1\n            continue\n        end\n\n        (elements, comment) = _get_line_elements(line)\n\n        first_element = strip(elements[1])\n\n        if is_v35 && (line_index == 3 || line_index == 4) &&\n           section_v35 == \"CASE IDENTIFICATION\"\n            comment_line = strip(line)\n            comment_key = line_index == 3 ? \"Comment_Line_1\" : \"Comment_Line_2\"\n\n            if haskey(pti_data, \"CASE IDENTIFICATION\") &&\n               !isempty(pti_data[\"CASE IDENTIFICATION\"])\n                pti_data[\"CASE IDENTIFICATION\"][1][comment_key] = comment_line\n                @debug \"Added $comment_key: $comment_line\" _group = IS.LOG_GROUP_PARSING\n            end\n            line_index += 1\n            continue\n        end\n\n        if is_v35 && line_index >= 3 && line_index < bus_data_start\n            line_index += 1\n            continue\n        end\n\n        if line_index > (is_v35 ? bus_data_start - 1 : 3) && length(elements) != 0 &&\n           first_element == \"Q\"\n            break\n        elseif line_index > (is_v35 ? bus_data_start - 1 : 3) && length(elements) != 0 &&\n               first_element == \"0\"\n            if line_index == bus_data_start\n                section = is_v35 ? popfirst!(sections_v35) : popfirst!(sections)\n            end\n\n            if length(elements) > 1\n                @info(\n                    \"At line $line_index, new section started with '0', but additional non-comment data is present. Pattern '^\\\\s*0\\\\s*[/]*.*' is reserved for section start/end.\",\n                )\n            elseif length(comment) > 0\n                @debug \"At line $line_index, switched to $section\" _group =\n                    IS.LOG_GROUP_PARSING\n            end\n\n            current_sections = is_v35 ? sections_v35 : sections\n            if !isempty(current_sections)\n                section = popfirst!(current_sections)\n            end\n\n            line_index += 1\n            continue\n        else\n            if line_index == bus_data_start\n                section = is_v35 ? popfirst!(sections_v35) : popfirst!(sections)\n                section_data = Dict{String, Any}()\n            end\n\n            if skip_lines > 0\n                skip_lines -= 1\n                line_index += 1\n                continue\n            end\n\n            if section == \"IMPEDANCE CORRECTION\" && is_v35\n                temporal_ic_elements = Vector{Vector{String}}()\n\n                while line_index <= length(data_lines)\n                    line = data_lines[line_index]\n\n                    if startswith(line, \"0 /\") || startswith(line, \"Q\")\n                        if !isempty(temporal_ic_elements)\n                            last_entry_elements = temporal_ic_elements[end]\n\n                            section_data_final = Dict{String, Any}()\n                            section_data_final[\"I\"] =\n                                parse(Int64, strip(last_entry_elements[1]))\n\n                            processing_elements = last_entry_elements[2:end]\n\n                            point_index = 1\n                            element_index = 1\n                            while element_index <= length(processing_elements) &&\n                                element_index + 2 <= length(processing_elements)\n                                t_str = strip(processing_elements[element_index])\n                                re_str = strip(processing_elements[element_index + 1])\n                                im_str = strip(processing_elements[element_index + 2])\n\n                                if !isempty(t_str) && !isempty(re_str) && !isempty(im_str)\n                                    section_data_final[\"T$point_index\"] =\n                                        parse(Float64, t_str)\n                                    section_data_final[\"Re(F$point_index)\"] =\n                                        parse(Float64, re_str)\n                                    section_data_final[\"Im(F$point_index)\"] =\n                                        parse(Float64, im_str)\n                                    point_index += 1\n                                end\n                                element_index += 3\n                            end\n\n                            if haskey(pti_data, section)\n                                push!(pti_data[section], section_data_final)\n                            else\n                                pti_data[section] = [section_data_final]\n                            end\n                        end\n                        break\n                    end\n\n                    if startswith(line, \"@!\")\n                        line_index += 1\n                        continue\n                    end\n\n                    if isempty(strip(line))\n                        line_index += 1\n                        continue\n                    end\n\n                    (elements, comment) = _get_line_elements(line)\n                    first_element = strip(elements[1])\n\n                    if tryparse(Int64, first_element) === nothing\n                        line_index += 1\n                        if !isempty(temporal_ic_elements)\n                            append!(temporal_ic_elements[end], elements)\n                        end\n                        continue\n                    end\n\n                    if !isempty(temporal_ic_elements)\n                        last_entry_elements = temporal_ic_elements[end]\n\n                        section_data_prev = Dict{String, Any}()\n                        section_data_prev[\"I\"] = parse(Int64, strip(last_entry_elements[1]))\n\n                        processing_elements = last_entry_elements[2:end]\n\n                        point_index = 1\n                        element_index = 1\n                        while element_index <= length(processing_elements) &&\n                            element_index + 2 <= length(processing_elements)\n                            t_str = strip(processing_elements[element_index])\n                            re_str = strip(processing_elements[element_index + 1])\n                            im_str = strip(processing_elements[element_index + 2])\n\n                            if !isempty(t_str) && !isempty(re_str) && !isempty(im_str)\n                                section_data_prev[\"T$point_index\"] = parse(Float64, t_str)\n                                section_data_prev[\"Re(F$point_index)\"] =\n                                    parse(Float64, re_str)\n                                section_data_prev[\"Im(F$point_index)\"] =\n                                    parse(Float64, im_str)\n                                point_index += 1\n                            end\n                            element_index += 3\n                        end\n\n                        if haskey(pti_data, section)\n                            push!(pti_data[section], section_data_prev)\n                        else\n                            pti_data[section] = [section_data_prev]\n                        end\n                    end\n\n                    push!(temporal_ic_elements, elements)\n                    line_index += 1\n                end\n\n            elseif !(\n                section in [\n                    \"CASE IDENTIFICATION\",\n                    \"SWITCHING DEVICE DATA\",\n                    \"TRANSFORMER\",\n                    \"VOLTAGE SOURCE CONVERTER\",\n                    \"IMPEDANCE CORRECTION\",\n                    \"MULTI-TERMINAL DC\",\n                    \"TWO-TERMINAL DC\",\n                    \"GNE DEVICE\",\n                    \"SUBSTATION DATA\",\n                ]\n            )\n                section_data = Dict{String, Any}()\n\n                try\n                    _parse_line_element!(section_data, elements, section, current_dtypes)\n                catch message\n                    throw(\n                        @error(\n                            \"Parsing failed at line $line_index: $(sprint(showerror, message))\"\n                        )\n                    )\n                end\n                line_index += 1\n\n            elseif section == \"CASE IDENTIFICATION\"\n                if line_index == header_line_start\n                    try\n                        _parse_line_element!(\n                            section_data,\n                            elements,\n                            section,\n                            current_dtypes,\n                        )\n                    catch message\n                        throw(\n                            @error(\n                                \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                            ),\n                        )\n                    end\n\n                    if section_data[\"REV\"] != \"\" && section_data[\"REV\"] < 33\n                        @info(\n                            \"Version $(section_data[\"REV\"]) of PTI format is unsupported, parser may not function correctly.\",\n                        )\n                    end\n\n                    if is_v35\n                        if haskey(pti_data, section)\n                            push!(pti_data[section], section_data)\n                        else\n                            pti_data[section] = [section_data]\n                        end\n                    end\n                else\n                    if is_v35\n                        if line_index == 3\n                            comment_line = strip(line)\n                            if haskey(pti_data, section) && !isempty(pti_data[section])\n                                pti_data[section][1][\"Comment_Line_1\"] = comment_line\n                            end\n                        elseif line_index == 4\n                            comment_line = strip(line)\n                            if haskey(pti_data, section) && !isempty(pti_data[section])\n                                pti_data[section][1][\"Comment_Line_2\"] = comment_line\n                            end\n                        end\n                    elseif !is_v35 && line_index > header_line_start\n                        section_data[\"Comment_Line_$(line_index - 1)\"] = strip(line)\n                    end\n                end\n\n                if line_index < (bus_data_start - 1)\n                    line_index += 1\n                    continue\n                end\n\n                line_index += 1\n\n            elseif section == \"SWITCHING DEVICE\"\n                if is_v35\n                    section_data = Dict{String, Any}()\n                    try\n                        _parse_line_element!(\n                            section_data,\n                            elements,\n                            section,\n                            current_dtypes,\n                        )\n                    catch message\n                        throw(\n                            @error(\n                                \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                            ),\n                        )\n                    end\n                else\n                    @info(\"SWITCHING DEVICE DATA section found in non-v35 file, skipping.\")\n                end\n                line_index += 1\n\n            elseif section == \"TRANSFORMER\"\n                section_data = Dict{String, Any}()\n                if parse(Int64, _get_line_elements(line)[1][3]) == 0 # two winding transformer\n                    winding = \"TWO-WINDING\"\n                    skip_lines = 3\n                elseif parse(Int64, _get_line_elements(line)[1][3]) != 0 # three winding transformer\n                    winding = \"THREE-WINDING\"\n                    skip_lines = 4\n                else\n                    @error(\"Cannot detect type of Transformer\")\n                end\n\n                try\n                    for transformer_line in 0:4\n                        if transformer_line == 0\n                            temp_section = section\n                        else\n                            temp_section =\n                                join([section, winding, \"LINE\", transformer_line], \" \")\n                        end\n\n                        if winding == \"TWO-WINDING\" && transformer_line == 4\n                            break\n                        else\n                            elements = _get_line_elements(\n                                data_lines[line_index + transformer_line],\n                            )[1]\n                            _parse_line_element!(\n                                section_data,\n                                elements,\n                                temp_section,\n                                current_dtypes,\n                            )\n                        end\n                    end\n                catch message\n                    throw(\n                        @error(\n                            \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                        ),\n                    )\n                end\n                line_index += 1\n\n            elseif section == \"VOLTAGE SOURCE CONVERTER\"\n                vsc_line_length = length(_get_line_elements(line)[1])\n                # VSC DC LINE DATA can have 5 or 11 elements in all cases possible\n                # \"CSC-VSC     \",1, 1.5800,  28,1.0000\n                # \"CSC-VSC     \",1, 1.5800,  28,1.0000,,,,,,\n                # \"CSC-VSC     \",1, 1.5800,  28,1.0000,1.0,0.0,1.0,0.0,1.0,0.0\n                # This is how originally the parser was written\n                if vsc_line_length == 5 || vsc_line_length == 11\n                    section_data = Dict{String, Any}()\n                    try\n                        _parse_line_element!(\n                            section_data,\n                            elements,\n                            section,\n                            current_dtypes,\n                        )\n                    catch message\n                        throw(\n                            @error(\n                                \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                            ),\n                        )\n                    end\n                    skip_sublines = 2\n                    line_index += 1\n                    continue\n\n                elseif skip_sublines > 0\n                    skip_sublines -= 1\n                    subsection_data = Dict{String, Any}()\n\n                    for (field, dtype) in _pti_dtypes[\"$section SUBLINES\"]\n                        element = popfirst!(elements)\n                        if element != \"\"\n                            subsection_data[field] = parse(dtype, element)\n                        else\n                            line_index += 1\n                            subsection_data[field] = \"\"\n                        end\n                    end\n\n                    if haskey(section_data, \"CONVERTER BUSES\")\n                        push!(section_data[\"CONVERTER BUSES\"], subsection_data)\n                    else\n                        section_data[\"CONVERTER BUSES\"] = [subsection_data]\n                        line_index += 1\n                        continue\n                    end\n                end\n                line_index += 1\n\n            elseif section == \"TWO-TERMINAL DC\"\n                section_data = Dict{String, Any}()\n                if length(_get_line_elements(line)[1]) == 12\n                    (elements, comment) = _get_line_elements(\n                        join(data_lines[line_index:(line_index + 2)], ','),\n                    )\n                    skip_lines = 2\n                end\n\n                try\n                    _parse_line_element!(section_data, elements, section, current_dtypes)\n                catch message\n                    throw(\n                        @error(\n                            \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                        ),\n                    )\n                end\n                line_index += 1\n\n            elseif section == \"IMPEDANCE CORRECTION\" && !is_v35\n                section_data = Dict{String, Any}()\n                try\n                    _parse_line_element!(section_data, elements, section, current_dtypes)\n                catch message\n                    throw(\n                        @error(\n                            \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                        ),\n                    )\n                end\n                line_index += 1\n\n            elseif section == \"MULTI-TERMINAL DC\"\n                if skip_sublines == 0\n                    section_data = Dict{String, Any}()\n                    try\n                        _parse_line_element!(\n                            section_data,\n                            elements,\n                            section,\n                            current_dtypes,\n                        )\n                    catch message\n                        throw(\n                            @error(\n                                \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                            ),\n                        )\n                    end\n\n                    if section_data[\"NCONV\"] > 0\n                        skip_sublines = section_data[\"NCONV\"]\n                        subsection = \"NCONV\"\n                        line_index += 1\n                        continue\n                    elseif section_data[\"NDCBS\"] > 0\n                        skip_sublines = section_data[\"NDCBS\"]\n                        subsection = \"NDCBS\"\n                        line_index += 1\n                        continue\n                    elseif section_data[\"NDCLN\"] > 0\n                        skip_sublines = section_data[\"NDCLN\"]\n                        subsection = \"NDCLN\"\n                        line_index += 1\n                        continue\n                    end\n                end\n\n                if skip_sublines > 0\n                    skip_sublines -= 1\n\n                    subsection_data = Dict{String, Any}()\n                    try\n                        _parse_line_element!(\n                            subsection_data,\n                            elements,\n                            \"$section $subsection\",\n                            current_dtypes,\n                        )\n                    catch message\n                        throw(\n                            error(\n                                \"Parsing failed at line $line_index: $(sprint(showerror, message))\",\n                            ),\n                        )\n                    end\n\n                    if haskey(section_data, \"$(subsection[2:end])\")\n                        section_data[\"$(subsection[2:end])\"] =\n                            push!(section_data[\"$(subsection[2:end])\"], subsection_data)\n                        if skip_sublines > 0 && subsection != \"NDCLN\"\n                            line_index += 1\n                            continue\n                        end\n                    else\n                        section_data[\"$(subsection[2:end])\"] = [subsection_data]\n                        if skip_sublines > 0 && subsection != \"NDCLN\"\n                            line_index += 1\n                            continue\n                        end\n                    end\n\n                    if skip_sublines == 0 && subsection != \"NDCLN\"\n                        if subsection == \"NDCBS\"\n                            skip_sublines = section_data[\"NDCLN\"]\n                            subsection = \"NDCLN\"\n                            line_index += 1\n                            continue\n                        elseif subsection == \"NCONV\"\n                            skip_sublines = section_data[\"NDCBS\"]\n                            subsection = \"NDCBS\"\n                            line_index += 1\n                            continue\n                        end\n                    elseif skip_sublines == 0 && subsection == \"NDCLN\"\n                        subsection = \"\"\n                    else\n                        line_index += 1\n                        continue\n                    end\n                end\n                line_index += 1\n\n            elseif section == \"SUBSTATION DATA\" && is_v35\n                if startswith(line, \"@!\")\n                    line_index += 1\n                    continue\n                else\n                    if length(elements) == 4 && occursin('\\'', elements[1])\n                        first_part = elements[1]\n                        if occursin(\",'\", first_part)\n                            comma_quote_pos = findfirst(\",'\", first_part)\n                            if comma_quote_pos !== nothing\n                                is_part = first_part[1:(comma_quote_pos[1] - 1)]\n                                name_part = first_part[(comma_quote_pos[1] + 1):end]\n\n                                corrected_elements = [\n                                    is_part,\n                                    name_part,\n                                    elements[2],\n                                    elements[3],\n                                    elements[4],\n                                ]\n\n                                if length(corrected_elements) == 5 &&\n                                   occursin('\\'', corrected_elements[2]) &&\n                                   tryparse(Float64, strip(corrected_elements[3])) !==\n                                   nothing &&\n                                   tryparse(Float64, strip(corrected_elements[4])) !==\n                                   nothing &&\n                                   tryparse(Float64, strip(corrected_elements[5])) !==\n                                   nothing\n                                    @debug \"Parsing substation data line: $line\" _group =\n                                        IS.LOG_GROUP_PARSING\n                                    section_data = Dict{String, Any}()\n                                    line_index = process_substation_data!(\n                                        section_data,\n                                        corrected_elements,\n                                        section,\n                                        current_dtypes,\n                                        data_lines,\n                                        line_index,\n                                        pti_data,\n                                    )\n                                end\n                            end\n                        end\n\n                    elseif length(elements) == 5 &&\n                           occursin('\\'', elements[2]) &&\n                           tryparse(Float64, strip(elements[3])) !== nothing &&\n                           tryparse(Float64, strip(elements[4])) !== nothing &&\n                           tryparse(Float64, strip(elements[5])) !== nothing\n                        section_data = Dict{String, Any}()\n                        line_index = process_substation_data!(\n                            section_data,\n                            elements,\n                            section,\n                            current_dtypes,\n                            data_lines,\n                            line_index,\n                            pti_data,\n                        )\n                    end\n\n                    line_index += 1\n                    continue\n                end\n                line_index += 1\n\n            elseif section == \"GNE DEVICE\"\n                # TODO: handle multiple lines of GNE Device\n                @info(\"GNE DEVICE parsing is not supported.\")\n                line_index += 1\n            else\n                line_index += 1\n            end\n        end\n        if subsection != \"\"\n            @debug \"appending data\" _group = IS.LOG_GROUP_PARSING\n        end\n\n        if haskey(pti_data, section)\n            if section == \"IMPEDANCE CORRECTION\" &&\n               pti_data[\"CASE IDENTIFICATION\"][1][\"REV\"] == 35\n                continue\n            else\n                push!(pti_data[section], section_data)\n            end\n        else\n            pti_data[section] = [section_data]\n        end\n    end\n\n    _split_breakers_and_branches!(pti_data)\n    _populate_defaults!(pti_data)\n    _correct_nothing_values!(pti_data)\n\n    return pti_data\nend\n\n\"\"\"\n    parse_pti(filename::String)\n\nOpen PTI raw file given by `filename`, returning a `Dict` of the data parsed\ninto the proper types.\n\"\"\"\nfunction parse_pti(filename::String)::Dict\n    pti_data = open(filename) do f\n        parse_pti(f)\n    end\n\n    return pti_data\nend\n\n\"\"\"\n    parse_pti(io::IO)\n\nReads PTI data in `io::IO`, returning a `Dict` of the data parsed into the\nproper types.\n\"\"\"\nfunction parse_pti(io::IO)::Dict\n    pti_data = _parse_pti_data(io)\n    try\n        pti_data[\"CASE IDENTIFICATION\"][1][\"NAME\"] = match(\n            r\"^\\<file\\s[\\/\\\\]*(?:.*[\\/\\\\])*(.*)\\.raw\\>$\",\n            lowercase(io.name),\n        ).captures[1]\n    catch\n        throw(error(\"This file is unrecognized and cannot be parsed\"))\n    end\n\n    return pti_data\nend\n\nfunction _split_breakers_and_branches!(data::Dict)\n    if !haskey(data, \"BRANCH\")\n        @info \"No BRANCH section found in the system.\"\n        return data\n    end\n    breakers = sizehint!(eltype(data[\"BRANCH\"])[], length(data[\"BRANCH\"]))\n    delete_ixs = Int[]\n    for (ix, item) in enumerate(data[\"BRANCH\"])\n        if first(item[\"CKT\"]) == '@' || first(item[\"CKT\"]) == '*'\n            push!(breakers, item)\n            push!(delete_ixs, ix)\n        end\n    end\n    if isempty(delete_ixs)\n        @info \"No breakers modeled as branches using @ or * found in the system.\"\n        return data\n    else\n        @info \"Found $(length(breakers)) breakers in the system modeled as branches.\"\n    end\n    deleteat!(data[\"BRANCH\"], delete_ixs)\n    data[\"SWITCHES_AS_BRANCHES\"] = breakers\n    return data\nend\n\n\"\"\"\n    _populate_defaults!(pti_data)\n\nInternal function. Populates empty fields with PSS(R)E PTI v33 default values\n\"\"\"\nfunction _populate_defaults!(data::Dict)\n    for section in _pti_sections\n        if haskey(data, section)\n            component_defaults = _pti_defaults[section]\n            for component in data[section]\n                for (field, field_value) in component\n                    if isa(field_value, Array)\n                        sub_component_defaults = component_defaults[field]\n                        for sub_component in field_value\n                            for (sub_field, sub_field_value) in sub_component\n                                if sub_field_value == \"\"\n                                    try\n                                        sub_component[sub_field] =\n                                            sub_component_defaults[sub_field]\n                                    catch msg\n                                        if isa(msg, KeyError)\n                                            @warn(\n                                                \"'$sub_field' in '$field' in '$section' has no default value\",\n                                            )\n                                        else\n                                            rethrow(msg)\n                                        end\n                                    end\n                                end\n                            end\n                        end\n                    elseif field_value == \"\" &&\n                           !(field in [\"Comment_Line_1\", \"Comment_Line_2\"]) &&\n                           !startswith(field, \"DUM\")\n                        try\n                            component[field] = component_defaults[field]\n                        catch msg\n                            if isa(msg, KeyError)\n                                @warn(\"'$field' in '$section' has no default value\",)\n                            else\n                                rethrow(msg)\n                            end\n                        end\n                    end\n                end\n            end\n        end\n    end\nend\n"
  },
  {
    "path": "src/parsers/pm_io.jl",
    "content": "include(\"pm_io/matpower.jl\")\ninclude(\"pm_io/common.jl\")\ninclude(\"pm_io/pti.jl\")\ninclude(\"pm_io/psse.jl\")\ninclude(\"pm_io/data.jl\")\n"
  },
  {
    "path": "src/parsers/power_models_data.jl",
    "content": "\"\"\"Container for data parsed by PowerModels\"\"\"\nstruct PowerModelsData\n    data::Dict{String, Any}\nend\n\n\"\"\"\nConstructs PowerModelsData from a raw file.\nCurrently Supports MATPOWER and PSSE data files parsed by PowerModels.\n\"\"\"\nfunction PowerModelsData(file::Union{String, IO}; kwargs...)\n    validate = get(kwargs, :pm_data_corrections, true)\n    import_all = get(kwargs, :import_all, false)\n    correct_branch_rating = get(kwargs, :correct_branch_rating, true)\n    pm_dict = parse_file(\n        file;\n        import_all = import_all,\n        validate = validate,\n        correct_branch_rating = correct_branch_rating,\n    )\n    pm_data = PowerModelsData(pm_dict)\n    correct_pm_transformer_status!(pm_data)\n    return pm_data\nend\n\n\"\"\"\nConstructs a System from PowerModelsData.\n\n# Arguments\n- `pm_data::Union{PowerModelsData, Union{String, IO}}`: PowerModels data object or supported\nload flow case (*.m, *.raw)\n\n# Keyword arguments\n- `ext::Dict`: Contains user-defined parameters. Should only contain standard types.\n- `runchecks::Bool`: Run available checks on input fields and when add_component! is called.\n  Throws InvalidValue if an error is found.\n- `time_series_in_memory::Bool=false`: Store time series data in memory instead of HDF5.\n- `config_path::String`: specify path to validation config file\n- `pm_data_corrections::Bool=true` : Run the PowerModels data corrections (aka :validate in PowerModels)\n- `import_all:Bool=false` : Import all fields from PTI files\n\n# Examples\n```julia\nsys = System(\n    pm_data, config_path = \"ACTIVSg25k_validation.json\",\n    bus_name_formatter = x->string(x[\"name\"]*\"-\"*string(x[\"index\"])),\n    load_name_formatter = x->strip(join(x[\"source_id\"], \"_\"))\n)\n```\n\"\"\"\nfunction System(pm_data::PowerModelsData; kwargs...)\n    runchecks = get(kwargs, :runchecks, true)\n    data = pm_data.data\n    if length(data[\"bus\"]) < 1\n        throw(DataFormatError(\"There are no buses in this file.\"))\n    end\n\n    @info \"Constructing System from Power Models\" data[\"name\"] data[\"source_type\"]\n\n    sys = System(data[\"baseMVA\"]; kwargs...)\n    source_type = data[\"source_type\"]\n\n    bus_number_to_bus = read_bus!(sys, data; kwargs...)\n    read_loads!(sys, data, bus_number_to_bus; kwargs...)\n    read_loadzones!(sys, data, bus_number_to_bus; kwargs...)\n    read_gen!(sys, data, bus_number_to_bus; kwargs...)\n    for component_type in [\"switch\", \"breaker\"]\n        read_switch_breaker!(sys, data, bus_number_to_bus, component_type; kwargs...)\n    end\n    read_branch!(sys, data, bus_number_to_bus; kwargs...)\n    read_switched_shunt!(sys, data, bus_number_to_bus; kwargs...)\n    read_shunt!(sys, data, bus_number_to_bus; kwargs...)\n    read_dcline!(sys, data, bus_number_to_bus, source_type; kwargs...)\n    read_vscline!(sys, data, bus_number_to_bus; kwargs...)\n    read_facts!(sys, data, bus_number_to_bus; kwargs...)\n    read_storage!(sys, data, bus_number_to_bus; kwargs...)\n    read_3w_transformer!(sys, data, bus_number_to_bus; kwargs...)\n    if runchecks\n        check(sys)\n    end\n\n    substation_data = get(data, \"substation_data\", [])\n    add_geographic_info_to_buses!(sys, substation_data)\n\n    return sys\nend\n\nfunction correct_pm_transformer_status!(pm_data::PowerModelsData)\n    for (k, branch) in pm_data.data[\"branch\"]\n        f_bus_bvolt = pm_data.data[\"bus\"][branch[\"f_bus\"]][\"base_kv\"]\n        t_bus_bvolt = pm_data.data[\"bus\"][branch[\"t_bus\"]][\"base_kv\"]\n        percent_difference =\n            abs(f_bus_bvolt - t_bus_bvolt) / ((f_bus_bvolt + t_bus_bvolt) / 2)\n        if !branch[\"transformer\"] &&\n           percent_difference > BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL\n            branch[\"transformer\"] = true\n            branch[\"base_power\"] = pm_data.data[\"baseMVA\"]\n            branch[\"ext\"] = Dict{String, Any}()\n            @warn \"Branch $(branch[\"f_bus\"]) - $(branch[\"t_bus\"]) has different voltage levels endpoints (from: $(f_bus_bvolt)kV, to: $(t_bus_bvolt)kV) which exceed the $(BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL*100)% threshold; converting to transformer.\"\n            if !haskey(branch, \"base_voltage_from\")\n                branch[\"base_voltage_from\"] = f_bus_bvolt\n                branch[\"base_voltage_to\"] = t_bus_bvolt\n            end\n        end\n    end\nend\n\n\"\"\"\nInternal component name retrieval from pm2ps_dict\n\"\"\"\nfunction _get_pm_dict_name(device_dict::Dict)::String\n    if haskey(device_dict, \"shunt_bus\")\n        # With shunts, we have FixedAdmittance and SwitchedAdmittance types.\n        # To avoid potential name collision, we add the connected bus number to the name.\n        name = join(strip.(string.((device_dict[\"shunt_bus\"], device_dict[\"name\"]))), \"-\")\n    elseif haskey(device_dict, \"name\")\n        name = string(device_dict[\"name\"])\n    elseif haskey(device_dict, \"source_id\")\n        name = strip(join(string.(device_dict[\"source_id\"]), \"-\"))\n    else\n        name = string(device_dict[\"index\"])\n    end\n    return name\nend\n\nfunction _get_pm_bus_name(device_dict::Dict, unique_names::Bool)\n    if haskey(device_dict, \"name\")\n        if unique_names\n            name = strip(device_dict[\"name\"])\n        else\n            name = strip(device_dict[\"name\"]) * \"_\" * string(device_dict[\"bus_i\"])\n        end\n    else\n        name = strip(join(string.(device_dict[\"source_id\"]), \"-\"))\n    end\n    return name\nend\n\n\"\"\"\nInternal branch name retrieval from pm2ps_dict\n\"\"\"\nfunction _get_pm_branch_name(device_dict, bus_f::ACBus, bus_t::ACBus)\n    # Additional if-else are used to catch line id in PSSe parsing cases\n    if haskey(device_dict, \"name\")\n        index = device_dict[\"name\"]\n    elseif device_dict[\"source_id\"][1] == \"branch\" && length(device_dict[\"source_id\"]) > 2\n        index = strip(device_dict[\"source_id\"][4])\n    elseif (\n        device_dict[\"source_id\"][1] == \"switch\" || device_dict[\"source_id\"][1] == \"breaker\"\n    ) && length(device_dict[\"source_id\"]) > 2\n        index = string(device_dict[\"source_id\"][4][2])\n    elseif device_dict[\"source_id\"][1] == \"transformer\" &&\n           length(device_dict[\"source_id\"]) > 3\n        index = strip(device_dict[\"source_id\"][5])\n    else\n        index = device_dict[\"index\"]\n    end\n    return \"$(get_name(bus_f))-$(get_name(bus_t))-i_$index\"\nend\n\nfunction _is_psse_branch_source_id(device_dict::Dict)\n    if !haskey(device_dict, \"source_id\") || isempty(device_dict[\"source_id\"])\n        return false\n    end\n\n    source_type = device_dict[\"source_id\"][1]\n    return source_type in (\"branch\", \"switch\", \"breaker\", \"transformer\")\nend\n\nfunction _get_pm_branch_name_with_counter!(\n    device_dict::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus,\n    branch_pair_counts::Dict{Tuple{String, String}, Int},\n)\n    if _is_psse_branch_source_id(device_dict)\n        pair_key = (get_name(bus_f), get_name(bus_t))\n        branch_pair_counts[pair_key] = get(branch_pair_counts, pair_key, 0) + 1\n        index = branch_pair_counts[pair_key]\n        return \"$(pair_key[1])-$(pair_key[2])-i_$(index)\"\n    end\n\n    return _get_pm_branch_name(device_dict, bus_f, bus_t)\nend\n\n\"\"\"\nInternal 3WT name retrieval from pm2ps_dict\n\"\"\"\nfunction _get_pm_3w_name(\n    device_dict,\n    bus_primary::ACBus,\n    bus_secondary::ACBus,\n    bus_tertiary::ACBus,\n)\n    ckt = device_dict[\"circuit\"]\n    return \"$(get_name(bus_primary))-$(get_name(bus_secondary))-$(get_name(bus_tertiary))-i_$ckt\"\nend\n\n\"\"\"Add geographic coordinates to all buses using pre-built lookup\"\"\"\nfunction add_geographic_info_to_buses!(sys, substation_data)\n    if isempty(substation_data)\n        @warn \"No substation data found\"\n        return\n    end\n\n    bus_coords_lookup = Dict{Int, GeographicInfo}()\n\n    for (_, substation) in substation_data\n        if haskey(substation, \"nodes\") && haskey(substation, \"latitude\") &&\n           haskey(substation, \"longitude\")\n            lat, lon = substation[\"latitude\"], substation[\"longitude\"]\n\n            geo_info = GeographicInfo(;\n                geo_json = Dict(\n                    \"type\" => \"Point\",\n                    \"coordinates\" => [lon, lat],\n                ),\n            )\n            for node in substation[\"nodes\"]\n                if haskey(node, \"I\")\n                    bus_coords_lookup[node[\"I\"]] = geo_info\n                end\n            end\n        end\n    end\n\n    begin_supplemental_attributes_update(sys) do\n        buses_with_coords = 0\n        buses_without_coords = 0\n\n        for bus in get_components(ACBus, sys)\n            bus_number = get_number(bus)\n\n            if haskey(bus_coords_lookup, bus_number)\n                geo_info = bus_coords_lookup[bus_number]\n                add_supplemental_attribute!(sys, bus, geo_info)\n                buses_with_coords += 1\n            else\n                buses_without_coords += 1\n            end\n        end\n\n        @info \"Added coordinates to $(buses_with_coords) buses, $(buses_without_coords) buses without coordinates\"\n    end\nend\n\n\"\"\"\nParses ITC data from a dictionary and constructs a lookup table\nof piecewise linear scaling functions.\n\"\"\"\nfunction _impedance_correction_table_lookup(data::Dict)\n    ict_instances = Dict{Tuple{Int64, WindingCategory}, ImpedanceCorrectionData}()\n\n    @info \"Reading Impedance Correction Table data\"\n    if !haskey(data, \"impedance_correction\")\n        @info \"There is no Impedance Correction Table data in this file\"\n        return ict_instances\n    end\n\n    for (_, table_data) in data[\"impedance_correction\"]\n        table_number = table_data[\"table_number\"]\n        x = table_data[\"tap_or_angle\"]\n        y = table_data[\"scaling_factor\"]\n\n        if length(x) == length(y)\n            if length(x) < 2\n                @warn \"Skipping impedance correction entry due to insufficient data points ($(length(x)) < 2): $(x)\"\n                continue\n            end\n            pwl_data = PiecewiseLinearData([(x[i], y[i]) for i in eachindex(x)])\n            table_type =\n                if (\n                    x[1] >= PSSE_PARSER_TAP_RATIO_LBOUND &&\n                    x[1] <= PSSE_PARSER_TAP_RATIO_UBOUND\n                )\n                    ImpedanceCorrectionTransformerControlMode.TAP_RATIO\n                else\n                    ImpedanceCorrectionTransformerControlMode.PHASE_SHIFT_ANGLE\n                end\n\n            for winding_index in instances(WindingCategory)\n                ict_instances[(table_number, winding_index)] = ImpedanceCorrectionData(;\n                    table_number = table_number,\n                    impedance_correction_curve = pwl_data,\n                    transformer_winding = winding_index,\n                    transformer_control_mode = table_type,\n                )\n            end\n        else\n            throw(\n                DataFormatError(\n                    \"Impedance correction mismatch at table $table_number: tap/angle and scaling count differs.\",\n                ),\n            )\n        end\n    end\n\n    return ict_instances\nend\n\n\"\"\"\nFunction to attach ICTs to a single Transformer component.\n\"\"\"\nfunction _attach_single_ict!(\n    sys::System,\n    transformer::Union{TwoWindingTransformer, ThreeWindingTransformer},\n    name::String,\n    d::Dict,\n    table_key::String,\n    winding_idx::WindingCategory,\n    ict_instances::Dict{Tuple{Int64, WindingCategory}, ImpedanceCorrectionData},\n)\n    if isempty(ict_instances)\n        return\n    end\n    if haskey(d, table_key)\n        table_number = d[table_key]\n        cache_key = (table_number, winding_idx)\n        if haskey(ict_instances, cache_key)\n            ict = ict_instances[cache_key]\n            add_supplemental_attribute!(sys, transformer, ict)\n        else\n            @debug \"No correction table associated with transformer $name for winding $winding_idx.\"\n        end\n    end\n    return\nend\n\n\"\"\"\nAttaches the corresponding ICT data to a Transformer2W component.\n\"\"\"\nfunction _attach_impedance_correction_tables!(\n    sys::System,\n    transformer::TwoWindingTransformer,\n    name::String,\n    d::Dict,\n    ict_instances::Dict{Tuple{Int64, WindingCategory}, ImpedanceCorrectionData},\n)\n    _attach_single_ict!(\n        sys,\n        transformer,\n        name,\n        d,\n        \"correction_table\",\n        WindingCategory.TR2W_WINDING,\n        ict_instances,\n    )\n    return\nend\n\n\"\"\"\nAttaches the corresponding ICT data to a Transformer3W component.\n\"\"\"\nfunction _attach_impedance_correction_tables!(\n    sys::System,\n    transformer::ThreeWindingTransformer,\n    name::String,\n    d::Dict,\n    ict_instances::Dict{Tuple{Int64, WindingCategory}, ImpedanceCorrectionData},\n)\n    if isempty(ict_instances)\n        return\n    end\n    for winding_category in instances(WindingCategory)\n        winding_category == WindingCategory.TR2W_WINDING && continue\n        key = \"$(WINDING_NAMES[winding_category])_correction_table\"\n        _attach_single_ict!(sys, transformer, name, d, key, winding_category, ict_instances)\n    end\n    return\nend\n\n\"\"\"\nCreates a PowerSystems.ACBus from a PowerSystems bus dictionary\n\"\"\"\nfunction make_bus(bus_dict::Dict{String, Any})\n    bus = ACBus(\n        bus_dict[\"number\"],\n        bus_dict[\"name\"],\n        bus_dict[\"available\"],\n        bus_dict[\"bustype\"],\n        bus_dict[\"angle\"],\n        bus_dict[\"voltage\"],\n        bus_dict[\"voltage_limits\"],\n        bus_dict[\"base_voltage\"],\n        bus_dict[\"area\"],\n        bus_dict[\"zone\"],\n    )\n    return bus\nend\n\nfunction make_bus(\n    bus_name::Union{String, SubString{String}},\n    bus_number::Int,\n    d,\n    bus_types,\n    area::Area,\n)\n    bus = make_bus(\n        Dict{String, Any}(\n            \"name\" => bus_name,\n            \"number\" => bus_number,\n            \"available\" => d[\"bus_status\"],\n            \"bustype\" => bus_types[d[\"bus_type\"]],\n            \"angle\" => d[\"va\"],\n            \"voltage\" => d[\"vm\"],\n            \"voltage_limits\" => (min = d[\"vmin\"], max = d[\"vmax\"]),\n            \"base_voltage\" => d[\"base_kv\"],\n            \"area\" => area,\n            \"zone\" => nothing,\n        ),\n    )\n    return bus\nend\n\n# Disabling this because not all matpower files define areas even when bus definitions\n# contain area references.\n#function read_area!(sys::System, data::Dict; kwargs...)\n#    if !haskey(data, \"areas\")\n#        @info \"There are no Areas in this file\"\n#        return\n#    end\n#\n#    for (key, val) in data[\"areas\"]\n#        area = Area(string(val[\"col_1\"]))\n#        add_component!(sys, area; skip_validation = SKIP_PM_VALIDATION)\n#    end\n#end\n\nfunction read_bus!(sys::System, data::Dict; kwargs...)\n    @info \"Reading bus data\"\n\n    bus_number_to_bus = Dict{Int, ACBus}()\n\n    bus_types = instances(ACBusTypes)\n    unique_bus_names = true\n    bus_data = SortedDict{Int, Any}()\n    # Bus name uniqueness is not enforced by PSSE. This loop avoids forcing the users to have to\n    # pass the bus formatter always for larger datasets.\n    bus_names = Set{String}()\n    for (k, b) in data[\"bus\"]\n        # If buses aren't unique stop searching and growing the set\n        if unique_bus_names && haskey(b, \"name\")\n            if b[\"name\"] ∈ bus_names\n                unique_bus_names = false\n            end\n            push!(bus_names, b[\"name\"])\n        end\n        bus_data[k] = b\n    end\n    if isempty(bus_data)\n        @error \"No bus data found\" # TODO : need for a model without a bus\n    end\n\n    default_bus_naming = x -> _get_pm_bus_name(x, unique_bus_names)\n\n    _get_name = get(kwargs, :bus_name_formatter, default_bus_naming)\n\n    default_area_naming = string\n    # The formatter for area_name should be a function that transform the Area Int to a String\n    _get_name_area = get(kwargs, :area_name_formatter, default_area_naming)\n\n    for (i, (d_key, d)) in enumerate(bus_data)\n        # d id the data dict for each bus\n        # d_key is bus key\n        bus_name = strip(_get_name(d))\n        bus_number = Int(d[\"bus_i\"])\n\n        area_name = _get_name_area(d[\"area\"])\n        area = get_component(Area, sys, area_name)\n        if isnothing(area)\n            area = Area(area_name)\n            add_component!(sys, area; skip_validation = SKIP_PM_VALIDATION)\n        end\n\n        # Store area data into ext dictionary\n        ext = Dict{String, Any}(\n            \"ARNAME\" => \"\",\n            \"I\" => \"\",\n            \"ISW\" => \"\",\n            \"PDES\" => \"\",\n            \"PTOL\" => \"\",\n        )\n        if data[\"source_type\"] == \"pti\" && haskey(data, \"area_interchange\")\n            for (_, area_data) in data[\"area_interchange\"]\n                if haskey(area_data, \"area_number\") &&\n                   string(area_data[\"area_number\"]) == area_name\n                    ext[\"ARNAME\"] = strip(get(area_data, \"area_name\", \"\"))\n                    ext[\"I\"] = string(get(area_data, \"area_number\", \"\"))\n                    ext[\"ISW\"] = string(get(area_data, \"bus_number\", \"\"))\n                    ext[\"PDES\"] = get(area_data, \"net_interchange\", \"\")\n                    ext[\"PTOL\"] = get(area_data, \"tol_interchange\", \"\")\n                    break  # Only one match is allowed\n                end\n            end\n        end\n        set_ext!(area, ext)\n        if !haskey(d, \"bus_status\")\n            d[\"bus_status\"] = true\n        end\n        bus = make_bus(bus_name, bus_number, d, bus_types, area)\n        has_component(ACBus, sys, bus_name) && throw(\n            DataFormatError(\n                \"Found duplicate bus names for $(get_name(bus)), consider reviewing your `bus_name_formatter` function\",\n            ),\n        )\n\n        bus_number_to_bus[bus.number] = bus\n        add_component!(sys, bus; skip_validation = SKIP_PM_VALIDATION)\n    end\n\n    if data[\"source_type\"] == \"pti\" && haskey(data, \"interarea_transfer\")\n        # get Inter-area Transfers as AreaInterchange\n        for (k, d) in data[\"interarea_transfer\"]\n            area_from_name = _get_name_area(d[\"area_from\"])\n            area_to_name = _get_name_area(d[\"area_to\"])\n            transfer_id = get(d, \"transfer_id\", \"1\") # 1 by default\n\n            from_area = get_component(Area, sys, area_from_name)\n            to_area = get_component(Area, sys, area_to_name)\n\n            name = \"$(area_from_name)_$(area_to_name)_$(transfer_id)\"\n            available = true\n            active_power_flow = d[\"power_transfer\"]\n            flow_limits = (from_to = -INFINITE_BOUND, to_from = INFINITE_BOUND)\n\n            ext = Dict{String, Any}(\n                \"index\" => d[\"index\"],\n                \"source_id\" => [\"interarea_transfer\", k],\n            )\n\n            interarea_inter = AreaInterchange(;\n                name = name,\n                available = available,\n                active_power_flow = active_power_flow,\n                from_area = from_area,\n                to_area = to_area,\n                flow_limits = flow_limits,\n                ext = ext,\n            )\n\n            add_component!(sys, interarea_inter; skip_validation = SKIP_PM_VALIDATION)\n        end\n    end\n\n    return bus_number_to_bus\nend\n\nfunction make_interruptible_powerload(d::Dict, bus::ACBus, sys_mbase::Float64; kwargs...)\n    operation_cost = LoadCost(;\n        variable = zero(CostCurve),\n        fixed = 0.0,\n    )\n\n    _get_name = get(kwargs, :load_name_formatter, x -> strip(join(x[\"source_id\"])))\n    return InterruptiblePowerLoad(;\n        name = _get_name(d),\n        available = d[\"status\"],\n        bus = bus,\n        active_power = d[\"pd\"],\n        reactive_power = d[\"qd\"],\n        max_active_power = d[\"pd\"],\n        max_reactive_power = d[\"qd\"],\n        base_power = sys_mbase,\n        operation_cost = operation_cost,\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction make_interruptible_standardload(d::Dict, bus::ACBus, sys_mbase::Float64; kwargs...)\n    operation_cost = LoadCost(;\n        variable = zero(CostCurve),\n        fixed = 0.0,\n    )\n\n    _get_name = get(kwargs, :load_name_formatter, x -> strip(join(x[\"source_id\"])))\n    return InterruptibleStandardLoad(;\n        name = _get_name(d),\n        available = d[\"status\"],\n        bus = bus,\n        base_power = sys_mbase,\n        conformity = d[\"conformity\"],\n        operation_cost = operation_cost,\n        constant_active_power = d[\"pd\"],\n        constant_reactive_power = d[\"qd\"],\n        current_active_power = d[\"pi\"],\n        current_reactive_power = d[\"qi\"],\n        impedance_active_power = d[\"py\"],\n        impedance_reactive_power = d[\"qy\"],\n        max_constant_active_power = d[\"pd\"],\n        max_constant_reactive_power = d[\"qd\"],\n        max_current_active_power = d[\"pi\"],\n        max_current_reactive_power = d[\"qi\"],\n        max_impedance_active_power = d[\"py\"],\n        max_impedance_reactive_power = d[\"qy\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction make_power_load(d::Dict, bus::ACBus, sys_mbase::Float64; kwargs...)\n    _get_name = get(kwargs, :load_name_formatter, x -> strip(join(x[\"source_id\"])))\n    return PowerLoad(;\n        name = _get_name(d),\n        available = d[\"status\"],\n        bus = bus,\n        active_power = d[\"pd\"],\n        reactive_power = d[\"qd\"],\n        max_active_power = d[\"pd\"],\n        max_reactive_power = d[\"qd\"],\n        base_power = sys_mbase,\n        conformity = d[\"conformity\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction make_standard_load(d::Dict, bus::ACBus, sys_mbase::Float64; kwargs...)\n    _get_name = get(kwargs, :load_name_formatter, x -> strip(join(x[\"source_id\"])))\n    return StandardLoad(;\n        name = _get_name(d),\n        available = d[\"status\"],\n        bus = bus,\n        constant_active_power = d[\"pd\"],\n        constant_reactive_power = d[\"qd\"],\n        current_active_power = d[\"pi\"],\n        current_reactive_power = d[\"qi\"],\n        impedance_active_power = d[\"py\"],\n        impedance_reactive_power = d[\"qy\"],\n        max_constant_active_power = d[\"pd\"],\n        max_constant_reactive_power = d[\"qd\"],\n        max_current_active_power = d[\"pi\"],\n        max_current_reactive_power = d[\"qi\"],\n        max_impedance_active_power = d[\"py\"],\n        max_impedance_reactive_power = d[\"qy\"],\n        base_power = sys_mbase,\n        conformity = d[\"conformity\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction read_loads!(sys::System, data, bus_number_to_bus::Dict{Int, ACBus}; kwargs...)\n    @info \"Reading Load data in PowerModels dict to populate System ...\"\n\n    if !haskey(data, \"load\")\n        @error \"There are no loads in this file\"\n        return\n    end\n\n    sys_mbase = data[\"baseMVA\"]\n    for d_key in keys(data[\"load\"])\n        d = data[\"load\"][d_key]\n        bus = bus_number_to_bus[d[\"load_bus\"]]\n        is_interruptible = haskey(d, \"interruptible\")\n        if data[\"source_type\"] == \"pti\" && is_interruptible && d[\"interruptible\"] != 1\n            load = make_standard_load(d, bus, sys_mbase; kwargs...)\n            has_component(StandardLoad, sys, get_name(load)) && throw(\n                DataFormatError(\n                    \"Found duplicate load names of $(summary(load)), consider formatting names with `load_name_formatter` kwarg\",\n                ),\n            )\n        elseif data[\"source_type\"] == \"pti\" && is_interruptible && d[\"interruptible\"] == 1\n            load = make_interruptible_standardload(d, bus, sys_mbase; kwargs...)\n            has_component(InterruptibleStandardLoad, sys, get_name(load)) && throw(\n                DataFormatError(\n                    \"Found duplicate interruptible load names of $(summary(load)), consider formatting names with `load_name_formatter` kwarg\",\n                ),\n            )\n        else\n            load = make_power_load(d, bus, sys_mbase; kwargs...)\n            has_component(PowerLoad, sys, get_name(load)) && throw(\n                DataFormatError(\n                    \"Found duplicate load names of $(summary(load)), consider formatting names with `load_name_formatter` kwarg\",\n                ),\n            )\n        end\n        add_component!(sys, load; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction make_loadzone(\n    name::String,\n    active_power::Float64,\n    reactive_power::Float64;\n    kwargs...,\n)\n    return LoadZone(;\n        name = name,\n        peak_active_power = active_power,\n        peak_reactive_power = reactive_power,\n    )\nend\n\nfunction read_loadzones!(\n    sys::System,\n    data::Dict{String, Any},\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading LoadZones data in PowerModels dict to populate System ...\"\n    zones = Set{Int}()\n    zone_bus_map = Dict{Int, Vector}()\n    for (_, bus) in data[\"bus\"]\n        push!(zones, bus[\"zone\"])\n        push!(get!(zone_bus_map, bus[\"zone\"], Vector()), bus)\n    end\n\n    load_zone_map =\n        Dict{Int, Dict{String, Float64}}(i => Dict(\"pd\" => 0.0, \"qd\" => 0.0) for i in zones)\n    for (key, load) in data[\"load\"]\n        zone = data[\"bus\"][load[\"load_bus\"]][\"zone\"]\n        load_zone_map[zone][\"pd\"] += load[\"pd\"]\n        load_zone_map[zone][\"qd\"] += load[\"qd\"]\n        # Use get with defaults because matpower data doesn't have other load representations\n        load_zone_map[zone][\"pd\"] += get(load, \"pi\", 0.0)\n        load_zone_map[zone][\"qd\"] += get(load, \"qi\", 0.0)\n        load_zone_map[zone][\"pd\"] += get(load, \"py\", 0.0)\n        load_zone_map[zone][\"qd\"] += get(load, \"qy\", 0.0)\n    end\n\n    default_loadzone_naming = string\n    # The formatter for loadzone_name should be a function that transform the LoadZone Int to a String\n    _get_name = get(kwargs, :loadzone_name_formatter, default_loadzone_naming)\n\n    @info \"Reading Zone data\"\n    if !haskey(data, \"zone\")\n        @info \"There is no Zone data in this file\"\n    else\n        for (_, v) in data[\"zone\"]\n            zone_number = v[\"zone_number\"]\n            if !(zone_number in zones)\n                @warn \"Skipping empty LoadZone $(zone_number)-$(v[\"zone_name\"])\"\n            end\n        end\n    end\n\n    for zone in zones\n        name = _get_name(zone)\n        load_zone = make_loadzone(\n            name,\n            load_zone_map[zone][\"pd\"],\n            load_zone_map[zone][\"qd\"];\n            kwargs...,\n        )\n        add_component!(sys, load_zone; skip_validation = SKIP_PM_VALIDATION)\n        for bus in zone_bus_map[zone]\n            set_load_zone!(bus_number_to_bus[bus[\"bus_i\"]], load_zone)\n        end\n    end\nend\n\nfunction make_hydro_dispatch(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    curtailcost = HydroGenerationCost(zero(CostCurve), 0.0)\n\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    base_conversion = sys_mbase / mbase\n    return HydroDispatch(; # No way to define storage parameters for gens in PM so can only make HydroDispatch\n        name = gen_name,\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        active_power = d[\"pg\"] * base_conversion,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = calculate_gen_rating(d[\"pmax\"], d[\"qmax\"], base_conversion),\n        prime_mover_type = parse_enum_mapping(PrimeMovers, d[\"type\"]),\n        active_power_limits = (\n            min = d[\"pmin\"] * base_conversion,\n            max = d[\"pmax\"] * base_conversion,\n        ),\n        reactive_power_limits = (\n            min = d[\"qmin\"] * base_conversion,\n            max = d[\"qmax\"] * base_conversion,\n        ),\n        ramp_limits = calculate_ramp_limit(d, gen_name),\n        time_limits = nothing,\n        operation_cost = curtailcost,\n        base_power = mbase,\n    )\nend\n\nfunction make_hydro_reservoir(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    curtailcost = HydroGenerationCost(zero(CostCurve), 0.0)\n\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    base_conversion = sys_mbase / mbase\n    return HydroDispatch(; # No way to define storage parameters for gens in PM so can only make HydroDispatch\n        name = gen_name,\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        active_power = d[\"pg\"] * base_conversion,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = calculate_gen_rating(d[\"pmax\"], d[\"qmax\"], base_conversion),\n        prime_mover_type = parse_enum_mapping(PrimeMovers, d[\"type\"]),\n        active_power_limits = (\n            min = d[\"pmin\"] * base_conversion,\n            max = d[\"pmax\"] * base_conversion,\n        ),\n        reactive_power_limits = (\n            min = d[\"qmin\"] * base_conversion,\n            max = d[\"qmax\"] * base_conversion,\n        ),\n        ramp_limits = calculate_ramp_limit(d, gen_name),\n        time_limits = nothing,\n        operation_cost = curtailcost,\n        base_power = mbase,\n    )\nend\n\nfunction make_renewable_dispatch(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    cost = RenewableGenerationCost(zero(CostCurve))\n\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    base_conversion = sys_mbase / mbase\n\n    rating = calculate_gen_rating(d[\"pmax\"], d[\"qmax\"], base_conversion)\n    if rating > mbase\n        @warn \"rating is larger than base power for $gen_name, setting to $mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        rating = mbase\n    end\n\n    generator = RenewableDispatch(;\n        name = gen_name,\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        active_power = d[\"pg\"] * base_conversion,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = rating * base_conversion,\n        prime_mover_type = parse_enum_mapping(PrimeMovers, d[\"type\"]),\n        reactive_power_limits = (\n            min = d[\"qmin\"] * base_conversion,\n            max = d[\"qmax\"] * base_conversion,\n        ),\n        power_factor = 1.0,\n        operation_cost = cost,\n        base_power = mbase,\n    )\n\n    return generator\nend\n\nfunction make_renewable_fix(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    base_conversion = sys_mbase / mbase\n    generator = RenewableNonDispatch(;\n        name = gen_name,\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        active_power = d[\"pg\"] * base_conversion,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = float(d[\"pmax\"]) * base_conversion,\n        prime_mover_type = parse_enum_mapping(PrimeMovers, d[\"type\"]),\n        power_factor = 1.0,\n        base_power = mbase,\n    )\n\n    return generator\nend\n\nfunction make_generic_battery(\n    storage_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n)\n    energy_rating = iszero(d[\"energy_rating\"]) ? d[\"energy\"] : d[\"energy_rating\"]\n    storage = EnergyReservoirStorage(;\n        name = storage_name,\n        available = Bool(d[\"status\"]),\n        bus = bus,\n        prime_mover_type = PrimeMovers.BA,\n        storage_technology_type = StorageTech.OTHER_CHEM,\n        storage_capacity = energy_rating,\n        storage_level_limits = (min = 0.0, max = energy_rating),\n        initial_storage_capacity_level = d[\"energy\"] / energy_rating,\n        rating = d[\"thermal_rating\"],\n        active_power = d[\"ps\"],\n        input_active_power_limits = (min = 0.0, max = d[\"charge_rating\"]),\n        output_active_power_limits = (min = 0.0, max = d[\"discharge_rating\"]),\n        efficiency = (in = d[\"charge_efficiency\"], out = d[\"discharge_efficiency\"]),\n        reactive_power = d[\"qs\"],\n        reactive_power_limits = (min = d[\"qmin\"], max = d[\"qmax\"]),\n        base_power = d[\"thermal_rating\"],\n    )\n    return storage\nend\n\nfunction _is_likely_motor_load(d::Dict, gen_name::Union{SubString{String}, String})\n    # A motor load is likely if it has a negative active power and a non-zero reactive power.\n    # This is a heuristic and may not be accurate for all cases.\n    # likely_motor_load\n    if d[\"pmin\"] < 0 && d[\"pmax\"] < 0 && d[\"pg\"] < 0\n        @warn \"Generator $gen_name is likely a motor load with negative active power: $(d[\"pg\"]) and negative power limits: (min = $(d[\"pmin\"]), max = $(d[\"pmax\"])) \\\n        this component will be parsed as a thermal generator with negative active power limits. You can convert the device to a MotorLoad for more accurate modeling.\"\n    end\n\n    if d[\"pmin\"] == 0 && d[\"pmax\"] == 0 && d[\"pg\"] < 0\n        @warn \"Generator $gen_name is likely a motor load with negative active power: $(d[\"pg\"]) and undefined active power limits \\\n        this component will be parsed as a thermal generator with negative active power injection. You can convert the device to a MotorLoad for more accurate modeling.\"\n    end\n\n    if d[\"pmin\"] < 0 && d[\"pmax\"] == 0\n        @warn \"Generator $gen_name is likely something that is not a ThermalGenerators with negative power limits: (min = $(d[\"pmin\"]), max = $(d[\"pmax\"])) \\\n        this component will be parsed as a thermal generator with negative active power limits. Check this entry for more accurate modeling.\"\n    end\n    return\nend\n\n# TODO test this more directly?\n\"\"\"\nThe polynomial term follows the convention that for an n-degree polynomial, at least n + 1 components are needed.\n    c(p) = c_n*p^n+...+c_1p+c_0\n    c_o is stored in the  field in of the Econ Struct\n\"\"\"\nfunction make_thermal_gen(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    if haskey(d, \"model\")\n        model = GeneratorCostModels(d[\"model\"])\n        # Input data layout: table B-4 of https://matpower.org/docs/MATPOWER-manual.pdf\n        if model == GeneratorCostModels.PIECEWISE_LINEAR\n            # For now, we make the fixed cost the y-intercept of the first segment of the\n            # piecewise curve and the variable cost a PiecewiseLinearData representing\n            # the data minus this fixed cost; in a future update, there will be no\n            # separation between the PiecewiseLinearData and the fixed cost.\n            cost_component = d[\"cost\"]\n            power_p = [i for (ix, i) in enumerate(cost_component) if isodd(ix)]\n            cost_p = [i for (ix, i) in enumerate(cost_component) if iseven(ix)]\n            points = collect(zip(power_p, cost_p))\n            (first_x, first_y) = first(points)\n            fixed = max(0.0,\n                first_y - first(get_slopes(PiecewiseLinearData(points))) * first_x,\n            )\n            cost = PiecewiseLinearData([(x, y - fixed) for (x, y) in points])\n        elseif model == GeneratorCostModels.POLYNOMIAL\n            # For now, we make the variable cost a QuadraticFunctionData with all but the\n            # constant term and make the fixed cost the constant term; in a future update,\n            # there will be no separation between the QuadraticFunctionData and the fixed\n            # cost.\n            # This transforms [3.0, 1.0, 4.0, 2.0] into [(1, 4.0), (2, 1.0), (3, 3.0)]\n            coeffs = enumerate(reverse(d[\"cost\"][1:(end - 1)]))\n            coeffs = Dict((i, c / sys_mbase^i) for (i, c) in coeffs)\n            quadratic_degrees = [2, 1, 0]\n            (keys(coeffs) <= Set(quadratic_degrees)) || throw(\n                ArgumentError(\n                    \"Can only handle polynomials up to degree two; given coefficients $coeffs\",\n                ),\n            )\n            cost = QuadraticFunctionData(get.(Ref(coeffs), quadratic_degrees, 0)...)\n            fixed = (d[\"ncost\"] >= 1) ? last(d[\"cost\"]) : 0.0\n        end\n        cost = CostCurve(InputOutputCurve((cost)), UnitSystem.DEVICE_BASE)\n        startup = d[\"startup\"]\n        shutdn = d[\"shutdown\"]\n    else\n        @warn \"Generator cost data not included for Generator: $gen_name\"\n        tmpcost = ThermalGenerationCost(nothing)\n        cost = tmpcost.variable\n        fixed = tmpcost.fixed\n        startup = tmpcost.start_up\n        shutdn = tmpcost.shut_down\n    end\n\n    operation_cost = ThermalGenerationCost(;\n        variable = cost,\n        fixed = fixed,\n        start_up = startup,\n        shut_down = shutdn,\n    )\n\n    if !haskey(d, \"ext\")\n        d[\"ext\"] = Dict{String, Float64}()\n    end\n\n    if haskey(d, \"r_source\") && haskey(d, \"x_source\")\n        d[\"ext\"][\"r\"] = d[\"r_source\"]\n        d[\"ext\"][\"x\"] = d[\"x_source\"]\n    end\n\n    if haskey(d, \"rt_source\") && haskey(d, \"xt_source\")\n        d[\"ext\"][\"rt\"] = d[\"rt_source\"]\n        d[\"ext\"][\"xt\"] = d[\"xt_source\"]\n    end\n\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    base_conversion = sys_mbase / mbase\n    _is_likely_motor_load(d, gen_name)\n    thermal_gen = ThermalStandard(;\n        name = gen_name,\n        status = Bool(d[\"gen_status\"]),\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        active_power = d[\"pg\"] * base_conversion,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = calculate_gen_rating(d[\"pmax\"], d[\"qmax\"], base_conversion),\n        prime_mover_type = parse_enum_mapping(PrimeMovers, d[\"type\"]),\n        fuel = parse_enum_mapping(ThermalFuels, d[\"fuel\"]),\n        active_power_limits = (\n            min = d[\"pmin\"] * base_conversion,\n            max = d[\"pmax\"] * base_conversion,\n        ),\n        reactive_power_limits = (\n            min = d[\"qmin\"] * base_conversion,\n            max = d[\"qmax\"] * base_conversion,\n        ),\n        ramp_limits = calculate_ramp_limit(d, gen_name),\n        time_limits = nothing,\n        operation_cost = operation_cost,\n        base_power = mbase,\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\n\n    return thermal_gen\nend\n\nfunction make_synchronous_condenser(\n    gen_name::Union{SubString{String}, String},\n    d::Dict,\n    bus::ACBus,\n    sys_mbase::Float64,\n)\n    ext = get(d, \"ext\", Dict{String, Any}())\n    if haskey(d, \"r_source\") && haskey(d, \"x_source\")\n        ext[\"r\"] = d[\"r_source\"]\n        ext[\"x\"] = d[\"x_source\"]\n    end\n\n    if haskey(d, \"rt_source\") && haskey(d, \"xt_source\")\n        ext[\"rt\"] = d[\"rt_source\"]\n        ext[\"xt\"] = d[\"xt_source\"]\n    end\n\n    if d[\"mbase\"] != 0.0\n        mbase = d[\"mbase\"]\n    else\n        @warn \"Generator $gen_name has base power equal to zero: $(d[\"mbase\"]). Changing it to system base: $sys_mbase\" _group =\n            IS.LOG_GROUP_PARSING\n        mbase = sys_mbase\n    end\n\n    # NOTE: qmax and qmin can be both negatives, so this approach is taken for the rating.\n    base_conversion = sys_mbase / mbase\n    synchronous_condenser = SynchronousCondenser(;\n        name = gen_name,\n        available = Bool(d[\"gen_status\"]),\n        bus = bus,\n        reactive_power = d[\"qg\"] * base_conversion,\n        rating = max(abs(d[\"qmax\"]), abs(d[\"qmin\"])) * base_conversion,\n        reactive_power_limits = (\n            min = d[\"qmin\"] * base_conversion,\n            max = d[\"qmax\"] * base_conversion,\n        ),\n        base_power = mbase,\n        ext = ext,\n    )\n\n    return synchronous_condenser\nend\n\n\"\"\"\nTransfer generators to ps_dict according to their classification\n\"\"\"\nfunction read_gen!(sys::System, data::Dict, bus_number_to_bus::Dict{Int, ACBus}; kwargs...)\n    @info \"Reading generator data\"\n\n    if !haskey(data, \"gen\")\n        @error \"There are no Generators in this file\"\n        return nothing\n    end\n\n    generator_mapping = get(kwargs, :generator_mapping, GENERATOR_MAPPING_FILE_PM)\n    try\n        generator_mapping = get_generator_mapping(generator_mapping)\n    catch e\n        @error \"Error loading generator mapping $(generator_mapping)\"\n        rethrow(e)\n    end\n\n    sys_mbase = data[\"baseMVA\"]\n\n    _get_name = get(kwargs, :gen_name_formatter, _get_pm_dict_name)\n    for (name, pm_gen) in data[\"gen\"]\n        gen_name = _get_name(pm_gen)\n\n        bus = bus_number_to_bus[pm_gen[\"gen_bus\"]]\n        pm_gen[\"fuel\"] = get(pm_gen, \"fuel\", \"OTHER\")\n        pm_gen[\"type\"] = get(pm_gen, \"type\", \"OT\")\n        @debug \"Found generator\" _group = IS.LOG_GROUP_PARSING gen_name bus pm_gen[\"fuel\"] pm_gen[\"type\"]\n\n        gen_type = get_generator_type(pm_gen[\"fuel\"], pm_gen[\"type\"], generator_mapping)\n        if gen_type == ThermalStandard\n            generator = make_thermal_gen(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == HydroDispatch\n            generator = make_hydro_dispatch(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == HydroTurbine\n            # This method adds a\n            generator = make_hydro_reservoir(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == RenewableDispatch\n            generator = make_renewable_dispatch(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == RenewableNonDispatch\n            generator = make_renewable_fix(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == SynchronousCondenser\n            generator = make_synchronous_condenser(gen_name, pm_gen, bus, sys_mbase)\n        elseif gen_type == EnergyReservoirStorage\n            @warn \"EnergyReservoirStorage should be defined as a PowerModels storage... Skipping\"\n            continue\n        else\n            @error \"Skipping unsupported generator\" gen_type\n            continue\n        end\n\n        has_component(typeof(generator), sys, get_name(generator)) && throw(\n            DataFormatError(\n                \"Found duplicate $(typeof(generator)) names of $(get_name(generator)), consider formatting names with `gen_name_formatter` kwarg\",\n            ),\n        )\n        add_component!(sys, generator; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nconst _SHIFT_TO_GROUP_MAP = Dict{Float64, WindingGroupNumber}(\n    0.0 => WindingGroupNumber.GROUP_0,\n    -30.0 => WindingGroupNumber.GROUP_1,\n    -150.0 => WindingGroupNumber.GROUP_5,\n    180.0 => WindingGroupNumber.GROUP_6,\n    150.0 => WindingGroupNumber.GROUP_7,\n    30.0 => WindingGroupNumber.GROUP_11,\n)\n\nfunction _add_vector_control_group(d::Dict, angle_key::String, group_key::String)\n    angle = d[angle_key]\n    for (angle_key_deg, group) in _SHIFT_TO_GROUP_MAP\n        if isapprox(rad2deg(angle), angle_key_deg)\n            d[group_key] = group\n            return\n        end\n    end\n    d[group_key] = WindingGroupNumber.UNDEFINED\n    return\nend\n\nfunction get_branch_type_matpower(\n    d::Dict,\n)\n    tap = d[\"tap\"]\n    shift = d[\"shift\"]\n    is_transformer = d[\"transformer\"]\n    if !is_transformer\n        is_transformer = (tap != 0.0) && (tap != 1.0) || (shift != 0.0)\n    end\n\n    is_transformer || return Line\n\n    _add_vector_control_group(d, \"shift\", \"group_number\")\n\n    if d[\"group_number\"] == WindingGroupNumber.UNDEFINED\n        return PhaseShiftingTransformer\n    elseif tap != 1.0\n        return TapTransformer\n    else\n        return Transformer2W\n    end\nend\n\nfunction get_branch_type_psse(\n    d::Dict,\n)\n    if d[\"br_r\"] == 0.0 && d[\"br_x\"] == 0.0\n        return DiscreteControlledACBranch\n    end\n\n    is_transformer = d[\"transformer\"]\n    tap = d[\"tap\"]\n\n    if !is_transformer\n        if (tap != 0.0) && (tap != 1.0)\n            @warn \"Transformer $d has tap ratio $tap, which is not 0.0 or 1.0; this is not a valid value for a Line. Parsing entry as a Transformer\"\n            is_transformer = true\n            _add_vector_control_group(d, \"shift\", \"group_number\")\n        else\n            return Line\n        end\n    end\n\n    _add_vector_control_group(d, \"shift\", \"group_number\")\n    is_tap_controllable, is_alpha_controllable = _determine_control_modes(d, \"COD1\", \"tap\")\n    if d[\"group_number\"] == WindingGroupNumber.UNDEFINED || is_alpha_controllable\n        return PhaseShiftingTransformer\n    elseif (is_tap_controllable || (tap != 1.0)) &&\n           d[\"group_number\"] != WindingGroupNumber.UNDEFINED\n        return TapTransformer\n    elseif !is_tap_controllable && d[\"group_number\"] != WindingGroupNumber.UNDEFINED\n        return Transformer2W\n    else\n        error(\"Couldn't infer the branch type for branch $d\")\n    end\nend\n\nfunction make_branch(\n    name::String,\n    d::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus,\n    source_type::String;\n    kwargs...,\n)\n    if source_type == \"matpower\"\n        branch_type = get_branch_type_matpower(d)\n    elseif source_type == \"pti\"\n        branch_type = get_branch_type_psse(d)\n    else\n        error(\"Source Type $source_type not supported\")\n    end\n\n    if d[\"transformer\"] && branch_type == Line\n        throw(\n            DataFormatError(\n                \"Branch data mismatched, cannot build the branch correctly for $d\",\n            ),\n        )\n    elseif branch_type == DiscreteControlledACBranch\n        value = _make_switch_from_zero_impedance_line(name, d, bus_f, bus_t)\n    elseif branch_type == Transformer2W\n        value = make_transformer_2w(name, d, bus_f, bus_t; kwargs...)\n    elseif branch_type == TapTransformer\n        value = make_tap_transformer(name, d, bus_f, bus_t; kwargs...)\n    elseif branch_type == PhaseShiftingTransformer\n        value = make_phase_shifting_transformer(name, d, bus_f, bus_t; kwargs...)\n    elseif branch_type == Line\n        value = make_line(name, d, bus_f, bus_t)\n    else\n        error(\"Unsupported branch type $branch_type\")\n    end\n    return value\nend\n\nfunction _make_switch_from_zero_impedance_line(\n    name::String,\n    d::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    available_value = d[\"br_status\"] == 1\n    if get_bustype(bus_f) == ACBusTypes.ISOLATED ||\n       get_bustype(bus_t) == ACBusTypes.ISOLATED\n        available_value = false\n    end\n    if available_value == true\n        status_value = DiscreteControlledBranchStatus.CLOSED\n    else\n        status_value = DiscreteControlledBranchStatus.OPEN\n    end\n    @warn \"Branch $name has zero impedance and available = $available_value; converting to a DiscreteControlledACBranch of type SWITCH with available = $available_value and branch_status = $status_value\"\n    return DiscreteControlledACBranch(;\n        name = name,\n        available = Bool(available_value),\n        active_power_flow = pf,\n        reactive_power_flow = qf,\n        arc = Arc(bus_f, bus_t),\n        r = d[\"br_r\"],\n        x = d[\"br_x\"],\n        rating = _get_rating(\"Line\", name, d, \"rate_a\"),\n        discrete_branch_type = DiscreteControlledBranchType.SWITCH,\n        branch_status = status_value,\n    )\nend\n\nfunction _get_rating(\n    branch_type::String,\n    name::AbstractString,\n    line_data::Dict,\n    key::String,\n)\n    haskey(line_data, key) || return key == \"rate_a\" ? INFINITE_BOUND : nothing\n\n    if isapprox(line_data[key], 0.0)\n        @info(\n            \"$branch_type $name rating value: $(line_data[key]). Unbounded value implied as per PSSe Manual\"\n        )\n        return INFINITE_BOUND\n    else\n        return line_data[key]\n    end\nend\n\nfunction make_line(name::String, d::Dict, bus_f::ACBus, bus_t::ACBus)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    available_value = d[\"br_status\"] == 1\n    if get_bustype(bus_f) == ACBusTypes.ISOLATED ||\n       get_bustype(bus_t) == ACBusTypes.ISOLATED\n        available_value = false\n    end\n\n    ext = haskey(d, \"ext\") ? d[\"ext\"] : Dict{String, Any}()\n\n    return Line(;\n        name = name,\n        available = available_value,\n        active_power_flow = pf,\n        reactive_power_flow = qf,\n        arc = Arc(bus_f, bus_t),\n        r = d[\"br_r\"],\n        x = d[\"br_x\"],\n        b = (from = d[\"b_fr\"], to = d[\"b_to\"]),\n        rating = _get_rating(\"Line\", name, d, \"rate_a\"),\n        angle_limits = (min = d[\"angmin\"], max = d[\"angmax\"]),\n        rating_b = _get_rating(\"Line\", name, d, \"rate_b\"),\n        rating_c = _get_rating(\"Line\", name, d, \"rate_c\"),\n        ext = ext,\n    )\nend\n\nfunction make_switch_breaker(name::String, d::Dict, bus_f::ACBus, bus_t::ACBus)\n    return DiscreteControlledACBranch(;\n        name = name,\n        available = Bool(d[\"state\"]),\n        active_power_flow = d[\"active_power_flow\"],\n        reactive_power_flow = d[\"reactive_power_flow\"],\n        arc = Arc(bus_f, bus_t),\n        r = d[\"r\"],\n        x = d[\"x\"],\n        rating = d[\"rating\"],\n        discrete_branch_type = d[\"discrete_branch_type\"],\n        branch_status = d[\"state\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction read_switch_breaker!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus},\n    device_type::String;\n    kwargs...,\n)\n    @info \"Reading $device_type data\"\n    if !haskey(data, device_type)\n        @info \"There is no $device_type data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :branch_name_formatter, _get_pm_branch_name)\n\n    for (_, d) in data[device_type]\n        bus_f = bus_number_to_bus[d[\"f_bus\"]]\n        bus_t = bus_number_to_bus[d[\"t_bus\"]]\n        name = _get_name(d, bus_f, bus_t)\n        value = make_switch_breaker(name, d, bus_f, bus_t)\n\n        add_component!(sys, value; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction make_transformer_2w(\n    name::String,\n    d::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus;\n    kwargs...,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    available_value = d[\"br_status\"] == 1\n    if get_bustype(bus_f) == ACBusTypes.ISOLATED ||\n       get_bustype(bus_t) == ACBusTypes.ISOLATED\n        available_value = false\n    end\n\n    return Transformer2W(;\n        name = name,\n        available = available_value,\n        active_power_flow = pf,\n        reactive_power_flow = qf,\n        arc = Arc(bus_f, bus_t),\n        r = d[\"br_r\"],\n        x = d[\"br_x\"],\n        primary_shunt = d[\"g_fr\"] + im * d[\"b_fr\"],\n        winding_group_number = d[\"group_number\"],\n        rating = _get_rating(\"Transformer2W\", name, d, \"rate_a\"),\n        rating_b = _get_rating(\"Transformer2W\", name, d, \"rate_b\"),\n        rating_c = _get_rating(\"Transformer2W\", name, d, \"rate_c\"),\n        base_power = d[\"base_power\"],\n        # for psse inputs, these numbers may be different than the buses' base voltages\n        base_voltage_primary = d[\"base_voltage_from\"],\n        base_voltage_secondary = d[\"base_voltage_to\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction make_3w_transformer(\n    name::String,\n    d::Dict,\n    bus_primary::ACBus,\n    bus_secondary::ACBus,\n    bus_tertiary::ACBus,\n    star_bus::ACBus,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    return Transformer3W(;\n        name = name,\n        available = d[\"available\"],\n        primary_star_arc = Arc(bus_primary, star_bus),\n        secondary_star_arc = Arc(bus_secondary, star_bus),\n        tertiary_star_arc = Arc(bus_tertiary, star_bus),\n        star_bus = star_bus,\n        active_power_flow_primary = pf,\n        reactive_power_flow_primary = qf,\n        active_power_flow_secondary = pf,\n        reactive_power_flow_secondary = qf,\n        active_power_flow_tertiary = pf,\n        reactive_power_flow_tertiary = qf,\n        r_primary = d[\"r_primary\"],\n        x_primary = d[\"x_primary\"],\n        r_secondary = d[\"r_secondary\"],\n        x_secondary = d[\"x_secondary\"],\n        r_tertiary = d[\"r_tertiary\"],\n        x_tertiary = d[\"x_tertiary\"],\n        rating = d[\"rating\"],\n        r_12 = d[\"r_12\"],\n        x_12 = d[\"x_12\"],\n        r_23 = d[\"r_23\"],\n        x_23 = d[\"x_23\"],\n        r_13 = d[\"r_13\"],\n        x_13 = d[\"x_13\"],\n        base_power_12 = d[\"base_power_12\"],\n        base_power_23 = d[\"base_power_23\"],\n        base_power_13 = d[\"base_power_13\"],\n        base_voltage_primary = d[\"base_voltage_primary\"],\n        base_voltage_secondary = d[\"base_voltage_secondary\"],\n        base_voltage_tertiary = d[\"base_voltage_tertiary\"],\n        g = d[\"g\"],\n        b = d[\"b\"],\n        primary_turns_ratio = d[\"primary_turns_ratio\"],\n        secondary_turns_ratio = d[\"secondary_turns_ratio\"],\n        tertiary_turns_ratio = d[\"tertiary_turns_ratio\"],\n        available_primary = d[\"available_primary\"],\n        available_secondary = d[\"available_secondary\"],\n        available_tertiary = d[\"available_tertiary\"],\n        rating_primary = _get_rating(\"Transformer3W\", name, d, \"rating_primary\"),\n        rating_secondary = _get_rating(\"Transformer3W\", name, d, \"rating_secondary\"),\n        rating_tertiary = _get_rating(\"Transformer3W\", name, d, \"rating_tertiary\"),\n        primary_group_number = d[\"primary_group_number\"],\n        secondary_group_number = d[\"secondary_group_number\"],\n        tertiary_group_number = d[\"tertiary_group_number\"],\n        control_objective_primary = get(d, \"COD1\", -99),\n        control_objective_secondary = get(d, \"COD2\", -99),\n        control_objective_tertiary = get(d, \"COD3\", -99),\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction make_3w_phase_shifting_transformer(\n    name::String,\n    d::Dict,\n    bus_primary::ACBus,\n    bus_secondary::ACBus,\n    bus_tertiary::ACBus,\n    star_bus::ACBus,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    return PhaseShiftingTransformer3W(;\n        name = name,\n        available = d[\"available\"],\n        primary_star_arc = Arc(bus_primary, star_bus),\n        secondary_star_arc = Arc(bus_secondary, star_bus),\n        tertiary_star_arc = Arc(bus_tertiary, star_bus),\n        star_bus = star_bus,\n        active_power_flow_primary = pf,\n        reactive_power_flow_primary = qf,\n        active_power_flow_secondary = pf,\n        reactive_power_flow_secondary = qf,\n        active_power_flow_tertiary = pf,\n        reactive_power_flow_tertiary = qf,\n        r_primary = d[\"r_primary\"],\n        x_primary = d[\"x_primary\"],\n        r_secondary = d[\"r_secondary\"],\n        x_secondary = d[\"x_secondary\"],\n        r_tertiary = d[\"r_tertiary\"],\n        x_tertiary = d[\"x_tertiary\"],\n        rating = d[\"rating\"],\n        r_12 = d[\"r_12\"],\n        x_12 = d[\"x_12\"],\n        r_23 = d[\"r_23\"],\n        x_23 = d[\"x_23\"],\n        r_13 = d[\"r_13\"],\n        x_13 = d[\"x_13\"],\n        α_primary = d[\"primary_phase_shift_angle\"],\n        α_secondary = d[\"secondary_phase_shift_angle\"],\n        α_tertiary = d[\"tertiary_phase_shift_angle\"],\n        base_power_12 = d[\"base_power_12\"],\n        base_power_23 = d[\"base_power_23\"],\n        base_power_13 = d[\"base_power_13\"],\n        base_voltage_primary = d[\"base_voltage_primary\"],\n        base_voltage_secondary = d[\"base_voltage_secondary\"],\n        base_voltage_tertiary = d[\"base_voltage_tertiary\"],\n        g = d[\"g\"],\n        b = d[\"b\"],\n        primary_turns_ratio = d[\"primary_turns_ratio\"],\n        secondary_turns_ratio = d[\"secondary_turns_ratio\"],\n        tertiary_turns_ratio = d[\"tertiary_turns_ratio\"],\n        available_primary = d[\"available_primary\"],\n        available_secondary = d[\"available_secondary\"],\n        available_tertiary = d[\"available_tertiary\"],\n        rating_primary = _get_rating(\n            \"PhaseShiftingTransformer3W\",\n            name,\n            d,\n            \"rating_primary\",\n        ),\n        rating_secondary = _get_rating(\n            \"PhaseShiftingTransformer3W\",\n            name,\n            d,\n            \"rating_secondary\",\n        ),\n        rating_tertiary = _get_rating(\n            \"PhaseShiftingTransformer3W\",\n            name,\n            d,\n            \"rating_tertiary\",\n        ),\n        control_objective_primary = get(d, \"COD1\", -99),\n        control_objective_secondary = get(d, \"COD2\", -99),\n        control_objective_tertiary = get(d, \"COD3\", -99),\n        ext = d[\"ext\"],\n    )\nend\n\nfunction make_tap_transformer(\n    name::String,\n    d::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus;\n    kwargs...,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    available_value = d[\"br_status\"] == 1\n    if get_bustype(bus_f) == ACBusTypes.ISOLATED ||\n       get_bustype(bus_t) == ACBusTypes.ISOLATED\n        available_value = false\n    end\n\n    ext = haskey(d, \"ext\") ? d[\"ext\"] : Dict{String, Any}()\n    control_objective_formatter =\n        get(kwargs, :transformer_control_objective_formatter, nothing)\n    control_objective = if control_objective_formatter !== nothing\n        result = control_objective_formatter(name)\n        result !== nothing ? result : get(d, \"COD1\", -99)\n    else\n        get(d, \"COD1\", -99)\n    end\n\n    return TapTransformer(;\n        name = name,\n        available = available_value,\n        active_power_flow = pf,\n        reactive_power_flow = qf,\n        arc = Arc(bus_f, bus_t),\n        r = d[\"br_r\"],\n        x = d[\"br_x\"],\n        tap = d[\"tap\"],\n        primary_shunt = d[\"g_fr\"] + im * d[\"b_fr\"],\n        winding_group_number = d[\"group_number\"],\n        base_power = d[\"base_power\"],\n        rating = _get_rating(\"TapTransformer\", name, d, \"rate_a\"),\n        rating_b = _get_rating(\"TapTransformer\", name, d, \"rate_b\"),\n        rating_c = _get_rating(\"TapTransformer\", name, d, \"rate_c\"),\n        # for psse inputs, these numbers may be different than the buses' base voltages\n        base_voltage_primary = d[\"base_voltage_from\"],\n        base_voltage_secondary = d[\"base_voltage_to\"],\n        control_objective = control_objective,\n        ext = ext,\n    )\nend\n\nfunction make_phase_shifting_transformer(\n    name::String,\n    d::Dict,\n    bus_f::ACBus,\n    bus_t::ACBus;\n    kwargs...,\n)\n    pf = get(d, \"pf\", 0.0)\n    qf = get(d, \"qf\", 0.0)\n    available_value = d[\"br_status\"] == 1\n    if get_bustype(bus_f) == ACBusTypes.ISOLATED ||\n       get_bustype(bus_t) == ACBusTypes.ISOLATED\n        available_value = false\n    end\n\n    ext = haskey(d, \"ext\") ? d[\"ext\"] : Dict{String, Any}()\n    control_objective_formatter =\n        get(kwargs, :transformer_control_objective_formatter, nothing)\n    control_objective = if control_objective_formatter !== nothing\n        result = control_objective_formatter(name)\n        result !== nothing ? result : get(d, \"COD1\", -99)\n    else\n        get(d, \"COD1\", -99)\n    end\n\n    return PhaseShiftingTransformer(;\n        name = name,\n        available = available_value,\n        active_power_flow = pf,\n        reactive_power_flow = qf,\n        arc = Arc(bus_f, bus_t),\n        r = d[\"br_r\"],\n        x = d[\"br_x\"],\n        tap = d[\"tap\"],\n        primary_shunt = d[\"g_fr\"] + im * d[\"b_fr\"],\n        α = d[\"shift\"],\n        base_power = d[\"base_power\"],\n        rating = _get_rating(\"PhaseShiftingTransformer\", name, d, \"rate_a\"),\n        rating_b = _get_rating(\"PhaseShiftingTransformer\", name, d, \"rate_b\"),\n        rating_c = _get_rating(\"PhaseShiftingTransformer\", name, d, \"rate_c\"),\n        # for psse inputs, these numbers may be different than the buses' base voltages\n        base_voltage_primary = d[\"base_voltage_from\"],\n        base_voltage_secondary = d[\"base_voltage_to\"],\n        control_objective = control_objective,\n        ext = ext,\n    )\nend\n\nfunction read_branch!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus}; kwargs...,\n)\n    @info \"Reading branch data\"\n    if !haskey(data, \"branch\")\n        @info \"There is no Branch data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :branch_name_formatter, nothing)\n    ict_instances = _impedance_correction_table_lookup(data)\n    branch_pair_counts = Dict{Tuple{String, String}, Int}()\n\n    source_type = data[\"source_type\"]\n    for d in values(data[\"branch\"])\n        bus_f = bus_number_to_bus[d[\"f_bus\"]]\n        bus_t = bus_number_to_bus[d[\"t_bus\"]]\n        name = if isnothing(_get_name)\n            if source_type == \"pti\"\n                _get_pm_branch_name_with_counter!(d, bus_f, bus_t, branch_pair_counts)\n            else\n                _get_pm_branch_name(d, bus_f, bus_t)\n            end\n        else\n            _get_name(d, bus_f, bus_t)\n        end\n        value = make_branch(name, d, bus_f, bus_t, source_type; kwargs...)\n\n        if !isnothing(value)\n            add_component!(sys, value; skip_validation = SKIP_PM_VALIDATION)\n        else\n            continue\n        end\n\n        if isa(value, TwoWindingTransformer)\n            _attach_impedance_correction_tables!(\n                sys,\n                value,\n                name,\n                d,\n                ict_instances,\n            )\n        end\n    end\n    return\nend\n\nfunction read_3w_transformer!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading 3W transformer data\"\n    if !haskey(data, \"3w_transformer\")\n        @info \"There is no 3W transformer data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :xfrm_3w_name_formatter, _get_pm_3w_name)\n\n    ict_instances = _impedance_correction_table_lookup(data)\n\n    for (_, d) in data[\"3w_transformer\"]\n        bus_primary = bus_number_to_bus[d[\"bus_primary\"]]\n        bus_secondary = bus_number_to_bus[d[\"bus_secondary\"]]\n        bus_tertiary = bus_number_to_bus[d[\"bus_tertiary\"]]\n        star_bus = bus_number_to_bus[d[\"star_bus\"]]\n\n        name = _get_name(d, bus_primary, bus_secondary, bus_tertiary)\n        three_winding_transformer_type = get_three_winding_transformer_type(d)\n        if three_winding_transformer_type == PhaseShiftingTransformer3W\n            value = make_3w_phase_shifting_transformer(\n                name,\n                d,\n                bus_primary,\n                bus_secondary,\n                bus_tertiary,\n                star_bus,\n            )\n        elseif three_winding_transformer_type == Transformer3W\n            value = make_3w_transformer(\n                name,\n                d,\n                bus_primary,\n                bus_secondary,\n                bus_tertiary,\n                star_bus,\n            )\n        else\n            error(\n                \"Unsupported three winding transformer type $three_winding_transformer_type\",\n            )\n        end\n\n        add_component!(sys, value; skip_validation = SKIP_PM_VALIDATION)\n\n        _attach_impedance_correction_tables!(sys, value, name, d, ict_instances)\n    end\nend\n\nfunction _determine_control_modes(d::Dict, control_flag::String, tap_key::String)\n    control_code = get(d, control_flag, -99)\n    tap = d[tap_key]\n\n    is_tap_controllable = false\n    is_alpha_controllable = false\n\n    # There is no control\n    if control_code == 0\n        is_tap_controllable = false\n        is_alpha_controllable = false\n        # Reactive Power Control\n    elseif control_code ∈ [1, -1]\n        is_tap_controllable = true\n        is_alpha_controllable = false\n        # Voltage Control\n    elseif control_code ∈ [2, -2]\n        is_tap_controllable = true\n        is_alpha_controllable = false\n        # Active Power Control\n    elseif control_code ∈ [3, -3]\n        is_tap_controllable = true\n        is_alpha_controllable = true\n        # DC Line Control\n    elseif control_code ∈ [4, -4]\n        is_tap_controllable = true\n        is_alpha_controllable = true\n        # Asymmetric Active Power Control\n    elseif control_code ∈ [5, -5]\n        is_tap_controllable = true\n        is_alpha_controllable = true\n    elseif control_code == -99\n        @warn \"Can't determine control objective for the transformer from the $(control_flag) field for $d\"\n        if d[\"shift\"] != 0.0\n            is_alpha_controllable = true\n        elseif (tap != 0.0) || (tap != 1.0)\n            is_tap_controllable = true\n        else\n            @warn \"Can't determine control objective for the other fields. Will return a Transformer2W\"\n        end\n    else\n        error(d)\n    end\n    return is_tap_controllable, is_alpha_controllable\nend\n\nfunction get_three_winding_transformer_type(d::Dict)\n    _add_vector_control_group(d, \"primary_phase_shift_angle\", \"primary_group_number\")\n    _add_vector_control_group(d, \"secondary_phase_shift_angle\", \"secondary_group_number\")\n    _add_vector_control_group(d, \"tertiary_phase_shift_angle\", \"tertiary_group_number\")\n    # NOTE: with current three winding transformer type hierarchy, tap controllable and not controllable three winding transformers are Transformer3W\n    _, primary_is_alpha_controllable =\n        _determine_control_modes(d, \"COD1\", \"primary_turns_ratio\")\n    _, secondary_is_alpha_controllable =\n        _determine_control_modes(d, \"COD2\", \"secondary_turns_ratio\")\n    _, tertiary_is_alpha_controllable =\n        _determine_control_modes(d, \"COD3\", \"tertiary_turns_ratio\")\n    if d[\"primary_group_number\"] == WindingGroupNumber.UNDEFINED ||\n       d[\"secondary_group_number\"] == WindingGroupNumber.UNDEFINED ||\n       d[\"tertiary_group_number\"] == WindingGroupNumber.UNDEFINED ||\n       primary_is_alpha_controllable || secondary_is_alpha_controllable ||\n       tertiary_is_alpha_controllable\n        return PhaseShiftingTransformer3W\n    else\n        return Transformer3W\n    end\nend\n\nfunction make_dcline(name::String, d::Dict, bus_f::ACBus, bus_t::ACBus, source_type::String)\n    if source_type == \"pti\"\n        return TwoTerminalLCCLine(;\n            name = name,\n            available = d[\"available\"],\n            arc = Arc(bus_f, bus_t),\n            active_power_flow = get(d, \"pf\", 0.0),\n            r = d[\"r\"],\n            transfer_setpoint = d[\"transfer_setpoint\"],\n            scheduled_dc_voltage = d[\"scheduled_dc_voltage\"],\n            rectifier_bridges = d[\"rectifier_bridges\"],\n            rectifier_delay_angle_limits = d[\"rectifier_delay_angle_limits\"],\n            rectifier_rc = d[\"rectifier_rc\"],\n            rectifier_xc = d[\"rectifier_xc\"],\n            rectifier_base_voltage = d[\"rectifier_base_voltage\"],\n            inverter_bridges = d[\"inverter_bridges\"],\n            inverter_extinction_angle_limits = d[\"inverter_extinction_angle_limits\"],\n            inverter_rc = d[\"inverter_rc\"],\n            inverter_xc = d[\"inverter_xc\"],\n            inverter_base_voltage = d[\"inverter_base_voltage\"],\n            power_mode = d[\"power_mode\"],\n            switch_mode_voltage = d[\"switch_mode_voltage\"],\n            compounding_resistance = d[\"compounding_resistance\"],\n            min_compounding_voltage = d[\"min_compounding_voltage\"],\n            rectifier_transformer_ratio = d[\"rectifier_transformer_ratio\"],\n            rectifier_tap_setting = d[\"rectifier_tap_setting\"],\n            rectifier_tap_limits = d[\"rectifier_tap_limits\"],\n            rectifier_tap_step = d[\"rectifier_tap_step\"],\n            rectifier_delay_angle = d[\"rectifier_delay_angle\"],\n            rectifier_capacitor_reactance = d[\"rectifier_capacitor_reactance\"],\n            inverter_transformer_ratio = d[\"inverter_transformer_ratio\"],\n            inverter_tap_setting = d[\"inverter_tap_setting\"],\n            inverter_tap_limits = d[\"inverter_tap_limits\"],\n            inverter_tap_step = d[\"inverter_tap_step\"],\n            inverter_extinction_angle = d[\"inverter_extinction_angle\"],\n            inverter_capacitor_reactance = d[\"inverter_capacitor_reactance\"],\n            active_power_limits_from = d[\"active_power_limits_from\"],\n            active_power_limits_to = d[\"active_power_limits_to\"],\n            reactive_power_limits_from = d[\"reactive_power_limits_from\"],\n            reactive_power_limits_to = d[\"reactive_power_limits_to\"],\n            loss = LinearCurve(d[\"loss1\"], d[\"loss0\"]),\n            ext = get(d, \"ext\", Dict{String, Any}()),\n        )\n    elseif source_type == \"matpower\"\n        return TwoTerminalGenericHVDCLine(;\n            name = name,\n            available = d[\"br_status\"] == 1,\n            active_power_flow = get(d, \"pf\", 0.0),\n            arc = Arc(bus_f, bus_t),\n            active_power_limits_from = (min = d[\"pminf\"], max = d[\"pmaxf\"]),\n            active_power_limits_to = (min = d[\"pmint\"], max = d[\"pmaxt\"]),\n            reactive_power_limits_from = (min = d[\"qminf\"], max = d[\"qmaxf\"]),\n            reactive_power_limits_to = (min = d[\"qmint\"], max = d[\"qmaxt\"]),\n            loss = LinearCurve(d[\"loss1\"], d[\"loss0\"]),\n        )\n    else\n        error(\"Not supported source type for DC lines: $source_type\")\n    end\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus},\n    source_type::String;\n    kwargs...,\n)\n    @info \"Reading DC Line data\"\n    if !haskey(data, \"dcline\")\n        @info \"There is no DClines data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :dcline_name_formatter, _get_pm_branch_name)\n\n    for (d_key, d) in data[\"dcline\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        bus_f = bus_number_to_bus[d[\"f_bus\"]]\n        bus_t = bus_number_to_bus[d[\"t_bus\"]]\n        name = _get_name(d, bus_f, bus_t)\n        dcline = make_dcline(name, d, bus_f, bus_t, source_type)\n        add_component!(sys, dcline; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction make_vscline(name::String, d::Dict, bus_f::ACBus, bus_t::ACBus)\n    return TwoTerminalVSCLine(;\n        name = name,\n        available = d[\"available\"],\n        arc = Arc(bus_f, bus_t),\n        active_power_flow = get(d, \"pf\", 0.0),\n        rating = d[\"rating\"],\n        active_power_limits_from = (min = d[\"pminf\"], max = d[\"pmaxf\"]),\n        active_power_limits_to = (min = d[\"pmint\"], max = d[\"pmaxt\"]),\n        g = d[\"r\"] == 0.0 ? 0.0 : 1.0 / d[\"r\"],\n        dc_current = get(d, \"if\", 0.0),\n        reactive_power_from = get(d, \"qf\", 0.0),\n        dc_voltage_control_from = d[\"dc_voltage_control_from\"],\n        ac_voltage_control_from = d[\"ac_voltage_control_from\"],\n        dc_setpoint_from = d[\"dc_setpoint_from\"],\n        ac_setpoint_from = d[\"ac_setpoint_from\"],\n        converter_loss_from = d[\"converter_loss_from\"],\n        max_dc_current_from = d[\"max_dc_current_from\"],\n        rating_from = d[\"rating_from\"],\n        reactive_power_limits_from = (min = d[\"qminf\"], max = d[\"qmaxf\"]),\n        power_factor_weighting_fraction_from = d[\"power_factor_weighting_fraction_from\"],\n        reactive_power_to = get(d, \"qt\", 0.0),\n        dc_voltage_control_to = d[\"dc_voltage_control_to\"],\n        ac_voltage_control_to = d[\"ac_voltage_control_to\"],\n        dc_setpoint_to = d[\"dc_setpoint_to\"],\n        ac_setpoint_to = d[\"ac_setpoint_to\"],\n        converter_loss_to = d[\"converter_loss_to\"],\n        max_dc_current_to = d[\"max_dc_current_to\"],\n        rating_to = d[\"rating_to\"],\n        reactive_power_limits_to = (min = d[\"qmint\"], max = d[\"qmaxt\"]),\n        power_factor_weighting_fraction_to = d[\"power_factor_weighting_fraction_to\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction read_vscline!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading VSC Line data\"\n    if !haskey(data, \"vscline\")\n        @info \"There is no VSC lines data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :vsc_line_name_formatter, _get_pm_branch_name)\n\n    for (d_key, d) in data[\"vscline\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        bus_f = bus_number_to_bus[d[\"f_bus\"]]\n        bus_t = bus_number_to_bus[d[\"t_bus\"]]\n        name = _get_name(d, bus_f, bus_t)\n        vscline = make_vscline(name, d, bus_f, bus_t)\n        add_component!(sys, vscline; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction make_switched_shunt(name::String, d::Dict, bus::ACBus)\n    params = Dict(\n        :name => name,\n        :available => Bool(d[\"status\"]),\n        :bus => bus,\n        :Y => (d[\"gs\"] + d[\"bs\"]im),\n        :number_of_steps => d[\"step_number\"],\n        :Y_increase => d[\"y_increment\"],\n        :admittance_limits => d[\"admittance_limits\"],\n        :ext => d[\"ext\"],\n    )\n\n    if haskey(d, \"initial_status\")\n        params[:initial_status] = d[\"initial_status\"]\n    end\n\n    return SwitchedAdmittance(; params...)\nend\n\nfunction read_switched_shunt!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading switched shunt data\"\n    if !haskey(data, \"switched_shunt\")\n        @info \"There is no switched shunt data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :switched_shunt_name_formatter, _get_pm_dict_name)\n\n    for (d_key, d) in data[\"switched_shunt\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        name = _get_name(d)\n        bus = bus_number_to_bus[d[\"shunt_bus\"]]\n        shunt = make_switched_shunt(name, d, bus)\n\n        add_component!(sys, shunt; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction make_shunt(name::String, d::Dict, bus::ACBus)\n    return FixedAdmittance(;\n        name = name,\n        available = Bool(d[\"status\"]),\n        bus = bus,\n        Y = (d[\"gs\"] + d[\"bs\"]im),\n    )\nend\n\nfunction make_facts(name::String, d::Dict, bus::ACBus)\n    if d[\"tbus\"] != 0\n        @warn \"Series FACTs not supported.\"\n    end\n\n    if d[\"control_mode\"] > 3\n        throw(DataFormatError(\"Operation mode not supported.\"))\n    end\n\n    if d[\"reactive_power_required\"] < 0\n        throw(DataFormatError(\"% MVAr required must me positive.\"))\n    end\n\n    return FACTSControlDevice(;\n        name = name,\n        available = Bool(d[\"available\"]),\n        bus = bus,\n        control_mode = d[\"control_mode\"],\n        voltage_setpoint = d[\"voltage_setpoint\"],\n        max_shunt_current = d[\"max_shunt_current\"],\n        reactive_power_required = d[\"reactive_power_required\"],\n        ext = get(d, \"ext\", Dict{String, Any}()),\n    )\nend\n\nfunction read_facts!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading FACTS data\"\n    if !haskey(data, \"facts\")\n        @info \"There is no facts data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :bus_name_formatter, _get_pm_dict_name)\n\n    for (d_key, d) in data[\"facts\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        name = _get_name(d)\n        bus = bus_number_to_bus[d[\"bus\"]]\n        full_name = \"$(d[\"bus\"])_$(name)\"\n        facts = make_facts(full_name, d, bus)\n\n        add_component!(sys, facts; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction read_shunt!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading shunt data\"\n    if !haskey(data, \"shunt\")\n        @info \"There is no shunt data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :shunt_name_formatter, _get_pm_dict_name)\n\n    for (d_key, d) in data[\"shunt\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        name = _get_name(d)\n        bus = bus_number_to_bus[d[\"shunt_bus\"]]\n        shunt = make_shunt(name, d, bus)\n\n        add_component!(sys, shunt; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n\nfunction read_storage!(\n    sys::System,\n    data::Dict,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading storage data\"\n    if !haskey(data, \"storage\")\n        @info \"There is no storage data in this file\"\n        return\n    end\n\n    _get_name = get(kwargs, :gen_name_formatter, _get_pm_dict_name)\n\n    for (d_key, d) in data[\"storage\"]\n        d[\"name\"] = get(d, \"name\", d_key)\n        name = _get_name(d)\n        bus = bus_number_to_bus[d[\"storage_bus\"]]\n        storage = make_generic_battery(name, d, bus)\n\n        add_component!(sys, storage; skip_validation = SKIP_PM_VALIDATION)\n    end\nend\n"
  },
  {
    "path": "src/parsers/power_system_table_data.jl",
    "content": "const POWER_SYSTEM_DESCRIPTOR_FILE =\n    joinpath(dirname(pathof(PowerSystems)), \"descriptors\", \"power_system_inputs.json\")\n\nconst INPUT_CATEGORY_NAMES = [\n    (\"branch\", InputCategory.BRANCH),\n    (\"bus\", InputCategory.BUS),\n    (\"dc_branch\", InputCategory.DC_BRANCH),\n    (\"gen\", InputCategory.GENERATOR),\n    (\"load\", InputCategory.LOAD),\n    (\"reserves\", InputCategory.RESERVE),\n    (\"storage\", InputCategory.STORAGE),\n]\n\nstruct PowerSystemTableData\n    base_power::Float64\n    category_to_df::Dict{InputCategory, DataFrames.DataFrame}\n    timeseries_metadata_file::Union{String, Nothing}\n    directory::String\n    user_descriptors::Dict\n    descriptors::Dict\n    generator_mapping::Dict{NamedTuple, DataType}\nend\n\nfunction PowerSystemTableData(\n    data::Dict{String, Any},\n    directory::String,\n    user_descriptors::Union{String, Dict},\n    descriptors::Union{String, Dict},\n    generator_mapping::Dict;\n    timeseries_metadata_file = joinpath(directory, \"timeseries_pointers\"),\n)\n    category_to_df = Dict{InputCategory, DataFrames.DataFrame}()\n\n    if !haskey(data, \"bus\")\n        throw(DataFormatError(\"key 'bus' not found in input data\"))\n    end\n\n    if !haskey(data, \"base_power\")\n        @warn \"key 'base_power' not found in input data; using default=$(DEFAULT_BASE_MVA)\"\n    end\n    base_power = get(data, \"base_power\", DEFAULT_BASE_MVA)\n\n    for (name, category) in INPUT_CATEGORY_NAMES\n        val = get(data, name, nothing)\n        if isnothing(val)\n            @debug \"key '$name' not found in input data, set to nothing\" _group =\n                IS.LOG_GROUP_PARSING\n        else\n            category_to_df[category] = val\n        end\n    end\n\n    if !isfile(timeseries_metadata_file)\n        if isfile(string(timeseries_metadata_file, \".json\"))\n            timeseries_metadata_file = string(timeseries_metadata_file, \".json\")\n        elseif isfile(string(timeseries_metadata_file, \".csv\"))\n            timeseries_metadata_file = string(timeseries_metadata_file, \".csv\")\n        else\n            timeseries_metadata_file = nothing\n        end\n    end\n\n    if user_descriptors isa AbstractString\n        user_descriptors = _read_config_file(user_descriptors)\n    end\n\n    if descriptors isa AbstractString\n        descriptors = _read_config_file(descriptors)\n    end\n\n    return PowerSystemTableData(\n        base_power,\n        category_to_df,\n        timeseries_metadata_file,\n        directory,\n        user_descriptors,\n        descriptors,\n        generator_mapping,\n    )\nend\n\n\"\"\"\nReads in all the data stored in csv files in a `directory`\n\n!!! warning\n\n    This parser is planned for deprecation. `PowerSystems.jl` will be\n    moving to a database solution for handling data. There are plans to eventually include\n    utility functions to translate from .csv files to the database, but there will probably\n    be a gap in support. **Users are recommended to write their own custom Julia code to\n    import data from their unique data formats, rather than relying on this parsing\n    code.** See [How-to Build a `System` from CSV Files](@ref system_from_csv) for an example.\n\n# Arguments\n- `directory::AbstractString`: directory containing CSV files\n- `base_power::Float64`: base power for [`System`](@ref)\n- `user_descriptor_file::AbstractString`: customized input descriptor file. [Example](https://github.com/Sienna-Platform/PowerSystemsTestData/blob/master/RTS_GMLC/user_descriptors.yaml)\n- `descriptor_file=POWER_SYSTEM_DESCRIPTOR_FILE`: `PowerSystems.jl` descriptor file. [Default](https://github.com/Sienna-Platform/PowerSystems.jl/blob/main/src/descriptors/power_system_inputs.json)\n- `generator_mapping_file=GENERATOR_MAPPING_FILE_CDM`: generator mapping configuration file. [Default](https://github.com/Sienna-Platform/PowerSystems.jl/blob/main/src/parsers/generator_mapping_cdm.yaml)\n- `timeseries_metadata_file = joinpath(directory, \"timeseries_pointers\")`: Time series pointers .json file. [Example](https://github.com/Sienna-Platform/PowerSystemsTestData/blob/master/RTS_GMLC/timeseries_pointers.json)\n\nThe general format for data in the `directory` is:\n- bus.csv (required)\n    + columns specifying `area` and `zone` will create a corresponding set of `Area` and `LoadZone` objects.\n    + columns specifying `max_active_power` or `max_reactive_power` will create `PowerLoad` objects when nonzero values are encountered and will contribute to the `peak_active_power` and `peak_reactive_power` values for the\n        corresponding `LoadZone` object.\n- branch.csv\n- dc_branch.csv\n- gen.csv\n- load.csv\n- reserves.csv\n- storage.csv\n\n# Custom construction of generators\n\nEach generator will be defined as a concrete subtype of [`Generator`](@ref),\nbased on the `fuel` and `type` columns in `gen.csv` and the `generator_mapping_file`.\nThe default mapping file\nis [`src/parsers/generator_mapping.yaml`](https://github.com/Sienna-Platform/PowerSystems.jl/blob/main/src/parsers/generator_mapping.yaml). You can override this behavior by specifying your own file.\n\n# Custom Column names\n\n`PowerSystems` provides am input mapping capability that allows you to keep your own\ncolumn names. For example, when parsing raw data for a generator the code expects a column\ncalled `name`. If the raw data instead defines that column as `GEN UID` then\nyou can change the `custom_name` field under the `generator` category to\n`GEN UID` in your YAML file.\n\nTo enable the parsing of a custom set of csv files, you can generate a configuration\nfile (such as `user_descriptors.yaml`) from the defaults, which are stored\nin [`src/descriptors/power_system_inputs.json`](https://github.com/Sienna-Platform/PowerSystems.jl/blob/main/src/descriptors/power_system_inputs.json).\n\n```python\npython ./bin/generate_config_file.py ./user_descriptors.yaml\n```\n\nNext, edit this file with your customizations.\n\nNote that the user-specific customizations are stored in YAML rather than JSON\nto allow for easier editing. The next few sections describe changes you can\nmake to this YAML file.  Do not edit the default JSON file.\n\n## Per-unit conversion\n\n`PowerSystems` defines whether it expects a column value to be per-unit system base,\nper-unit device base, or natural units in `power_system_inputs.json`. If it expects a\nper-unit convention that differs from your values then you can set the `unit_system` in\n`user_descriptors.yaml` and `PowerSystems` will automatically convert the values. For\nexample, if you have a `max_active_power` value stored in natural units (MW), but\n`power_system_inputs.json` specifies `unit_system: device_base`, you can enter\n`unit_system: natural_units` in `user_descriptors.yaml` and `PowerSystems` will divide\nthe value by the value of the corresponding entry in the column identified by the\n`base_reference` field in `power_system_inputs.json`. You can also override the\n`base_reference` setting by adding `base_reference: My Column` to make device base\nper-unit conversion by dividing the value by the entry in `My Column`. System base\nper-unit conversions always divide the value by the system `base_power` value\ninstantiated when constructing a `System`.\n\n`PowerSystems` provides a limited set of unit conversions. For example, if\n`power_system_inputs.json` indicates that a value's unit is degrees but\nyour values are in radians then you can set `unit: radian` in\nyour YAML file. Other valid `unit` entries include `GW`, `GWh`, `MW`, `MWh`, `kW`,\nand `kWh`.\n\n# Examples\n```julia\ndata_dir = \"/data/my-data-dir\"\nbase_power = 100.0\ndescriptors = \"./user_descriptors.yaml\"\ntimeseries_metadata_file = \"./timeseries_pointers.json\"\ngenerator_mapping_file = \"./generator_mapping.yaml\"\ndata = PowerSystemTableData(\n    data_dir,\n    base_power,\n    descriptors;\n    timeseries_metadata_file = timeseries_metadata_file,\n    generator_mapping_file = generator_mapping_file,\n)\nsys = System(data; time_series_in_memory = true)\n```\n\"\"\"\nfunction PowerSystemTableData(\n    directory::AbstractString,\n    base_power::Float64,\n    user_descriptor_file::AbstractString;\n    descriptor_file = POWER_SYSTEM_DESCRIPTOR_FILE,\n    generator_mapping_file = GENERATOR_MAPPING_FILE_CDM,\n    timeseries_metadata_file = joinpath(directory, \"timeseries_pointers\"),\n)\n    files = readdir(directory)\n    REGEX_DEVICE_TYPE = r\"(.*?)\\.csv\"\n    REGEX_IS_FOLDER = r\"^[A-Za-z]+$\"\n    data = Dict{String, Any}()\n\n    if length(files) == 0\n        error(\"No files in the folder\")\n    else\n        data[\"base_power\"] = base_power\n    end\n\n    encountered_files = 0\n    for d_file in files\n        try\n            if match(REGEX_IS_FOLDER, d_file) !== nothing\n                @info \"Parsing csv files in $d_file ...\"\n                d_file_data = Dict{String, Any}()\n                for file in readdir(joinpath(directory, d_file))\n                    if match(REGEX_DEVICE_TYPE, file) !== nothing\n                        @info \"Parsing csv data in $file ...\"\n                        encountered_files += 1\n                        fpath = joinpath(directory, d_file, file)\n                        raw_data = DataFrames.DataFrame(CSV.File(fpath))\n                        d_file_data[split(file, r\"[.]\")[1]] = raw_data\n                    end\n                end\n\n                if length(d_file_data) > 0\n                    data[d_file] = d_file_data\n                    @info \"Successfully parsed $d_file\"\n                end\n\n            elseif match(REGEX_DEVICE_TYPE, d_file) !== nothing\n                @info \"Parsing csv data in $d_file ...\"\n                encountered_files += 1\n                fpath = joinpath(directory, d_file)\n                raw_data = DataFrames.DataFrame(CSV.File(fpath))\n                data[split(d_file, r\"[.]\")[1]] = raw_data\n                @info \"Successfully parsed $d_file\"\n            end\n        catch ex\n            @error \"Error occurred while parsing $d_file\" exception = ex\n            throw(ex)\n        end\n    end\n    if encountered_files == 0\n        error(\"No csv files or folders in $directory\")\n    end\n\n    generator_mapping = Dict{NamedTuple, DataType}()\n    try\n        generator_mapping = get_generator_mapping(generator_mapping_file)\n    catch e\n        @error \"Error loading generator mapping $(generator_mapping_file)\"\n        rethrow(e)\n    end\n\n    return PowerSystemTableData(\n        data,\n        directory,\n        user_descriptor_file,\n        descriptor_file,\n        generator_mapping;\n        timeseries_metadata_file = timeseries_metadata_file,\n    )\nend\n\n\"\"\"\nReturn the custom name stored in the user descriptor file.\n\nThrows DataFormatError if a required value is not found in the file.\n\"\"\"\nfunction get_user_field(\n    data::PowerSystemTableData,\n    category::InputCategory,\n    field::AbstractString,\n)\n    if !haskey(data.user_descriptors, category)\n        throw(DataFormatError(\"Invalid category=$category\"))\n    end\n\n    try\n        for item in data.user_descriptors[category]\n            if item[\"name\"] == field\n                return item[\"custom_name\"]\n            end\n        end\n    catch\n        (err)\n        if err == KeyError\n            msg = \"Failed to find category=$category field=$field in input descriptors $err\"\n            throw(DataFormatError(msg))\n        else\n            throw(err)\n        end\n    end\nend\n\n\"\"\"Return a vector of user-defined fields for the category.\"\"\"\nfunction get_user_fields(data::PowerSystemTableData, category::InputCategory)\n    if !haskey(data.user_descriptors, category)\n        throw(DataFormatError(\"Invalid category=$category\"))\n    end\n\n    return [x[\"name\"] for x in data.user_descriptors[category]]\nend\n\n\"\"\"Return the dataframe for the category.\"\"\"\nfunction get_dataframe(data::PowerSystemTableData, category::InputCategory)\n    df = get(data.category_to_df, category, DataFrames.DataFrame())\n    isempty(df) && @warn(\"Missing $category data.\")\n    return df\nend\n\n\"\"\"\nReturn a NamedTuple of parameters from the descriptor file for each row of a dataframe,\nmaking type conversions as necessary.\n\nRefer to the PowerSystems descriptor file for field names that will be created.\n\"\"\"\nfunction iterate_rows(data::PowerSystemTableData, category; na_to_nothing = true)\n    df = get_dataframe(data, category)\n    field_infos = _get_field_infos(data, category, names(df))\n    Channel() do channel\n        for row in eachrow(df)\n            obj = _read_data_row(data, row, field_infos; na_to_nothing = na_to_nothing)\n            put!(channel, obj)\n        end\n    end\nend\n\n\"\"\"\nConstruct a System from [`PowerSystemTableData`](@ref) data.\n\n!!! warning\n\n    This parser is planned for deprecation. `PowerSystems.jl` will be\n    moving to a database solution for handling data. There are plans to eventually include\n    utility functions to translate from .csv files to the database, but there will probably\n    be a gap in support. **Users are recommended to write their own custom Julia code to\n    import data from their unique data formats, rather than relying on this parsing\n    code.** See [How-to Build a `System` from CSV Files](@ref system_from_csv) for an example.\n\n# Arguments\n- `time_series_resolution::Union{DateTime, Nothing}=nothing`: only store time_series that match\n  this resolution.\n- `time_series_in_memory::Bool=false`: Store time series data in memory instead of HDF5 file\n- `time_series_directory=nothing`: Store time series data in directory instead of tmpfs\n- `runchecks::Bool=true`: Validate struct fields.\n\nThrows DataFormatError if time_series with multiple resolutions are detected.\n- A time_series has a different resolution than others.\n- A time_series has a different horizon than others.\n\n\"\"\"\nfunction System(\n    data::PowerSystemTableData;\n    time_series_resolution = nothing,\n    time_series_in_memory = false,\n    time_series_directory = nothing,\n    runchecks = true,\n    kwargs...,\n)\n    sys = System(\n        data.base_power;\n        time_series_in_memory = time_series_in_memory,\n        time_series_directory = time_series_directory,\n        runchecks = runchecks,\n        kwargs...,\n    )\n    set_units_base_system!(sys, IS.UnitSystem.DEVICE_BASE)\n\n    loadzone_csv_parser!(sys, data)\n    bus_csv_parser!(sys, data)\n\n    # Services and time_series must be last.\n    parsers = (\n        (get_dataframe(data, InputCategory.BRANCH), branch_csv_parser!),\n        (get_dataframe(data, InputCategory.DC_BRANCH), dc_branch_csv_parser!),\n        (get_dataframe(data, InputCategory.GENERATOR), gen_csv_parser!),\n        (get_dataframe(data, InputCategory.LOAD), load_csv_parser!),\n        (get_dataframe(data, InputCategory.RESERVE), services_csv_parser!),\n    )\n\n    for (val, parser) in parsers\n        if !isempty(val)\n            parser(sys, data)\n        end\n    end\n\n    timeseries_metadata_file =\n        get(kwargs, :timeseries_metadata_file, getfield(data, :timeseries_metadata_file))\n\n    if !isnothing(timeseries_metadata_file)\n        add_time_series!(sys, timeseries_metadata_file; resolution = time_series_resolution)\n    end\n\n    check(sys)\n    return sys\nend\n\n\"\"\"\nAdd buses and areas to the System from the raw data.\n\n\"\"\"\nfunction bus_csv_parser!(sys::System, data::PowerSystemTableData)\n    for (ix, bus) in enumerate(iterate_rows(data, InputCategory.BUS))\n        name = bus.name\n        bus_type =\n            isnothing(bus.bus_type) ? nothing : get_enum_value(ACBusTypes, bus.bus_type)\n        voltage_limits = make_minmaxlimits(bus.voltage_limits_min, bus.voltage_limits_max)\n\n        area_name = string(get(bus, :area, \"area\"))\n        area = get_component(Area, sys, area_name)\n        if isnothing(area)\n            area = Area(area_name)\n            add_component!(sys, area)\n        end\n        zone = get(bus, :zone, nothing)\n        bus_id = isnothing(bus.bus_id) ? ix : bus.bus_id\n\n        ps_bus = ACBus(;\n            number = bus_id,\n            name = name,\n            available = true,\n            bustype = bus_type,\n            angle = bus.angle,\n            magnitude = bus.voltage,\n            voltage_limits = voltage_limits,\n            base_voltage = bus.base_voltage,\n            area = area,\n            load_zone = get_component(LoadZone, sys, string(zone)),\n        )\n        add_component!(sys, ps_bus)\n\n        # add load if the following info is nonzero\n        if (bus.max_active_power != 0.0) || (bus.max_reactive_power != 0.0)\n            load = PowerLoad(;\n                name = name,\n                available = true,\n                bus = ps_bus,\n                active_power = bus.active_power,\n                reactive_power = bus.reactive_power,\n                base_power = bus.base_power,\n                max_active_power = bus.max_active_power,\n                max_reactive_power = bus.max_reactive_power,\n            )\n            add_component!(sys, load)\n        end\n\n        if (bus.shunt_b != 0.0) || (bus.shunt_g != 0.0)\n            shunt = FixedAdmittance(;\n                name = name,\n                available = true,\n                bus = ps_bus,\n                Y = (bus.shunt_g + bus.shunt_b * im),\n            )\n            add_component!(sys, shunt)\n        end\n    end\nend\n\nfunction get_branch_type(\n    tap::Float64,\n    is_transformer::Union{Bool, Nothing},\n)\n    if isnothing(is_transformer)\n        is_transformer = (tap != 0.0) && (tap != 1.0)\n    end\n\n    is_transformer || return Line\n\n    return tap == 1.0 ? Transformer2W : TapTransformer\nend\n\n\"\"\"\nAdd branches to the System from the raw data.\n\"\"\"\nfunction branch_csv_parser!(sys::System, data::PowerSystemTableData)\n    available = true\n\n    for branch in iterate_rows(data, InputCategory.BRANCH)\n        bus_from = get_bus(sys, branch.connection_points_from)\n        bus_to = get_bus(sys, branch.connection_points_to)\n        name = get(branch, :name, get_name(bus_from) * \"_\" * get_name(bus_to))\n        connection_points = Arc(bus_from, bus_to)\n        pf = branch.active_power_flow\n        qf = branch.reactive_power_flow\n\n        # Table Model doesn't support PhaseShifters\n        branch_type =\n            get_branch_type(\n                branch.tap,\n                get(branch, :is_transformer, nothing),\n            )\n\n        if branch_type == Line\n            b = branch.primary_shunt / 2\n            value = Line(;\n                name = name,\n                available = available,\n                active_power_flow = pf,\n                reactive_power_flow = qf,\n                arc = connection_points,\n                r = branch.r,\n                x = branch.x,\n                b = (from = b, to = b),\n                rating = branch.rate,\n                angle_limits = (\n                    min = branch.min_angle_limits,\n                    max = branch.max_angle_limits,\n                ),\n            )\n        elseif branch_type == Transformer2W\n            value = Transformer2W(;\n                name = name,\n                available = available,\n                active_power_flow = pf,\n                reactive_power_flow = qf,\n                arc = connection_points,\n                r = branch.r,\n                x = branch.x,\n                primary_shunt = branch.primary_shunt,\n                winding_group_number = WindingGroupNumber.UNDEFINED,\n                rating = branch.rate,\n                base_power = data.base_power, # use system base power\n            )\n        elseif branch_type == TapTransformer\n            value = TapTransformer(;\n                name = name,\n                available = available,\n                active_power_flow = pf,\n                reactive_power_flow = qf,\n                arc = connection_points,\n                r = branch.r,\n                x = branch.x,\n                primary_shunt = branch.primary_shunt,\n                winding_group_number = WindingGroupNumber.UNDEFINED,\n                tap = branch.tap,\n                rating = branch.rate,\n                base_power = data.base_power, # use system base power\n            )\n        else\n            error(\"Unsupported branch type $branch_type\")\n        end\n\n        add_component!(sys, value)\n    end\nend\n\n\"\"\"\nAdd DC branches to the System from raw data.\n\"\"\"\nfunction dc_branch_csv_parser!(sys::System, data::PowerSystemTableData)\n    function make_dc_limits(dc_branch, min, max)\n        min_lim = dc_branch[min]\n        if isnothing(dc_branch[min]) && isnothing(dc_branch[max])\n            throw(DataFormatError(\"valid limits required for $min , $max\"))\n        elseif isnothing(dc_branch[min])\n            min_lim = dc_branch[max] * -1.0\n        end\n        return (min = min_lim, max = dc_branch[max])\n    end\n\n    for dc_branch in iterate_rows(data, InputCategory.DC_BRANCH)\n        available = true\n        bus_from = get_bus(sys, dc_branch.connection_points_from)\n        bus_to = get_bus(sys, dc_branch.connection_points_to)\n        connection_points = Arc(bus_from, bus_to)\n\n        if dc_branch.control_mode == \"Power\"\n            mw_load = dc_branch.mw_load\n\n            activepowerlimits_from = make_dc_limits(\n                dc_branch,\n                :min_active_power_limit_from,\n                :max_active_power_limit_from,\n            )\n            activepowerlimits_to = make_dc_limits(\n                dc_branch,\n                :min_active_power_limit_to,\n                :max_active_power_limit_to,\n            )\n            reactivepowerlimits_from = make_dc_limits(\n                dc_branch,\n                :min_reactive_power_limit_from,\n                :max_reactive_power_limit_from,\n            )\n            reactivepowerlimits_to = make_dc_limits(\n                dc_branch,\n                :min_reactive_power_limit_to,\n                :max_reactive_power_limit_to,\n            )\n\n            loss = LinearCurve(dc_branch.loss) #TODO: Can we infer this from the other data?,\n\n            value = TwoTerminalGenericHVDCLine(;\n                name = dc_branch.name,\n                available = available,\n                active_power_flow = dc_branch.active_power_flow,\n                arc = connection_points,\n                active_power_limits_from = activepowerlimits_from,\n                active_power_limits_to = activepowerlimits_to,\n                reactive_power_limits_from = reactivepowerlimits_from,\n                reactive_power_limits_to = reactivepowerlimits_to,\n                loss = loss,\n            )\n        else\n            error(\n                \"Only control mode = Power is supported for DC Branch $(dc_branch.name) in TableData.\",\n            )\n        end\n\n        add_component!(sys, value)\n    end\nend\n\n\"\"\"\nAdd generators to the System from the raw data.\n\n\"\"\"\nstruct _HeatRateColumns\n    columns::Base.Iterators.Zip{Tuple{Array{Symbol, 1}, Array{Symbol, 1}}}\nend\nstruct _CostPointColumns\n    columns::Base.Iterators.Zip{Tuple{Array{Symbol, 1}, Array{Symbol, 1}}}\nend\n\nfunction gen_csv_parser!(sys::System, data::PowerSystemTableData)\n    output_point_fields = Vector{Symbol}()\n    heat_rate_fields = Vector{Symbol}()\n    cost_point_fields = Vector{Symbol}()\n    fields = get_user_fields(data, InputCategory.GENERATOR)\n\n    for field in fields\n        if occursin(\"output_point\", field)\n            push!(output_point_fields, Symbol(field))\n        elseif occursin(\"heat_rate_\", field)\n            push!(heat_rate_fields, Symbol(field))\n        elseif occursin(\"cost_point_\", field)\n            push!(cost_point_fields, Symbol(field))\n        end\n    end\n\n    @assert length(output_point_fields) > 0\n\n    if length(heat_rate_fields) > 0 && length(cost_point_fields) > 0\n        throw(IS.ConflictingInputsError(\"Heat rate and cost points are both defined\"))\n    elseif length(heat_rate_fields) > 0\n        cost_colnames = _HeatRateColumns(zip(heat_rate_fields, output_point_fields))\n    elseif length(cost_point_fields) > 0\n        cost_colnames = _CostPointColumns(zip(cost_point_fields, output_point_fields))\n    else\n        throw(IS.DataFormatError(\"Configuration for cost terms not recognized\"))\n    end\n\n    gen_storage = cache_storage(data::PowerSystemTableData)\n\n    for gen in iterate_rows(data, InputCategory.GENERATOR)\n        reservoirs = nothing # For hydro generators with reservoirs\n        @debug \"making generator:\" _group = IS.LOG_GROUP_PARSING gen.name\n        bus = get_bus(sys, gen.bus_id)\n        if isnothing(bus)\n            throw(DataFormatError(\"could not find $(gen.bus_id)\"))\n        end\n\n        # Returns a vector of reservoirs when applicable to hydro turbines\n        generator, reservoirs =\n            make_generator(data, gen, cost_colnames, bus, gen_storage)\n        @debug \"adding gen:\" _group = IS.LOG_GROUP_PARSING generator\n        if !isnothing(generator)\n            add_component!(sys, generator)\n        end\n        if !isnothing(reservoirs)\n            @debug \"adding reservoirs:\" _group = IS.LOG_GROUP_PARSING generator\n            add_components!(sys, reservoirs)\n        end\n    end\n    return\nend\n\nfunction cache_storage(data::PowerSystemTableData)\n    storage = Dict{String, Any}()\n    gen_head_dict = Dict()\n    gen_tail_dict = Dict()\n    if !haskey(data.category_to_df, InputCategory.STORAGE)\n        return gen_head_dict, gen_tail_dict\n    end\n    for s in iterate_rows(data, InputCategory.STORAGE)\n        if occursin(\"head\", normalize(s.position; casefold = true))\n            if !haskey(gen_head_dict, s.generator_name)\n                gen_head_dict[s.generator_name] = s\n            else\n                throw(DataFormatError(\"Duplicate head storage found for gen $s\"))\n            end\n        elseif occursin(\"tail\", normalize(s.position; casefold = true))\n            if !haskey(gen_tail_dict, s.generator_name)\n                gen_tail_dict[s.generator_name] = s\n            else\n                throw(DataFormatError(\"Duplicate tail storage found for gen $s\"))\n            end\n        end\n    end\n    storage[\"head\"] = gen_head_dict\n    storage[\"tail\"] = gen_tail_dict\n    return storage\nend\n\n\"\"\"\n    load_csv_parser!(sys::System, data::PowerSystemTableData)\n\nAdd loads to the System from the raw load data.\n\n\"\"\"\nfunction load_csv_parser!(sys::System, data::PowerSystemTableData)\n    for rawload in iterate_rows(data, InputCategory.LOAD)\n        bus = get_bus(sys, rawload.bus_id)\n        if isnothing(bus)\n            throw(\n                DataFormatError(\n                    \"could not find bus_number=$(rawload.bus_id) for load=$(rawload.name)\",\n                ),\n            )\n        end\n\n        load = PowerLoad(;\n            name = rawload.name,\n            available = rawload.available,\n            bus = bus,\n            active_power = rawload.active_power,\n            reactive_power = rawload.reactive_power,\n            max_active_power = rawload.max_active_power,\n            max_reactive_power = rawload.max_reactive_power,\n            base_power = rawload.base_power,\n        )\n        add_component!(sys, load)\n    end\nend\n\n\"\"\"\n    loadzone_csv_parser!(sys::System, data::PowerSystemTableData)\n\nAdd branches to the System from the raw data.\n\n\"\"\"\nfunction loadzone_csv_parser!(sys::System, data::PowerSystemTableData)\n    buses = get_dataframe(data, InputCategory.BUS)\n    zone_column = get_user_field(data, InputCategory.BUS, \"zone\")\n    if !in(zone_column, names(buses))\n        @warn \"Missing Data : no 'zone' information for buses, cannot create loads based on zones\"\n        return\n    end\n\n    zones = unique(buses[!, zone_column])\n    for zone in zones\n        bus_numbers = Set{Int}()\n        active_powers = Vector{Float64}()\n        reactive_powers = Vector{Float64}()\n        for (ix, bus) in enumerate(iterate_rows(data, InputCategory.BUS))\n            bus_number = isnothing(bus.bus_id) ? ix : bus.bus_id\n            if bus.zone == zone\n                push!(bus_numbers, bus_number)\n\n                active_power = bus.max_active_power\n                push!(active_powers, active_power)\n\n                reactive_power = bus.max_reactive_power\n                push!(reactive_powers, reactive_power)\n            end\n        end\n\n        name = string(zone)\n        load_zone = LoadZone(name, sum(active_powers), sum(reactive_powers))\n        add_component!(sys, load_zone)\n    end\nend\n\n\"\"\"\nAdd services to the System from the raw data.\n\"\"\"\nfunction services_csv_parser!(sys::System, data::PowerSystemTableData)\n    bus_id_column = get_user_field(data, InputCategory.BUS, \"bus_id\")\n    bus_area_column = get_user_field(data, InputCategory.BUS, \"area\")\n\n    # Shortcut for data that looks like \"(val1,val2,val3)\"\n    function make_array(x)\n        if isnothing(x)\n            return x\n        else\n            y = split(strip(x, ['(', ')']), \",\")\n            # Remove extra space at the beginning if needed\n            return replace.(y, r\"^ *\" => \"\")\n        end\n    end\n\n    function _add_device!(contributing_devices, device_categories, name)\n        component = []\n        for dev_category in device_categories\n            component_type = _get_component_type_from_category(dev_category)\n            components = get_components_by_name(component_type, sys, name)\n            if length(components) == 0\n                # There multiple categories, so we might not find a match in some.\n                continue\n            elseif length(components) == 1\n                push!(component, components[1])\n            else\n                msg = \"Found duplicate names type=$component_type name=$name\"\n                throw(DataFormatError(msg))\n            end\n        end\n        if length(component) > 1\n            msg = \"Found duplicate components with name=$name\"\n            throw(DataFormatError(msg))\n        elseif length(component) == 1\n            push!(contributing_devices, component[1])\n        end\n    end\n\n    for reserve in iterate_rows(data, InputCategory.RESERVE)\n        device_categories = make_array(reserve.eligible_device_categories)\n        device_subcategories =\n            make_array(get(reserve, :eligible_device_subcategories, nothing))\n        devices = make_array(get(reserve, :contributing_devices, nothing))\n        regions = make_array(reserve.eligible_regions) #TODO: rename to \"area\"\n        requirement = get(reserve, :requirement, nothing)\n        contributing_devices = Vector{Device}()\n\n        if isnothing(device_subcategories)\n            @info(\"Adding contributing components for $(reserve.name) by component name\")\n            for device in devices\n                @assert supports_services(device)\n                _add_device!(contributing_devices, device_categories, device)\n            end\n        else\n            @info(\"Adding contributing generators for $(reserve.name) by category\")\n            for gen in iterate_rows(data, InputCategory.GENERATOR)\n                buses = get_dataframe(data, InputCategory.BUS)\n                bus_ids = buses[!, bus_id_column]\n                gen_type =\n                    get_generator_type(gen.fuel, gen.unit_type, data.generator_mapping)\n                sys_gen = get_component(gen_type, sys, gen.name)\n                @assert supports_services(sys_gen)\n                if isnothing(sys_gen)\n                    error(\n                        \"Failed to find generator: type = $gen_type name = $(gen.name) \" *\n                        \"fuel = $(gen.fuel) unit_type = $(gen.unit_type)\",\n                    )\n                end\n                area = string(\n                    buses[bus_ids .== get_number(get_bus(sys_gen)), bus_area_column][1],\n                )\n                if gen.category in device_subcategories && area in regions\n                    _add_device!(contributing_devices, device_categories, gen.name)\n                end\n            end\n\n            unused_categories = setdiff(\n                device_subcategories,\n                get_dataframe(data, InputCategory.GENERATOR)[\n                    !,\n                    get_user_field(data, InputCategory.GENERATOR, \"category\"),\n                ],\n            )\n            for cat in unused_categories\n                @warn(\n                    \"Device category: $cat not found in generators data; adding contributing devices by category only supported for generator data\"\n                )\n            end\n        end\n\n        if length(contributing_devices) == 0\n            throw(\n                DataFormatError(\n                    \"did not find contributing devices for service $(reserve.name)\",\n                ),\n            )\n        end\n\n        direction = get_reserve_direction(reserve.direction)\n        if isnothing(requirement)\n            service = ConstantReserve{direction}(reserve.name, true, reserve.timeframe, 0.0)\n        else\n            service = VariableReserve{direction}(\n                reserve.name,\n                true,\n                reserve.timeframe,\n                requirement,\n            )\n        end\n\n        add_service!(sys, service, contributing_devices)\n    end\nend\n\nfunction get_reserve_direction(direction::AbstractString)\n    if lowercase(direction) == \"up\"\n        return ReserveUp\n    elseif lowercase(direction) == \"down\"\n        return ReserveDown\n    else\n        throw(DataFormatError(\"invalid reserve direction $direction\"))\n    end\nend\n\n\"\"\"Creates a generator of any type.\"\"\"\nfunction make_generator(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus,\n    gen_storage,\n)\n    generator = nothing\n    gen_type =\n        get_generator_type(gen.fuel, get(gen, :unit_type, nothing), data.generator_mapping)\n\n    reservoirs = nothing\n    if isnothing(gen_type)\n        @error \"Cannot recognize generator type\" gen.name\n    elseif gen_type == ThermalStandard\n        generator = make_thermal_generator(data, gen, cost_colnames, bus)\n    elseif gen_type == ThermalMultiStart\n        generator = make_thermal_generator_multistart(data, gen, cost_colnames, bus)\n    elseif gen_type == SynchronousCondenser\n        generator = make_synchronous_condenser_generator(gen, bus)\n    elseif gen_type == HydroDispatch\n        generator = make_hydro_dispatch(data, gen, cost_colnames, bus)\n    elseif gen_type == HydroTurbine\n        generator, reservoirs =\n            make_hydro_turbine(data, gen, cost_colnames, bus, gen_storage)\n    elseif gen_type == HydroPumpTurbine\n        # For HydroPump it can only return 2 reservoirs. First is head second is tail\n        generator, reservoirs =\n            make_hydro_pump_storage(data, gen, cost_colnames, bus, gen_storage)\n    elseif gen_type <: RenewableGen\n        generator = make_renewable_generator(gen_type, data, gen, cost_colnames, bus)\n    elseif gen_type == EnergyReservoirStorage\n        head_dict = gen_storage[\"head\"]\n        if !haskey(head_dict, gen.name)\n            throw(DataFormatError(\"Cannot find storage for $(gen.name) in storage.csv\"))\n        end\n        storage = head_dict[gen.name]\n        generator = make_storage(data, gen, bus, storage)\n    else\n        @error \"Skipping unsupported generator\" gen.name gen_type\n    end\n\n    if abs(get_base_power(generator)) <= 1e-6\n        @warn \"Generator $(summary(generator)) has base power of zero: changing device \" *\n              \"base power to match system base power, $(data.base_power)\"\n        set_base_power!(generator, data.base_power)\n    end\n\n    return generator, reservoirs\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_HeatRateColumns,\n) where {T <: ThermalGen}\n    fuel_price = gen.fuel_price / 1000.0\n\n    # We check if there is any Quadratic or Linear Data defined. If not we fall back to create PiecewiseIncrementalCurve\n    quadratic_fields = (gen.heat_rate_a0, gen.heat_rate_a1, gen.heat_rate_a2)\n\n    if any(field -> field != nothing, quadratic_fields)\n        var_cost, fixed =\n            create_poly_cost(gen, [\"heat_rate_a0\", \"heat_rate_a1\", \"heat_rate_a2\"])\n    else\n        cost_pairs = get_cost_pairs(gen, cost_colnames)\n        var_cost, fixed = create_pwinc_cost(gen, cost_pairs)\n    end\n    parse_maybe_nothing(x) =\n        isnothing(x) ? 0.0 : (x isa Number ? Float64(x) : tryparse(Float64, x))\n    vom_cost = parse_maybe_nothing(getfield(gen, Symbol(\"variable_cost\")))\n    vom_data = LinearCurve(vom_cost)\n\n    startup_cost, shutdown_cost = calculate_uc_cost(data, gen, fuel_price)\n    fuel_offtake = LinearCurve(0.0)\n    op_cost = ThermalGenerationCost(\n        FuelCurve(var_cost, UnitSystem.NATURAL_UNITS, fuel_price, fuel_offtake, vom_data),\n        fixed * fuel_price,\n        startup_cost,\n        shutdown_cost,\n    )\n    return op_cost\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_CostPointColumns,\n) where {T <: ThermalGen}\n    fuel_price = gen.fuel_price / 1000.0\n    cost_pairs = get_cost_pairs(gen, cost_colnames)\n    var_cost = create_pwl_cost(gen, cost_pairs)\n    startup_cost, shutdown_cost = calculate_uc_cost(data, gen, fuel_price)\n    parse_maybe_nothing(x) =\n        isnothing(x) ? 0.0 : (x isa Number ? Float64(x) : tryparse(Float64, x))\n    vom_cost = parse_maybe_nothing(getfield(gen, Symbol(\"variable_cost\")))\n    vom_data = LinearCurve(vom_cost)\n\n    op_cost = ThermalGenerationCost(\n        CostCurve(var_cost, UnitSystem.NATURAL_UNITS, vom_data),\n        gen.fixed_cost,\n        startup_cost,\n        shutdown_cost,\n    )\n    return op_cost\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_HeatRateColumns,\n) where {T <: HydroGen}\n    fuel_price = gen.fuel_price / 1000.0\n    cost_pairs = get_cost_pairs(gen, cost_colnames)\n    var_cost, fixed = create_pwinc_cost(gen, cost_pairs)\n    op_cost = HydroGenerationCost(\n        FuelCurve(var_cost, UnitSystem.NATURAL_UNITS, fuel_price),\n        fixed * fuel_price)\n    return op_cost\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_CostPointColumns,\n) where {T <: HydroGen}\n    cost_pairs = get_cost_pairs(gen, cost_colnames)\n    var_cost = create_pwl_cost(gen, cost_pairs)\n    op_cost = HydroGenerationCost(\n        CostCurve(var_cost, UnitSystem.NATURAL_UNITS),\n        gen.fixed_cost)\n    return op_cost\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_HeatRateColumns,\n) where {T <: RenewableGen}\n    @warn \"Heat rate parsing not valid for RenewableGen replacing with zero cost\"\n    parse_maybe_nothing(x) =\n        isnothing(x) ? 0.0 : (x isa Number ? Float64(x) : tryparse(Float64, x))\n    vom_cost = parse_maybe_nothing(getfield(gen, Symbol(\"variable_cost\")))\n    vom_data = LinearCurve(vom_cost)\n    var_cost = CostCurve(;\n        value_curve = LinearCurve(0.0),\n        power_units = UnitSystem.NATURAL_UNITS,\n        vom_cost = vom_data,\n    )\n    op_cost = RenewableGenerationCost(var_cost)\n    return op_cost\nend\n\nfunction make_cost(\n    ::Type{T},\n    data,\n    gen,\n    cost_colnames::_CostPointColumns,\n) where {T <: RenewableGen}\n    cost_pairs = get_cost_pairs(gen, cost_colnames)\n    parse_maybe_nothing(x) =\n        isnothing(x) ? 0.0 : (x isa Number ? Float64(x) : tryparse(Float64, x))\n    vom_cost = parse_maybe_nothing(getfield(gen, Symbol(\"variable_cost\")))\n    vom_data = LinearCurve(vom_cost)\n    var_cost = CostCurve(;\n        value_curve = cost_pairs,\n        power_units = UnitSystem.NATURAL_UNITS,\n        vom_cost = vom_data,\n    )\n    op_cost = RenewableGenerationCost(var_cost)\n    return op_cost\nend\n\nfunction get_cost_pairs(gen::NamedTuple, cost_colnames)\n    base_power = gen.base_mva * gen.active_power_limits_max\n    vals = []\n    for (c, pt) in cost_colnames.columns\n        x = getfield(gen, pt)\n        y = getfield(gen, c)\n\n        if !in(nothing, [x, y])\n            push!(vals,\n                (x = tryparse(Float64, string(x)) * base_power,\n                    y = tryparse(Float64, string(y))))\n        end\n    end\n\n    if isempty(vals)\n        return vals\n    else\n        last_increasing_point =\n            findfirst(x -> x < 0.0, [diff(getfield.(vals, :x))..., -Inf])\n        return vals[1:last_increasing_point]\n    end\nend\n\nfunction create_pwl_cost(\n    gen,\n    cost_pairs,\n)\n    if length(cost_pairs) > 1\n        var_cost = PiecewisePointCurve(PiecewiseLinearData(cost_pairs))\n    elseif length(cost_pairs) == 1\n        # if there is only one point, use it to determine the constant $/MW cost\n        var_cost = LinearCurve(cost_pairs[1].y / cost_pairs[1].x)\n    else\n        @warn \"$(gen.name) has no costs defined, using 0.0\" cost_pairs maxlog = 5\n        var_cost = LinearCurve(0.0)\n    end\n\n    return var_cost\nend\n\n\"\"\"\n    create_poly_cost(gen, cost_colnames)\n\nReturn a Polynomial function cost based on the coeffiecients provided on gen.\n\nThree supported cases,\n  1. If three values are passed then we have data looking like: `a2 * x^2 + a1 * x + a0`,\n  2. If `a1` and `a0` are passed then we have data looking like: `a1 * x + a0`,\n  3. If only `a1` is passed then we have data looking like: `a1 * x`.\n\"\"\"\nfunction create_poly_cost(\n    gen, cost_colnames,\n)\n    fixed_cost = 0.0\n    parse_maybe_nothing(x) =\n        isnothing(x) ? nothing : (x isa Number ? Float64(x) : tryparse(Float64, x))\n    a2 = parse_maybe_nothing(getfield(gen, Symbol(\"heat_rate_a2\")))\n    a1 = parse_maybe_nothing(getfield(gen, Symbol(\"heat_rate_a1\")))\n    a0 = parse_maybe_nothing(getfield(gen, Symbol(\"heat_rate_a0\")))\n\n    if !isnothing(a2) && (isnothing(a1) || isnothing(a0))\n        throw(\n            DataFormatError(\n                \"All coefficients must be passed if quadratic term is passed.\",\n            ),\n        )\n    end\n\n    if !any(isnothing.([a2, a1, a0]))\n        @debug \"QuadraticCurve created for $(gen.name)\"\n        return QuadraticCurve(a2, a1, a0), fixed_cost\n    end\n    if all(isnothing.([a2, a0])) && !isnothing(a1)\n        @debug \"LinearCurve created for $(gen.name)\"\n        return LinearCurve(a1), fixed_cost\n    end\n    @debug \"LinearCurve created for $(gen.name)\"\n    return LinearCurve(a1, a0), fixed_cost\nend\n\nfunction create_pwinc_cost(\n    gen,\n    cost_pairs,\n)\n    if length(cost_pairs) > 1\n        x_points = getfield.(cost_pairs, :x)\n        y_points = getfield.(cost_pairs, :y)\n        var_cost = PiecewiseIncrementalCurve(\n            first(y_points) * first(x_points),\n            x_points,\n            y_points[2:end],\n        )\n    elseif length(cost_pairs) == 1\n        # if there is only one point, use it to determine the constant $/MW cost\n        var_cost = LinearCurve(cost_pairs[1].y)\n    else\n        @warn \"Unable to calculate variable cost for $(gen.name), defaulting to LinearCurve(0.0)\" cost_pairs maxlog =\n            5\n        var_cost = LinearCurve(0.0)\n    end\n\n    return var_cost, 0.0\nend\n\nfunction calculate_uc_cost(data, gen, fuel_cost)\n    startup_cost = gen.startup_cost\n    if isnothing(startup_cost)\n        if !isnothing(gen.startup_heat_cold_cost)\n            startup_cost = gen.startup_heat_cold_cost * fuel_cost * 1000\n        else\n            startup_cost = 0.0\n            @warn \"No startup_cost defined for $(gen.name), setting to $startup_cost\" maxlog =\n                5\n        end\n    end\n\n    shutdown_cost = get(gen, :shutdown_cost, nothing)\n    if isnothing(shutdown_cost)\n        @warn \"No shutdown_cost defined for $(gen.name), setting to 0.0\" maxlog = 1\n        shutdown_cost = 0.0\n    end\n\n    return startup_cost, shutdown_cost\nend\n\nfunction make_minmaxlimits(min::Union{Nothing, Float64}, max::Union{Nothing, Float64})\n    if isnothing(min) && isnothing(max)\n        minmax = nothing\n    else\n        minmax = (min = min, max = max)\n    end\n    return minmax\nend\n\nfunction make_ramplimits(\n    gen;\n    ramplimcol = :ramp_limits,\n    rampupcol = :ramp_up,\n    rampdncol = :ramp_down,\n)\n    ramp = get(gen, ramplimcol, nothing)\n    if !isnothing(ramp)\n        up = ramp\n        down = ramp\n    else\n        up = get(gen, rampupcol, ramp)\n        up = typeof(up) <: AbstractString ? tryparse(Float64, up) : up\n        down = get(gen, rampdncol, ramp)\n        down = typeof(down) <: AbstractString ? tryparse(Float64, down) : down\n    end\n    ramplimits = isnothing(up) && isnothing(down) ? nothing : (up = up, down = down)\n    return ramplimits\nend\n\nfunction make_timelimits(gen, up_column::Symbol, down_column::Symbol)\n    up_time = get(gen, up_column, nothing)\n    up_time = typeof(up_time) <: AbstractString ? tryparse(Float64, up_time) : up_time\n\n    down_time = get(gen, down_column, nothing)\n    down_time =\n        typeof(down_time) <: AbstractString ? tryparse(Float64, down_time) : down_time\n\n    timelimits =\n        if isnothing(up_time) && isnothing(down_time)\n            nothing\n        else\n            (up = up_time, down = down_time)\n        end\n    return timelimits\nend\n\nfunction make_reactive_params(\n    gen;\n    powerfield = :reactive_power,\n    minfield = :reactive_power_limits_min,\n    maxfield = :reactive_power_limits_max,\n)\n    reactive_power = get(gen, powerfield, 0.0)\n    reactive_power_limits_min = get(gen, minfield, nothing)\n    reactive_power_limits_max = get(gen, maxfield, nothing)\n    if isnothing(reactive_power_limits_min) && isnothing(reactive_power_limits_max)\n        reactive_power_limits = nothing\n    elseif isnothing(reactive_power_limits_min)\n        reactive_power_limits = (min = 0.0, max = reactive_power_limits_max)\n    else\n        reactive_power_limits =\n            (min = reactive_power_limits_min, max = reactive_power_limits_max)\n    end\n    return reactive_power, reactive_power_limits\nend\n\nfunction make_synchronous_condenser_generator(\n    gen,\n    bus,\n)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n\n    return SynchronousCondenser(;\n        name = gen.name,\n        available = gen.available,\n        bus = bus,\n        reactive_power = reactive_power,\n        rating = rating,\n        reactive_power_limits = reactive_power_limits,\n        base_power = gen.base_mva,\n    )\nend\n\nfunction make_thermal_generator(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames::Union{_CostPointColumns, _HeatRateColumns},\n    bus,\n)\n    @debug \"Making ThermaStandard\" _group = IS.LOG_GROUP_PARSING gen.name\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n    ramplimits = make_ramplimits(gen)\n    timelimits = make_timelimits(gen, :min_up_time, :min_down_time)\n    primemover = parse_enum_mapping(PrimeMovers, gen.unit_type)\n    fuel = parse_enum_mapping(ThermalFuels, gen.fuel)\n\n    base_power = gen.base_mva\n\n    op_cost = make_cost(ThermalStandard, data, gen, cost_colnames)\n\n    gen_must_run = isnothing(gen.must_run) ? false : gen.must_run\n    if !isa(gen_must_run, Bool)\n        gen_must_run = parse(Bool, lowercase(String(gen_must_run)))\n    end\n\n    return ThermalStandard(;\n        name = gen.name,\n        available = gen.available,\n        status = gen.status_at_start,\n        bus = bus,\n        active_power = gen.active_power,\n        reactive_power = reactive_power,\n        rating = rating,\n        prime_mover_type = primemover,\n        fuel = fuel,\n        active_power_limits = active_power_limits,\n        reactive_power_limits = reactive_power_limits,\n        ramp_limits = ramplimits,\n        time_limits = timelimits,\n        operation_cost = op_cost,\n        base_power = base_power,\n        must_run = gen_must_run,\n    )\nend\n\nfunction make_thermal_generator_multistart(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus,\n)\n    thermal_gen = make_thermal_generator(data, gen, cost_colnames, bus)\n\n    @debug \"Making ThermalMultiStart\" _group = IS.LOG_GROUP_PARSING gen.name\n\n    # Get base operation cost from thermal generator\n    base_op_cost = get_operation_cost(thermal_gen)\n\n    # Extract time limits for hot/warm/cold starts\n    lag_hot =\n        if isnothing(gen.hot_start_time)\n            get_time_limits(thermal_gen).down\n        else\n            gen.hot_start_time\n        end\n    lag_warm = isnothing(gen.warm_start_time) ? 0.0 : gen.warm_start_time\n    lag_cold = isnothing(gen.cold_start_time) ? 0.0 : gen.cold_start_time\n    startup_timelimits = (hot = lag_hot, warm = lag_warm, cold = lag_cold)\n    start_types = sum(values(startup_timelimits) .> 0.0)\n\n    # Power trajectory for startup/shutdown ramps\n    startup_ramp = isnothing(gen.startup_ramp) ? 0.0 : gen.startup_ramp\n    shutdown_ramp = isnothing(gen.shutdown_ramp) ? 0.0 : gen.shutdown_ramp\n    power_trajectory = (startup = startup_ramp, shutdown = shutdown_ramp)\n\n    # Multi-start costs - use base cost as fallback if not specified\n    # Convert to Float64 since CSV values may be parsed as Int64\n    base_start_cost = get_start_up(base_op_cost)\n    hot_start_cost =\n        isnothing(gen.hot_start_cost) ? base_start_cost : Float64(gen.hot_start_cost)\n    warm_start_cost =\n        isnothing(gen.warm_start_cost) ? hot_start_cost : Float64(gen.warm_start_cost)\n    cold_start_cost =\n        isnothing(gen.cold_start_cost) ? warm_start_cost : Float64(gen.cold_start_cost)\n    startup_cost = (hot = hot_start_cost, warm = warm_start_cost, cold = cold_start_cost)\n\n    # Shutdown cost\n    base_shutdown_cost = get_shut_down(base_op_cost)\n    shutdown_cost =\n        isnothing(gen.shutdown_cost) ? base_shutdown_cost : Float64(gen.shutdown_cost)\n\n    # Create new operation cost with multi-start stages\n    op_cost = ThermalGenerationCost(\n        get_variable(base_op_cost),\n        get_fixed(base_op_cost),\n        startup_cost,\n        shutdown_cost,\n    )\n\n    return ThermalMultiStart(;\n        name = get_name(thermal_gen),\n        available = get_available(thermal_gen),\n        status = get_status(thermal_gen),\n        bus = get_bus(thermal_gen),\n        active_power = get_active_power(thermal_gen),\n        reactive_power = get_reactive_power(thermal_gen),\n        rating = get_rating(thermal_gen),\n        prime_mover_type = get_prime_mover_type(thermal_gen),\n        fuel = get_fuel(thermal_gen),\n        active_power_limits = get_active_power_limits(thermal_gen),\n        reactive_power_limits = get_reactive_power_limits(thermal_gen),\n        ramp_limits = get_ramp_limits(thermal_gen),\n        power_trajectory = power_trajectory,\n        time_limits = get_time_limits(thermal_gen),\n        start_time_limits = startup_timelimits,\n        start_types = start_types,\n        operation_cost = op_cost,\n        base_power = get_base_power(thermal_gen),\n        time_at_status = get_time_at_status(thermal_gen),\n        must_run = get_must_run(thermal_gen),\n    )\nend\n\nfunction make_hydro_dispatch(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus::ACBus,\n)\n    @debug \"Creating $(gen.name) as HydroDispatch\" _group = IS.LOG_GROUP_PARSING\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n    ramp_limits = make_ramplimits(gen)\n    time_limits = make_timelimits(gen, :min_up_time, :min_down_time)\n    base_power = gen.base_mva\n    operation_cost = make_cost(HydroGen, data, gen, cost_colnames)\n    hydro_gen = HydroDispatch(;\n        name = gen.name,\n        available = gen.available,\n        bus = bus,\n        active_power = gen.active_power,\n        reactive_power = reactive_power,\n        rating = rating,\n        prime_mover_type = parse_enum_mapping(PrimeMovers, gen.unit_type),\n        active_power_limits = active_power_limits,\n        reactive_power_limits = reactive_power_limits,\n        ramp_limits = ramp_limits,\n        time_limits = time_limits,\n        base_power = base_power,\n        operation_cost = operation_cost,\n    )\n    return hydro_gen\nend\n\nfunction _make_hydro_reservoirs(\n    data::PowerSystemTableData,\n    gen,\n    gen_storage,\n    tail_required::Bool,\n)\n    if !haskey(data.category_to_df, InputCategory.STORAGE)\n        throw(DataFormatError(\"Storage information must defined in storage.csv\"))\n    end\n\n    head_dict = gen_storage[\"head\"]\n    if !haskey(head_dict, gen.name)\n        throw(\n            DataFormatError(\"Cannot find head storage for $(gen.name) in storage.csv\"),\n        )\n    end\n    reservoir_data = head_dict[gen.name]\n    head_reservoir = HydroReservoir(;\n        name = string(reservoir_data.name, \"_head\"),\n        available = reservoir_data.available,\n        storage_level_limits = (\n            min = reservoir_data.min_storage_capacity,\n            max = reservoir_data.storage_capacity,\n        ),\n        initial_level = reservoir_data.energy_level,\n        spillage_limits = nothing,\n        inflow = 1.0,\n        outflow = 1.0,\n        level_targets = reservoir_data.storage_target,\n        intake_elevation = 0.0,\n        head_to_volume_factor = LinearCurve(1.0),\n        operation_cost = HydroReservoirCost(),\n        level_data_type = ReservoirDataType.ENERGY,\n    )\n    tail_dict = gen_storage[\"tail\"]\n    if !haskey(tail_dict, gen.name) && tail_required\n        throw(\n            DataFormatError(\"Cannot find tail storage for $(gen.name) in storage.csv\"),\n        )\n    elseif !haskey(tail_dict, gen.name) && !tail_required\n        tail_reservoir = nothing\n    else\n        reservoir_data = tail_dict[gen.name]\n        tail_reservoir = HydroReservoir(;\n            name = string(reservoir_data.name, \"_tail\"),\n            available = reservoir_data.available,\n            storage_level_limits = (\n                min = reservoir_data.min_storage_capacity,\n                max = reservoir_data.storage_capacity,\n            ),\n            initial_level = reservoir_data.energy_level,\n            spillage_limits = nothing,\n            inflow = 1.0,\n            outflow = 1.0,\n            level_targets = reservoir_data.storage_target,\n            intake_elevation = 0.0,\n            head_to_volume_factor = LinearCurve(1.0),\n            operation_cost = HydroReservoirCost(),\n            level_data_type = ReservoirDataType.ENERGY,\n        )\n    end\n    return head_reservoir, tail_reservoir\nend\n\nfunction make_hydro_turbine(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus::ACBus,\n    gen_storage::Dict{String, Any},\n)\n    @debug \"Creating $(gen.name) as HydroTurbine\" _group = IS.LOG_GROUP_PARSING\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n    ramp_limits = make_ramplimits(gen)\n    time_limits = make_timelimits(gen, :min_up_time, :min_down_time)\n    base_power = gen.base_mva\n    operation_cost = make_cost(HydroGen, data, gen, cost_colnames)\n    head_reservoir, tail_reservoir = _make_hydro_reservoirs(data, gen, gen_storage, false)\n    if isnothing(tail_reservoir)\n        reservoirs = [head_reservoir]\n    else\n        reservoirs = [head_reservoir, tail_reservoir]\n    end\n    hydro_gen = HydroTurbine(;\n        name = gen.name,\n        available = gen.available,\n        bus = bus,\n        active_power = gen.active_power,\n        reactive_power = reactive_power,\n        rating = rating,\n        active_power_limits = active_power_limits,\n        reactive_power_limits = reactive_power_limits,\n        base_power = base_power,\n        operation_cost = operation_cost,\n        ramp_limits = ramp_limits,\n        time_limits = time_limits,\n        outflow_limits = nothing,\n    )\n    set_downstream_turbines!(reservoirs[1], [hydro_gen])\n    if !isnothing(tail_reservoir)\n        set_upstream_turbines!(reservoirs[2], [hydro_gen])\n    end\n    return hydro_gen, reservoirs\nend\n\nfunction make_hydro_pump_storage(\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus::ACBus,\n    gen_storage,\n)\n    @debug \"Creating $(gen.name) as HydroPumpTurbine\" _group = IS.LOG_GROUP_PARSING\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n    ramp_limits = make_ramplimits(gen)\n    time_limits = make_timelimits(gen, :min_up_time, :min_down_time)\n    base_power = gen.base_mva\n    head_reservoir, tail_reservoir = make_hydro_reservoirs(data, gen, gen_storage, true)\n    operation_cost = make_cost(HydroGen, data, gen, cost_colnames)\n    pump_active_power_limits = (\n        min = gen.pump_active_power_limits_min,\n        max = gen.pump_active_power_limits_max,\n    )\n    (pump_reactive_power, pump_reactive_power_limits) = make_reactive_params(\n        gen;\n        powerfield = :pump_reactive_power,\n        minfield = :pump_reactive_power_limits_min,\n        maxfield = :pump_reactive_power_limits_max,\n    )\n\n    pump_rating = calculate_gen_rating(\n        pump_active_power_limits,\n        pump_reactive_power_limits,\n        1.0,\n    )\n    pump_ramp_limits = make_ramplimits(\n        gen;\n        ramplimcol = :pump_ramp_limits,\n        rampupcol = :pump_ramp_up,\n        rampdncol = :pump_ramp_down,\n    )\n    pump_time_limits = make_timelimits(gen, :pump_min_up_time, :pump_min_down_time)\n\n    hydro_gen = HydroPumpTurbine(;\n        name = gen.name,\n        available = gen.available,\n        bus = bus,\n        active_power = gen.active_power,\n        reactive_power = reactive_power,\n        rating = rating,\n        active_power_limits = active_power_limits,\n        rating_pump = pump_rating,\n        reactive_power_limits = pump_reactive_power_limits,\n        active_power_limits_pump = pump_active_power_limits,\n        outflow_limits = nothing,\n        head_reservoir = head_reservoir,\n        tail_reservoir = tail_reservoir,\n        power_house_elevation = 0.0,\n        ramp_limits_pump = pump_ramp_limits,\n        time_limits_pump = pump_time_limits,\n        base_power = base_power,\n        operation_cost = operation_cost,\n    )\n    set_downstream_turbines!(head_reservoir, [hydro_gen])\n    set_upstream_turbines!(tail_reservoir, [hydro_gen])\n    return hydro_gen, [head_reservoir, tail_reservoir]\nend\n\nfunction make_renewable_generator(\n    gen_type,\n    data::PowerSystemTableData,\n    gen,\n    cost_colnames,\n    bus::ACBus,\n)\n    @debug \"Making RenewableGen\" _group = IS.LOG_GROUP_PARSING gen.name\n    generator = nothing\n    active_power_limits =\n        (min = gen.active_power_limits_min, max = gen.active_power_limits_max)\n    (reactive_power, reactive_power_limits) = make_reactive_params(gen)\n    rating = calculate_gen_rating(active_power_limits, reactive_power_limits, 1.0)\n    base_power = gen.base_mva\n    operation_cost = make_cost(RenewableGen, data, gen, cost_colnames)\n\n    if gen_type == RenewableDispatch\n        @debug \"Creating $(gen.name) as RenewableDispatch\" _group = IS.LOG_GROUP_PARSING\n        generator = RenewableDispatch(;\n            name = gen.name,\n            available = gen.available,\n            bus = bus,\n            active_power = gen.active_power,\n            reactive_power = reactive_power,\n            rating = rating,\n            prime_mover_type = parse_enum_mapping(PrimeMovers, gen.unit_type),\n            reactive_power_limits = reactive_power_limits,\n            power_factor = gen.power_factor,\n            operation_cost = operation_cost,\n            base_power = base_power,\n        )\n    elseif gen_type == RenewableNonDispatch\n        @debug \"Creating $(gen.name) as RenewableNonDispatch\" _group = IS.LOG_GROUP_PARSING\n        generator = RenewableNonDispatch(;\n            name = gen.name,\n            available = gen.available,\n            bus = bus,\n            active_power = gen.active_power,\n            reactive_power = reactive_power,\n            rating = rating,\n            prime_mover_type = parse_enum_mapping(PrimeMovers, gen.unit_type),\n            power_factor = gen.power_factor,\n            base_power = base_power,\n        )\n    else\n        error(\"Unsupported type $gen_type\")\n    end\n\n    return generator\nend\n\nfunction make_storage(data::PowerSystemTableData, gen, bus, storage)\n    @debug \"Making Storage\" _group = IS.LOG_GROUP_PARSING storage.name\n    input_active_power_limits = (\n        min = storage.input_active_power_limit_min,\n        max = storage.input_active_power_limit_max,\n    )\n    output_active_power_limits = (\n        min = storage.output_active_power_limit_min,\n        max = if isnothing(storage.output_active_power_limit_max)\n            gen.active_power_limits_max\n        else\n            storage.output_active_power_limit_max\n        end,\n    )\n    efficiency = (in = storage.input_efficiency, out = storage.output_efficiency)\n    (reactive_power, reactive_power_limits) = make_reactive_params(storage)\n    battery = EnergyReservoirStorage(;\n        name = gen.name,\n        available = storage.available,\n        bus = bus,\n        prime_mover_type = parse_enum_mapping(PrimeMovers, gen.unit_type),\n        storage_technology_type = StorageTech.OTHER_CHEM,\n        storage_capacity = storage.storage_capacity,\n        storage_level_limits = (\n            min = storage.min_storage_capacity / storage.storage_capacity,\n            max = 1.0,\n        ),\n        initial_storage_capacity_level = storage.energy_level / storage.storage_capacity,\n        rating = storage.rating,\n        active_power = storage.active_power,\n        input_active_power_limits = input_active_power_limits,\n        output_active_power_limits = output_active_power_limits,\n        efficiency = efficiency,\n        reactive_power = reactive_power,\n        reactive_power_limits = reactive_power_limits,\n        base_power = storage.base_power,\n        operation_cost = StorageCost(),\n    )\n\n    return battery\nend\n\nconst CATEGORY_STR_TO_COMPONENT = Dict{String, DataType}(\n    \"ACBus\" => ACBus,\n    \"Generator\" => Generator,\n    \"Reserve\" => Service,\n    \"LoadZone\" => LoadZone,\n    \"ElectricLoad\" => ElectricLoad,\n    \"Storage\" => Storage,\n)\n\nfunction _get_component_type_from_category(category::AbstractString)\n    component_type = get(CATEGORY_STR_TO_COMPONENT, category, nothing)\n    if isnothing(component_type)\n        throw(DataFormatError(\"unsupported category=$category\"))\n    end\n\n    return component_type\nend\n\nfunction _read_config_file(file_path::String)\n    return open(file_path) do io\n        data = YAML.load(io)\n        # Replace keys with enums.\n        config_data = Dict{InputCategory, Vector}()\n        for (key, val) in data\n            # TODO: need to change user_descriptors.yaml to use reserve instead.\n            if key == \"reserves\"\n                key = \"reserve\"\n            end\n            config_data[get_enum_value(InputCategory, key)] = val\n        end\n        return config_data\n    end\nend\n\n\"\"\"Stores user-customized information for required dataframe columns.\"\"\"\nstruct _FieldInfo\n    name::String\n    custom_name::String\n    per_unit_conversion::NamedTuple{\n        (:From, :To, :Reference),\n        Tuple{UnitSystem, UnitSystem, String},\n    }\n    unit_conversion::Union{NamedTuple{(:From, :To), Tuple{String, String}}, Nothing}\n    default_value::Any\n    # TODO unit, value ranges and options\nend\n\nfunction _get_field_infos(data::PowerSystemTableData, category::InputCategory, df_names)\n    if !haskey(data.user_descriptors, category)\n        throw(DataFormatError(\"Invalid category=$category\"))\n    end\n\n    if !haskey(data.descriptors, category)\n        throw(DataFormatError(\"Invalid category=$category\"))\n    end\n\n    # Cache whether PowerSystems uses a column's values as system-per-unit.\n    # The user's descriptors indicate that the raw data is already system-per-unit or not.\n    per_unit = Dict{String, IS.UnitSystem}()\n    unit = Dict{String, Union{String, Nothing}}()\n    custom_names = Dict{String, String}()\n    for descriptor in data.user_descriptors[category]\n        custom_name = descriptor[\"custom_name\"]\n        if descriptor[\"custom_name\"] in df_names\n            per_unit[descriptor[\"name\"]] = get_enum_value(\n                IS.UnitSystem,\n                get(descriptor, \"unit_system\", \"NATURAL_UNITS\"),\n            )\n            unit[descriptor[\"name\"]] = get(descriptor, \"unit\", nothing)\n            custom_names[descriptor[\"name\"]] = custom_name\n        else\n            @warn \"User-defined column name $custom_name is not in dataframe.\"\n        end\n    end\n\n    fields = Vector{_FieldInfo}()\n\n    for item in data.descriptors[category]\n        name = item[\"name\"]\n        item_unit_system =\n            get_enum_value(IS.UnitSystem, get(item, \"unit_system\", \"NATURAL_UNITS\"))\n        per_unit_reference = get(item, \"base_reference\", \"base_power\")\n        default_value = get(item, \"default_value\", \"required\")\n        if default_value == \"system_base_power\"\n            default_value = data.base_power\n        end\n\n        if name in keys(custom_names)\n            custom_name = custom_names[name]\n\n            if item_unit_system == IS.UnitSystem.NATURAL_UNITS &&\n               per_unit[name] != IS.UnitSystem.NATURAL_UNITS\n                throw(DataFormatError(\"$name cannot be defined as $(per_unit[name])\"))\n            end\n\n            pu_conversion = (\n                From = per_unit[name],\n                To = item_unit_system,\n                Reference = per_unit_reference,\n            )\n\n            expected_unit = get(item, \"unit\", nothing)\n            if !isnothing(expected_unit) &&\n               !isnothing(unit[name]) &&\n               expected_unit != unit[name]\n                unit_conversion = (From = unit[name], To = expected_unit)\n            else\n                unit_conversion = nothing\n            end\n        else\n            custom_name = name\n            pu_conversion = (\n                From = item_unit_system,\n                To = item_unit_system,\n                Reference = per_unit_reference,\n            )\n            unit_conversion = nothing\n        end\n\n        push!(\n            fields,\n            _FieldInfo(name, custom_name, pu_conversion, unit_conversion, default_value),\n        )\n    end\n\n    return fields\nend\n\n\"\"\"Reads values from dataframe row and performs necessary conversions.\"\"\"\nfunction _read_data_row(data::PowerSystemTableData, row, field_infos; na_to_nothing = true)\n    fields = Vector{String}()\n    vals = Vector()\n    for field_info in field_infos\n        if field_info.custom_name in names(row)\n            value = row[field_info.custom_name]\n        else\n            value = field_info.default_value\n            value == \"required\" && throw(DataFormatError(\"$(field_info.name) is required\"))\n            @debug \"Column $(field_info.custom_name) doesn't exist in df, enabling use of default value of $(field_info.default_value)\" _group =\n                IS.LOG_GROUP_PARSING maxlog = 1\n        end\n        if ismissing(value)\n            throw(DataFormatError(\"$(field_info.custom_name) value missing\"))\n        end\n        if na_to_nothing && value == \"NA\"\n            value = nothing\n        end\n\n        if !isnothing(value)\n            if field_info.per_unit_conversion.From == IS.UnitSystem.NATURAL_UNITS &&\n               field_info.per_unit_conversion.To == IS.UnitSystem.SYSTEM_BASE\n                @debug \"convert to $(field_info.per_unit_conversion.To)\" _group =\n                    IS.LOG_GROUP_PARSING field_info.custom_name\n                value = value isa AbstractString ? tryparse(Float64, value) : value\n                value = data.base_power == 0.0 ? 0.0 : value / data.base_power\n            elseif field_info.per_unit_conversion.From == IS.UnitSystem.NATURAL_UNITS &&\n                   field_info.per_unit_conversion.To == IS.UnitSystem.DEVICE_BASE\n                reference_idx = findfirst(\n                    x -> x.name == field_info.per_unit_conversion.Reference,\n                    field_infos,\n                )\n                isnothing(reference_idx) && throw(\n                    DataFormatError(\n                        \"$(field_info.per_unit_conversion.Reference) not found in table with $(field_info.custom_name)\",\n                    ),\n                )\n                reference_info = field_infos[reference_idx]\n                @debug \"convert to $(field_info.per_unit_conversion.To) using $(reference_info.custom_name)\" _group =\n                    IS.LOG_GROUP_PARSING field_info.custom_name maxlog = 1\n                reference_value =\n                    get(row, reference_info.custom_name, reference_info.default_value)\n                reference_value == \"required\" && throw(\n                    DataFormatError(\n                        \"$(reference_info.name) is required for p.u. conversion\",\n                    ),\n                )\n                value = value isa AbstractString ? tryparse(Float64, value) : value\n                value = reference_value == 0.0 ? 0.0 : value / reference_value\n            elseif field_info.per_unit_conversion.From != field_info.per_unit_conversion.To\n                throw(\n                    DataFormatError(\n                        \"conversion not supported from $(field_info.per_unit_conversion.From) to $(field_info.per_unit_conversion.To) for $(field_info.custom_name)\",\n                    ),\n                )\n            end\n        else\n            @debug \"$(field_info.custom_name) is nothing\" _group = IS.LOG_GROUP_PARSING maxlog =\n                1\n        end\n\n        # TODO: need special handling for units\n        if !isnothing(field_info.unit_conversion)\n            @debug \"convert units\" _group = IS.LOG_GROUP_PARSING field_info.custom_name maxlog =\n                1\n            value = convert_units!(value, field_info.unit_conversion)\n        end\n        # TODO: validate ranges and option lists\n        push!(fields, field_info.name)\n        push!(vals, value)\n    end\n    return NamedTuple{Tuple(Symbol.(fields))}(vals)\nend\n"
  },
  {
    "path": "src/parsers/powerflowdata_data.jl",
    "content": "\"\"\"Container for data parsed by PowerFlowData\"\"\"\nstruct PowerFlowDataNetwork\n    data::PowerFlowData.Network\nend\n\n\"\"\"\nConstructs PowerFlowDataNetwork from a raw file.\nCurrently Supports PSSE data files v30, v32 and v33\n\"\"\"\nfunction PowerFlowDataNetwork(file::Union{String, IO}; kwargs...)\n    return PowerFlowDataNetwork(PowerFlowData.parse_network(file))\nend\n\n\"\"\"\nConstructs a System from PowerModelsData.\n\n# Arguments\n- `pfd_data::Union{PowerFlowDataNetwork, Union{String, IO}}`: PowerModels data object or supported\nload flow case (*.m, *.raw)\n\n# Keyword arguments\n- `ext::Dict`: Contains user-defined parameters. Should only contain standard types.\n- `runchecks::Bool`: Run available checks on input fields and when add_component! is called.\n  Throws InvalidValue if an error is found.\n- `time_series_in_memory::Bool=false`: Store time series data in memory instead of HDF5.\n- `config_path::String`: specify path to validation config file\n- `pm_data_corrections::Bool=true` : Run the PowerModels data corrections (aka :validate in PowerModels)\n- `import_all:Bool=false` : Import all fields from PTI files\n\n# Examples\n```julia\nsys = System(\n    pm_data, config_path = \"ACTIVSg25k_validation.json\",\n    bus_name_formatter = x->string(x[\"name\"]*\"-\"*string(x[\"index\"])),\n    load_name_formatter = x->strip(join(x[\"source_id\"], \"_\"))\n)\n```\n\"\"\"\nfunction System(net_data::PowerFlowDataNetwork; kwargs...)\n    runchecks = get(kwargs, :runchecks, true)\n    data = net_data.data\n    if length(data.buses) < 1\n        throw(DataFormatError(\"There are no buses in this file.\"))\n    end\n\n    @info \"Constructing System from PowerFlowData version v$(data.caseid.rev)\"\n\n    if isa(data.caseid.sbase, Missing)\n        error(\"Base power not specified in .raw file. Data parsing can not continue\")\n    end\n\n    if isa(data.caseid.basfrq, Missing)\n        @warn \"Frequency value missing from .raw file. Using default 60 Hz\"\n        frequency = 60.0\n    else\n        frequency = data.caseid.basfrq\n    end\n\n    sys = System(data.caseid.sbase; frequency = frequency, kwargs...)\n    bus_number_to_bus = read_bus!(sys, data.buses, data; kwargs...)\n    read_loads!(sys, data.loads, data.caseid.sbase, bus_number_to_bus; kwargs...)\n    read_gen!(sys, data.generators, data.caseid.sbase, bus_number_to_bus; kwargs...)\n    read_branch!(\n        sys,\n        data.branches,\n        data.caseid.sbase,\n        bus_number_to_bus;\n        kwargs...,\n    )\n    read_branch!(sys, data.transformers, data.caseid.sbase, bus_number_to_bus; kwargs...)\n    read_shunt!(sys, data.fixed_shunts, data.caseid.sbase, bus_number_to_bus; kwargs...)\n    read_switched_shunt!(\n        sys,\n        data.switched_shunts,\n        data.caseid.sbase,\n        bus_number_to_bus;\n        kwargs...,\n    )\n    read_dcline!(\n        sys,\n        data.two_terminal_dc,\n        data.caseid.sbase,\n        bus_number_to_bus;\n        kwargs...,\n    )\n    read_dcline!(\n        sys,\n        data.multi_terminal_dc,\n        data.caseid.sbase,\n        bus_number_to_bus;\n        kwargs...,\n    )\n\n    read_dcline!(\n        sys,\n        data.vsc_dc,\n        data.caseid.sbase,\n        bus_number_to_bus;\n        kwargs...,\n    )\n\n    if runchecks\n        check(sys)\n    end\n    return sys\nend\n\nfunction read_bus!(\n    sys::System,\n    buses::PowerFlowData.Buses33,\n    data::PowerFlowData.Network;\n    kwargs...,\n)\n    bus_number_to_bus = Dict{Int, ACBus}()\n    bus_types = instances(ACBusTypes)\n\n    for ix in eachindex(buses.i)\n        # d id the data dict for each bus\n        # d_key is bus key\n        bus_name = strip(buses.name[ix]) * \"_$(buses.i[ix])\" * \"_$(buses.ide[ix])\"\n        has_component(ACBus, sys, bus_name) && throw(\n            DataFormatError(\n                \"Found duplicate bus names of $bus_name, consider formatting names with `bus_name_formatter` kwarg\",\n            ),\n        )\n        bus_number = buses.i[ix]\n        if isempty(data.area_interchanges)\n            area_name = string(buses.area[ix])\n            @debug \"File doesn't contain area names\"\n        else\n            area_ix = findfirst(data.area_interchanges.i .== buses.area[ix])\n            area_name = data.area_interchanges.arname[area_ix]\n        end\n\n        area = get_component(Area, sys, area_name)\n        if isnothing(area)\n            area = Area(area_name)\n            add_component!(sys, area; skip_validation = SKIP_PM_VALIDATION)\n        end\n\n        # TODO: LoadZones need to be created and populated here\n        if isempty(data.zones)\n            zone_name = string(buses.zone[ix])\n            @debug \"File doesn't contain load zones\"\n        else\n            zone_ix = findfirst(data.zones.i .== buses.zone[ix])\n            zone_name = \"$(data.zones.zoname[zone_ix])_$(data.zones.i[zone_ix])\"\n        end\n        zone = get_component(LoadZone, sys, zone_name)\n        if isnothing(zone)\n            zone = LoadZone(zone_name, 0.0, 0.0)\n            add_component!(sys, zone; skip_validation = SKIP_PM_VALIDATION)\n        end\n\n        zone = get_component(LoadZone, sys, zone_name)\n        if isnothing(zone)\n            zone = LoadZone(zone_name, 0.0, 0.0)\n            add_component!(sys, zone; skip_validation = SKIP_PM_VALIDATION)\n        end\n\n        bus = ACBus(\n            bus_number,\n            bus_name,\n            true,\n            bus_types[buses.ide[ix]],\n            clamp(buses.va[ix] * (π / 180), -π / 2, π / 2),\n            buses.vm[ix],\n            (min = buses.nvlo[ix], max = buses.nvhi[ix]),\n            buses.basekv[ix],\n            area,\n            zone,\n        )\n\n        bus_number_to_bus[bus_number] = bus\n\n        add_component!(sys, bus; skip_validation = SKIP_PM_VALIDATION)\n    end\n    # TODO: Checking for surplus Areas or LoadZones in the data which don't get populated in the sys above\n    # but are available in the raw file\n    if ~isempty(data.area_interchanges)\n        for area_name in data.area_interchanges.arname\n            area = get_component(Area, sys, area_name)\n            if isnothing(area)\n                area = Area(area_name)\n                add_component!(sys, area; skip_validation = SKIP_PM_VALIDATION)\n            end\n        end\n    end\n\n    if ~isempty(data.zones)\n        for (i, name) in zip(data.zones.i, data.zones.zoname)\n            zone_name = \"$(name)_$(i)\"\n            zone = get_component(LoadZone, sys, zone_name)\n            if isnothing(zone)\n                zone = LoadZone(zone_name, 0.0, 0.0)\n                add_component!(sys, zone; skip_validation = SKIP_PM_VALIDATION)\n            end\n        end\n    end\n    return bus_number_to_bus\nend\n\nfunction read_bus!(\n    sys::System,\n    buses::PowerFlowData.Buses30,\n    data::PowerFlowData.Network;\n    kwargs...,\n)\n    bus_number_to_bus = Dict{Int, ACBus}()\n\n    bus_types = instances(ACBusTypes)\n\n    for ix in 1:length(buses)\n        # d id the data dict for each bus\n        # d_key is bus key\n        bus_name = strip(buses.name[ix]) * \"_$(buses.i[ix])\" * \"_$(buses.ide[ix])\"\n        has_component(ACBus, sys, bus_name) && throw(\n            DataFormatError(\n                \"Found duplicate bus names of $bus_name, consider formatting names with `bus_name_formatter` kwarg\",\n            ),\n        )\n        bus_number = buses.i[ix]\n        if isempty(data.area_interchanges)\n            area_name = string(buses.area[ix])\n            @debug \"File doesn't contain area names\"\n        else\n            area_ix = data.area_interchanges.i .== buses.area[ix]\n            if all(.!area_ix)\n                error(\"Area numbering is incorrectly specified in PSSe file\")\n            end\n            area_name = first(data.area_interchanges.arname[area_ix])\n        end\n        area = get_component(Area, sys, area_name)\n        if isnothing(area)\n            area = Area(area_name)\n            add_component!(sys, area; skip_validation = SKIP_PM_VALIDATION)\n        end\n\n        # TODO: LoadZones need to be created and populated here\n\n        bus = ACBus(\n            bus_number,\n            bus_name,\n            true,\n            bus_types[buses.ide[ix]],\n            clamp(buses.va[ix] * (π / 180), -π / 2, π / 2),\n            buses.vm[ix],\n            nothing, # PSSe 30 data doesn't have magnitude limits\n            buses.basekv[ix],\n            area,\n        )\n\n        bus_number_to_bus[bus_number] = bus\n\n        add_component!(sys, bus; skip_validation = SKIP_PM_VALIDATION)\n\n        if buses.bl[ix] > 0 || buses.gl[ix] > 0\n            shunt = FixedAdmittance(bus_name, true, bus, buses.gl[ix] + 1im * buses.bl[ix])\n            add_component!(sys, shunt; skip_validation = SKIP_PM_VALIDATION)\n        end\n    end\n\n    return bus_number_to_bus\nend\n\nfunction read_loads!(\n    sys::System,\n    loads::PowerFlowData.Loads,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    if isempty(loads)\n        @error \"There are no loads in this file\"\n        return\n    end\n    for ix in eachindex(loads.i)\n        bus = bus_number_to_bus[loads.i[ix]]\n        load_name = \"load-$(get_name(bus))~$(loads.id[ix])\"\n        if has_component(StandardLoad, sys, load_name)\n            throw(DataFormatError(\"Found duplicate load names of $(load_name)\"))\n        end\n\n        load = StandardLoad(;\n            name = load_name,\n            available = loads.status[ix],\n            bus = bus,\n            constant_active_power = loads.pl[ix] / sys_mbase,\n            constant_reactive_power = loads.ql[ix] / sys_mbase,\n            impedance_active_power = loads.yp[ix] / sys_mbase,\n            impedance_reactive_power = loads.yq[ix] / sys_mbase,\n            current_active_power = loads.ip[ix] / sys_mbase,\n            current_reactive_power = loads.iq[ix] / sys_mbase,\n            max_constant_active_power = loads.pl[ix] / sys_mbase,\n            max_constant_reactive_power = loads.ql[ix] / sys_mbase,\n            max_impedance_active_power = loads.yp[ix] / sys_mbase,\n            max_impedance_reactive_power = loads.yq[ix] / sys_mbase,\n            max_current_active_power = loads.ip[ix] / sys_mbase,\n            max_current_reactive_power = loads.iq[ix] / sys_mbase,\n            base_power = sys_mbase,\n        )\n\n        add_component!(sys, load; skip_validation = SKIP_PM_VALIDATION)\n    end\n    # Populate Areas and LoadZones with peak active and reactive power\n    areas = get_components(Area, sys)\n    if ~isnothing(areas)\n        for area in areas\n            area_comps = get_components_in_aggregation_topology(StandardLoad, sys, area)\n            if (isempty(area_comps))\n                set_peak_active_power!(area, 0.0)\n                set_peak_reactive_power!(area, 0.0)\n            else\n                set_peak_active_power!(\n                    area,\n                    sum(get.(get_ext.(area_comps), \"active_power_load\", 0.0)),\n                )\n                set_peak_reactive_power!(\n                    area,\n                    sum(get.(get_ext.(area_comps), \"reactive_power_load\", 0.0)),\n                )\n            end\n        end\n    end\n    zones = get_components(LoadZone, sys)\n    if ~isnothing(zones)\n        for zone in zones\n            zone_comps = get_components_in_aggregation_topology(StandardLoad, sys, zone)\n            if (isempty(zone_comps))\n                set_peak_active_power!(zone, 0.0)\n                set_peak_reactive_power!(zone, 0.0)\n            else\n                set_peak_active_power!(\n                    zone,\n                    sum(get.(get_ext.(zone_comps), \"active_power_load\", 0.0)),\n                )\n                set_peak_reactive_power!(\n                    zone,\n                    sum(get.(get_ext.(zone_comps), \"reactive_power_load\", 0.0)),\n                )\n            end\n        end\n    end\n    return nothing\nend\n\nfunction _get_active_power_limits(\n    pt::Float64,\n    pb::Float64,\n    machine_base::Float64,\n    system_base::Float64,\n)\n    min_p = 0.0\n    if pb < 0.0\n        @info \"Min power in dataset is negative, active_power_limits minimum set to 0.0\"\n    else\n        min_p = pb\n    end\n\n    if machine_base != system_base && pt >= machine_base\n        @info \"Max active power limit is $(pt/machine_base) than the generator base. Check the data\"\n    end\n\n    return (min = min_p / machine_base, max = pt / machine_base)\nend\n\nfunction read_gen!(\n    sys::System,\n    gens::PowerFlowData.Generators,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading generator data\"\n\n    if isempty(gens)\n        @error \"There are no generators in this file\"\n        return\n    end\n\n    for ix in eachindex(gens.i)\n        bus = get(bus_number_to_bus, gens.i[ix], nothing)\n        if isnothing(bus)\n            error(\"Incorrect bus id for generator $(gens.i[ix])-$(gens.id[ix])\")\n        end\n\n        gen_name = \"gen-$(get_name(bus))~$(gens.id[ix])\"\n        if has_component(ThermalStandard, sys, gen_name)\n            throw(DataFormatError(\"Found duplicate load names of $(gen_name)\"))\n        end\n        ireg_bus_num = gens.ireg[ix] == 0 ? gens.i[ix] : gens.ireg[ix]\n\n        thermal_gen = ThermalStandard(;\n            name = gen_name,\n            available = gens.stat[ix] > 0 ? true : false,\n            status = gens.stat[ix] > 0 ? true : false,\n            bus = bus,\n            active_power = gens.pg[ix] / gens.mbase[ix],\n            reactive_power = gens.qg[ix] / gens.mbase[ix],\n            active_power_limits = _get_active_power_limits(\n                gens.pt[ix],\n                gens.pb[ix],\n                gens.mbase[ix],\n                sys_mbase,\n            ),\n            reactive_power_limits = (\n                min = gens.qb[ix] / sys_mbase,\n                max = gens.qt[ix] / sys_mbase,\n            ),\n            base_power = gens.mbase[ix],\n            rating = gens.mbase[ix],\n            ramp_limits = nothing,\n            time_limits = nothing,\n            operation_cost = ThermalGenerationCost(nothing),\n            ext = Dict(\n                \"IREG\" => ireg_bus_num,\n                \"WMOD\" => gens.wmod[ix],\n                \"WPF\" => gens.wpf[ix],\n            ),\n        )\n\n        add_component!(sys, thermal_gen; skip_validation = SKIP_PM_VALIDATION)\n    end\n    return nothing\nend\n\nfunction read_branch!(\n    sys::System,\n    branches::PowerFlowData.Branches30,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading line data\"\n\n    if isempty(branches)\n        @error \"There are no lines in this file\"\n        return\n    end\n\n    for ix in eachindex(branches.i)\n        if branches.i[ix] < 0\n            i_ix = abs(branches.i[ix])\n            @warn \"Branch index $(branches.i[ix]) corrected to $i_ix\"\n        end\n\n        if branches.j[ix] < 0\n            j_ix = abs(branches.i[ix])\n            @warn \"Branch index $(branches.j[ix]) corrected to $j_ix\"\n        end\n\n        bus_from = bus_number_to_bus[abs(branches.i[ix])]\n        bus_to = bus_number_to_bus[abs(branches.j[ix])]\n        branch_name = \"line-$(get_name(bus_from))-$(get_name(bus_to))-$(branches.ckt[ix])\"\n        max_rate = max(branches.rate_a[ix], branches.rate_b[ix], branches.rate_c[ix])\n        if max_rate == 0.0\n            max_rate = abs(1 / (branches.r[ix] + 1im * branches.x[ix])) * sys_mbase\n        end\n        branch = Line(;\n            name = branch_name,\n            available = branches.st[ix] > 0 ? true : false,\n            active_power_flow = 0.0,\n            reactive_power_flow = 0.0,\n            arc = Arc(bus_from, bus_to),\n            r = branches.r[ix],\n            x = branches.x[ix],\n            b = (from = branches.bi[ix], to = branches.bj[ix]),\n            angle_limits = (min = -π / 2, max = π / 2),\n            rating = max_rate,\n        )\n\n        add_component!(sys, branch; skip_validation = SKIP_PM_VALIDATION)\n    end\n\n    return nothing\nend\n\nfunction read_branch!(\n    sys::System,\n    branches::PowerFlowData.Branches33,\n    sys_mbase::Float64,\n    rating_flag::Int8,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading line data\"\n\n    if isempty(branches)\n        @error \"There are no lines in this file\"\n        return\n    end\n\n    for ix in eachindex(branches.i)\n        bus_from = bus_number_to_bus[branches.i[ix]]\n        bus_to = bus_number_to_bus[branches.j[ix]]\n        branch_name = \"line-$(get_name(bus_from))-$(get_name(bus_to))~$(branches.ckt[ix])\"\n\n        max_rate = max(branches.rate_a[ix], branches.rate_b[ix], branches.rate_c[ix])\n\n        if get_base_voltage(bus_from) != get_base_voltage(bus_to)\n            @warn(\"bad line data $branch_name. Transforming this Line to Transformer2W.\")\n            # Method needed for NTPS to make this data into a transformer\n            transformer_name = \"transformer-$(get_name(bus_from))-$(get_name(bus_to))~$(branches.ckt[ix])\"\n            transformer = Transformer2W(;\n                name = transformer_name,\n                available = branches.st[ix] > 0 ? true : false,\n                active_power_flow = 0.0,\n                reactive_power_flow = 0.0,\n                arc = Arc(bus_from, bus_to),\n                r = branches.r[ix],\n                x = branches.x[ix],\n                primary_shunt = 0.0,\n                winding_group_number = WindingGroupNumber(0),\n                rating = max_rate,\n                base_power = get_base_power(sys), # add system base power\n                ext = Dict(\n                    \"line_to_xfr\" => true,\n                ),\n            )\n            add_component!(sys, transformer; skip_validation = SKIP_PM_VALIDATION)\n\n            continue\n        end\n\n        rated_current = 0.0\n        if (rating_flag > 0)\n            rated_current = (max_rate / (sqrt(3) * get_base_voltage(bus_from))) * 10^3\n        end\n\n        branch = Line(;\n            name = branch_name,\n            available = branches.st[ix] > 0 ? true : false,\n            active_power_flow = 0.0,\n            reactive_power_flow = 0.0,\n            arc = Arc(bus_from, bus_to),\n            r = branches.r[ix],\n            x = branches.x[ix],\n            b = (from = branches.bi[ix], to = branches.bj[ix]),\n            angle_limits = (min = -π / 2, max = π / 2),\n            rating = max_rate,\n            ext = Dict(\n                \"length\" => branches.len[ix],\n                \"rated_current(A)\" => rated_current,\n            ),\n        )\n\n        add_component!(sys, branch; skip_validation = SKIP_PM_VALIDATION)\n    end\n\n    return nothing\nend\n\nfunction read_branch!(\n    sys::System,\n    transformers::PowerFlowData.Transformers,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading transformer data\"\n\n    if isempty(transformers)\n        @error \"There are no transformers in this file\"\n        return\n    end\n\n    for ix in eachindex(transformers.i)\n        bus_i = bus_number_to_bus[transformers.i[ix]]\n        bus_j = bus_number_to_bus[transformers.j[ix]]\n        if transformers.k[ix] > 0\n            @error \"Three-winding transformer from PowerFlowData inputs not implemented. Data will be ignored\"\n            continue\n        else\n            to_from_name = \"$(get_name(bus_i))-$(get_name(bus_j))\"\n        end\n\n        if transformers.ang1[ix] != 0\n            @error \"Phase Shifting transformer from PowerFlowData inputs not implemented. Data will be ignored\"\n            continue\n        end\n\n        transformer_name = \"transformer-$to_from_name-$(transformers.ckt[ix])\"\n\n        if !(transformers.cz[ix] in [1, 2, 3])\n            @warn(\n                \"transformer CZ value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CZ\"]), should be 1, 2 or 3\",\n            )\n            transformers.cz[ix] = 1\n        end\n\n        if !(transformers.cw[ix] in [1, 2, 3])\n            @warn(\n                \"transformer CW value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CW\"]), should be 1, 2 or 3\",\n            )\n            transformers.cw[ix] = 1\n        end\n\n        if !(transformers.cm[ix] in [1, 2])\n            @warn(\n                \"transformer CM value outside of valid bounds assuming the default value of 1.  Given $(transformer[\"CM\"]), should be 1 or 2\",\n            )\n            transformers.cm[ix] = 1\n        end\n\n        # Unit Transformations\n        if transformers.cz[ix] == 1  # \"for resistance and reactance in pu on system MVA base and winding voltage base\"\n            br_r, br_x = transformers.r1_2[ix], transformers.x1_2[ix]\n        else  # NOT \"for resistance and reactance in pu on system MVA base and winding voltage base\"\n            if transformers.cz[ix] == 3  # \"for transformer load loss in watts and impedance magnitude in pu on a specified MVA base and winding voltage base.\"\n                br_r = 1e-6 * transformers.r1_2[ix] / transformers.sbase1_2[ix]\n                br_x = sqrt(transformers.x1_2[ix]^2 - br_r^2)\n            else\n                br_r, br_x = transformers.r1_2[ix], transformers.x1_2[ix]\n            end\n            per_unit_factor =\n                (\n                    transformers.nomv1[ix]^2 /\n                    get_base_voltage(bus_i)^2\n                ) * (sys_mbase / transformers.sbase1_2[ix])\n            if per_unit_factor == 0\n                @warn \"Per unit conversion for transformer $to_from_name couldn't be done, assuming system base instead. Check field NOMV1 is valid\"\n                per_unit_factor = 1\n            end\n            br_r *= per_unit_factor\n            br_x *= per_unit_factor\n        end\n\n        # Zeq scaling for tap2 (see eq (4.21b) in PROGRAM APPLICATION GUIDE 1 in PSSE installation folder)\n        # Unit Transformations\n        if transformers.cw[ix] == 1  # \"for off-nominal turns ratio in pu of winding bus base voltage\"\n            br_r *= transformers.windv2[ix]^2\n            br_x *= transformers.windv2[ix]^2\n        else  # NOT \"for off-nominal turns ratio in pu of winding bus base voltage\"\n            if transformers.cw[ix] == 2  # \"for winding voltage in kV\"\n                br_r *=\n                    (\n                        transformers.windv2[ix] /\n                        get_base_voltage(bus_j)\n                    )^2\n                br_x *=\n                    (\n                        transformers.windv2[ix] /\n                        get_base_voltage(bus_j)\n                    )^2\n            else  # \"for off-nominal turns ratio in pu of nominal winding voltage, NOMV1, NOMV2 and NOMV3.\"\n                br_r *=\n                    (\n                        transformers.windv2[ix] * (\n                            transformers.nomv2[ix] /\n                            get_base_voltage(bus_j)\n                        )\n                    )^2\n                br_x *=\n                    (\n                        transformers.windv2[ix] * (\n                            transformers.nomv2[ix] /\n                            get_base_voltage(bus_j)\n                        )\n                    )^2\n            end\n        end\n\n        max_rate =\n            max(transformers.rata1[ix], transformers.ratb1[ix], transformers.ratc1[ix])\n\n        tap_value = transformers.windv1[ix] / transformers.windv2[ix]\n\n        # Unit Transformations\n        if transformers.cw[ix] != 1  # NOT \"for off-nominal turns ratio in pu of winding bus base voltage\"\n            tap_value *= get_base_voltage(bus_j) / get_base_voltage(bus_i)\n            if transformers.cw[ix] == 3  # \"for off-nominal turns ratio in pu of nominal winding voltage, NOMV1, NOMV2 and NOMV3.\"\n                tap_value *= transformers.nomv1[ix] / transformers.nomv2[ix]\n            end\n        end\n\n        transformer = TapTransformer(;\n            name = transformer_name,\n            available = transformers.stat[ix] > 0 ? true : false,\n            active_power_flow = 0.0,\n            reactive_power_flow = 0.0,\n            arc = Arc(bus_i, bus_j),\n            r = br_r,\n            x = br_x,\n            tap = tap_value,\n            primary_shunt = transformers.mag2[ix],\n            winding_group_number = WindingGroupNumber(0),\n            base_power = get_base_power(sys),\n            rating = max_rate,\n        )\n        add_component!(sys, transformer; skip_validation = SKIP_PM_VALIDATION)\n    end\n\n    return nothing\nend\n\nfunction read_shunt!(\n    ::System,\n    ::Nothing,\n    ::Float64,\n    ::Dict{Int, ACBus};\n    kwargs...,\n)\n    @debug \"No data for Fixed Shunts\"\n    return\nend\n\nfunction read_shunt!(\n    sys::System,\n    data::PowerFlowData.FixedShunts,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"FixedShunts parsing from PowerFlowData inputs not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_switched_shunt!(\n    sys::System,\n    ::Nothing,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @debug \"No data for Switched Shunts\"\n    return\nend\n\nfunction read_switched_shunt!(\n    sys::System,\n    ::PowerFlowData.SwitchedShunts30,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"SwitchedShunts parsing from PSS/e v30 files not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_switched_shunt!(\n    sys::System,\n    data::PowerFlowData.SwitchedShunts33,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @info \"Reading line data\"\n    @warn \"All switched shunts will be converted to fixed shunts\"\n\n    if isempty(data)\n        @error \"There are no lines in this file\"\n        return\n    end\n\n    @error \"SwitchedShunts parsing from PSS/e v33 files not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    ::Nothing,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @debug \"No data for HVDC Line\"\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::PowerFlowData.TwoTerminalDCLines30,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"TwoTerminalDCLines parsing from PSS/e v30 files not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::PowerFlowData.TwoTerminalDCLines33,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::PowerFlowData.VSCDCLines,\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"VSCDCLines parsing from PSS/e files not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::PowerFlowData.MultiTerminalDCLines{PowerFlowData.DCLineID30},\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"MultiTerminalDCLines parsing from PSS/e files v30 not implemented. Data will be ignored\"\n    return\nend\n\nfunction read_dcline!(\n    sys::System,\n    data::PowerFlowData.MultiTerminalDCLines{PowerFlowData.DCLineID33},\n    sys_mbase::Float64,\n    bus_number_to_bus::Dict{Int, ACBus};\n    kwargs...,\n)\n    @error \"MultiTerminalDCLines parsing from PSS/e files v30 not implemented. Data will be ignored\"\n    return\nend\n"
  },
  {
    "path": "src/parsers/psse_dynamic_data.jl",
    "content": "# Additional constants for repeated structs\nconst TGOV1DU = SteamTurbineGov1\n\nconst GEN_COMPONENT_TABLE =\n    Dict(\"Machine\" => 1, \"Shaft\" => 2, \"AVR\" => 3, \"TurbineGov\" => 4, \"PSS\" => 5)\n\nconst INV_COMPONENT_TABLE = Dict(\n    \"Converter\" => 1,\n    \"ActivePowerControl\" => 2,\n    \"ReactivePowerControl\" => 3,\n    \"InnerControl\" => 4,\n    \"DCSource\" => 5,\n    \"FrequencyEstimator\" => 6,\n    \"Filter\" => 7,\n)\n\n\"\"\"\nParse .dyr file into a dictionary indexed by bus number.\nEach bus number key has a dictionary indexed by component type and id.\n\nComments in .dyr files are not supported (beginning of lines with //).\n\n\"\"\"\nfunction _parse_dyr_file(file::AbstractString)\n    dyr_text = read(file, String)\n    start = 1\n    parsed_values = Dict{Int, Dict}()\n    while start < length(dyr_text)\n        val = findnext('/', dyr_text, start)\n        if isnothing(val)\n            break\n        end\n        text = strip(dyr_text[start:(val - 1)])\n        if !isempty(text)\n            line = replace(text, \"\\'\" => \"\")\n            line = replace(line, \",\" => \" \")\n            val_array = strip.(split(line))\n            bus = parse(Int, val_array[1])\n            model = string(val_array[2])\n            id = string(val_array[3])\n            component_dict = get!(parsed_values, bus, Dict{Tuple{String, String}, Array}())\n            component_dict[(model, id)] = parse.(Float64, val_array[4:end])\n        end\n        start = val + 1\n    end\n    return parsed_values\nend\n\nfunction _parse_input_types(_v, val)\n    # If the parameter is a Float64, then use the value directly as the argument.\n    # Typically uses for the resistance that is not available in .dyr files.\n    if isa(_v, Float64)\n        if isnan(_v)\n            error(\"nan for $(_v)\")\n        end\n        return _v\n        # If the parameter is an Int, then use the integer as the key of the value in the dictionary.\n    elseif isa(_v, Int)\n        return val[_v]\n    elseif _v == \"NaN\"\n        return NaN\n        # If the parameter is a tuple (as a string), then construct the tuple directly.\n    elseif isa(_v, String)\n        #TODO: Generalize n-length tuple\n        m = match(r\"^\\((\\d+)\\s*,\\s*(\\d+)\\)$\", _v)\n        m2 = match(r\"^\\((\\d+)\\s*,\\s*(\\d+),\\s*(\\d+)\\)$\", _v)\n        if m !== nothing\n            _tuple_ix = parse.(Int, m.captures)\n            return Tuple(val[_tuple_ix])\n        elseif m2 !== nothing\n            _tuple_ix = parse.(Int, m2.captures)\n            return Tuple(val[_tuple_ix])\n        else\n            error(\"String $(_v) not recognized for parsing\")\n        end\n    else\n        error(\"invalid input value $val\")\n    end\n    return\nend\n\n\"\"\"\nPopulate arguments in a vector for each dynamic component (except Shafts).\nReturns a vector with the parameter values of the argument of each component.\n\n\"\"\"\nfunction _populate_args(param_map::Vector, val)\n    struct_args = Vector{Any}(undef, length(param_map))\n    _populate_args!(struct_args, param_map, val, \"\")\n    return struct_args\nend\n\nfunction _populate_args!(struct_args, param_map::Vector, val, ::String)\n    for (ix, _v) in enumerate(param_map)\n        parameter_value = _parse_input_types(_v, val)\n        if !all(isnan.(parameter_value))\n            struct_args[ix] = parameter_value\n        end\n    end\n    return\nend\n\nfunction _populate_args!(struct_args, param_dic::Dict, val, id::String)\n    param_map = param_dic[id]\n    _populate_args!(struct_args, param_map, val, id)\n    return\nend\n\n\"\"\"\nCreate a SingleMass shaft struct directly using the parameter mapping.\n\n\"\"\"\nfunction _make_shaft(param_map, val)\n    constructor_shaft =\n        (args...) -> InteractiveUtils.getfield(PowerSystems, :SingleMass)(args...)\n    shaft_args = _populate_args(param_map, val)\n    return constructor_shaft(shaft_args...)\nend\n\nfunction _make_source(g::StaticInjection, r::Float64, x::Float64, sys_base::Float64)\n    # Transform Z_source to System Base\n    machine_base = get_base_power(g)\n    r_sysbase = r * (sys_base / machine_base)\n    x_sysbase = x * (sys_base / machine_base)\n    return Source(;\n        name = get_name(g),\n        available = true,\n        bus = get_bus(g),\n        active_power = get_active_power(g),\n        reactive_power = get_reactive_power(g),\n        R_th = r_sysbase,\n        X_th = x_sysbase,\n    )\nend\n\nfunction _assign_missing_components!(\n    components_dict::Dict,\n    component_table,\n    ::Type{T},\n) where {T <: DynamicGenerator}\n    for va in values(components_dict)\n        if length(va) == length(keys(component_table))\n            if ismissing(va[component_table[\"AVR\"]])\n                va[component_table[\"AVR\"]] = AVRFixed(1.0)\n            end\n            if ismissing(va[component_table[\"TurbineGov\"]])\n                va[component_table[\"TurbineGov\"]] = TGFixed(1.0)\n            end\n            if ismissing(va[component_table[\"PSS\"]])\n                va[component_table[\"PSS\"]] = PSSFixed(0.0)\n            end\n        end\n    end\n    return\nend\n\nfunction _assign_missing_components!(\n    components_dict::Dict,\n    component_table,\n    ::Type{T},\n) where {T <: DynamicInverter}\n    for va in values(components_dict)\n        if length(va) == length(keys(component_table))\n            if ismissing(va[component_table[\"Converter\"]])\n                va[component_table[\"Converter\"]] = AverageConverter(750.0, 2.75)\n            end\n            if ismissing(va[component_table[\"Filter\"]])\n                va[component_table[\"Filter\"]] = RLFilter(0.0, 0.0)\n            end\n            if ismissing(va[component_table[\"FrequencyEstimator\"]])\n                va[component_table[\"FrequencyEstimator\"]] = FixedFrequency()\n            end\n            if ismissing(va[component_table[\"DCSource\"]])\n                va[component_table[\"DCSource\"]] = FixedDCSource(750.0)\n            end\n        end\n    end\n    return\nend\n\n\"\"\"\nParse a .dyr file directly from its name by constructing its dictionary of dictionaries.\n\n\"\"\"\nfunction _parse_dyr_components(dyr_file::AbstractString)\n    ext = splitext(dyr_file)[2]\n    if lowercase(ext) in [\".dyr\"]\n        data = _parse_dyr_file(dyr_file)\n        return _parse_dyr_components(data)\n    else\n        throw(DataFormatError(\"$dyr_file is not a .dyr file type\"))\n    end\nend\n\nfunction _make_bus_inverters_dictionary(bus_data, inv_map, inv_keys, param_map)\n    bus_dict_values = Dict{String, Any}()\n    for (componentID, componentValues) in bus_data\n        # ComponentID is a tuple:\n        # ComponentID[1] is the PSSE name\n        # ComponentID[2] is the number ID of the generator/inverter\n        # Fill array of 7 components per inverter\n        # Only create if name is in the supported keys in the mapping\n        if componentID[1] in inv_keys\n            # Get the component dictionary\n            temp = get!(bus_dict_values, componentID[2], Dict{Any, Vector{Any}}())\n            components_dict = inv_map[componentID[1]]\n            for (inv_field, struct_as_str) in components_dict\n                param_vec = get!(\n                    temp,\n                    (inv_field, struct_as_str),\n                    _instantiate_param_vector_size(struct_as_str, param_map),\n                )\n                params_ix = param_map[struct_as_str]\n                _populate_args!(param_vec, params_ix, componentValues, componentID[1])\n            end\n        end\n    end\n    return bus_dict_values\nend\n\n\"\"\"\nParse dictionary of dictionaries of data (from `_parse_dyr_file`) into a dictionary of struct components.\nThe function receives the parsed dictionary and constructs a dictionary indexed by bus, that contains a\ndictionary with each dynamic generator and dynamic inverter components (indexed via its id).\n\nFor Generators, each dictionary indexed by id contains a vector with 5 of its components:\n* Machine\n* Shaft\n* AVR\n* TurbineGov\n* PSS\n\nFor Inverters, each dictionary indexed by id contains a vector with 7 of its components:\n* Converter\n* ActivePowerControl\n* ReactivePowerControl\n* InnerControl\n* DCSource\n* FrequencyEstimator\n* Filter\n\n\"\"\"\nfunction _parse_dyr_components(data::Dict)\n    yaml_mapping = open(PSSE_DYR_MAPPING_FILE) do io\n        aux = YAML.load(io)\n        return aux\n    end\n    # param_map contains the mapping between struct params and dyr file.\n    param_map = yaml_mapping[\"parameter_mapping\"][1]\n    # gen_map contains all the supported structs for generators\n    gen_map = yaml_mapping[\"generator_mapping\"][1]\n    # inv_map contains al the supported structs for inverters\n    inv_map = yaml_mapping[\"inverter_mapping\"][1]\n    # additional_map contains all the supported structs for additional injectors\n    additional_map = yaml_mapping[\"additional_mapping\"][1]\n    gen_keys = Set(keys(gen_map))\n    inv_keys = Set(keys(inv_map))\n    additional_keys = Set(keys(additional_map))\n\n    # dic will contain the dictionary index by bus.\n    # Each entry will be a dictionary, with id as keys, that contains the vector of components\n    system_dic = Dict{Int, Any}()\n    for (bus_num, bus_data) in data # bus_data is a dictionary with values per component (key)\n        bus_dict = Dict{String, Any}()\n        inverters_dict = Dict{String, Any}()\n        for (componentID, componentValues) in bus_data\n            # ComponentID is a tuple:\n            # ComponentID[1] is the PSSE name\n            # ComponentID[2] is the number ID of the generator/inverter\n            if componentID[1] in gen_keys\n                _parse_dyr_generator_components!(\n                    bus_dict,\n                    componentID,\n                    componentValues,\n                    gen_map,\n                    param_map,\n                )\n            elseif componentID[1] in inv_keys\n                if isempty(inverters_dict)\n                    # Since a single PSSe inverter component contributes to more than one PSY component\n                    # We need to map all the other components beforehand if Inverter components are present\n                    inverters_dict = _make_bus_inverters_dictionary(\n                        bus_data,\n                        inv_map,\n                        inv_keys,\n                        param_map,\n                    )\n                end\n                _parse_dyr_inverter_components!(\n                    bus_dict,\n                    inverters_dict,\n                    componentID,\n                    inv_map,\n                )\n            elseif componentID[1] in additional_keys\n                #TODO: Make multiple dispatch for this\n                _parse_dera1!(\n                    bus_dict,\n                    componentID,\n                    componentValues,\n                    param_map,\n                    bus_num,\n                )\n            else\n                @warn \"$(componentID[1]) at bus $bus_num, id $(componentID[2]), not supported in PowerSystems.jl. Skipping data.\"\n            end\n        end\n        _assign_missing_components!(bus_dict, GEN_COMPONENT_TABLE, DynamicGenerator)\n        _assign_missing_components!(bus_dict, INV_COMPONENT_TABLE, DynamicInverter)\n        system_dic[bus_num] = bus_dict\n    end\n    return system_dic\nend\n\n\"\"\"\nParse dictionary of data (from `_parse_dyr_file`) into a dictionary of DERA1.\nThe function receives the parsed dictionary and constructs a dictionary indexed by bus, that contains a\ndictionary with each DERA1 indexed by its id.\n\n\"\"\"\nfunction _parse_dera1!(\n    bus_dict,\n    componentID,\n    componentValues,\n    param_map::Dict,\n    bus_num::Int,\n)\n    temp = get!(bus_dict, componentID[2], fill!(Vector{Any}(undef, 1), missing))\n    params_ix = param_map[\"AggregateDistributedGenerationA\"]\n    constructor_dera =\n        (args...) ->\n            InteractiveUtils.getfield(PowerSystems, :AggregateDistributedGenerationA)(\n                args...,\n            )\n    dera1_args = _populate_args(params_ix, componentValues)\n    # Update name\n    dera1_args[1] = componentID[1] * \"_\" * string(bus_num) * \"_\" * componentID[2]\n    # Transform Flags to Int\n    dera1_args[2:7] = Int64.(dera1_args[2:7])\n    # Transform vl tuples to vector of tuples\n    dera1_args[24] = [dera1_args[24]]\n    dera1_args[25] = [dera1_args[25]]\n    dera1 = constructor_dera(dera1_args...)\n    temp[1] = dera1\n    return\nend\n\n\"\"\"\nParse dictionary of data (from `_parse_dyr_file`) into a dictionary of struct components.\nThe function receives the parsed dictionary and constructs a dictionary indexed by bus, that contains a\ndictionary with each dynamic generator indexed by its id.\n\n\"\"\"\nfunction _parse_dyr_generator_components!(\n    bus_dict::Dict,\n    componentID,\n    componentValues,\n    gen_map::Dict,\n    param_map::Dict,\n)\n    # Fill array of 5 components per generator\n    temp = get!(bus_dict, componentID[2], fill!(Vector{Any}(undef, 5), missing))\n    # Get the component dictionary\n    for (gen_field, struct_as_str) in gen_map[componentID[1]]\n        # Get the parameter indices w/r to componentValues\n        params_ix = param_map[struct_as_str]\n        # Construct Shaft if it appears\n        if occursin(\"Shaft\", struct_as_str)\n            temp[2] = _make_shaft(params_ix, componentValues)\n            continue\n        end\n        # Construct Components\n        component_constructor =\n            (args...) ->\n                InteractiveUtils.getfield(PowerSystems, Symbol(struct_as_str))(args...)\n        if struct_as_str == \"BaseMachine\"\n            struct_args = [\n                0.0,    # R\n                1e-5,   # X\n                1.0,    # eq_p\n            ]\n        else\n            struct_args = _populate_args(params_ix, componentValues)\n        end\n        _convert_argument_types_for_gen!(struct_as_str, struct_args)\n        temp[GEN_COMPONENT_TABLE[gen_field]] = component_constructor(struct_args...)\n    end\n    return\nend\n\n\"\"\"\nParse dictionary of data (from `_parse_dyr_file`) into a dictionary of struct components.\nThe function receives the parsed dictionary and constructs a dictionary indexed by bus, that contains a\ndictionary with each dynamic inverter indexed by its id.\n\n\"\"\"\nfunction _parse_dyr_inverter_components!(\n    bus_dict::Dict,\n    inv_dict::Dict,\n    componentID::NTuple{2, String},\n    inv_map::Dict,\n)\n    # Needs to be extended when supporting more parsing\n    name_to_keys = Dict(\n        \"REGCA1\" => [(\"Converter\", \"RenewableEnergyConverterTypeA\")],\n        \"REECB1\" => [(\"InnerControl\", \"RECurrentControlB\")],\n        \"REPCA1\" => [\n            (\"ActivePowerControl\", \"ActiveRenewableControllerAB\"),\n            (\"ReactivePowerControl\", \"ReactiveRenewableControllerAB\"),\n        ],\n    )\n\n    # Fill array of 7 components per inverter\n    temp = get!(bus_dict, componentID[2], fill!(Vector{Any}(undef, 7), missing))\n\n    for (inv_field, struct_as_str) in name_to_keys[componentID[1]]\n        values = inv_dict[componentID[2]][(inv_field, struct_as_str)]\n        _convert_argument_types!(struct_as_str, values)\n        component_constructor =\n            (args...) ->\n                InteractiveUtils.getfield(PowerSystems, Symbol(struct_as_str))(args...)\n        temp[INV_COMPONENT_TABLE[inv_field]] = component_constructor(values...)\n    end\n\n    return\nend\n\n\"\"\"\nConstruct appropiate vector size for components that collect parameters from\nmore than 2 PSS/E components\n\n\"\"\"\nfunction _instantiate_param_vector_size(str::AbstractString, param_map::Dict)\n    if str == \"ActiveRenewableControllerAB\"\n        return fill!(Vector{Any}(undef, 17), missing)\n    elseif str == \"ReactiveRenewableControllerAB\"\n        return fill!(Vector{Any}(undef, 25), missing)\n    elseif str == \"RECurrentControlB\"\n        return fill!(Vector{Any}(undef, 12), missing)\n    elseif str in keys(param_map)\n        return fill!(Vector{Any}(undef, length(param_map[str])), missing)\n    else\n        error(\"String $(str) not supported in the parser\")\n    end\nend\n\n\"\"\"\nConvert specific parameters to types that are not Float64 for\nspecific inverter components\n\n\"\"\"\nfunction _convert_argument_types!(str::AbstractString, struct_args::Vector)\n    if str == \"ActiveRenewableControllerAB\"\n        struct_args[1:5] .= Int.(struct_args[1:5])\n        struct_args[4] = string(struct_args[4])\n    elseif str == \"ReactiveRenewableControllerAB\"\n        struct_args[1:8] .= Int.(struct_args[1:8])\n        struct_args[4] = string(struct_args[4])\n    elseif str == \"RECurrentControlB\"\n        struct_args[1:2] .= Int.(struct_args[1:2])\n    elseif str == \"RenewableEnergyConverterTypeA\"\n        # No changes to struct_args\n    else\n        error(\"$str not defined for dynamic component arguments\")\n    end\nend\n\n\"\"\"\nConvert specific parameters to types that are not Float64 for\nspecific generator components\n\n\"\"\"\nfunction _convert_argument_types_for_gen!(str::AbstractString, struct_args::Vector)\n    if (str == \"DEGOV1\") || (str == \"PIDGOV\")\n        struct_args[1] = Int(struct_args[1])\n    end\n    return\nend\n\n\"\"\"\nAdd to a system already created the dynamic components.\nThe system should already be parsed from a .raw file.\n\n# Examples:\n```julia\ndyr_file = \"Example.dyr\"\nadd_dyn_injectors!(sys, dyr_file)\n```\n\n\"\"\"\nfunction add_dyn_injectors!(sys::System, dyr_file::AbstractString)\n    bus_dict_gen = _parse_dyr_components(dyr_file)\n    _add_dyn_injectors!(sys, bus_dict_gen)\n    return\nend\n\n# This function is future proofed to allow adding dynamic injector models to FACTS and other VAR control devices.\n# By dispatchting on specific types, we can add more injectors in the future.\n# We add new _add_dyn_injectors! methods for each new type of injector.\nfunction _add_dyn_injectors!(sys::System, bus_dict_gen::Dict)\n    _add_dyn_injectors!(sys, bus_dict_gen, ThermalStandard)\n    _add_dyn_injectors!(sys, bus_dict_gen, SynchronousCondenser)\n    return\nend\n\nfunction _add_dyn_injectors!(::System, ::Dict, InjectorType::DataType)\n    error(\"Attaching dynamic injectors of type $InjectorType is not supported yet.\")\nend\n\nfunction _add_dyn_injectors!(\n    sys::System,\n    bus_dict_gen::Dict,\n    InjectorType::Type{T},\n) where {T <: Union{ThermalStandard, SynchronousCondenser}}\n    @info \"Generators provided in .dyr, without a generator in .raw file will be skipped.\"\n    for g in get_components(InjectorType, sys)\n        _num = get_number(get_bus(g))\n        _name = get_name(g)\n        _id = split(_name, \"-\")[end]\n        temp_dict = get(bus_dict_gen, _num, nothing)\n        if temp_dict === nothing\n            @warn \"Generator at bus $(_num), id $(_id), not found in Dynamic Data.\\nVoltage Source will be used to model it.\"\n            r, x = get_ext(g)[\"r\"], get_ext(g)[\"x\"]\n            if x == 0.0\n                @warn \"No series reactance found. Setting it to 1e-6\"\n                x = 1e-6\n            end\n            s = _make_source(g, r, x, get_base_power(sys))\n            remove_component!(typeof(g), sys, _name)\n            add_component!(sys, s)\n        elseif all(.!ismissing.(temp_dict[_id]))\n            if length(temp_dict[_id]) == 5 # Generator has 5 components\n                # Obtain Machine from Dictionary\n                machine = temp_dict[_id][1]\n                # Update R,X from RSORCE and XSORCE from RAW file\n                r, x = get_ext(g)[\"r\"], get_ext(g)[\"x\"]\n                set_R!(machine, r)\n                # Obtain Shaft from dictionary\n                shaft = temp_dict[_id][2]\n                if typeof(machine) == BaseMachine\n                    if x == 0.0\n                        @warn \"No series reactance found. Setting it to 1e-6\"\n                        x = 1e-6\n                    end\n                    set_Xd_p!(machine, x)\n                    if get_H(shaft) == 0.0\n                        @info \"Machine at bus $(_num), id $(_id) has zero inertia. Modeling it as Voltage Source\"\n                        s = _make_source(g, r, x, get_base_power(sys))\n                        remove_component!(typeof(g), sys, _name)\n                        add_component!(sys, s)\n                        # Don't add DynamicComponent in case of adding Source\n                        continue\n                    end\n                end\n                # Add Dynamic Generator\n                dyn_gen = DynamicGenerator(get_name(g), 1.0, temp_dict[_id]...)\n                add_component!(sys, dyn_gen, g)\n            elseif length(temp_dict[_id]) == 7 # Inverter has 7 components (6 if Outer is put together)\n                dyn_inv = DynamicInverter(get_name(g), 1.0, temp_dict[_id]...)\n                add_component!(sys, dyn_inv, g)\n            elseif length(temp_dict[_id]) == 1\n                #TODO: While we only have 1 thing (DERA1) it will work,\n                #TODO: but we need to generalize this for any generic dynamic injector\n                dyn_inj = temp_dict[_id][1]\n                set_name!(dyn_inj, get_name(g))\n                add_component!(sys, dyn_inj, g)\n            else\n                @assert false\n            end\n        else\n            error(\"Generator at bus $(_num), id $(_id), name $(_name), not supported\")\n        end\n    end\nend\n"
  },
  {
    "path": "src/parsers/psse_dynamic_mapping.yaml",
    "content": "######################################\n######### Dynamic Generator ##########\n######################################\n\ngenerator_mapping:\n- {\n#############################\n######### Machines ##########\n#############################\n\nGENROU:\n{\n  Machine: RoundRotorQuadratic,\n  Shaft: RoundRotorShaft\n},\nGENSAL:\n{\n  Machine: SalientPoleQuadratic,\n  Shaft: SalientPoleShaft\n},\nGENROE:\n{\n  Machine: RoundRotorExponential,\n  Shaft: RoundRotorShaft\n},\nGENSAE:\n{\n  Machine: SalientPoleExponential,\n  Shaft: SalientPoleShaft\n},\nGENCLS:\n{\n  Machine: BaseMachine,\n  Shaft: ClsShaft\n},\n\n#############################\n#### Excitation Systems #####\n#############################\n\nIEEET1:\n{\n  AVR: IEEET1\n},\nESDC1A:\n{\n  AVR: ESDC1A\n},\nESDC2A:\n{\n  AVR: ESDC2A\n},\nESAC1A:\n{\n  AVR: ESAC1A\n},\nESAC6A:\n{\n  AVR: ESAC6A\n},\nEXAC1:\n{\n  AVR: EXAC1\n},\nEXAC1A:\n{\n  AVR: EXAC1A\n},\nEXAC2:\n{\n  AVR: EXAC2\n},\nEXPIC1:\n{\n  AVR: EXPIC1\n},\nESST1A:\n{\n  AVR: ESST1A\n},\nESST4B:\n{\n  AVR: ESST4B\n},\nSCRX:\n{\n  AVR: SCRX\n},\nSEXS:\n{\n  AVR: SEXS\n},\nEXST1:\n{\n  AVR: EXST1\n},\nESAC8B:\n{\n  AVR: ESAC8B\n},\nST6B:\n{\n  AVR: ST6B\n},\nST8C:\n{\n  AVR: ST8C\n},\n\n#############################\n#### Turbine Governors ######\n#############################\n\nGAST:\n{\n  TurbineGov: GasTG\n},\nGGOV1:\n{\n  TurbineGov: GeneralGovModel\n},\nHYGOV:\n{\n  TurbineGov: HydroTurbineGov\n},\nIEEEG1:\n{\n  TurbineGov: IEEETurbineGov1\n},\nTGOV1:\n{\n  TurbineGov: SteamTurbineGov1\n},\nTGOV1DU:\n{\n  TurbineGov: TGOV1DU\n},\nDEGOV1:\n{\n  TurbineGov: DEGOV1\n},\nPIDGOV:\n{\n  TurbineGov: PIDGOV\n},\nWPIDHY:\n{\n  TurbineGov: WPIDHY\n},\n\n######################################\n###### Power System Stabilizers ######\n######################################\n\nIEEEST:\n{\n  PSS: IEEEST\n},\nSTAB1:\n{\n  PSS: STAB1\n}\n}\n\n\n######################################\n######### Dynamic Inverter ###########\n######################################\n\ninverter_mapping:\n- {\n  #############################\n  ######### Converter #########\n  #############################\n  REGCA1:\n  {\n    Converter: RenewableEnergyConverterTypeA\n  },\n\n  REECB1:\n  {\n    ActivePowerControl: ActiveRenewableControllerAB,\n    ReactivePowerControl: ReactiveRenewableControllerAB,\n    InnerControl: RECurrentControlB\n  },\n\n  REPCA1:\n  {\n    ActivePowerControl: ActiveRenewableControllerAB,\n    ReactivePowerControl: ReactiveRenewableControllerAB,\n  }\n\n}\n\n######################################\n######### Additional Models ##########\n######################################\n\nadditional_mapping:\n- {\n  DERA1:\n  {\n    DynamicInjection: AggregateDistributedGenerationA\n  }\n}\n\n\n###################\n##### Mapping #####\n###################\n\nparameter_mapping:\n- {\n  ##################\n  ### Generators ###\n  ##################\n  #Machines\n  RoundRotorQuadratic: [0.0, #R\n                        1,  #Td0_p\n                        2,  #Td0_pp\n                        3,  #Tq0_p\n                        4,  #Tq0_pp\n                        7,  #Xd\n                        8,  #Xq\n                        9,  #Xd_p\n                        10, #Xq_p\n                        11, #Xd_pp\n                        12, #Xl,\n                        '(13, 14)'], #(Se(1.0), Se(1.2))\n  RoundRotorExponential: [0.0, 1, 2, 3, 4, 7, 8, 9, 10, 11, 12, '(13, 14)'],\n  SalientPoleQuadratic: [0.0, #R\n                        1,  #Td0_p\n                        2,  #Td0_pp\n                        3,  #Tq0_pp\n                        6,  #Xd\n                        7,  #Xq\n                        8,  #Xd_p\n                        9, #Xd_pp\n                        10, #Xl,\n                        '(11, 12)'], #(Se(1.0), Se(1.2))\n  SalientPoleExponential: [0.0, 1, 2, 3, 6, 7, 8, 9, 10, '(11, 12)'],\n  #Shafts\n  RoundRotorShaft: [5, 6],\n  SalientPoleShaft: [4, 5],\n  BaseMachine: [],\n  ClsShaft: [1, 2],\n  #AVRs\n  IEEET1: [1, 2, 3, '(5, 4)', 6, 7, 8, 9, 10, '(11, 13)', '(12, 14)'],\n  ESDC1A: [1, 2, 3, 4, 5, '(7, 6)', 8, 9, 10, 11, 12, '(13, 15)', '(14, 16)'],\n  ESDC2A: [1, 2, 3, 4, 5, '(7, 6)', 8, 9, 10, 11, 12, '(13, 15)', '(14, 16)'],\n  ESAC1A: [1, 2, 3, 4, 5, '(7, 6)', 8, 9, 10, 11, 12, 13, '(14, 16)', '(15, 17)', '(19, 18)'],\n  ESAC6A: [1, 2, 3, 4, 5, 6, '(8, 7)', '(10, 9)', 11, 12, 13, 14, 15, 16, 17, 18, 19, '(20, 22)','(21, 23)'],\n  EXAC1: [1, 2, 3, 4 , 5, '(7, 6)', 8, 9, 10, 11, 12, 13, '(14, 16)', '(15, 17)'],\n  EXAC1A: [1, 2, 3, 4 , 5, '(7, 6)', 8, 9, 10, 11, 12, 13, '(14, 16)', '(15, 17)'],\n  EXAC2: [1, 2, 3, 4 , 5, '(7, 6)', 8, '(10, 9)', 11, 12, 13, 14, 15, 16, 17, 18, 19, '(20, 22)', '(21, 23)'],\n  EXPIC1: [1, 2, 3, '(5, 4)', 6, 7, 8, '(10, 9)', 11, 12, 13, '(15, 14)', 16, 17, '(18, 20)', '(19, 21)', 22, 23, 24],\n  ESST1A: [1, 2, 3, '(5, 4)', 6, 7, 8, 9, 10, 11, '(13, 12)', '(15, 14)', 16, 17, 18, 19, 20],\n  ESST4B: [1, 2, 3, '(5, 4)', 6, 7, 8, '(10, 9)', 11, 12, 13, 14, 15, 16, 17],\n  SCRX: [1, 2, 3, 4, '(5, 6)', 7, 8],\n  SEXS: [1, 2, 3, 4, '(5, 6)'],\n  EXST1: [1, '(3, 2)', 4, 5, 6, 7, '(9, 8)', 10, 11, 12],\n  ESAC8B: [1, 2, 3, 4, 5, 6, 7, '(9, 8)', 10, 11, '(12, 14)', '(13, 15)'],\n  ST6B: [1, 2, 3, 4, 5, 6, '(8, 7)', 9, 10, 11, 12, 13, '(15, 14)', 16, 17],\n  ST8C: [1, 2, 3, 4, 5, 6, 7, '(9, 8)', 10, 11, '(13, 12)', 14, 15, '(17, 16)', 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28],\n  #TGs\n  GasTG: [1, 2, 3, 4, 5, 6, '(8, 7)', 9],\n  GeneralGovModel: [1, 2, 3, 4, '(6, 5)', 7, 8, 9, 10, '(12, 11)', 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, '(35, 34)'],\n  HydroTurbineGov: [1, 2, 3, 4, 5, 6, '(8, 7)', 9, 10, 11, 12],\n  IEEETurbineGov1: [1, 2, 3, 4, 5, 6, '(8, 7)', 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],\n  SteamTurbineGov1: [1, 2, '(4, 3)', 5, 6, 7, 0.0, 0.0, 0.0],\n  TGOV1DU: [1, 2, '(4, 3)', 5, 6, 7, 8, 9, 10],\n  DEGOV1: [1, 2, 3, 4, 5, 6, 7, 8, 9, '(11, 10)', 12, 13],\n  PIDGOV: [1, 2, 3, 4, 5, 6, 7, 8, 9, '(10, 11, 13)', '(12, 14, 15)', '(17, 16)', 18, 19, '(21, 20)'],\n  WPIDHY: [1, 2, 3, 4, 5, 6, 7, '(9, 8)', '(11, 10)', 12, '(14, 13)', 15, '(16, 17, 19)', '(18, 20, 21)'],\n  #PSSs:\n  IEEEST: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, '(17, 16)', 18, 19],\n  STAB1: [1, 2, 3, 4, 5, 6, 7],\n\n  ###################\n  #### Inverters ####\n  ###################\n\n  #Converters\n  RenewableEnergyConverterTypeA: [2, 3, 4, 5, 6, 7, '(9, 8)', 10, 11, 12, '(14, 13)', 15, 1],\n\n  #ActivePowerControl\n  ActiveRenewableControllerAB: \n  {\n    REECB1: ['NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN',  '(26, 25)', '(28, 27)', 30],\n    REPCA1: [1, 2, 3, 4, 7, 23, 24, 25, '(26, 27)', '(29, 28)', '(31, 30)', 32, 33, 34, 'NaN', 'NaN', 'NaN']\n  },\n\n  #ReactivePowerControl\n  ReactiveRenewableControllerAB: \n  {\n    #         bus,  from_b, to_b, b_id,  VC,    Ref,   PF, V, T_f,  K_p,   K_i,   T_ft,  T_fv,   V_fr,  R_c,   X_c,   K_c,   e_lim, dbd,   Q_lim, Tp,  Qlim_in,   V_lim,     Kqp, Kqi\n    REECB1: ['NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 2, 3, 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN', 15, '(17, 16)', '(19, 18)', 20, 21],\n    REPCA1: [1, 2, 3, 4, 5, 6, 'NaN', 'NaN', 8, 9, 10, 11, 12, 13, 14, 15, 16, '(18, 17)', '(19, 20)', '(22, 21)', 'NaN', 'NaN', 'NaN', 'NaN', 'NaN']\n  },\n\n  #Inner Control\n  RECurrentControlB:\n  {\n    REECB1: [4, 5, '(6, 7)', 8, '(9, 10)', 11, '(13, 12)', 14, 22, 23, 24, 29]\n  },\n\n  # Additional Components\n  AggregateDistributedGenerationA: ['NaN', 1, 2, 3, 4, 5, 6, 7, 8, '(9, 10)', 11, 13, 14, 15, 16, '(17, 18)', '(20, 19)', '(22, 21)', '(24, 23)', 25, 26, 27, 28, '(29, 30)', '(31, 32)', 37, 38, 39, 40, 41, 42, 43, 44, 45, '(47, 46)',]\n\n\n}\n"
  },
  {
    "path": "src/parsers/psse_metadata_reimport.jl",
    "content": "# Parse the `<name>_export_metadata.json` file written alongside PSS/E files by PowerFlows.jl\n\n# Currently the following mappings are used here:\n#   area_mapping: maps Sienna name to PSS/E number for all areas\n#   zone_mapping: maps Sienna name to PSS/E number for all load zones\n#   bus_name_mapping: maps Sienna name to PSS/E name for all buses\n#   bus_number_mapping: maps Sienna number to PSS/E number for all buses\n#   load_name_mapping: maps (Sienna bus, Sienna name) to PSS/E name for all loads\n#   shunt_name_mapping: maps (Sienna bus, Sienna name) to PSS/E name for all shunts\n#   switched_shunt_name_mapping: maps (Sienna bus, Sienna name) to PSS/E name for all switched shunts\n#   generator_name_mapping: maps (Sienna bus 1, Sienna bus 2, Sienna name) to PSS/E name for all generators\n#   xfrm_3w_name_formatter: maps (Sienna bus 1, Sienna bus 2, Sienna bus 3, Sienna name) to PSS/E name for all 3W transformers \n#   dcline_name_formatter: maps (Sienna bus 1, Sienna bus 2, Sienna name) to PSS/E name for all DC lines\n#   vscline_name_formatter: maps (Sienna bus 1, Sienna bus 2, Sienna name) to PSS/E name for all VSC lines\n#   branch_name_mapping: maps (Sienna bus 1, Sienna bus 2, Sienna name) to PSS/E name for all non-transformer branches\n#   transformer_ckt_mapping: maps (Sienna bus1, Sienna bus2, Sienna name) to PSS/E CKT field for all transformers\n\n# Mappings are stored in the file in the Sienna -> PSS/E direction, so they need to be\n# reversed for use here. Wherever a tuple is indicated above, the presentation in the file\n# is of the elements joined with underscores to form a single string.\n\n# NOTE for the moment, this feature is mostly tested in the PowerFlows.jl unit tests.\n\nconst PSSE_EXPORT_METADATA_EXTENSION = \"_export_metadata.json\"\n\nreverse_dict(d::Dict) = Dict(map(reverse, collect(d)))\n\nfunction split_first_rest(s::AbstractString; delim = \"_\")\n    splitted = split(s, delim)\n    return first(splitted), join(splitted[2:end], delim)\nend\n\n\"Convert a s_bus_n_s_name => p_name dictionary to a (p_bus_n, p_name) => s_name dictionary\"\ndeserialize_reverse_component_ids(\n    mapping,\n    bus_number_mapping,\n    ::T,\n) where {T <: Type{Int64}} =\n    Dict(\n        let\n            (s_bus_n, s_name) = split_first_rest(s_bus_n_s_name)\n            p_bus_n = bus_number_mapping[s_bus_n]\n            (p_bus_n, p_name) => s_name\n        end\n        for (s_bus_n_s_name, p_name) in mapping)\ndeserialize_reverse_component_ids(\n    mapping,\n    bus_number_mapping,\n    ::T,\n) where {T <: Type{Tuple{Int64, Int64}}} =\n    Dict(\n        let\n            (s_buses, s_name) = split_first_rest(s_buses_s_name)\n            (s_bus_1, s_bus_2) = split(s_buses, \"-\")\n            (p_bus_1, p_bus_2) = bus_number_mapping[s_bus_1], bus_number_mapping[s_bus_2]\n            ((p_bus_1, p_bus_2), p_name) => s_name\n        end\n        for (s_buses_s_name, p_name) in mapping)\n\n\"\"\"\nUse PSS/E exporter metadata to build a function that maps component names back to their\noriginal Sienna values.\n\"\"\"\nfunction name_formatter_from_component_ids(raw_name_mapping, bus_number_mapping, sig)\n    reversed_name_mapping =\n        deserialize_reverse_component_ids(raw_name_mapping, bus_number_mapping, sig)\n    function component_id_formatter(device_dict)\n        (p_bus_n, p_name) = device_dict[\"source_id\"][2:3]\n        (p_bus_n isa Integer) || (p_bus_n = parse(Int64, p_bus_n))\n        new_name = reversed_name_mapping[(p_bus_n, p_name)]\n        return new_name\n    end\n    return component_id_formatter\nend\n\n# Assumes bus_number_mapping is 1-to-1, given by its coming from reverse_dict\nfunction remap_bus_numbers!(sys::System, bus_number_mapping)\n    for bus in collect(get_components(Bus, sys))\n        old_number = get_number(bus)\n        new_number_str = get(bus_number_mapping, old_number, string(old_number))\n        new_number = parse(Int, new_number_str)\n        if new_number != old_number\n            # This will throw an exception if one bus's PSS/E number is another bus's\n            # Sienna number. That never happens because _psse_bus_numbers on the\n            # exporting side guarantees that bus numbers that are already compliant with\n            # the PSS/E spec will not be changed.\n            set_bus_number!(sys, bus, new_number)\n        end\n    end\nend\n\n\"\"\"\nParse an export_metadata dictionary, returning the kwargs that should be passed to the\nSystem constructor and the bus number remapping that should be used to effect the\nretransformation.\n\"\"\"\nfunction parse_export_metadata_dict(md::Dict)\n    bus_name_map = reverse_dict(md[\"bus_name_mapping\"])  # PSS/E bus name -> Sienna bus name\n    all_branch_name_map = deserialize_reverse_component_ids(\n        merge(\n            md[\"branch_name_mapping\"],\n            md[\"transformer_ckt_mapping\"],\n        ),\n        md[\"bus_number_mapping\"],\n        Tuple{Int64, Int64},\n    )\n    bus_name_formatter = device_dict -> begin\n        bus_name = device_dict[\"name\"]\n        get(bus_name_map, bus_name, bus_name)\n    end\n\n    gen_name_formatter = name_formatter_from_component_ids(\n        md[\"generator_name_mapping\"],\n        md[\"bus_number_mapping\"],\n        Int64,\n    )\n    load_name_formatter = name_formatter_from_component_ids(\n        md[\"load_name_mapping\"],\n        md[\"bus_number_mapping\"],\n        Int64,\n    )\n\n    function branch_name_formatter(\n        device_dict::Dict,\n        bus_f::ACBus,\n        bus_t::ACBus,\n    )::String\n        sid = device_dict[\"source_id\"]\n\n        (p_bus_1, p_bus_2, p_name) =\n            (length(sid) == 6) ? [sid[2], sid[3], sid[5]] : last(sid, 3)\n\n        if sid[1] in [\"switch\", \"breaker\"]\n            p_name = replace(p_name, r\"[@*]\" => \"_\")\n        end\n        bus_f_name = get_name(bus_f)\n        bus_t_name = get_name(bus_t)\n        key = ((p_bus_1, p_bus_2), p_name)\n        def_name = \"$(bus_f_name)-$(bus_t_name)-i_$(p_name)\"\n        new_name = get(all_branch_name_map, key, def_name)\n        return new_name\n    end\n\n    function xfrm_3w_name_formatter(\n        device_dict::Dict,\n        p_bus::ACBus,\n        s_bus::ACBus,\n        t_bus::ACBus,\n    )::String\n        bus_primary = get_name(p_bus)\n        bus_secondary = get_name(s_bus)\n        bus_tertiary = get_name(t_bus)\n        ckt = device_dict[\"circuit\"]\n\n        return \"$(bus_primary)-$(bus_secondary)-$(bus_tertiary)-i_$(ckt)\"\n    end\n\n    function make_switched_shunt_name_formatter(mapping, bus_number_mapping)\n        reversed_name_mapping = Dict{Tuple{Int, String}, String}()\n        for (s_bus_n_s_name, p_name) in mapping\n            parts = split(s_bus_n_s_name, \"_\")\n            s_bus_n = parts[1]\n            s_shunt_name = join(parts[2:end], \"_\")\n            p_bus_n = bus_number_mapping[s_bus_n]\n            reversed_name_mapping[(p_bus_n, s_shunt_name)] = p_name\n        end\n        return function (device_dict)\n            sid = device_dict[\"source_id\"]\n            p_bus_n = sid[2]\n            p_name = sid[3]\n            get(reversed_name_mapping, (p_bus_n, p_name), \"$(p_bus_n)-$(p_name)\")\n        end\n    end\n\n    function make_hvdc_name_formatter(mapping)\n        reversed_mapping = reverse_dict(mapping)\n        return function (device_dict, bus_f::ACBus, bus_t::ACBus)\n            bus_f_name = get_name(bus_f)\n            bus_t_name = get_name(bus_t)\n            name = device_dict[\"name\"]\n            key = string(bus_f_name, \"-\", bus_t_name, \"-i_\", name)\n            new_name = get(reversed_mapping, key, key)\n            return new_name\n        end\n    end\n\n    shunt_name_formatter = name_formatter_from_component_ids(\n        md[\"shunt_name_mapping\"],\n        md[\"bus_number_mapping\"],\n        Int64,\n    )\n    switched_shunt_name_formatter = make_switched_shunt_name_formatter(\n        md[\"switched_shunt_name_mapping\"],\n        md[\"bus_number_mapping\"],\n    )\n    dcline_name_formatter = make_hvdc_name_formatter(\n        md[\"dcline_name_mapping\"],\n    )\n    vscline_name_formatter = make_hvdc_name_formatter(\n        md[\"vsc_line_name_mapping\"],\n    )\n    loadzone_name_map = reverse_dict(md[\"zone_mapping\"])\n    get!(loadzone_name_map, 1, \"1\")\n    loadzone_name_formatter = name -> loadzone_name_map[name]\n    area_name_map = reverse_dict(md[\"area_mapping\"])\n    get!(area_name_map, 1, \"1\")\n    area_name_formatter = name -> area_name_map[name]\n    transformer_control_objective_map = md[\"transformer_control_objective_mapping\"]\n    transformer_control_objective_formatter =\n        name -> get(transformer_control_objective_map, name, nothing)\n    sys_kwargs = Dict(\n        :area_name_formatter => area_name_formatter,\n        :loadzone_name_formatter => loadzone_name_formatter,\n        :bus_name_formatter => bus_name_formatter,\n        :load_name_formatter => load_name_formatter,\n        :shunt_name_formatter => shunt_name_formatter,\n        :gen_name_formatter => gen_name_formatter,\n        :branch_name_formatter => branch_name_formatter,\n        :xfrm_3w_name_formatter => xfrm_3w_name_formatter,\n        :switched_shunt_name_formatter => switched_shunt_name_formatter,\n        :transformer_control_objective_formatter =>\n            transformer_control_objective_formatter,\n        :dcline_name_formatter => dcline_name_formatter,\n        :vscline_name_formatter => vscline_name_formatter,\n    )\n    bus_number_mapping = reverse_dict(md[\"bus_number_mapping\"])  # PSS/E bus name -> Sienna bus name\n\n    return sys_kwargs, bus_number_mapping\nend\n\n\"Construct a System from a `.raw` file and a dictionary corresponding to the `<name>_export_metadata.json` file\"\nfunction System(file_path::AbstractString, md::Dict; kwargs...)\n    sys_kwargs, bus_number_mapping = parse_export_metadata_dict(md)\n    sys = system_via_power_models(file_path; merge(sys_kwargs, kwargs)...)\n    # Remap bus numbers last because everything has been added to the system using PSS/E bus numbers\n    remap_bus_numbers!(sys, bus_number_mapping)\n    return sys\nend\n\nfunction system_from_psse_reimport(file_path::AbstractString; kwargs...)\n    md_path = joinpath(\n        dirname(file_path),\n        splitext(basename(file_path))[1] * PSSE_EXPORT_METADATA_EXTENSION,\n    )\n    if isfile(md_path)\n        @info \"Found a PowerFlows.jl PSS/E export metadata file at $md_path, will use it to perform remapping for round trip\"\n        md = JSON3.read(md_path, Dict)\n        return System(file_path, md; kwargs...)\n    else\n        @info \"Did not find a PowerFlows.jl PSS/E export metadata file at $md_path, will not do any remapping\"\n        return system_via_power_models(file_path; kwargs...)\n    end\nend\n"
  },
  {
    "path": "src/plant_attribute.jl",
    "content": "\"\"\"\nSupertype for power plant supplemental attributes that group generating units.\n\nConcrete subtypes include [`ThermalPowerPlant`](@ref), [`HydroPowerPlant`](@ref),\n[`RenewablePowerPlant`](@ref), [`CombinedCycleBlock`](@ref), and\n[`CombinedCycleFractional`](@ref).\n\"\"\"\nabstract type PowerPlant <: SupplementalAttribute end\n\n\"\"\"Get `internal`.\"\"\"\nget_internal(x::PowerPlant) = x.internal\n\n\"\"\"\nAttribute to represent [`ThermalGen`](@ref) power plants with synchronous generation.\nFor Combined Cycle plants consider using [`CombinedCycleBlock`](@ref).\n\nThe shaft map field is used to represent shared shafts between units.\n\n# Arguments\n- `name::String`: Name of the power plant\n- `shaft_map::Dict{Int, Vector{Base.UUID}}`: Mapping of shaft numbers to unit UUIDs (multiple units can share a shaft)\n- `reverse_shaft_map::Dict{Base.UUID, Int}`: Reverse mapping from unit UUID to shaft number\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct ThermalPowerPlant <: PowerPlant\n    name::String\n    shaft_map::Dict{Int, Vector{Base.UUID}}\n    reverse_shaft_map::Dict{Base.UUID, Int}\n    internal::InfrastructureSystemsInternal\nend\n\n# Deserialization variant: converts string-keyed dicts from JSON\nfunction ThermalPowerPlant(\n    name::String,\n    shaft_map::Dict{String, <:Any},\n    reverse_shaft_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return ThermalPowerPlant(\n        name,\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in shaft_map\n        ),\n        Dict{Base.UUID, Int}(Base.UUID(k) => v for (k, v) in reverse_shaft_map),\n        internal,\n    )\nend\n\n\"\"\"\n    ThermalPowerPlant(; name, shaft_map, reverse_shaft_map, internal)\n\nConstruct a [`ThermalPowerPlant`](@ref).\n\n# Arguments\n- `name::String`: Name of the power plant\n- `shaft_map::Dict{Int, Vector{Base.UUID}}`: (default: empty dict) Mapping of shaft numbers to unit UUIDs\n- `reverse_shaft_map::Dict{Base.UUID, Int}`: (default: empty dict) Reverse mapping from unit UUID to shaft number\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction ThermalPowerPlant(;\n    name::String,\n    shaft_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    reverse_shaft_map::AbstractDict = Dict{Base.UUID, Int}(),\n    internal::InfrastructureSystemsInternal = InfrastructureSystemsInternal(),\n)\n    return ThermalPowerPlant(name, shaft_map, reverse_shaft_map, internal)\nend\n\n\"\"\"Get [`ThermalPowerPlant`](@ref) `name`.\"\"\"\nget_name(value::ThermalPowerPlant) = value.name\n\"\"\"Get [`ThermalPowerPlant`](@ref) `shaft_map`.\"\"\"\nget_shaft_map(value::ThermalPowerPlant) = value.shaft_map\n\"\"\"Get [`ThermalPowerPlant`](@ref) `reverse_shaft_map`.\"\"\"\nget_reverse_shaft_map(value::ThermalPowerPlant) = value.reverse_shaft_map\n\n\"\"\"\nAttribute to represent combined cycle generation by block configuration that shares heat recovery converstions.\nFor aggregate representations consider using [`CombinedCycleFractional`](@ref).\n\n# Arguments\n- `name::String`: Name of the combined cycle block\n- `configuration::CombinedCycleConfiguration`: Configuration type of the combined cycle\n- `heat_recovery_to_steam_factor::Float64`: Factor for heat recovery to steam conversion\n- `hrsg_ct_map::Dict{Int, Vector{Base.UUID}}`: Mapping of HRSG numbers to CT unit UUIDs (CTs as HRSG inputs)\n- `hrsg_ca_map::Dict{Int, Vector{Base.UUID}}`: Mapping of HRSG numbers to CA unit UUIDs (CAs as HRSG outputs)\n- `ct_hrsg_map::Dict{Base.UUID, Vector{Int}}`: Reverse mapping from CT unit UUID to HRSG numbers (a CT can feed multiple HRSGs)\n- `ca_hrsg_map::Dict{Base.UUID, Vector{Int}}`: Reverse mapping from CA unit UUID to HRSG numbers (a CA can receive from multiple HRSGs)\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct CombinedCycleBlock <: PowerPlant\n    name::String\n    configuration::CombinedCycleConfiguration\n    heat_recovery_to_steam_factor::Float64\n    hrsg_ct_map::Dict{Int, Vector{Base.UUID}}\n    hrsg_ca_map::Dict{Int, Vector{Base.UUID}}\n    ct_hrsg_map::Dict{Base.UUID, Vector{Int}}\n    ca_hrsg_map::Dict{Base.UUID, Vector{Int}}\n    internal::InfrastructureSystemsInternal\nend\n\n# Deserialization variant: converts string-keyed dicts from JSON\nfunction CombinedCycleBlock(\n    name::String,\n    configuration::CombinedCycleConfiguration,\n    heat_recovery_to_steam_factor::Float64,\n    hrsg_ct_map::Dict{String, <:Any},\n    hrsg_ca_map::Dict{String, <:Any},\n    ct_hrsg_map::Dict{String, <:Any},\n    ca_hrsg_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return CombinedCycleBlock(\n        name,\n        configuration,\n        heat_recovery_to_steam_factor,\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in hrsg_ct_map\n        ),\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in hrsg_ca_map\n        ),\n        Dict{Base.UUID, Vector{Int}}(Base.UUID(k) => v for (k, v) in ct_hrsg_map),\n        Dict{Base.UUID, Vector{Int}}(Base.UUID(k) => v for (k, v) in ca_hrsg_map),\n        internal,\n    )\nend\n\n# Deserialization variant: configuration is also serialized as a string\nfunction CombinedCycleBlock(\n    name::String,\n    configuration::String,\n    heat_recovery_to_steam_factor::Float64,\n    hrsg_ct_map::Dict{String, <:Any},\n    hrsg_ca_map::Dict{String, <:Any},\n    ct_hrsg_map::Dict{String, <:Any},\n    ca_hrsg_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return CombinedCycleBlock(\n        name,\n        IS.deserialize(CombinedCycleConfiguration, configuration),\n        heat_recovery_to_steam_factor,\n        hrsg_ct_map,\n        hrsg_ca_map,\n        ct_hrsg_map,\n        ca_hrsg_map,\n        internal,\n    )\nend\n\n\"\"\"\n    CombinedCycleBlock(; name, configuration, heat_recovery_to_steam_factor, hrsg_ct_map, hrsg_ca_map, ct_hrsg_map, ca_hrsg_map, internal)\n\nConstruct a [`CombinedCycleBlock`](@ref).\n\n# Arguments\n- `name::String`: Name of the combined cycle block\n- `configuration::CombinedCycleConfiguration`: Configuration type of the combined cycle\n- `heat_recovery_to_steam_factor::Float64`: (default: `0.0`) Factor for heat recovery to steam conversion\n- `hrsg_ct_map::AbstractDict`: (default: empty dict) Mapping of HRSG numbers to CT unit UUIDs (CTs as HRSG inputs)\n- `hrsg_ca_map::AbstractDict`: (default: empty dict) Mapping of HRSG numbers to CA unit UUIDs (CAs as HRSG outputs)\n- `ct_hrsg_map::AbstractDict`: (default: empty dict) Reverse mapping from CT unit UUID to HRSG numbers\n- `ca_hrsg_map::AbstractDict`: (default: empty dict) Reverse mapping from CA unit UUID to HRSG numbers\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction CombinedCycleBlock(;\n    name,\n    configuration,\n    heat_recovery_to_steam_factor = 0.0,\n    hrsg_ct_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    hrsg_ca_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    ct_hrsg_map::AbstractDict = Dict{Base.UUID, Vector{Int}}(),\n    ca_hrsg_map::AbstractDict = Dict{Base.UUID, Vector{Int}}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    return CombinedCycleBlock(\n        name,\n        configuration,\n        heat_recovery_to_steam_factor,\n        hrsg_ct_map,\n        hrsg_ca_map,\n        ct_hrsg_map,\n        ca_hrsg_map,\n        internal,\n    )\nend\n\n\"\"\"Get [`CombinedCycleBlock`](@ref) `name`.\"\"\"\nget_name(value::CombinedCycleBlock) = value.name\n\"\"\"Get [`CombinedCycleBlock`](@ref) `configuration`.\"\"\"\nget_configuration(value::CombinedCycleBlock) = value.configuration\n\"\"\"Get [`CombinedCycleBlock`](@ref) `heat_recovery_to_steam_factor`.\"\"\"\nget_heat_recovery_to_steam_factor(value::CombinedCycleBlock) =\n    value.heat_recovery_to_steam_factor\n\"\"\"Get [`CombinedCycleBlock`](@ref) `hrsg_ct_map`.\"\"\"\nget_hrsg_ct_map(value::CombinedCycleBlock) = value.hrsg_ct_map\n\"\"\"Get [`CombinedCycleBlock`](@ref) `hrsg_ca_map`.\"\"\"\nget_hrsg_ca_map(value::CombinedCycleBlock) = value.hrsg_ca_map\n\"\"\"Get [`CombinedCycleBlock`](@ref) `ct_hrsg_map`.\"\"\"\nget_ct_hrsg_map(value::CombinedCycleBlock) = value.ct_hrsg_map\n\"\"\"Get [`CombinedCycleBlock`](@ref) `ca_hrsg_map`.\"\"\"\nget_ca_hrsg_map(value::CombinedCycleBlock) = value.ca_hrsg_map\n\n\"\"\"\nAttribute to represent combined cycle generation when each unit represents a specific configuration and aggregate heat rate.\nFor block-level representations consider using [`CombinedCycleBlock`](@ref).\n\n# Arguments\n- `name::String`: Name of the combined cycle fractional plant\n- `configuration::CombinedCycleConfiguration`: Configuration type of the combined cycle\n- `operation_exclusion_map::Dict{Int, Vector{Base.UUID}}`: Mapping of operation exclusion group numbers to unit UUIDs (only units in the same group can operate simultaneously)\n- `inverse_operation_exclusion_map::Dict{Base.UUID, Int}`: Reverse mapping from unit UUID to exclusion group number\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct CombinedCycleFractional <: PowerPlant\n    name::String\n    configuration::CombinedCycleConfiguration\n    operation_exclusion_map::Dict{Int, Vector{Base.UUID}}\n    inverse_operation_exclusion_map::Dict{Base.UUID, Int}\n    internal::InfrastructureSystemsInternal\nend\n\n# Deserialization variant: converts string-keyed dicts from JSON\nfunction CombinedCycleFractional(\n    name::String,\n    configuration::CombinedCycleConfiguration,\n    operation_exclusion_map::Dict{String, <:Any},\n    inverse_operation_exclusion_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return CombinedCycleFractional(\n        name,\n        configuration,\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in operation_exclusion_map\n        ),\n        Dict{Base.UUID, Int}(\n            Base.UUID(k) => v for (k, v) in inverse_operation_exclusion_map\n        ),\n        internal,\n    )\nend\n\n# Deserialization variant: configuration is also serialized as a string\nfunction CombinedCycleFractional(\n    name::String,\n    configuration::String,\n    operation_exclusion_map::Dict{String, <:Any},\n    inverse_operation_exclusion_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return CombinedCycleFractional(\n        name,\n        IS.deserialize(CombinedCycleConfiguration, configuration),\n        operation_exclusion_map,\n        inverse_operation_exclusion_map,\n        internal,\n    )\nend\n\n\"\"\"\n    CombinedCycleFractional(; name, configuration, operation_exclusion_map, inverse_operation_exclusion_map, internal)\n\nConstruct a [`CombinedCycleFractional`](@ref).\n\n# Arguments\n- `name::String`: Name of the combined cycle fractional plant\n- `configuration::CombinedCycleConfiguration`: Configuration type of the combined cycle\n- `operation_exclusion_map::AbstractDict`: (default: empty dict) Mapping of operation exclusion group numbers to unit UUIDs\n- `inverse_operation_exclusion_map::AbstractDict`: (default: empty dict) Reverse mapping from unit UUID to exclusion group number\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction CombinedCycleFractional(;\n    name,\n    configuration,\n    operation_exclusion_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    inverse_operation_exclusion_map::AbstractDict = Dict{Base.UUID, Int}(),\n    internal = InfrastructureSystemsInternal(),\n)\n    return CombinedCycleFractional(\n        name,\n        configuration,\n        operation_exclusion_map,\n        inverse_operation_exclusion_map,\n        internal,\n    )\nend\n\n\"\"\"Get [`CombinedCycleFractional`](@ref) `name`.\"\"\"\nget_name(value::CombinedCycleFractional) = value.name\n\"\"\"Get [`CombinedCycleFractional`](@ref) `configuration`.\"\"\"\nget_configuration(value::CombinedCycleFractional) = value.configuration\n\"\"\"Get [`CombinedCycleFractional`](@ref) `operation_exclusion_map`.\"\"\"\nget_operation_exclusion_map(value::CombinedCycleFractional) =\n    value.operation_exclusion_map\n\"\"\"Get [`CombinedCycleFractional`](@ref) `inverse_operation_exclusion_map`.\"\"\"\nget_inverse_operation_exclusion_map(value::CombinedCycleFractional) =\n    value.inverse_operation_exclusion_map\n\n\"\"\"\nAttribute to represent hydro power plants with shared penstocks.\n\n# Arguments\n- `name::String`: Name of the hydro power plant\n- `penstock_map::Dict{Int, Vector{Base.UUID}}`: Mapping of penstock numbers to unit UUIDs (multiple units can share a penstock)\n- `reverse_penstock_map::Dict{Base.UUID, Int}`: Reverse mapping from unit UUID to penstock number\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct HydroPowerPlant <: PowerPlant\n    name::String\n    penstock_map::Dict{Int, Vector{Base.UUID}}\n    reverse_penstock_map::Dict{Base.UUID, Int}\n    internal::InfrastructureSystemsInternal\nend\n\n# Deserialization variant: converts string-keyed dicts from JSON\nfunction HydroPowerPlant(\n    name::String,\n    penstock_map::Dict{String, <:Any},\n    reverse_penstock_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return HydroPowerPlant(\n        name,\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in penstock_map\n        ),\n        Dict{Base.UUID, Int}(Base.UUID(k) => v for (k, v) in reverse_penstock_map),\n        internal,\n    )\nend\n\n\"\"\"\n    HydroPowerPlant(; name, penstock_map, reverse_penstock_map, internal)\n\nConstruct a [`HydroPowerPlant`](@ref).\n\n# Arguments\n- `name::String`: Name of the hydro power plant\n- `penstock_map::Dict{Int, Vector{Base.UUID}}`: (default: empty dict) Mapping of penstock numbers to unit UUIDs\n- `reverse_penstock_map::Dict{Base.UUID, Int}`: (default: empty dict) Reverse mapping from unit UUID to penstock number\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction HydroPowerPlant(;\n    name::String,\n    penstock_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    reverse_penstock_map::AbstractDict = Dict{Base.UUID, Int}(),\n    internal::InfrastructureSystemsInternal = InfrastructureSystemsInternal(),\n)\n    return HydroPowerPlant(name, penstock_map, reverse_penstock_map, internal)\nend\n\n\"\"\"Get [`HydroPowerPlant`](@ref) `name`.\"\"\"\nget_name(value::HydroPowerPlant) = value.name\n\"\"\"Get [`HydroPowerPlant`](@ref) `penstock_map`.\"\"\"\nget_penstock_map(value::HydroPowerPlant) = value.penstock_map\n\"\"\"Get [`HydroPowerPlant`](@ref) `reverse_penstock_map`.\"\"\"\nget_reverse_penstock_map(value::HydroPowerPlant) = value.reverse_penstock_map\n\n\"\"\"\nAttribute to represent renewable power plants.\n\n# Arguments\n- `name::String`: Name of the renewable power plant\n- `pcc_map::Dict{Int, Vector{Base.UUID}}`: Mapping of PCC numbers to unit UUIDs (multiple units can share a PCC)\n- `reverse_pcc_map::Dict{Base.UUID, Int}`: Reverse mapping from unit UUID to PCC number\n- `internal::InfrastructureSystemsInternal`: (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nstruct RenewablePowerPlant <: PowerPlant\n    name::String\n    pcc_map::Dict{Int, Vector{Base.UUID}}\n    reverse_pcc_map::Dict{Base.UUID, Int}\n    internal::InfrastructureSystemsInternal\nend\n\n# Deserialization variant: converts string-keyed dicts from JSON\nfunction RenewablePowerPlant(\n    name::String,\n    pcc_map::Dict{String, <:Any},\n    reverse_pcc_map::Dict{String, <:Any},\n    internal::InfrastructureSystemsInternal,\n)\n    return RenewablePowerPlant(\n        name,\n        Dict{Int, Vector{Base.UUID}}(\n            parse(Int, k) => Base.UUID.(v) for (k, v) in pcc_map\n        ),\n        Dict{Base.UUID, Int}(Base.UUID(k) => v for (k, v) in reverse_pcc_map),\n        internal,\n    )\nend\n\n\"\"\"\n    RenewablePowerPlant(; name, pcc_map, reverse_pcc_map, internal)\n\nConstruct a [`RenewablePowerPlant`](@ref). This supports multiple point of common coupling (PCC) connections.\n\n# Arguments\n- `name::String`: Name of the renewable power plant\n- `pcc_map::Dict{Int, Vector{Base.UUID}}`: (default: empty dict) Mapping of PCC numbers to unit UUIDs\n- `reverse_pcc_map::Dict{Base.UUID, Int}`: (default: empty dict) Reverse mapping from unit UUID to PCC number\n- `internal::InfrastructureSystemsInternal`: (default: `InfrastructureSystemsInternal()`) (**Do not modify.**) PowerSystems internal reference\n\"\"\"\nfunction RenewablePowerPlant(;\n    name::String,\n    pcc_map::AbstractDict = Dict{Int, Vector{Base.UUID}}(),\n    reverse_pcc_map::AbstractDict = Dict{Base.UUID, Int}(),\n    internal::InfrastructureSystemsInternal = InfrastructureSystemsInternal(),\n)\n    return RenewablePowerPlant(name, pcc_map, reverse_pcc_map, internal)\nend\n\n\"\"\"Get [`RenewablePowerPlant`](@ref) `name`.\"\"\"\nget_name(value::RenewablePowerPlant) = value.name\n\"\"\"Get [`RenewablePowerPlant`](@ref) `pcc_map`.\"\"\"\nget_pcc_map(value::RenewablePowerPlant) = value.pcc_map\n\"\"\"Get [`RenewablePowerPlant`](@ref) `reverse_pcc_map`.\"\"\"\nget_reverse_pcc_map(value::RenewablePowerPlant) = value.reverse_pcc_map\n\n\"\"\"\n    get_components_in_shaft(sys::System, plant::ThermalPowerPlant, shaft_number::Int)\n\nGet all thermal generators connected to a specific shaft in a [`ThermalPowerPlant`](@ref).\n\n# Arguments\n- `sys::System`: The system containing the components\n- `plant::ThermalPowerPlant`: The thermal power plant\n- `shaft_number::Int`: The shaft number to query\n\n# Returns\n- `Vector{ThermalGen}`: Vector of thermal generators on the specified shaft\n\n# Throws\n- `ArgumentError`: If the shaft number does not exist in the plant\n\"\"\"\nfunction get_components_in_shaft(\n    sys::System,\n    plant::ThermalPowerPlant,\n    shaft_number::Int,\n)\n    shaft_map = get_shaft_map(plant)\n    if !haskey(shaft_map, shaft_number)\n        throw(\n            IS.ArgumentError(\n                \"Shaft number $shaft_number does not exist in plant $(get_name(plant))\",\n            ),\n        )\n    end\n\n    uuids = shaft_map[shaft_number]\n    all_components = get_associated_components(sys, plant; component_type = ThermalGen)\n    # Filter to only include components on this shaft\n    return filter(c -> IS.get_uuid(c) in uuids, all_components)\nend\n\n\"\"\"\n    get_components_in_penstock(sys::System, plant::HydroPowerPlant, penstock_number::Int)\n\nGet all hydro generators connected to a specific penstock in a [`HydroPowerPlant`](@ref).\n\n# Arguments\n- `sys::System`: The system containing the components\n- `plant::HydroPowerPlant`: The hydro power plant\n- `penstock_number::Int`: The penstock number to query\n\n# Returns\n- `Vector{Union{HydroTurbine, HydroPumpTurbine}}`: Vector of hydro generators on the specified penstock\n\n# Throws\n- `ArgumentError`: If the penstock number does not exist in the plant\n\"\"\"\nfunction get_components_in_penstock(\n    sys::System,\n    plant::HydroPowerPlant,\n    penstock_number::Int,\n)\n    penstock_map = get_penstock_map(plant)\n    if !haskey(penstock_map, penstock_number)\n        throw(\n            IS.ArgumentError(\n                \"Penstock number $penstock_number does not exist in plant $(get_name(plant))\",\n            ),\n        )\n    end\n\n    uuids = penstock_map[penstock_number]\n    all_components = get_associated_components(sys, plant; component_type = HydroGen)\n    # Filter to only include components on this penstock\n    return filter(c -> IS.get_uuid(c) in uuids, all_components)\nend\n\n\"\"\"\n    get_components_in_pcc(sys::System, plant::RenewablePowerPlant, pcc_number::Int)\n\nGet all renewable generators and storage devices connected to a specific PCC in a [`RenewablePowerPlant`](@ref).\n\n# Arguments\n- `sys::System`: The system containing the components\n- `plant::RenewablePowerPlant`: The renewable power plant\n- `pcc_number::Int`: The PCC (point of common coupling) number to query\n\n# Returns\n- `Vector{Union{RenewableGen, EnergyReservoirStorage}}`: Vector of components on the specified PCC\n\n# Throws\n- `ArgumentError`: If the PCC number does not exist in the plant\n\"\"\"\nfunction get_components_in_pcc(\n    sys::System,\n    plant::RenewablePowerPlant,\n    pcc_number::Int,\n)\n    pcc_map = get_pcc_map(plant)\n    if !haskey(pcc_map, pcc_number)\n        throw(\n            IS.ArgumentError(\n                \"PCC number $pcc_number does not exist in plant $(get_name(plant))\",\n            ),\n        )\n    end\n\n    uuids = pcc_map[pcc_number]\n    all_components = get_associated_components(sys, plant)\n    # Filter to only include components on this PCC\n    return filter(c -> IS.get_uuid(c) in uuids, all_components)\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::ThermalGen, attribute::ThermalPowerPlant; shaft_number::Int)\n\nAdd a thermal generator to a [`ThermalPowerPlant`](@ref) by associating it with a shaft number.\nThis attaches the plant as a supplemental attribute to the generator and records the\ngenerator's UUID in the plant's shaft map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to add to the plant\n- `attribute::ThermalPowerPlant`: The thermal power plant\n- `shaft_number::Int`: The shaft number to associate with the generator\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::ThermalPowerPlant;\n    shaft_number::Int,\n)\n    uuid = IS.get_uuid(component)\n    if haskey(attribute.reverse_shaft_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is already part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    IS.add_supplemental_attribute!(sys.data, component, attribute)\n    if haskey(attribute.shaft_map, shaft_number)\n        push!(attribute.shaft_map[shaft_number], uuid)\n    else\n        attribute.shaft_map[shaft_number] = [uuid]\n    end\n    attribute.reverse_shaft_map[uuid] = shaft_number\n    return\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::Union{HydroPumpTurbine, HydroTurbine}, attribute::HydroPowerPlant; penstock_number::Int)\n\nAdd a hydro generator to a [`HydroPowerPlant`](@ref) by associating it with a penstock number.\nThis attaches the plant as a supplemental attribute to the generator and records the\ngenerator's UUID in the plant's penstock map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::Union{HydroPumpTurbine, HydroTurbine}`: The hydro generator to add to the plant\n- `attribute::HydroPowerPlant`: The hydro power plant\n- `penstock_number::Int`: The penstock number to associate with the generator\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::Union{HydroPumpTurbine, HydroTurbine},\n    attribute::HydroPowerPlant,\n    penstock_number::Int,\n)\n    uuid = IS.get_uuid(component)\n    if haskey(attribute.reverse_penstock_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is already part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    IS.add_supplemental_attribute!(sys.data, component, attribute)\n    if haskey(attribute.penstock_map, penstock_number)\n        push!(attribute.penstock_map[penstock_number], uuid)\n    else\n        attribute.penstock_map[penstock_number] = [uuid]\n    end\n    attribute.reverse_penstock_map[uuid] = penstock_number\n    return\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::HydroDispatch, attribute::HydroPowerPlant, args...; kwargs...)\n\nError-throwing overload. HydroDispatch is not supported in a HydroPowerPlant.\n\"\"\"\nfunction add_supplemental_attribute!(\n    ::System,\n    ::HydroDispatch,\n    ::HydroPowerPlant,\n    args...;\n    kwargs...,\n)\n    throw(\n        IS.ArgumentError(\n            \"HydroDispatch is not supported in a HydroPowerPlant. Consider using HydroTurbine instead.\",\n        ),\n    )\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::Union{RenewableGen, EnergyReservoirStorage}, attribute::RenewablePowerPlant; pcc_number::Int=1)\n\nAdd a renewable generator or storage to a [`RenewablePowerPlant`](@ref) by associating it with a PCC number.\nThis attaches the plant as a supplemental attribute to the generator and records the\ngenerator's UUID in the plant's PCC map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::Union{RenewableGen, EnergyReservoirStorage}`: The renewable generator or storage to add to the plant\n- `attribute::RenewablePowerPlant`: The renewable power plant\n- `pcc_number::Int`: (default: 1) The PCC (point of common coupling) number to associate with the generator\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::Union{RenewableGen, EnergyReservoirStorage},\n    attribute::RenewablePowerPlant,\n    pcc_number::Int,\n)\n    uuid = IS.get_uuid(component)\n    if haskey(attribute.reverse_pcc_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Component $(get_name(component)) is already part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    IS.add_supplemental_attribute!(sys.data, component, attribute)\n    if haskey(attribute.pcc_map, pcc_number)\n        push!(attribute.pcc_map[pcc_number], uuid)\n    else\n        attribute.pcc_map[pcc_number] = [uuid]\n    end\n    attribute.reverse_pcc_map[uuid] = pcc_number\n    return\nend\n\n\"\"\"\n    remove_supplemental_attribute!(sys::System, component::ThermalGen, attribute::ThermalPowerPlant)\n\nRemove a thermal generator from a [`ThermalPowerPlant`](@ref).\nThis removes the plant as a supplemental attribute from the generator and removes the\ngenerator's UUID from the plant's shaft map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to remove from the plant\n- `attribute::ThermalPowerPlant`: The thermal power plant\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::ThermalPowerPlant,\n)\n    uuid = IS.get_uuid(component)\n    if !haskey(attribute.reverse_shaft_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is not part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    shaft_number = attribute.reverse_shaft_map[uuid]\n    filter!(x -> x != uuid, attribute.shaft_map[shaft_number])\n    if isempty(attribute.shaft_map[shaft_number])\n        delete!(attribute.shaft_map, shaft_number)\n    end\n    delete!(attribute.reverse_shaft_map, uuid)\n    IS.remove_supplemental_attribute!(sys.data, component, attribute)\n    return\nend\n\n\"\"\"\n    remove_supplemental_attribute!(sys::System, component::Union{HydroPumpTurbine, HydroTurbine}, attribute::HydroPowerPlant)\n\nRemove a hydro generator from a [`HydroPowerPlant`](@ref).\nThis removes the plant as a supplemental attribute from the generator and removes the\ngenerator's UUID from the plant's penstock map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::Union{HydroPumpTurbine, HydroTurbine}`: The hydro generator to remove from the plant\n- `attribute::HydroPowerPlant`: The hydro power plant\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::Union{HydroPumpTurbine, HydroTurbine},\n    attribute::HydroPowerPlant,\n)\n    uuid = IS.get_uuid(component)\n    if !haskey(attribute.reverse_penstock_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is not part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    penstock_number = attribute.reverse_penstock_map[uuid]\n    filter!(x -> x != uuid, attribute.penstock_map[penstock_number])\n    if isempty(attribute.penstock_map[penstock_number])\n        delete!(attribute.penstock_map, penstock_number)\n    end\n    delete!(attribute.reverse_penstock_map, uuid)\n    IS.remove_supplemental_attribute!(sys.data, component, attribute)\n    return\nend\n\n\"\"\"\n    remove_supplemental_attribute!(sys::System, component::Union{RenewableGen, EnergyReservoirStorage}, attribute::RenewablePowerPlant)\n\nRemove a renewable generator or storage from a [`RenewablePowerPlant`](@ref).\nThis removes the plant as a supplemental attribute from the generator and removes the\ngenerator's UUID from the plant's PCC map.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::Union{RenewableGen, EnergyReservoirStorage}`: The renewable generator or storage to remove from the plant\n- `attribute::RenewablePowerPlant`: The renewable power plant\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::Union{RenewableGen, EnergyReservoirStorage},\n    attribute::RenewablePowerPlant,\n)\n    uuid = IS.get_uuid(component)\n    if !haskey(attribute.reverse_pcc_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is not part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    pcc_number = attribute.reverse_pcc_map[uuid]\n    filter!(x -> x != uuid, attribute.pcc_map[pcc_number])\n    if isempty(attribute.pcc_map[pcc_number])\n        delete!(attribute.pcc_map, pcc_number)\n    end\n    delete!(attribute.reverse_pcc_map, uuid)\n    IS.remove_supplemental_attribute!(sys.data, component, attribute)\n    return\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::ThermalGen, attribute::CombinedCycleBlock; hrsg_number::Int)\n\nAdd a thermal generator to a [`CombinedCycleBlock`](@ref) by associating it with an HRSG number.\nOnly generators with CT (combustion turbine as HRSG input) or CA (combined cycle steam part as HRSG output)\nprime mover types can be added.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to add to the block (must have prime mover type CT or CA)\n- `attribute::CombinedCycleBlock`: The combined cycle block\n- `hrsg_number::Int`: The HRSG number to associate with the generator\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::CombinedCycleBlock;\n    hrsg_number::Int,\n)\n    uuid = IS.get_uuid(component)\n    if haskey(attribute.ct_hrsg_map, uuid) || haskey(attribute.ca_hrsg_map, uuid)\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is already part of block $(get_name(attribute))\",\n            ),\n        )\n    end\n    prime_mover = get_prime_mover_type(component)\n    if prime_mover == PrimeMovers.CT\n        IS.add_supplemental_attribute!(sys.data, component, attribute)\n        if haskey(attribute.hrsg_ct_map, hrsg_number)\n            push!(attribute.hrsg_ct_map[hrsg_number], uuid)\n        else\n            attribute.hrsg_ct_map[hrsg_number] = [uuid]\n        end\n        attribute.ct_hrsg_map[uuid] = [hrsg_number]\n    elseif prime_mover == PrimeMovers.CA\n        IS.add_supplemental_attribute!(sys.data, component, attribute)\n        if haskey(attribute.hrsg_ca_map, hrsg_number)\n            push!(attribute.hrsg_ca_map[hrsg_number], uuid)\n        else\n            attribute.hrsg_ca_map[hrsg_number] = [uuid]\n        end\n        attribute.ca_hrsg_map[uuid] = [hrsg_number]\n    else\n        throw(\n            IS.ArgumentError(\n                \"Invalid prime mover type $prime_mover for generator $(get_name(component)). Only CT and CA generators can be added to a CombinedCycleBlock.\",\n            ),\n        )\n    end\n    return\nend\n\n\"\"\"\n    remove_supplemental_attribute!(sys::System, component::ThermalGen, attribute::CombinedCycleBlock)\n\nRemove a thermal generator from a [`CombinedCycleBlock`](@ref).\nThis removes the block as a supplemental attribute from the generator and removes the\ngenerator's UUID from the block's HRSG maps.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to remove from the block\n- `attribute::CombinedCycleBlock`: The combined cycle block\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::CombinedCycleBlock,\n)\n    uuid = IS.get_uuid(component)\n    # Check if this is a CT (HRSG input)\n    if haskey(attribute.ct_hrsg_map, uuid)\n        hrsg_numbers = attribute.ct_hrsg_map[uuid]\n        for hrsg_number in hrsg_numbers\n            filter!(x -> x != uuid, attribute.hrsg_ct_map[hrsg_number])\n            if isempty(attribute.hrsg_ct_map[hrsg_number])\n                delete!(attribute.hrsg_ct_map, hrsg_number)\n            end\n        end\n        delete!(attribute.ct_hrsg_map, uuid)\n        # Check if this is a CA (HRSG output)\n    elseif haskey(attribute.ca_hrsg_map, uuid)\n        hrsg_numbers = attribute.ca_hrsg_map[uuid]\n        for hrsg_number in hrsg_numbers\n            filter!(x -> x != uuid, attribute.hrsg_ca_map[hrsg_number])\n            if isempty(attribute.hrsg_ca_map[hrsg_number])\n                delete!(attribute.hrsg_ca_map, hrsg_number)\n            end\n        end\n        delete!(attribute.ca_hrsg_map, uuid)\n    else\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is not part of block $(get_name(attribute))\",\n            ),\n        )\n    end\n    IS.remove_supplemental_attribute!(sys.data, component, attribute)\n    return\nend\n\n\"\"\"\n    add_supplemental_attribute!(sys::System, component::ThermalGen, attribute::CombinedCycleFractional; exclusion_group::Int)\n\nAdd a thermal generator to a [`CombinedCycleFractional`](@ref) by associating it with an exclusion group number.\nOnly generators with CC (combined cycle) prime mover type can be added.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to add to the plant (must have prime mover type CC)\n- `attribute::CombinedCycleFractional`: The combined cycle fractional plant\n- `exclusion_group::Int`: The exclusion group number to associate with the generator\n\"\"\"\nfunction add_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::CombinedCycleFractional;\n    exclusion_group::Int,\n)\n    uuid = IS.get_uuid(component)\n    # Check if already in any exclusion group\n    for (_, uuids) in attribute.operation_exclusion_map\n        if uuid in uuids\n            throw(\n                IS.ArgumentError(\n                    \"Generator $(get_name(component)) is already part of plant $(get_name(attribute))\",\n                ),\n            )\n        end\n    end\n    prime_mover = get_prime_mover_type(component)\n    if prime_mover != PrimeMovers.CC\n        throw(\n            IS.ArgumentError(\n                \"Invalid prime mover type $prime_mover for generator $(get_name(component)). Only CC generators can be added to a CombinedCycleFractional.\",\n            ),\n        )\n    end\n    IS.add_supplemental_attribute!(sys.data, component, attribute)\n    if haskey(attribute.operation_exclusion_map, exclusion_group)\n        push!(attribute.operation_exclusion_map[exclusion_group], uuid)\n    else\n        attribute.operation_exclusion_map[exclusion_group] = [uuid]\n    end\n    attribute.inverse_operation_exclusion_map[uuid] = exclusion_group\n    return\nend\n\n\"\"\"\n    remove_supplemental_attribute!(sys::System, component::ThermalGen, attribute::CombinedCycleFractional)\n\nRemove a thermal generator from a [`CombinedCycleFractional`](@ref).\nThis removes the plant as a supplemental attribute from the generator and removes the\ngenerator's UUID from the plant's exclusion maps.\n\n# Arguments\n- `sys::System`: The system containing the generator\n- `component::ThermalGen`: The thermal generator to remove from the plant\n- `attribute::CombinedCycleFractional`: The combined cycle fractional plant\n\"\"\"\nfunction remove_supplemental_attribute!(\n    sys::System,\n    component::ThermalGen,\n    attribute::CombinedCycleFractional,\n)\n    uuid = IS.get_uuid(component)\n    found = false\n    for (group, _) in attribute.operation_exclusion_map\n        if uuid in attribute.operation_exclusion_map[group]\n            filter!(x -> x != uuid, attribute.operation_exclusion_map[group])\n            if isempty(attribute.operation_exclusion_map[group])\n                delete!(attribute.operation_exclusion_map, group)\n            end\n            found = true\n            break\n        end\n    end\n    if !found\n        throw(\n            IS.ArgumentError(\n                \"Generator $(get_name(component)) is not part of plant $(get_name(attribute))\",\n            ),\n        )\n    end\n    delete!(attribute.inverse_operation_exclusion_map, uuid)\n    IS.remove_supplemental_attribute!(sys.data, component, attribute)\n    return\nend\n\n\"\"\"\n    get_components_in_exclusion_group(sys::System, plant::CombinedCycleFractional, exclusion_group::Int)\n\nGet all thermal generators in a specific exclusion group of a [`CombinedCycleFractional`](@ref).\n\n# Arguments\n- `sys::System`: The system containing the components\n- `plant::CombinedCycleFractional`: The combined cycle fractional plant\n- `exclusion_group::Int`: The exclusion group number to query\n\n# Returns\n- `Vector{ThermalGen}`: Vector of thermal generators in the specified exclusion group\n\n# Throws\n- `ArgumentError`: If the exclusion group does not exist in the plant\n\"\"\"\nfunction get_components_in_exclusion_group(\n    sys::System,\n    plant::CombinedCycleFractional,\n    exclusion_group::Int,\n)\n    exclusion_map = get_operation_exclusion_map(plant)\n    if !haskey(exclusion_map, exclusion_group)\n        throw(\n            IS.ArgumentError(\n                \"Exclusion group $exclusion_group does not exist in plant $(get_name(plant))\",\n            ),\n        )\n    end\n\n    uuids = exclusion_map[exclusion_group]\n    all_components = get_associated_components(sys, plant; component_type = ThermalGen)\n    # Filter to only include components in this exclusion group\n    return filter(c -> IS.get_uuid(c) in uuids, all_components)\nend\n"
  },
  {
    "path": "src/subsystems.jl",
    "content": "\"\"\"\nAdd a new subsystem to the system.\n\"\"\"\nfunction add_subsystem!(sys::System, subsystem_name::AbstractString)\n    _check_num_subsystems(sys)\n    IS.add_subsystem!(sys.data, subsystem_name)\nend\n\n\"\"\"\nReturn the number of subsystems stored in the system.\n\"\"\"\nget_num_subsystems(sys::System) = IS.get_num_subsystems(sys.data)\n\n\"\"\"\nReturn an iterator of all subsystem names in the system.\n\"\"\"\nget_subsystems(sys::System) = IS.get_subsystems(sys.data)\n\n\"\"\"\nRemove a subsystem from the system.\n\nThrows ArgumentError if the subsystem name is not stored.\n\"\"\"\nremove_subsystem!(sys::System, subsystem_name::AbstractString) =\n    IS.remove_subsystem!(sys.data, subsystem_name)\n\n\"\"\"\nReturn true if the system has one or more subsystems.\n\"\"\"\nfunction has_subsystems(sys::System)\n    for _ in get_subsystems(sys)\n        return true\n    end\n\n    return false\nend\n\n\"\"\"\nAdd a component to a subsystem.\n\"\"\"\nfunction add_component_to_subsystem!(\n    sys::System,\n    subsystem_name::AbstractString,\n    component::Component,\n)\n    IS.add_component_to_subsystem!(sys.data, subsystem_name, component)\n    handle_component_addition_to_subsystem!(sys, subsystem_name, component)\n    return\nend\n\n\"\"\"\nPeforms component-type-specific postprocessing when a component is added to a subsystem.\n\"\"\"\nhandle_component_addition_to_subsystem!(\n    ::System,\n    subsystem_name::AbstractString,\n    ::Component,\n) = nothing\n\n\"\"\"\nPeforms component-type-specific postprocessing when a component is removed from a subsystem.\n\"\"\"\nhandle_component_removal_from_subsystem!(\n    ::System,\n    subsystem_name::AbstractString,\n    ::Component,\n) = nothing\n\nfunction handle_component_addition_to_subsystem!(\n    sys::System,\n    subsystem_name::AbstractString,\n    component::StaticInjectionSubsystem,\n)\n    for subcomponent in get_subcomponents(component)\n        if !is_assigned_to_subsystem(sys, subcomponent, subsystem_name)\n            add_component_to_subsystem!(sys, subsystem_name, subcomponent)\n        end\n    end\nend\n\nfunction handle_component_removal_from_subsystem!(\n    sys::System,\n    subsystem_name::AbstractString,\n    component::StaticInjectionSubsystem,\n)\n    for subcomponent in get_subcomponents(component)\n        if is_assigned_to_subsystem(sys, subcomponent, subsystem_name)\n            remove_component_from_subsystem!(sys, subsystem_name, subcomponent)\n        end\n    end\nend\n\n\"\"\"\nReturn a Generator of all components in the subsystem.\n\nThrows ArgumentError if the subsystem name is not stored.\n\"\"\"\nget_subsystem_components(sys::System, subsystem_name::AbstractString) =\n    IS.get_subsystem_components(sys.data, subsystem_name)\n\n\"\"\"\nRemove a component from a subsystem.\n\nThrows ArgumentError if the subsystem name or component is not stored.\n\"\"\"\nfunction remove_component_from_subsystem!(\n    sys::System,\n    subsystem_name::AbstractString,\n    component::Component,\n)\n    IS.remove_component_from_subsystem!(sys.data, subsystem_name, component)\n    handle_component_removal_from_subsystem!(sys, subsystem_name, component)\n    return\nend\n\n\"\"\"\nRemove a component from all subsystems it belongs to.\n\"\"\"\nremove_component_from_subsystems!(\n    sys::System,\n    component::Component,\n) = remove_component_from_subsystems!(sys.data, component)\n\n\"\"\"\nReturn true if the component is in the subsystem.\n\"\"\"\nhas_component(\n    sys::System,\n    subsystem_name::AbstractString,\n    component::Component,\n) = IS.has_component(sys.data, subsystem_name, component)\n\n\"\"\"\nReturn a Vector of subsystem names that contain the component.\n\"\"\"\nget_assigned_subsystems(\n    sys::System,\n    component::Component,\n) = IS.get_assigned_subsystems(sys.data, component)\n\n\"\"\"\nReturn true if the component is assigned to any subsystems.\n\"\"\"\nis_assigned_to_subsystem(sys::System, component::Component) =\n    IS.is_assigned_to_subsystem(sys.data, component)\n\n\"\"\"\nReturn true if the component is assigned to the subsystem.\n\"\"\"\nis_assigned_to_subsystem(\n    sys::System,\n    component::Component,\n    subsystem_name::AbstractString,\n) = IS.is_assigned_to_subsystem(sys.data, component, subsystem_name)\n\n\"\"\"\nReturn the UUIDs of all components in the given subsystem.\n\"\"\"\nget_component_uuids(sys::System, subsystem_name::AbstractString) =\n    IS.get_component_uuids(sys.data, subsystem_name)\n\nfunction check_subsystems(sys::System, component::Component)\n    _check_arc_consistency(sys, component)\n    _check_branch_consistency(sys, component)\n    _check_device_service_consistency(sys, component)\n    _check_subcomponent_consistency(sys, component)\n    _check_topological_consistency(sys, component)\n    return\nend\n\nfunction _check_num_subsystems(sys::System)\n    num_buses = length(sys.bus_numbers)\n    if get_num_subsystems(sys) >= num_buses\n        throw(\n            IS.InvalidValue(\n                \"The number of subsystems cannot exceed the number of buses: $num_buses\",\n            ),\n        )\n    end\nend\n\n_check_arc_consistency(::System, ::Component) = nothing\n_check_branch_consistency(::System, ::Component) = nothing\n_check_device_service_consistency(::System, ::Component) = nothing\n_check_subcomponent_consistency(::System, ::Component) = nothing\n\nfunction _check_arc_consistency(sys::System, arc::Arc)\n    msg = \"An arc must be assigned to the same subystems as its buses.\"\n    _check_subsystem_assignments(sys, arc, get_from(arc), msg; symmetric_diff = false)\n    _check_subsystem_assignments(sys, arc, get_to(arc), msg; symmetric_diff = false)\nend\n\nfunction _check_branch_consistency(sys::System, branch::Branch)\n    msg = \"A branch must be assigned to the same subystems as its arc.\"\n    _check_subsystem_assignments(sys, branch, get_arc(branch), msg; symmetric_diff = true)\nend\n\nfunction _check_branch_consistency(\n    sys::System,\n    branch::ThreeWindingTransformer,\n)\n    msg = \"A branch must be assigned to the same subystems as its arc.\"\n    arcs = [\n        get_primary_star_arc(branch),\n        get_secondary_star_arc(branch),\n        get_tertiary_star_arc(branch),\n    ]\n    for arc in arcs\n        _check_subsystem_assignments(sys, branch, arc, msg; symmetric_diff = true)\n    end\nend\n\nfunction _check_branch_consistency(sys::System, branch::AreaInterchange)\n    msg = \"An area interchange must be assigned to the same subystems as its areas.\"\n    _check_subsystem_assignments(\n        sys,\n        branch,\n        get_from_area(branch),\n        msg;\n        symmetric_diff = false,\n    )\n    _check_subsystem_assignments(\n        sys,\n        branch,\n        get_to_area(branch),\n        msg;\n        symmetric_diff = false,\n    )\nend\n\nfunction _check_subcomponent_consistency(sys::System, component::StaticInjectionSubsystem)\n    for subcomponent in get_subcomponents(component)\n        _check_subsystem_assignments(\n            sys,\n            component,\n            subcomponent,\n            \"StaticInjectionSubsystems and their subcomponents be assigned to the same subsystems.\";\n            symmetric_diff = true,\n        )\n    end\nend\n\nfunction _check_topological_consistency(sys::System, component::Component)\n    for name in fieldnames(typeof(component))\n        val = getproperty(component, name)\n        if val isa Topology\n            _check_subsystem_assignments(\n                sys,\n                component,\n                val,\n                \"A component must be assigned to at least one subsystem as its topological component(s).\";\n                symmetric_diff = false,\n            )\n        end\n    end\nend\n\nfunction _check_device_service_consistency(sys::System, device::Device)\n    if !supports_services(device)\n        return\n    end\n    for service in get_services(device)\n        _check_subsystem_assignments(\n            sys,\n            device,\n            service,\n            \"A service must be assigned to the same subsystems as its contributing devices.\";\n            symmetric_diff = true,\n        )\n    end\n    return\nend\n\nfunction _check_subsystem_assignments(\n    sys::System,\n    component1::Component,\n    component2::Component,\n    message::AbstractString;\n    symmetric_diff::Bool,\n)\n    subsys1 = get_assigned_subsystems(sys, component1)\n    subsys2 = get_assigned_subsystems(sys, component2)\n    diff_method = symmetric_diff ? symdiff : setdiff\n    diff = diff_method(subsys1, subsys2)\n    if !isempty(diff)\n        throw(\n            IS.InvalidValue(\n                message *\n                \"$(summary(component1)): $subsys1 \" *\n                \"$(summary(component2)): $subsys2 \" *\n                \"diff: $diff\",\n            ),\n        )\n    end\nend\n"
  },
  {
    "path": "src/utils/IO/base_checks.jl",
    "content": "function orderedlimits(\n    limits::Union{NamedTuple{(:min, :max), Tuple{Float64, Float64}}, Nothing},\n    limitsname::String,\n)\n    if isa(limits, Nothing)\n        @info \"'$limitsname' limits defined as nothing\"\n    else\n        if limits.max < limits.min\n            throw(DataFormatError(\"$limitsname limits not in ascending order\"))\n        end\n    end\n\n    return limits\nend\n\n\"\"\"Throws DataFormatError if the array is not in ascending order.\"\"\"\nfunction check_ascending_order(array::Array{Int}, name::AbstractString)\n    for (i, num) in enumerate(array)\n        if i > 1 && num < array[i - 1]\n            throw(DataFormatError(\"$name Numbers are not in ascending order.\"))\n        end\n    end\n\n    return\nend\n\n\"\"\"Checks if a PowerSystemDevice has a field or subfield name.\"\"\"\nfunction isafield(component::Component, field::Symbol)\n    function _wrap(t, d = [])\n        fn = fieldnames(typeof(t))\n        for n in fn\n            push!(d, n)\n            f = getfield(t, n)\n            if length(fieldnames(typeof(f))) > 0\n                _wrap(f, d)\n            end\n        end\n        return d\n    end\n\n    allfields = _wrap(component)\n    return field in allfields\nend\n"
  },
  {
    "path": "src/utils/IO/branchdata_checks.jl",
    "content": "\nfunction sanitize_component!(line::Union{MonitoredLine, Line}, sys::System)\n    sanitize_angle_limits!(line)\n    return\nend\n\nfunction validate_component_with_system(line::Union{MonitoredLine, Line}, sys::System)\n    is_valid = true\n    if !check_endpoint_voltages(line)\n        is_valid = false\n    elseif !correct_rate_limits!(line, get_base_power(sys))\n        is_valid = false\n    end\n    return is_valid\nend\n\nfunction sanitize_angle_limits!(line::Union{Line, MonitoredLine})\n    max_limit = pi / 2\n    min_limit = -pi / 2\n\n    orderedlimits(line.angle_limits, \"Angles\")\n\n    if (line.angle_limits.max / max_limit > 3) ||\n       (-1 * line.angle_limits.min / max_limit > 3)\n        @warn \"The angle limits provided is larger than 3π/2 radians.\\n \" *\n              \"PowerSystems inferred the data provided in degrees and will transform it to radians\" _group =\n            IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n\n        if line.angle_limits.max / max_limit >= 0.99\n            line.angle_limits = (\n                min = line.angle_limits.min,\n                max = min(line.angle_limits.max * (π / 180), max_limit),\n            )\n        else\n            line.angle_limits =\n                (min = line.angle_limits.min, max = min(line.angle_limits.max, max_limit))\n        end\n\n        if (-1 * line.angle_limits.min / max_limit > 0.99)\n            line.angle_limits = (\n                min = max(line.angle_limits.min * (π / 180), min_limit),\n                max = line.angle_limits.max,\n            )\n        else\n            line.angle_limits =\n                (min = max(line.angle_limits.min, min_limit), max = line.angle_limits.max)\n        end\n    else\n        if line.angle_limits.max >= max_limit && line.angle_limits.min <= min_limit\n            line.angle_limits = (min = min_limit, max = max_limit)\n        elseif line.angle_limits.max >= max_limit && line.angle_limits.min >= min_limit\n            line.angle_limits = (min = line.angle_limits.min, max = max_limit)\n        elseif line.angle_limits.max <= max_limit && line.angle_limits.min <= min_limit\n            line.angle_limits = (min = min_limit, max = line.angle_limits.max)\n        elseif line.angle_limits.max == 0.0 && line.angle_limits.min == 0.0\n            line.angle_limits = (min = min_limit, max = max_limit)\n        end\n    end\n    return\nend\n\n# Building Synthetic Power Transmission Networks of Many Voltage Levels, Spanning Multiple Areas\n# https://scholarspace.manoa.hawaii.edu/server/api/core/bitstreams/47b28d1e-7019-415f-9a88-e1ed37556342/content\n# https://www.mdpi.com/1996-1073/10/8/1233/htm\nconst MVA_LIMITS_LINES = Dict(\n    69.0 => (min = 12.0, max = 115.0),\n    115.0 => (min = 92.0, max = 255.0),\n    138.0 => (min = 141.0, max = 344.0),\n    161.0 => (min = 176.0, max = 410.0),\n    230.0 => (min = 327.0, max = 797.0),\n    345.0 => (min = 897.0, max = 1494.0),\n    500.0 => (min = 1732.0, max = 3464.0))\n\n# Building Synthetic Power Transmission Networks of Many Voltage Levels, Spanning Multiple Areas\n# https://scholarspace.manoa.hawaii.edu/server/api/core/bitstreams/47b28d1e-7019-415f-9a88-e1ed37556342/content\n# https://www.mdpi.com/1996-1073/10/8/1233/htm\nconst MVA_LIMITS_TRANSFORMERS = Dict(\n    69.0 => (min = 7.0, max = 115.0),\n    115.0 => (min = 17.0, max = 140.0),\n    138.0 => (min = 15.0, max = 239.0),\n    161.0 => (min = 30.0, max = 276.0),\n    230.0 => (min = 50.0, max = 470.0),\n    345.0 => (min = 160.0, max = 702.0),\n    500.0 => (min = 150.0, max = 1383.0),\n    765.0 => (min = 2200.0, max = 6900.0), # This value is 3x the SIL value from https://neos-guide.org/wp-content/uploads/2022/04/line_flow_approximation.pdf\n)\n\nfunction check_rating_values(line::Union{Line, MonitoredLine}, basemva::Float64)\n    arc = get_arc(line)\n    vrated = get_base_voltage(get_to(arc))\n    voltage_levels = collect(keys(MVA_LIMITS_LINES))\n    closestV_ix = findmin(abs.(voltage_levels .- vrated))\n    closest_v_level = voltage_levels[closestV_ix[2]]\n    closest_rate_range = MVA_LIMITS_LINES[closest_v_level]\n\n    # Assuming that the rate is in pu\n    for field in [:rating, :rating_b, :rating_c]\n        rating_value = getfield(line, field)\n        if isnothing(rating_value)\n            @assert field ∈ [:rating_b, :rating_c]\n            continue\n        end\n        if (rating_value >= 2.0 * closest_rate_range.max / basemva)\n            @warn \"$(field) $(round(rating_value*basemva; digits=2)) MW for $(get_name(line)) is 2x larger than the max expected rating $(closest_rate_range.max) MW for Line at a $(closest_v_level) kV Voltage level.\" _group =\n                IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n        elseif (rating_value >= closest_rate_range.max / basemva) ||\n               (rating_value <= closest_rate_range.min / basemva)\n            @info \"$(field) $(round(rating_value*basemva; digits=2)) MW for $(get_name(line)) is outside the expected range $(closest_rate_range) MW for Line at a $(closest_v_level) kV Voltage level.\" _group =\n                IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n        end\n    end\n\n    return true\nend\n\n\"\"\"\nCalculates the line rating based on the formula for the maximum transfer limit over an impedance\n\"\"\"\nfunction line_rating_calculation(l::Union{Line, MonitoredLine})\n    theta_max = max(abs(l.angle_limits.min), abs(l.angle_limits.max))\n\n    g = l.r / (l.r^2 + l.x^2)\n    b = -l.x / (l.r^2 + l.x^2)\n    y_mag = sqrt(g^2 + b^2)\n\n    from_voltage_limits = get_voltage_limits(get_arc(l).from)\n    to_voltage_limits = get_voltage_limits(get_arc(l).to)\n\n    fr_vmin = isnothing(from_voltage_limits) ? 0.9 : from_voltage_limits.min\n    to_vmin = isnothing(to_voltage_limits) ? 0.9 : from_voltage_limits.min\n\n    c_max = sqrt(fr_vmin^2 + to_vmin^2 - 2 * fr_vmin * to_vmin * cos(theta_max))\n    new_rate = y_mag * max(fr_vmin, to_vmin) * c_max\n\n    return new_rate\nend\n\nfunction correct_rate_limits!(branch::Union{Line, MonitoredLine}, basemva::Float64)\n    theoretical_line_rate_pu = line_rating_calculation(branch)\n    for field in [:rating, :rating_b, :rating_c]\n        rating_value = getfield(branch, field)\n        if isnothing(rating_value)\n            @assert field ∈ [:rating_b, :rating_c]\n            continue\n        end\n        if rating_value < 0.0\n            @error \"PowerSystems does not support negative line rates. $(field): $(rating)\"\n            return false\n        end\n        if rating_value == INFINITE_BOUND\n            @warn \"Data for branch $(summary(branch)) $(field) is set to INFINITE_BOUND. \\\n                PowerSystems will set a rate from line parameters to $(theoretical_line_rate_pu)\" _group =\n                IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n            setfield!(branch, field, theoretical_line_rate_pu)\n        end\n    end\n\n    return check_rating_values(branch, basemva)\nend\n\nfunction check_endpoint_voltages(line::Union{Line, MonitoredLine})\n    is_valid = true\n    arc = get_arc(line)\n    from_voltage = get_base_voltage(get_from(arc))\n    to_voltage = get_base_voltage(get_to(arc))\n    percent_difference = abs(from_voltage - to_voltage) / ((from_voltage + to_voltage) / 2)\n    if percent_difference > BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL\n        is_valid = false\n        @error \"Voltage endpoints of $(get_name(line)) have more than $(BRANCH_BUS_VOLTAGE_DIFFERENCE_TOL*100)% difference, cannot create Line. /\n        Check if the data corresponds to transformer data.\"\n    end\n\n    return is_valid\nend\n\nconst TYPICAL_XFRM_REACTANCE = (min = 0.05, max = 0.2) # per-unit\n\nfunction validate_component_with_system(\n    xfrm::TwoWindingTransformer,\n    sys::System,\n)\n    is_valid_reactance = check_transformer_reactance(xfrm)\n    is_valid_rating = check_rating_values(xfrm, get_base_power(sys))\n    return is_valid_reactance && is_valid_rating\nend\n\nfunction check_rating_values(\n    xfrm::TwoWindingTransformer,\n    ::Float64,\n)\n    arc = get_arc(xfrm)\n    v_from = get_base_voltage(get_from(arc))\n    v_to = get_base_voltage(get_to(arc))\n    vrated = maximum([v_from, v_to])\n    voltage_levels = collect(keys(MVA_LIMITS_TRANSFORMERS))\n    closestV_ix = findmin(abs.(voltage_levels .- vrated))\n    closest_v_level = voltage_levels[closestV_ix[2]]\n    closest_rate_range = MVA_LIMITS_TRANSFORMERS[closest_v_level]\n    device_base_power = get_base_power(xfrm)\n    # The rate is in device pu\n    for field in [:rating, :rating_b, :rating_c]\n        rating_value = getproperty(xfrm, field)\n        if isnothing(rating_value)\n            @assert field ∈ [:rating_b, :rating_c]\n            continue\n        end\n        if (rating_value * device_base_power >= 2.0 * closest_rate_range.max)\n            @warn \"$(field) $(round(rating_value*device_base_power; digits=2)) MW for $(get_name(xfrm)) is 2x larger than the max expected rating $(closest_rate_range.max) MW for Transformer at a $(closest_v_level) kV Voltage level.\" _group =\n                IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n        elseif (rating_value * device_base_power >= closest_rate_range.max) ||\n               (rating_value * device_base_power <= closest_rate_range.min)\n            @info \"$(field) $(round(rating_value*device_base_power; digits=2)) MW for $(get_name(xfrm)) is outside the expected range $(closest_rate_range) MW for Transformer at a $(closest_v_level) kV Voltage level.\" _group =\n                IS.LOG_GROUP_PARSING maxlog = PS_MAX_LOG\n        end\n    end\n    return true\nend\n\nfunction check_transformer_reactance(\n    xfrm::TwoWindingTransformer,\n)\n    x_pu = getproperty(xfrm, :x)\n    if x_pu < TYPICAL_XFRM_REACTANCE.min\n        @warn \"Transformer $(get_name(xfrm)) per-unit reactance $(x_pu) is lower than the typical range $(TYPICAL_XFRM_REACTANCE). \\\n            Check if the reactance source data is correct.\" _group = IS.LOG_GROUP_PARSING maxlog =\n            PS_MAX_LOG\n    end\n    if x_pu > TYPICAL_XFRM_REACTANCE.max\n        @warn \"Transformer $(get_name(xfrm)) per-unit reactance $(x_pu) is higher than the typical range $(TYPICAL_XFRM_REACTANCE). \\\n            Check if the reactance source data is correct.\" _group = IS.LOG_GROUP_PARSING maxlog =\n            PS_MAX_LOG\n    end\n    return true\nend\n"
  },
  {
    "path": "src/utils/IO/system_checks.jl",
    "content": "\n### Utility Functions needed for the construction of the Power System, mostly used for consistency checking ####\n\n## Check that all the buses have a type defintion and that bus types are consistent with generator connections ##\n\nfunction buscheck(sys::System)\n    buses = get_components(ACBus, sys)\n    for b in buses\n        b_type = get_bustype(b)\n        if isnothing(b_type)\n            @warn \"Bus/Nodes data does not contain information to build an a network\" maxlog =\n                10\n        end\n    end\n    return\nend\n\n## Slack Bus Definition ##\n\nfunction slack_bus_check(buses)\n    slack = -9\n    for b in buses\n        if b.bustype == ACBusTypes.REF\n            slack = b.number\n            break\n        end\n    end\n    if slack == -9\n        @error \"Model doesn't contain a slack bus\"\n    end\n    return\nend\n\n# TODO: Check for islanded Buses\n\n# check for minimum timediff\nfunction minimumtimestep(time_series::Array{T}) where {T <: TimeSeriesData}\n    if length(time_series[1].data) > 1\n        timeseries = time_series[1].data\n        n = length(timeseries) - 1\n        ts = []\n        for i in 1:n\n            push!(\n                ts,\n                TimeSeries.timestamp(timeseries)[n + 1] -\n                TimeSeries.timestamp(timeseries)[n],\n            )\n        end\n        return minimum(ts)\n    else\n        ts = Dates.Dates.Minute(1)\n        return ts\n    end\nend\n\nfunction critical_components_check(sys::System)\n    critical_component_types = [ACBus, Generator, ElectricLoad]\n    for component_type in critical_component_types\n        components = get_available_components(component_type, sys)\n        if length(components) == 0\n            @warn \"There are no $(component_type) Components in the System\"\n        end\n    end\nend\n\n\"\"\"\n    adequacy_check(sys::System)\n\nChecks the system for sum(generator ratings) >= sum(load ratings).\n\n# Arguments\n- `sys::System`: system\n\"\"\"\nfunction adequacy_check(sys::System)\n    gen = total_capacity_rating(sys)\n    load = total_load_rating(sys)\n    load > gen && @warn \"System peak load ($load) exceeds total capacity capability ($gen).\"\n    return\nend\n\n\"\"\"\n    total_load_rating(sys::System)\n\nSum of load ratings.\n\n# Arguments\n- `sys::System`: system\n\"\"\"\nfunction total_load_rating(sys::System)\n    # Assumes system is in system base\n    base_power = get_base_power(sys)\n    static_loads = get_available_components(StaticLoad, sys)\n    sl = isempty(static_loads) ? 0.0 : sum(get_max_active_power.(static_loads)) * base_power\n    @debug \"System has $sl MW of StaticLoad\" _group = IS.LOG_GROUP_SYSTEM_CHECKS\n    # Total load calculation for admittances assumes P = Real(V^2*Y) with V=1.0\n    fa_loads = get_available_components(FixedAdmittance, sys)\n    fa = isempty(fa_loads) ? 0.0 : sum(real.(1.0 .* get_Y.(fa_loads))) * base_power\n    @debug \"System has $fa MW of FixedAdmittance\" _group = IS.LOG_GROUP_SYSTEM_CHECKS\n    sa_loads = get_available_components(SwitchedAdmittance, sys)\n    sa = isempty(sa_loads) ? 0.0 : sum(real.(1.0 .* get_Y.(sa_loads))) * base_power\n    @debug \"System has $fa MW of SwitchedAdmittance\" _group = IS.LOG_GROUP_SYSTEM_CHECKS\n    total_load = sl + fa + sa\n    @debug \"Total System Load: $total_load\" _group = IS.LOG_GROUP_SYSTEM_CHECKS\n    return total_load\nend\n\n\"\"\"\n    total_capacity_rating(sys::System)\n\nSum of system generator and storage ratings.\n\n# Arguments\n- `sys::System`: system\n\"\"\"\nfunction total_capacity_rating(sys::System)\n    total = 0\n    for component_type in (Generator, Storage)\n        components = get_available_components(component_type, sys)\n        if !isempty(components)\n            component_total = sum(get_rating.(components)) * get_base_power(sys)\n            @debug \"total rating for $component_type = $component_total\" _group =\n                IS.LOG_GROUP_SYSTEM_CHECKS\n            total += component_total\n        end\n    end\n\n    @debug \"Total System capacity: $total\" _group = IS.LOG_GROUP_SYSTEM_CHECKS\n    return total\nend\n"
  },
  {
    "path": "src/utils/conversion.jl",
    "content": "\"Convert Tuple to Min Max Named Tuple\"\nBase.convert(::Type{MinMax}, input::Tuple{Float64, Float64}) =\n    (min = input[1], max = input[2])\n\n\"Convert Tuple to Up Down Named Tuple\"\nBase.convert(::Type{UpDown}, input::Tuple{Float64, Float64}) =\n    (up = input[1], down = input[2])\n"
  },
  {
    "path": "src/utils/generate_struct_files.jl",
    "content": "\"\"\"\nGenerate a Julia source code file for one struct from a `StructDefinition`.\n\nRefer to `StructDefinition` and `StructField` for descriptions of the available fields.\n\n# Arguments\n- `definition::StructDefinition`: Defines the struct and all fields.\n- `filename::AbstractString`: Add the struct definition to this JSON file. Defaults to\n  `src/descriptors/power_system_structs.json`\n- `output_directory::AbstractString`: Generate the files in this directory. Defaults to\n  `src/models/generated`\n\"\"\"\nfunction generate_struct_file(\n    definition::StructDefinition;\n    filename = nothing,\n    output_directory = nothing,\n)\n    generate_struct_files(\n        [definition];\n        filename = filename,\n        output_directory = output_directory,\n    )\nend\n\n\"\"\"\nGenerate Julia source code files for multiple structs from a iterable of `StructDefinition`\ninstances.\n\nRefer to `StructDefinition` and `StructField` for descriptions of the available fields.\n\n# Arguments\n- `definitions`: Defines the structs and all fields.\n- `filename::AbstractString`: Add the struct definition to this JSON file. Defaults to\n  `src/descriptors/power_system_structs.json`\n- `output_directory::AbstractString`: Generate the files in this directory. Defaults to\n  `src/models/generated`\n\"\"\"\nfunction generate_struct_files(definitions; filename = nothing, output_directory = nothing)\n    if isnothing(filename)\n        filename = joinpath(\n            dirname(Base.find_package(\"PowerSystems\")),\n            \"descriptors\",\n            \"power_system_structs.json\",\n        )\n    end\n    if isnothing(output_directory)\n        output_directory =\n            joinpath(dirname(Base.find_package(\"PowerSystems\")), \"models\", \"generated\")\n    end\n\n    IS.generate_struct_files(\n        definitions;\n        filename = filename,\n        output_directory = output_directory,\n    )\nend\n"
  },
  {
    "path": "src/utils/logging.jl",
    "content": "\"\"\"\nCreates console and file loggers.\n\n**Note:** Log messages may not be written to the file until flush() or close() is called on\nthe returned logger.\n\n# Arguments\n- `console_level = Logging.Error`: level for console messages\n- `file_level = Logging.Info`: level for file messages\n- `filename::Union{Nothing, AbstractString} = \"power-systems.log\"`: log file; pass nothing\n  to disable file logging\n\n# Example\n```julia\nlogger = configure_logging(console_level = Logging.Info)\n@info \"log message\"\nclose(logger)\n```\n\"\"\"\nfunction configure_logging(;\n    console_level = Logging.Error,\n    file_level = Logging.Info,\n    filename::Union{Nothing, AbstractString} = \"power-systems.log\",\n)\n    return IS.configure_logging(;\n        console = true,\n        console_stream = stderr,\n        console_level = console_level,\n        file = filename !== nothing,\n        filename = filename,\n        file_level = file_level,\n        file_mode = \"w+\",\n        tracker = nothing,\n        set_global = true,\n    )\nend\n"
  },
  {
    "path": "src/utils/print.jl",
    "content": "# \"smart\" summary and REPL printing\n\nfunction Base.summary(sys::System)\n    return \"System (base power $(get_base_power(sys)))\"\nend\n\nfunction Base.show(io::IO, sys::System)\n    show_system_table(io, sys; backend = :auto)\n\n    if IS.get_num_components(sys) > 0\n        show_components_table(io, sys; backend = :auto)\n    end\n\n    println(io)\n    IS.show_time_series_data(io, sys.data; backend = :auto)\n    return\nend\n\nBase.show(io::IO, ::MIME\"text/plain\", sys::System) = show(io, sys)\n\nfunction Base.summary(io::IO, tech::DeviceParameter)\n    print(io, \"$(typeof(tech))\")\nend\n\nfunction Base.summary(io::IO, data::OperationalCost)\n    field_msgs = []\n    for field_name in fieldnames(typeof(data))\n        val = getproperty(data, field_name)\n        # Only the most important fields\n        (val isa ProductionVariableCostCurve) &&\n            push!(field_msgs, \"$(field_name): $(typeof(val))\")\n        (val isa TimeSeriesKey) &&\n            push!(field_msgs, \"$(field_name): time series \\\"$(get_name(val))\\\"\")\n    end\n    isempty(field_msgs) && return\n    print(io, \"$(typeof(data)) composed of \")\n    join(io, field_msgs, \", \")\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", data::OperationalCost)\n    print(io, \"$(typeof(data)): \")\n    for field_name in fieldnames(typeof(data))\n        val = getproperty(data, field_name)\n        val_printout =\n            replace(sprint(show, \"text/plain\", val; context = io), \"\\n\" => \"\\n  \")\n        print(io, \"\\n  $(field_name): $val_printout\")\n    end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", data::PowerSystemTableData)\n    println(io, \"$(typeof(data)):\")\n    println(io, \"  directory:  $(data.directory)\")\n    if !isnothing(data.timeseries_metadata_file)\n        println(io, \"  timeseries_metadata_file:  $(data.timeseries_metadata_file)\")\n    end\n    println(io, \"  base_power:  $(data.base_power)\")\n    for (field, df) in data.category_to_df\n        print(io, \"  $field:  \")\n        println(io, \"$(summary(df))\")\n    end\nend\n\nfunction Base.show(io::IO, ist::Component)\n    print(io, IS.strip_module_name(typeof(ist)), \"(\")\n    is_first = true\n    for (name, field_type) in zip(fieldnames(typeof(ist)), fieldtypes(typeof(ist)))\n        getter_name = Symbol(\"get_$name\")\n        if field_type <: InfrastructureSystemsInternal\n            continue\n        elseif hasproperty(PowerSystems, getter_name)\n            getter_func = getproperty(PowerSystems, getter_name)\n            val = getter_func(ist)\n        else\n            val = getproperty(ist, name)\n        end\n        if is_first\n            is_first = false\n        else\n            print(io, \", \")\n        end\n        print(io, val)\n    end\n    print(io, \")\")\n    return\nend\n\nfunction Base.show(io::IO, ::MIME\"text/plain\", ist::Component)\n    default_units = false\n    if !has_units_setting(ist)\n        print(io, \"\\n\")\n        @warn(\n            \"SystemUnitSetting not defined, using NATURAL_UNITS for displaying device specification.\"\n        )\n        set_units_setting!(\n            ist,\n            SystemUnitsSettings(100.0, UNIT_SYSTEM_MAPPING[\"NATURAL_UNITS\"]),\n        )\n        default_units = true\n    end\n    try\n        print(io, summary(ist), \":\")\n        for name in fieldnames(typeof(ist))\n            obj = getproperty(ist, name)\n            getter_name = Symbol(\"get_$name\")\n            if (obj isa InfrastructureSystemsInternal) && !default_units\n                print(io, \"\\n   \")\n                show(io, MIME\"text/plain\"(), obj.units_info)\n                continue\n            elseif obj isa InfrastructureSystemsType ||\n                   obj isa Vector{<:InfrastructureSystemsComponent}\n                val = summary(getproperty(ist, name))\n            elseif hasproperty(PowerSystems, getter_name)\n                getter_func = getproperty(PowerSystems, getter_name)\n                try\n                    val = getter_func(ist)\n                catch e\n                    @warn \"$(e.msg) Printing in DEVICE_BASE instead.\"\n                    val = with_units_base(ist, \"DEVICE_BASE\") do\n                        getter_func(ist)\n                    end\n                end\n            else\n                val = getproperty(ist, name)\n            end\n            print(io, \"\\n   \", name, \": \", val)\n        end\n        print(\n            io,\n            \"\\n   \",\n            \"has_supplemental_attributes\",\n            \": \",\n            string(has_supplemental_attributes(ist)),\n        )\n        print(io, \"\\n   \", \"has_time_series\", \": \", string(has_time_series(ist)))\n    finally\n        if default_units\n            set_units_setting!(ist, nothing)\n        end\n    end\n    return\nend\n\n\"\"\"\nShow all components of the given type in a table.\n\n# Arguments\n- `sys::System`: System containing the components.\n- `component_type::Type{<:Component}`: Type to display. Must be a concrete type.\n- `additional_columns::Union{Dict, Vector}`: Additional columns to display.\n  The Dict option is a mapping of column name to function. The function must accept\n  a component.\n  The Vector option is an array of field names for the `component_type`.\n\nExtra keyword arguments are forwarded to PrettyTables.pretty_table.\n\n# Examples\n```julia\nshow_components(sys, ThermalStandard)\nshow_components(sys, ThermalStandard, Dict(\"has_time_series\" => x -> has_time_series(x)))\nshow_components(sys, ThermalStandard, [:active_power, :reactive_power])\n```\n\"\"\"\nfunction show_components(\n    sys::System,\n    component_type::Type{<:Component},\n    additional_columns::Union{Dict, Vector} = Dict();\n    kwargs...,\n)\n    show_components(stdout, sys, component_type, additional_columns; kwargs...)\n    return\nend\n\nfunction show_components(\n    io::IO,\n    sys::System,\n    component_type::Type{<:Component},\n    additional_columns::Union{Dict, Vector} = Dict();\n    kwargs...,\n)\n    IS.show_components(\n        io,\n        sys.data.components,\n        component_type,\n        additional_columns;\n        kwargs...,\n    )\n    return\nend\n\n# The placement of the type in the argument list has been confusing for people. Support\n# it both before and after the system.\n\nshow_components(\n    component_type::Type{<:Component},\n    sys::System,\n    additional_columns::Union{Dict, Vector} = Dict();\n    kwargs...,\n) = show_components(sys, component_type, additional_columns; kwargs...)\n\nshow_components(\n    io::IO,\n    component_type::Type{<:Component},\n    sys::System,\n    additional_columns::Union{Dict, Vector} = Dict();\n    kwargs...,\n) = show_components(io, sys, component_type, additional_columns; kwargs...)\n\n\"\"\"\nShow a table with the summary of time series attached to the system.\n\"\"\"\nfunction show_time_series(sys::System)\n    IS.show_time_series_data(stdout, sys.data)\nend\n"
  },
  {
    "path": "src/utils/print_pt_v2.jl",
    "content": "function _make_backend_entry(backend::Val{T}) where {T}\n    return backend\nend\n\nfunction _make_backend_entry(backend::Symbol)\n    return Val(backend)\nend\n\nfunction _handle_kwargs(kwargs...)\n    kwargs = Dict{Symbol, Any}(kwargs...)\n    if haskey(kwargs, :stand_alone)\n        kwargs[:standalone] = kwargs[:stand_alone]\n        delete!(kwargs, :stand_alone)\n    end\n    backend_entry = pop!(kwargs, :backend, Val(:auto))\n    kwargs[:backend] = _make_backend_entry(backend_entry)\n    return kwargs\nend\n\nfunction show_system_table(io::IO, sys::System; kwargs...)\n    header = [\"Property\", \"Value\"]\n    num_components = get_num_components(sys)\n    table = [\n        \"Name\" isnothing(get_name(sys)) ? \"\" : get_name(sys)\n        \"Description\" isnothing(get_description(sys)) ? \"\" : get_description(sys)\n        \"System Units Base\" string(get_units_base(sys))\n        \"Base Power\" string(get_base_power(sys))\n        \"Base Frequency\" string(get_frequency(sys))\n        \"Num Components\" string(num_components)\n    ]\n    PrettyTables.pretty_table(\n        io,\n        table;\n        header = header,\n        title = \"System\",\n        alignment = :l,\n        _handle_kwargs(kwargs)...,\n    )\n    return\nend\n\nfunction show_components_table(io::IO, sys::System; kwargs...)\n    header = [\"Type\", \"Count\"]\n    components = sys.data.components\n\n    static_types = Vector{DataType}()\n    dynamic_types = Vector{DataType}()\n    for component_type in keys(components.data)\n        if component_type <: DynamicInjection\n            push!(dynamic_types, component_type)\n        else\n            push!(static_types, component_type)\n        end\n    end\n    static_data = Array{Any, 2}(undef, length(static_types), length(header))\n    dynamic_data = Array{Any, 2}(undef, length(dynamic_types), length(header))\n\n    static_type_names = [(IS.strip_module_name(x), x) for x in static_types]\n    sort!(static_type_names; by = x -> x[1])\n    for (i, (type_name, type)) in enumerate(static_type_names)\n        vals = components.data[type]\n        static_data[i, 1] = type_name\n        static_data[i, 2] = length(vals)\n    end\n\n    if !isempty(static_types)\n        println(io)\n        PrettyTables.pretty_table(\n            io,\n            static_data;\n            header = header,\n            title = \"Static Components\",\n            alignment = :l,\n            _handle_kwargs(kwargs)...,\n        )\n    end\n\n    dynamic_type_names = [(IS.strip_module_name(x), x) for x in dynamic_types]\n    sort!(dynamic_type_names; by = x -> x[1])\n    for (i, (type_name, type)) in enumerate(dynamic_type_names)\n        vals = components.data[type]\n        dynamic_data[i, 1] = type_name\n        dynamic_data[i, 2] = length(vals)\n    end\n\n    if !isempty(dynamic_types)\n        println(io)\n        PrettyTables.pretty_table(\n            io,\n            dynamic_data;\n            header = header,\n            title = \"Dynamic Components\",\n            alignment = :l,\n            _handle_kwargs(kwargs)...,\n        )\n    end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/html\", sys::System)\n    show_system_table(io, sys; backend = :html, stand_alone = false)\n\n    if get_num_components(sys) > 0\n        show_components_table(\n            io,\n            sys;\n            backend = Val(:html),\n            tf = PrettyTables.tf_html_simple,\n            standalone = false,\n        )\n    end\n\n    println(io)\n    IS.show_time_series_data(\n        io,\n        sys.data;\n        backend = Val(:html),\n        tf = PrettyTables.tf_html_simple,\n        standalone = false,\n    )\n    return\nend\n"
  },
  {
    "path": "src/utils/print_pt_v3.jl",
    "content": "# The predefined table format recipes for HTML output got removed in PT v3.\n# This is the CSS recipe copie from PT v2 for simple HTML tables.\nconst tf_html_simple = PrettyTables.HtmlTableFormat(;\n    css = \"\"\"\n    table, td, th {\n        border-collapse: collapse;\n        font-family: sans-serif;\n    }\n\n    td, th {\n        border-bottom: 0;\n        padding: 4px\n    }\n\n    tr:nth-child(odd) {\n        background: #eee;\n    }\n\n    tr:nth-child(even) {\n        background: #fff;\n    }\n\n    tr.header {\n        background: #fff !important;\n        font-weight: bold;\n    }\n\n    tr.subheader {\n        background: #fff !important;\n        color: dimgray;\n    }\n\n    tr.headerLastRow {\n        border-bottom: 2px solid black;\n    }\n\n    th.rowNumber, td.rowNumber {\n        text-align: right;\n    }\n    \"\"\",\n)\n\nfunction show_system_table(io::IO, sys::System; kwargs...)\n    column_labels = [\"Property\", \"Value\"]\n    num_components = get_num_components(sys)\n    table = [\n        \"Name\" isnothing(get_name(sys)) ? \"\" : get_name(sys)\n        \"Description\" isnothing(get_description(sys)) ? \"\" : get_description(sys)\n        \"System Units Base\" string(get_units_base(sys))\n        \"Base Power\" string(get_base_power(sys))\n        \"Base Frequency\" string(get_frequency(sys))\n        \"Num Components\" string(num_components)\n    ]\n    PrettyTables.pretty_table(\n        io,\n        table;\n        column_labels = column_labels,\n        title = \"System\",\n        alignment = :l,\n        kwargs...,\n    )\n    return\nend\n\nfunction show_components_table(io::IO, sys::System; kwargs...)\n    column_labels = [\"Type\", \"Count\"]\n    components = sys.data.components\n\n    static_types = Vector{DataType}()\n    dynamic_types = Vector{DataType}()\n    for component_type in keys(components.data)\n        if component_type <: DynamicInjection\n            push!(dynamic_types, component_type)\n        else\n            push!(static_types, component_type)\n        end\n    end\n    static_data = Array{Any, 2}(undef, length(static_types), length(column_labels))\n    dynamic_data = Array{Any, 2}(undef, length(dynamic_types), length(column_labels))\n\n    static_type_names = [(IS.strip_module_name(x), x) for x in static_types]\n    sort!(static_type_names; by = x -> x[1])\n    for (i, (type_name, type)) in enumerate(static_type_names)\n        vals = components.data[type]\n        static_data[i, 1] = type_name\n        static_data[i, 2] = length(vals)\n    end\n\n    if !isempty(static_types)\n        println(io)\n        PrettyTables.pretty_table(\n            io,\n            static_data;\n            column_labels = column_labels,\n            title = \"Static Components\",\n            alignment = :l,\n            kwargs...,\n        )\n    end\n\n    dynamic_type_names = [(IS.strip_module_name(x), x) for x in dynamic_types]\n    sort!(dynamic_type_names; by = x -> x[1])\n    for (i, (type_name, type)) in enumerate(dynamic_type_names)\n        vals = components.data[type]\n        dynamic_data[i, 1] = type_name\n        dynamic_data[i, 2] = length(vals)\n    end\n\n    if !isempty(dynamic_types)\n        println(io)\n        PrettyTables.pretty_table(\n            io,\n            dynamic_data;\n            column_labels = column_labels,\n            title = \"Dynamic Components\",\n            alignment = :l,\n            kwargs...,\n        )\n    end\nend\n\nfunction Base.show(io::IO, ::MIME\"text/html\", sys::System)\n    show_system_table(io, sys; backend = :html, stand_alone = false)\n\n    if get_num_components(sys) > 0\n        show_components_table(\n            io,\n            sys;\n            backend = :html,\n            table_format = tf_html_simple,\n            stand_alone = false,\n        )\n    end\n\n    println(io)\n    IS.show_time_series_data(\n        io,\n        sys.data;\n        backend = :html,\n        table_format = tf_html_simple,\n        stand_alone = false,\n    )\n    return\nend\n"
  },
  {
    "path": "test/Project.toml",
    "content": "[deps]\nAqua = \"4c88cf16-eb10-579e-8560-4a9242c79595\"\nCSV = \"336ed68f-0bac-5ca0-87d4-7b16caf5d00b\"\nDataFrames = \"a93c6f00-e57d-5684-b7b6-d8193f3e46c0\"\nDataStructures = \"864edb3b-99cc-5e75-8d2d-829cb0a9cfe8\"\nDates = \"ade2ca70-3891-5945-98fb-dc099432e06a\"\nDocStringExtensions = \"ffbed154-4ef7-542d-bbb7-c09d3a79fcae\"\nInfrastructureSystems = \"2cd47ed4-ca9b-11e9-27f2-ab636a7671f1\"\nInteractiveUtils = \"b77e0a4c-d291-57a0-90e8-8db25a27a240\"\nJSON3 = \"0f8b85d8-7281-11e9-16c2-39a750bddbf1\"\nLinearAlgebra = \"37e2e46d-f89d-539d-b4ee-838fcccc9c8e\"\nLogging = \"56ddb016-857b-54e1-b83d-db4d58db5568\"\nNLsolve = \"2774e3e8-f4cf-5e23-947b-6d7e65073b56\"\nPowerSystemCaseBuilder = \"f00506e0-b84f-492a-93c2-c0a9afc4364e\"\nPowerSystems = \"bcd98974-b02a-5e2f-9ee0-a103f5c450dd\"\nRandom = \"9a3f8284-a2c9-5f02-9a11-845980a1fd5c\"\nSparseArrays = \"2f01184e-e22b-5df5-ae63-d93ebab69eaf\"\nTest = \"8dfed614-e22c-5e08-85e1-65c5234f0b40\"\nTimeSeries = \"9e3dc215-6440-5c97-bce1-76c03772f85e\"\nUUIDs = \"cf7118a7-6976-5b1a-9a39-7adc72f591a4\"\nYAML = \"ddb6d928-2868-570f-bddf-ab3f9cf99eb6\"\n\n[compat]\nInfrastructureSystems = \"3\"\nPowerSystemCaseBuilder = \"^2\"\njulia = \"^1.10\"\n"
  },
  {
    "path": "test/common.jl",
    "content": "import InfrastructureSystems\nmutable struct TestDevice <: Device\n    name::String\nend\n\nmutable struct TestRenDevice <: RenewableGen\n    name::String\nend\n\nmutable struct TestInjector <: StaticInjection\n    name::String\nend\n\nstruct NonexistentComponent <: StaticInjection end\n\n\"\"\"Return the first component of type component_type that matches the name of other.\"\"\"\nfunction get_component_by_name(sys::System, component_type, other::Component)\n    for component in get_components(component_type, sys)\n        if get_name(component) == get_name(other)\n            return component\n        end\n    end\n\n    error(\"Did not find component $component\")\nend\n\n\"\"\"Return the Branch in the system that matches another by case-insensitive arc\nnames.\"\"\"\nfunction get_branch(sys::System, other::Branch)\n    for branch in get_components(Branch, sys)\n        if lowercase(other.arc.from.name) == lowercase(branch.arc.from.name) &&\n           lowercase(other.arc.to.name) == lowercase(branch.arc.to.name)\n            return branch\n        end\n    end\n\n    error(\"Did not find branch with buses $(other.arc.from.name) \", \"$(other.arc.to.name)\")\nend\n\nfunction create_rts_system(time_series_resolution = Dates.Hour(1))\n    data = PowerSystemTableData(RTS_GMLC_DIR, 100.0, DESCRIPTORS)\n    return System(data; time_series_resolution = time_series_resolution)\nend\n\nfunction create_system_with_dynamic_inverter()\n    nodes_OMIB = [\n        ACBus(\n            1, #number\n            \"Bus 1\", #Name\n            true, #available\n            \"REF\", #ACBusType (REF, PV, PQ)\n            0, #Angle in radians\n            1.06, #Voltage in pu\n            (min = 0.94, max = 1.06), #Voltage limits in pu\n            69,\n            nothing,\n            nothing,\n        ), #Base voltage in kV\n        ACBus(\n            2,\n            \"Bus 2\",\n            true,\n            \"PV\",\n            0,\n            1.045,\n            (min = 0.94, max = 1.06),\n            69,\n            nothing,\n            nothing,\n        ),\n    ]\n\n    battery = EnergyReservoirStorage(;\n        name = \"Battery\",\n        prime_mover_type = PrimeMovers.BA,\n        storage_technology_type = StorageTech.OTHER_CHEM,\n        available = true,\n        bus = nodes_OMIB[2],\n        initial_energy = 5.0,\n        state_of_charge_limits = (min = 5.0, max = 100.0),\n        rating = 0.0275, #Value in per_unit of the system\n        active_power = 0.01375,\n        input_active_power_limits = (min = 0.0, max = 50.0),\n        output_active_power_limits = (min = 0.0, max = 50.0),\n        reactive_power = 0.0,\n        reactive_power_limits = (min = -50.0, max = 50.0),\n        efficiency = (in = 0.80, out = 0.90),\n        base_power = 100.0,\n    )\n    converter = AverageConverter(\n        138.0, #Rated Voltage\n        100.0,\n    ) #Rated MVA\n\n    branch_OMIB = [\n        Line(\n            \"Line1\", #name\n            true, #available\n            0.0, #active power flow initial condition (from-to)\n            0.0, #reactive power flow initial condition (from-to)\n            Arc(; from = nodes_OMIB[1], to = nodes_OMIB[2]), #Connection between buses\n            0.01, #resistance in pu\n            0.05, #reactance in pu\n            (from = 0.0, to = 0.0), #susceptance in pu\n            18.046, #rate in MW\n            1.04,\n        ),\n    ]  #angle limits (-min and max)\n\n    dc_source = FixedDCSource(1500.0) #Not in the original data, guessed.\n\n    filt = LCLFilter(\n        0.08, #Series inductance lf in pu\n        0.003, #Series resitance rf in pu\n        0.074, #Shunt capacitance cf in pu\n        0.2, #Series reactance rg to grid connection (#Step up transformer or similar)\n        0.01,\n    ) #Series resistance lg to grid connection (#Step up transformer or similar)\n\n    pll = KauraPLL(\n        500.0, #ω_lp: Cut-off frequency for LowPass filter of PLL filter.\n        0.084, #k_p: PLL proportional gain\n        4.69,\n    ) #k_i: PLL integral gain\n\n    virtual_H = VirtualInertia(\n        2.0, #Ta:: VSM inertia constant\n        400.0, #kd:: VSM damping coefficient\n        20.0, #kω:: Frequency droop gain in pu\n        2 * pi * 50.0,\n    ) #ωb:: Rated angular frequency\n\n    Q_control = ReactivePowerDroop(\n        0.2, #kq:: Reactive power droop gain in pu\n        1000.0,\n    ) #ωf:: Reactive power cut-off low pass filter frequency\n\n    outer_control = OuterControl(virtual_H, Q_control)\n\n    vsc = VoltageModeControl(\n        0.59, #kpv:: Voltage controller proportional gain\n        736.0, #kiv:: Voltage controller integral gain\n        0.0, #kffv:: Binary variable enabling the voltage feed-forward in output of current controllers\n        0.0, #rv:: Virtual resistance in pu\n        0.2, #lv: Virtual inductance in pu\n        1.27, #kpc:: Current controller proportional gain\n        14.3, #kiv:: Current controller integral gain\n        0.0, #kffi:: Binary variable enabling the current feed-forward in output of current controllers\n        50.0, #ωad:: Active damping low pass filter cut-off frequency\n        0.2,\n    ) #kad:: Active damping gain\n\n    sys = System(100.0)\n    for bus in nodes_OMIB\n        add_component!(sys, bus)\n    end\n    for lines in branch_OMIB\n        add_component!(sys, lines)\n    end\n    add_component!(sys, battery)\n\n    test_inverter = DynamicInverter(\n        get_name(battery),\n        1.0, #ω_ref\n        converter, #Converter\n        outer_control, #OuterControl\n        vsc, #Voltage Source Controller\n        dc_source, #DC Source\n        pll, #Frequency Estimator\n        filt,\n    ) #Output Filter\n\n    add_component!(sys, test_inverter, battery)\n\n    return sys\nend\n\n\"\"\"\nCreate a system with supplemental attributes with the criteria below.\n\n- Two GeographicInfo instances each assigned to multiple components.\n- Two ThermalStandards each with two ForcedOutage instances and two PlannedOutage instances.\n- Each outage has time series.\n\"\"\"\nfunction create_system_with_outages()\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"c_sys5_uc\";\n        add_forecasts = true,\n    )\n    gens = collect(get_components(ThermalStandard, sys))\n    gen1 = gens[1]\n    gen2 = gens[2]\n    geo1 = GeographicInfo(; geo_json = Dict(\"type\" => \"Point\", \"coordinates\" => [1.0, 2.0]))\n    geo2 = GeographicInfo(; geo_json = Dict(\"type\" => \"Point\", \"coordinates\" => [3.0, 4.0]))\n    begin_time_series_update(sys) do\n        begin_supplemental_attributes_update(sys) do\n            add_supplemental_attribute!(sys, gen1, geo1)\n            add_supplemental_attribute!(sys, gen1.bus, geo1)\n            add_supplemental_attribute!(sys, gen2, geo2)\n            add_supplemental_attribute!(sys, gen2.bus, geo2)\n            initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n            end_time = Dates.DateTime(\"2020-01-01T23:00:00\")\n            dates = collect(initial_time:Dates.Hour(1):end_time)\n            fo1 = GeometricDistributionForcedOutage(;\n                mean_time_to_recovery = 1.0,\n                outage_transition_probability = 0.5,\n            )\n            fo2 = GeometricDistributionForcedOutage(;\n                mean_time_to_recovery = 2.0,\n                outage_transition_probability = 0.5,\n            )\n            po1 = PlannedOutage(; outage_schedule = \"1\")\n            po2 = PlannedOutage(; outage_schedule = \"2\")\n            add_supplemental_attribute!(sys, gen1, fo1)\n            add_supplemental_attribute!(sys, gen1, po1)\n            add_supplemental_attribute!(sys, gen2, fo2)\n            add_supplemental_attribute!(sys, gen2, po2)\n            for (i, outage) in enumerate((fo1, fo2, po1, po2))\n                data = collect(i:(i + 23))\n                ta = TimeSeries.TimeArray(dates, data, [\"1\"])\n                name = \"ts_$(i)\"\n                ts = SingleTimeSeries(; name = name, data = ta)\n                add_time_series!(sys, outage, ts)\n            end\n        end\n    end\n\n    return sys\nend\n\nfunction create_system_with_subsystems()\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"test_RTS_GMLC_sys\";\n        add_forecasts = true,\n        time_series_read_only = false,\n    )\n    add_subsystem!(sys, \"subsystem_1\")\n    for component in iterate_components(sys)\n        add_component_to_subsystem!(sys, \"subsystem_1\", component)\n    end\n\n    # TODO: Replace with multiple valid subsystems\n    return sys\nend\n\nfunction test_accessors(component)\n    ps_type = typeof(component)\n\n    for (field_name, field_type) in zip(fieldnames(ps_type), fieldtypes(ps_type))\n        if field_name === :name\n            func = getfield(InfrastructureSystems, Symbol(\"get_\" * string(field_name)))\n            _func! =\n                getfield(InfrastructureSystems, Symbol(\"set_\" * string(field_name) * \"!\"))\n        else\n            getter_name = Symbol(\"get_\" * string(field_name))\n            if !hasproperty(PowerSystems, getter_name)\n                continue\n            end\n            func = getfield(PowerSystems, getter_name)\n            if !hasmethod(func, (ps_type,))\n                continue\n            end\n            setter_name = Symbol(\"set_\" * string(field_name) * \"!\")\n            # In some cases there is a getter but no setter.\n            if hasproperty(PowerSystems, setter_name)\n                _func! = getfield(PowerSystems, setter_name)\n            else\n                _func! = nothing\n            end\n        end\n\n        val = func(component)\n        @test val isa field_type\n        try\n            if typeof(val) == Float64 || typeof(val) == Int\n                if !isnan(val)\n                    aux = val + 1\n                    if _func! !== nothing\n                        _func!(component, aux)\n                        @test func(component) == aux\n                    end\n                end\n            elseif typeof(val) == String\n                aux = val * \"1\"\n                if _func! !== nothing\n                    _func!(component, aux)\n                    @test func(component) == aux\n                end\n            elseif typeof(val) == Bool\n                aux = !val\n                if _func! !== nothing\n                    _func!(component, aux)\n                    @test func(component) == aux\n                end\n            else\n                _func! !== nothing && _func!(component, val)\n            end\n        catch MethodError\n            continue\n        end\n    end\nend\n\nfunction validate_serialization(\n    sys::System;\n    time_series_read_only = false,\n    runchecks = nothing,\n    assign_new_uuids = false,\n)\n    if runchecks === nothing\n        runchecks = PSY.get_runchecks(sys)\n    end\n    test_dir = mktempdir()\n    orig_dir = pwd()\n    cd(test_dir)\n\n    try\n        path = joinpath(test_dir, \"test_system_serialization.json\")\n        @info \"Serializing to $path\"\n        sys_ext = get_ext(sys)\n        sys_ext[\"data\"] = 5\n        ext_test_bus_name = \"\"\n        bus = collect(get_components(PSY.ACBus, sys))[1]\n        ext_test_bus_name = PSY.get_name(bus)\n        ext = PSY.get_ext(bus)\n        ext[\"test_field\"] = 1\n        to_json(sys, path; force = true)\n\n        data = open(path, \"r\") do io\n            JSON3.read(io)\n        end\n        @test data[\"data_format_version\"] == PSY.DATA_FORMAT_VERSION\n\n        sys2 = System(\n            path;\n            time_series_read_only = time_series_read_only,\n            runchecks = runchecks,\n            assign_new_uuids = assign_new_uuids,\n        )\n        isempty(get_bus_numbers(sys2)) && return false\n        sys_ext2 = get_ext(sys2)\n        sys_ext2[\"data\"] != 5 && return false\n        bus = PSY.get_component(PSY.ACBus, sys2, ext_test_bus_name)\n        ext = PSY.get_ext(bus)\n        ext[\"test_field\"] != 1 && return false\n        return sys2, PSY.compare_values(sys, sys2; compare_uuids = !assign_new_uuids)\n    finally\n        cd(orig_dir)\n    end\nend\n"
  },
  {
    "path": "test/runtests.jl",
    "content": "using Test\nusing Logging\nusing DataStructures\nusing Dates\nusing LinearAlgebra\nimport TimeSeries\nimport InteractiveUtils\nimport JSON3\nusing PowerSystemCaseBuilder\nimport PowerSystemCaseBuilder as PSB\nimport InfrastructureSystems as IS\nusing PowerSystems\nimport PowerSystems: PowerSystemTableData\nimport PowerSystems as PSY\n\nimport Aqua\nAqua.test_unbound_args(PowerSystems)\nAqua.test_undefined_exports(PowerSystems)\nAqua.test_ambiguities(PowerSystems)\nAqua.test_stale_deps(PowerSystems)\nAqua.test_deps_compat(PowerSystems)\n\nconst BASE_DIR = dirname(dirname(Base.find_package(\"PowerSystems\")))\nconst DATA_DIR = PSB.DATA_DIR\nconst TIME_SERIES_DIR = joinpath(DATA_DIR, \"forecasts\")\nconst MATPOWER_DIR = joinpath(DATA_DIR, \"matpower\")\nconst PSSE_RAW_DIR = joinpath(DATA_DIR, \"psse_raw\")\nconst PSSE_DYR_DIR = joinpath(DATA_DIR, \"psse_dyr\")\nconst PSSE_TEST_DIR = joinpath(DATA_DIR, \"PSSE_test\")\nconst RTS_GMLC_DIR = joinpath(DATA_DIR, \"RTS_GMLC\")\nconst TAMU_DIR = joinpath(DATA_DIR, \"ACTIVSg2000\")\nconst DESCRIPTORS = joinpath(RTS_GMLC_DIR, \"user_descriptors.yaml\")\nconst BAD_DATA = joinpath(DATA_DIR, \"bad_data_for_tests\")\n\nLOG_FILE = \"power-systems.log\"\nLOG_LEVELS = Dict(\n    \"Debug\" => Logging.Debug,\n    \"Info\" => Logging.Info,\n    \"Warn\" => Logging.Warn,\n    \"Error\" => Logging.Error,\n)\n\ninclude(\"common.jl\")\ninclude(joinpath(DATA_DIR, \"psy_data\", \"data_5bus_pu.jl\"))\ninclude(joinpath(DATA_DIR, \"psy_data\", \"data_14bus_pu.jl\"))\n\n\"\"\"\nCopied @includetests from https://github.com/ssfrr/TestSetExtensions.jl.\nIdeally, we could import and use TestSetExtensions.  Its functionality was broken by changes\nin Julia v0.7.  Refer to https://github.com/ssfrr/TestSetExtensions.jl/pull/7.\n\"\"\"\n\n\"\"\"\nIncludes the given test files, given as a list without their \".jl\" extensions.\nIf none are given it will scan the directory of the calling file and include all\nthe julia files.\n\"\"\"\nmacro includetests(testarg...)\n    if length(testarg) == 0\n        tests = []\n    elseif length(testarg) == 1\n        tests = testarg[1]\n    else\n        error(\"@includetests takes zero or one argument\")\n    end\n\n    quote\n        tests = $tests\n        rootfile = @__FILE__\n        if length(tests) == 0\n            tests = readdir(dirname(rootfile))\n            tests = filter(\n                f ->\n                    startswith(f, \"test_\") && endswith(f, \".jl\") && f != basename(rootfile),\n                tests,\n            )\n        else\n            tests = map(f -> string(f, \".jl\"), tests)\n        end\n        println()\n        for test in tests\n            print(splitext(test)[1], \": \")\n            include(test)\n            println()\n        end\n    end\nend\n\nfunction get_logging_level_from_env(env_name::String, default)\n    level = get(ENV, env_name, default)\n    return IS.get_logging_level(level)\nend\n\nfunction run_tests()\n    logging_config_filename = get(ENV, \"SIIP_LOGGING_CONFIG\", nothing)\n    if logging_config_filename !== nothing\n        config = IS.LoggingConfiguration(logging_config_filename)\n    else\n        config = IS.LoggingConfiguration(;\n            filename = LOG_FILE,\n            file_level = get_logging_level_from_env(\"SIIP_FILE_LOG_LEVEL\", \"Info\"),\n            console_level = get_logging_level_from_env(\"SIIP_CONSOLE_LOG_LEVEL\", \"Error\"),\n        )\n    end\n    console_logger = ConsoleLogger(config.console_stream, config.console_level)\n\n    IS.open_file_logger(config.filename, config.file_level) do file_logger\n        levels = (Logging.Info, Logging.Warn, Logging.Error)\n        multi_logger =\n            IS.MultiLogger([console_logger, file_logger], IS.LogEventTracker(levels))\n        global_logger(multi_logger)\n\n        if !isempty(config.group_levels)\n            IS.set_group_levels!(multi_logger, config.group_levels)\n        end\n\n        # Testing Topological components of the schema\n        @time @testset \"Begin PowerSystems tests\" begin\n            @includetests ARGS\n        end\n\n        @test length(IS.get_log_events(multi_logger.tracker, Logging.Error)) == 0\n        @info IS.report_log_summary(multi_logger)\n    end\nend\n\nlogger = global_logger()\n\ntry\n    run_tests()\nfinally\n    # Guarantee that the global logger is reset.\n    global_logger(logger)\n    nothing\nend\n"
  },
  {
    "path": "test/test_base_checks.jl",
    "content": "\n@testset \"Test base checks\" begin\n    unordered = [1, 4, 2, 6]\n\n    @test_throws(\n        PowerSystems.DataFormatError,\n        PowerSystems.check_ascending_order(unordered, \"test\")\n    )\n\n    ordered = sort(unordered)\n    PowerSystems.check_ascending_order(ordered, \"test\")\nend\n"
  },
  {
    "path": "test/test_base_power.jl",
    "content": "@testset \"Test zero base power correction\" begin\n    sys = @test_logs(\n        (:warn, r\".*changing device base power to match system base power.*\"),\n        match_mode = :any,\n        build_system(PSISystems, \"RTS_GMLC_DA_sys\"; force_build = true)\n    )\n    for comp in get_components(PSY.SynchronousCondenser, sys)\n        @test abs(get_base_power(comp)) > eps()\n    end\nend\n\nfunction thermal_with_base_power(bus::PSY.Bus, name::String, base_power::Float64)\n    return ThermalStandard(;\n        name = name,\n        available = true,\n        status = true,\n        bus = bus,\n        active_power = 1.0,\n        reactive_power = 0.0,\n        rating = 2.0,\n        active_power_limits = (min = 0, max = 2),\n        reactive_power_limits = (min = -2, max = 2),\n        ramp_limits = nothing,\n        operation_cost = ThermalGenerationCost(nothing),\n        base_power = base_power,\n        time_limits = nothing,\n        prime_mover_type = PrimeMovers.OT,\n        fuel = ThermalFuels.OTHER,\n        services = Device[],\n        dynamic_injector = nothing,\n        ext = Dict{String, Any}(),\n    )\nend\n\n@testset \"Test adding component with zero base power\" begin\n    sys = build_system(PSISystems, \"RTS_GMLC_DA_sys\")\n    bus = first(get_components(PSY.Bus, sys))\n    gen = thermal_with_base_power(bus, \"Test Gen with Zero Base Power\", 0.0)\n    @test_logs (:warn, \"Invalid range\") match_mode = :any add_component!(sys, gen)\n    gen2 = thermal_with_base_power(bus, \"Test Gen with Non-Zero Base Power\", 100.0)\n    @test_nowarn add_component!(sys, gen2)\n    # uncomment if we correct to non-zero base power.\n    #=\n    with_units_base(sys, \"SYSTEM_BASE\") do\n        gen_added = PSY.get_component(PSY.ThermalStandard, sys, \"Test Gen with Zero Base Power\")\n        PSY.set_reactive_power!(gen_added, 0.0)\n        @test !isnan(PSY.get_reactive_power(gen_added))\n    end\n    =#\nend\n"
  },
  {
    "path": "test/test_branchchecks_testing.jl",
    "content": "import TimeSeries: TimeArray\n\n@testset \"Time resolution\" begin\n    twomins = TimeArray([DateTime(today()) + Dates.Minute(i * 2) for i in 1:5], ones(5))\n    oneday = TimeArray([DateTime(today()) + Dates.Day(i) for i in 1:5], ones(5))\n    onesec = TimeArray([DateTime(today()) + Dates.Second(i) for i in 1:5], ones(5))\n    onehour = TimeArray([DateTime(today()) + Dates.Hour(i) for i in 1:5], ones(5))\n\n    @test PowerSystems.get_resolution(twomins) == Dates.Minute(2)\n    @test PowerSystems.get_resolution(oneday) == Dates.Day(1)\n    @test PowerSystems.get_resolution(onesec) == Dates.Second(1)\n    @test PowerSystems.get_resolution(onehour) == Dates.Hour(1)\nend\n\n@testset \"Angle limits\" begin\n    nodes5 = [\n        ACBus(\n            1,\n            \"nodeA\",\n            true,\n            PowerSystems.ACBusTypes.PV,\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        ),\n        ACBus(\n            2,\n            \"nodeB\",\n            true,\n            PowerSystems.ACBusTypes.PQ,\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        ),\n        ACBus(\n            3,\n            \"nodeC\",\n            true,\n            PowerSystems.ACBusTypes.PV,\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        ),\n        ACBus(\n            4,\n            \"nodeD\",\n            true,\n            PowerSystems.ACBusTypes.REF,\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        ),\n        ACBus(\n            5,\n            \"nodeE\",\n            true,\n            PowerSystems.ACBusTypes.PV,\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        ),\n    ]\n\n    branches_test = [\n        Line(\n            \"1\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[1], to = nodes5[2]),\n            0.00281,\n            0.0281,\n            (from = 0.00356, to = 0.00356),\n            400.0,\n            (min = -360.0, max = 360.0),\n        ),\n        Line(\n            \"2\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[1], to = nodes5[4]),\n            0.00304,\n            0.0304,\n            (from = 0.00329, to = 0.00329),\n            3960.0,\n            (min = -360.0, max = 75.0),\n        ),\n        Line(\n            \"3\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[1], to = nodes5[5]),\n            0.00064,\n            0.0064,\n            (from = 0.01563, to = 0.01563),\n            18812.0,\n            (min = -75.0, max = 360.0),\n        ),\n        Line(\n            \"4\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[2], to = nodes5[3]),\n            0.00108,\n            0.0108,\n            (from = 0.00926, to = 0.00926),\n            11148.0,\n            (min = 0.0, max = 0.0),\n        ),\n        Line(\n            \"5\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[3], to = nodes5[4]),\n            0.00297,\n            0.0297,\n            (from = 0.00337, to = 0.00337),\n            4053.0,\n            (min = -1.2, max = 60.0),\n        ),\n        Line(\n            \"6\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes5[4], to = nodes5[5]),\n            0.00297,\n            0.0297,\n            (from = 0.00337, to = 00.00337),\n            240.0,\n            (min = -1.17, max = 1.17),\n        ),\n    ]\n\n    foreach(x -> PowerSystems.sanitize_angle_limits!(x), branches_test)\n\n    @test branches_test[1].angle_limits == (min = -pi / 2, max = pi / 2)\n    @test branches_test[2].angle_limits == (min = -pi / 2, max = 75.0 * (π / 180))\n    @test branches_test[3].angle_limits == (min = -75.0 * (π / 180), max = pi / 2)\n    @test branches_test[4].angle_limits == (min = -pi / 2, max = pi / 2)\n    @test branches_test[5].angle_limits == (min = -1.2, max = 60.0 * (π / 180))\n    @test branches_test[6].angle_limits == (min = -1.17, max = 1.17)\n\n    bad_angle_limits = Line(\n        \"1\",\n        true,\n        0.0,\n        0.0,\n        Arc(; from = nodes5[1], to = nodes5[2]),\n        0.00281,\n        0.0281,\n        (from = 0.00356, to = 0.00356),\n        400.0,\n        (min = 360.0, max = -360.0),\n    )\n\n    @test_throws(\n        PowerSystems.DataFormatError,\n        PowerSystems.sanitize_angle_limits!(bad_angle_limits)\n    )\nend\n"
  },
  {
    "path": "test/test_busnumberchecks.jl",
    "content": "\nbase_dir = dirname(dirname(pathof(PowerSystems)))\n\n@testset \"Check bus index\" begin\n    # This signature is used to capture expected error logs from parsing matpower\n    test_bus_index =\n        () -> begin\n            sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n            @test sort([b.number for b in collect(get_components(ACBus, sys))]) ==\n                  [1, 2, 3, 4, 10]\n            @test sort(\n                collect(\n                    Set([b.arc.from.number for b in collect(get_components(Branch, sys))]),\n                ),\n            ) == [1, 2, 3, 4]\n            @test sort(\n                collect(\n                    Set([b.arc.to.number for b in collect(get_components(Branch, sys))]),\n                ),\n            ) == [2, 3, 4, 10]\n\n            # TODO: add test for loadzones testing MAPPING_BUSNUMBER2INDEX\n        end\n    @test_logs min_level = Logging.Error match_mode = :any test_bus_index()\nend\n\n@testset \"Test unique bus numbers\" begin\n    # This signature is used to capture expected error logs from parsing matpower\n    test_bus_numbers =\n        () -> begin\n            sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n            number = 100\n            bus1 = ACBus(;\n                number = number,\n                name = \"bus100\",\n                available = true,\n                bustype = ACBusTypes.PV,\n                angle = 1.0,\n                magnitude = 1.0,\n                voltage_limits = (min = -1.0, max = 1.0),\n                base_voltage = 1.0,\n            )\n            bus2 = ACBus(;\n                number = number,\n                name = \"bus101\",\n                available = true,\n                bustype = ACBusTypes.PV,\n                angle = 1.0,\n                magnitude = 1.0,\n                voltage_limits = (min = -1.0, max = 1.0),\n                base_voltage = 1.0,\n                area = nothing,\n                load_zone = nothing,\n            )\n\n            add_component!(sys, bus1)\n            @test_throws ArgumentError add_component!(sys, bus2)\n        end\n    @test_logs min_level = Logging.Error match_mode = :any test_bus_numbers()\nend\n\n@testset \"Test unique DCBus numbers\" begin\n    test_dcbus_numbers =\n        () -> begin\n            sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n            number = 200\n            dcbus_defaults = (;\n                available = true,\n                magnitude = 1.0,\n                voltage_limits = (min = -1.0, max = 1.0),\n                base_voltage = 1.0,\n            )\n            dcbus1 = DCBus(; number = number, name = \"dcbus200\", dcbus_defaults...)\n            dcbus2 = DCBus(; number = number, name = \"dcbus201\", dcbus_defaults...)\n\n            add_component!(sys, dcbus1)\n            @test_throws ArgumentError add_component!(sys, dcbus2)\n\n            # Also verify that a DCBus cannot share a number with an existing ACBus\n            existing_ac_number = first(get_bus_numbers(sys))\n            dcbus3 = DCBus(;\n                number = existing_ac_number,\n                name = \"dcbus_conflict\",\n                dcbus_defaults...,\n            )\n            @test_throws ArgumentError add_component!(sys, dcbus3)\n        end\n    @test_logs min_level = Logging.Error match_mode = :any test_dcbus_numbers()\nend\n"
  },
  {
    "path": "test/test_component_selector.jl",
    "content": "test_sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5_all_components\")\ngen_solitude = PSY.get_component(ThermalStandard, test_sys, \"Solitude\")::Component  # Error if `nothing`\ngen_sundance = get_component(ThermalStandard, test_sys, \"Sundance\")::Component\nset_available!(gen_sundance, false)\ngen_wind = get_component(RenewableDispatch, test_sys, \"WindBusA\")::Component\n\ntest_sys2 = PSB.build_system(PSB.PSISystems, \"5_bus_hydro_uc_sys\")\ngen_sundance2 = get_component(ThermalStandard, test_sys2, \"Sundance\")::Component\nset_available!(gen_sundance2, false)\n\nsort_name!(x) = sort!(collect(x); by = get_name)\n\n# NOTE we are not constraining the second type parameter\nGCReturnType = IS.FlattenIteratorWrapper{<:IS.InfrastructureSystemsComponent, <:Any}\n\n\"Helper function to test the return type of `get_components` whenever we call it\"\nfunction get_components_rt(args...; kwargs...)\n    result = get_components(args...; kwargs...)\n    @test result isa GCReturnType\n    return result\nend\n\n@testset \"Test helper functions\" begin\n    @test subtype_to_string(ThermalStandard) == \"ThermalStandard\"\n    @test component_to_qualified_string(ThermalStandard, \"Solitude\") ==\n          \"ThermalStandard__Solitude\"\n    @test component_to_qualified_string(gen_solitude) == \"ThermalStandard__Solitude\"\nend\n\n@testset \"Test NameComponentSelector\" begin\n    test_gen_ent = PSY.NameComponentSelector(ThermalStandard, \"Solitude\", nothing)\n    named_test_gen_ent = PSY.NameComponentSelector(ThermalStandard, \"Solitude\", \"SolGen\")\n\n    # Equality\n    @test PSY.NameComponentSelector(ThermalStandard, \"Solitude\", nothing) == test_gen_ent\n    @test PSY.NameComponentSelector(ThermalStandard, \"Solitude\", \"SolGen\") ==\n          named_test_gen_ent\n\n    # Construction\n    @test make_selector(ThermalStandard, \"Solitude\") == test_gen_ent\n    @test make_selector(ThermalStandard, \"Solitude\"; name = \"SolGen\") == named_test_gen_ent\n    @test make_selector(gen_solitude) == test_gen_ent\n\n    # Naming\n    @test get_name(test_gen_ent) == \"ThermalStandard__Solitude\"\n    @test get_name(named_test_gen_ent) == \"SolGen\"\n\n    # Contents\n    @test collect(get_components_rt(make_selector(NonexistentComponent, \"\"), test_sys)) ==\n          Vector{Component}()\n    the_components = collect(get_components_rt(test_gen_ent, test_sys))\n    @test length(the_components) == 1\n    @test typeof(first(the_components)) == ThermalStandard\n    @test get_name(first(the_components)) == \"Solitude\"\n    @test collect(\n        get_components_rt(\n            get_available,\n            make_selector(gen_sundance),\n            test_sys,\n        ),\n    ) ==\n          Vector{Component}()\n    @test collect(get_available_components(make_selector(gen_sundance), test_sys)) ==\n          Vector{Component}()\n    @test get_component(x -> true, test_gen_ent, test_sys) ==\n          first(the_components)\n    @test isnothing(get_component(x -> false, test_gen_ent, test_sys))\n    @test isnothing(get_available_component(make_selector(gen_sundance), test_sys))\n\n    @test only(get_groups(test_gen_ent, test_sys)) == test_gen_ent\nend\n\n@testset \"Test ListComponentSelector\" begin\n    comp_ent_1 = make_selector(ThermalStandard, \"Sundance\")\n    comp_ent_2 = make_selector(RenewableDispatch, \"WindBusA\")\n    test_list_ent = PSY.ListComponentSelector((comp_ent_1, comp_ent_2), nothing)\n    named_test_list_ent = PSY.ListComponentSelector((comp_ent_1, comp_ent_2), \"TwoComps\")\n\n    # Equality\n    @test PSY.ListComponentSelector((comp_ent_1, comp_ent_2), nothing) == test_list_ent\n    @test PSY.ListComponentSelector((comp_ent_1, comp_ent_2), \"TwoComps\") ==\n          named_test_list_ent\n\n    # Construction\n    @test make_selector(comp_ent_1, comp_ent_2;) == test_list_ent\n    @test make_selector(comp_ent_1, comp_ent_2; name = \"TwoComps\") ==\n          named_test_list_ent\n\n    # Naming\n    @test get_name(test_list_ent) ==\n          \"[ThermalStandard__Sundance, RenewableDispatch__WindBusA]\"\n    @test get_name(named_test_list_ent) == \"TwoComps\"\n\n    # Contents\n    @test collect(get_components_rt(make_selector(), test_sys)) == Vector{Component}()\n    the_components = collect(get_components_rt(test_list_ent, test_sys))\n    @test length(the_components) == 2\n\n    @test collect(get_groups(make_selector(), test_sys)) ==\n          Vector{ComponentSelector}()\n    the_groups = collect(get_groups(test_list_ent, test_sys))\n    @test length(the_groups) == 2\nend\n\n@testset \"Test TypeComponentSelector\" begin\n    test_sub_ent = PSY.TypeComponentSelector(ThermalStandard, :all, nothing)\n    named_test_sub_ent = PSY.TypeComponentSelector(ThermalStandard, :all, \"Thermals\")\n\n    # Equality\n    @test PSY.TypeComponentSelector(ThermalStandard, :all, nothing) == test_sub_ent\n    @test PSY.TypeComponentSelector(ThermalStandard, :all, \"Thermals\") == named_test_sub_ent\n\n    # Construction\n    @test make_selector(ThermalStandard) == make_selector(ThermalStandard; groupby = :each)\n    @test make_selector(ThermalStandard; groupby = :all) == test_sub_ent\n    @test make_selector(ThermalStandard; groupby = :all, name = \"Thermals\") ==\n          named_test_sub_ent\n    @test make_selector(ThermalStandard; groupby = string) isa PSY.TypeComponentSelector\n\n    # Naming\n    @test get_name(test_sub_ent) == \"ThermalStandard\"\n    @test get_name(named_test_sub_ent) == \"Thermals\"\n\n    # Contents\n    answer = sort_name!(get_components_rt(ThermalStandard, test_sys))\n\n    @test collect(get_components_rt(make_selector(NonexistentComponent), test_sys)) ==\n          Vector{Component}()\n    the_components = sort_name!(get_components_rt(test_sub_ent, test_sys))\n    @test all(the_components .== answer)\n    @test !(\n        gen_sundance in\n        collect(get_components_rt(get_available, test_sub_ent, test_sys)))\n    @test !(gen_sundance in collect(get_available_components(test_sub_ent, test_sys)))\n\n    # Grouping inherits from `DynamicallyGroupedComponentSelector` and is tested elsewhere\nend\n\n@testset \"Test TopologyComponentSelector\" begin\n    topo1 = get_component(Area, test_sys2, \"1\")\n    topo2 = get_component(LoadZone, test_sys2, \"2\")\n    @assert !isnothing(topo1) && !isnothing(topo2) \"Relies on an out-of-date `5_bus_hydro_uc_sys` definition\"\n    test_topo_ent1 =\n        PSY.TopologyComponentSelector(ThermalStandard, Area, \"1\", :all, nothing)\n    test_topo_ent2 =\n        PSY.TopologyComponentSelector(StaticInjection, LoadZone, \"2\", :all, \"Zone_2\")\n\n    # Equality\n    @test PSY.TopologyComponentSelector(ThermalStandard, Area, \"1\", :all, nothing) ==\n          test_topo_ent1\n    @test PSY.TopologyComponentSelector(StaticInjection, LoadZone, \"2\", :all, \"Zone_2\") ==\n          test_topo_ent2\n\n    # Construction\n    @test make_selector(ThermalStandard, Area, \"1\") ==\n          make_selector(ThermalStandard, Area, \"1\"; groupby = :each)\n    @test make_selector(ThermalStandard, Area, \"1\"; groupby = :all) == test_topo_ent1\n    @test make_selector(StaticInjection, LoadZone, \"2\"; groupby = :all, name = \"Zone_2\") ==\n          test_topo_ent2\n    @test make_selector(StaticInjection, LoadZone, \"2\"; groupby = string) isa\n          PSY.TopologyComponentSelector\n\n    # Naming\n    @test get_name(test_topo_ent1) == \"Area__1__ThermalStandard\"\n    @test get_name(test_topo_ent2) == \"Zone_2\"\n\n    # Contents\n    empty_topo_ent = make_selector(NonexistentComponent, Area, \"1\")\n    @test collect(get_components_rt(empty_topo_ent, test_sys2)) == Vector{Component}()\n\n    nonexistent_topo_ent = make_selector(ThermalStandard, Area, \"NonexistentArea\")\n    @test collect(get_components_rt(nonexistent_topo_ent, test_sys2)) == Vector{Component}()\n\n    answers =\n        sort_name!.((\n            get_components_in_aggregation_topology(\n                ThermalStandard,\n                test_sys2,\n                get_component(Area, test_sys2, \"1\"),\n            ),\n            get_components_in_aggregation_topology(\n                StaticInjection,\n                test_sys2,\n                get_component(LoadZone, test_sys2, \"2\"),\n            )))\n    for (ent, ans) in zip((test_topo_ent1, test_topo_ent2), answers)\n        @assert length(ans) > 0 \"Relies on an out-of-date `5_bus_hydro_uc_sys` definition\"\n\n        the_components = get_components_rt(ent, test_sys2)\n        @test all(sort_name!(the_components) .== ans)\n        @test Set(collect(get_components_rt(x -> true, ent, test_sys2))) ==\n              Set(the_components)\n        @test length(\n            collect(get_components_rt(x -> false, ent, test_sys2)),\n        ) ==\n              0\n    end\nend\n\n@testset \"Test FilterComponentSelector\" begin\n    starts_with_s(x) = lowercase(first(get_name(x))) == 's'\n    test_filter_ent =\n        PSY.FilterComponentSelector(ThermalStandard, starts_with_s, :all, nothing)\n    named_test_filter_ent = PSY.FilterComponentSelector(\n        ThermalStandard, starts_with_s, :all, \"ThermStartsWithS\")\n\n    # Equality\n    @test PSY.FilterComponentSelector(ThermalStandard, starts_with_s, :all, nothing) ==\n          test_filter_ent\n    @test PSY.FilterComponentSelector(\n        ThermalStandard, starts_with_s, :all, \"ThermStartsWithS\") == named_test_filter_ent\n\n    # Construction\n    @test make_selector(starts_with_s, ThermalStandard) ==\n          make_selector(starts_with_s, ThermalStandard; groupby = :each)\n    @test make_selector(starts_with_s, ThermalStandard; groupby = :all) == test_filter_ent\n    @test make_selector(\n        starts_with_s,\n        ThermalStandard;\n        groupby = :all,\n        name = \"ThermStartsWithS\",\n    ) == named_test_filter_ent\n    @test make_selector(starts_with_s, ThermalStandard; groupby = string) isa\n          PSY.FilterComponentSelector\n\n    # Naming\n    @test get_name(test_filter_ent) == \"starts_with_s__ThermalStandard\"\n    @test get_name(named_test_filter_ent) == \"ThermStartsWithS\"\n\n    # Contents\n    answer = filter(starts_with_s, collect(get_components_rt(ThermalStandard, test_sys)))\n\n    @test collect(\n        get_components_rt(make_selector(x -> true, NonexistentComponent), test_sys),\n    ) ==\n          Vector{Component}()\n    @test collect(get_components_rt(make_selector(x -> false, Component), test_sys)) ==\n          Vector{Component}()\n    @test all(collect(get_components_rt(test_filter_ent, test_sys)) .== answer)\n    @test !(\n        gen_sundance in\n        collect(\n            get_components_rt(get_available, test_filter_ent, test_sys),\n        ))\n    @test !(gen_sundance in collect(get_available_components(test_filter_ent, test_sys)))\nend\n\n@testset \"Test RegroupedComponentSelector\" begin\n    comp_ent_1 = make_selector(ThermalStandard, \"Sundance\")\n    comp_ent_2 = make_selector(RenewableDispatch, \"WindBusA\")\n    test_list_ent = PSY.ListComponentSelector((comp_ent_1, comp_ent_2), nothing)\n    test_sel = PSY.RegroupedComponentSelector(test_list_ent, :all)\n\n    # Equality\n    @test PSY.RegroupedComponentSelector(test_list_ent, :all) == test_sel\n\n    # Naming\n    @test get_name(test_sel) == get_name(test_list_ent)\n\n    # Contents\n    @test Set(collect(get_components_rt(test_sel, test_sys))) ==\n          Set(collect(get_components_rt(test_list_ent, test_sys)))\nend\n\n@testset \"Test DynamicallyGroupedComponentSelector grouping\" begin\n    # We'll use TopologyComponentSelector as the token example\n    @assert PSY.TopologyComponentSelector <: DynamicallyGroupedComponentSelector\n\n    all_selector = make_selector(ThermalStandard, Area, \"1\"; groupby = :all)\n    each_selector = make_selector(ThermalStandard, Area, \"1\"; groupby = :each)\n    @test make_selector(ThermalStandard, Area, \"1\") == each_selector\n    @test_throws ArgumentError make_selector(ThermalStandard, Area, \"1\"; groupby = :other)\n    # @show get_name.(get_components_rt(all_selector, test_sys2))\n    partition_selector = make_selector(ThermalStandard, Area, \"1\";\n        groupby = x -> occursin(\" \", get_name(x)))\n\n    @test only(get_groups(all_selector, test_sys2)) == all_selector\n    @test Set(get_name.(get_groups(each_selector, test_sys2))) ==\n          Set((\n        component_to_qualified_string.(Ref(ThermalStandard),\n        get_name.(get_components_rt(each_selector, test_sys2)))\n    ))\n    @test length(\n        collect(\n            get_groups(x -> length(get_name(x)) == 8, each_selector, test_sys2),\n        ),\n    ) == 2\n    @test Set(get_name.(get_groups(partition_selector, test_sys2))) ==\n          Set([\"true\", \"false\"])\n    @test length(\n        collect(\n            get_groups(x -> length(get_name(x)) == 8, partition_selector, test_sys2),\n        ),\n    ) == 1\n\n    # Also test briefly with something from IS\n    @assert PSY.TypeComponentSelector <: DynamicallyGroupedComponentSelector\n    @test length(\n        collect(\n            get_groups(make_selector(ThermalStandard;\n                    groupby = x -> length(get_name(x))), test_sys),\n        ),\n    ) == 3\n\n    # Test proper handling of availability\n    sel = make_selector(ThermalStandard; groupby = :each)\n    @test length(get_groups(sel, test_sys2)) >\n          length(get_available_groups(sel, test_sys2)) ==\n          length(get_available_components(sel, test_sys2)) ==\n          length(get_available_components(ThermalStandard, test_sys2)) ==\n          length(get_components(get_available, ThermalStandard, test_sys2))\nend\n\n@testset \"Test rebuild_selector\" begin\n    @assert !(PSY.NameComponentSelector <: PSY.DynamicallyGroupedComponentSelector)\n    @assert PSY.TopologyComponentSelector <: PSY.DynamicallyGroupedComponentSelector\n\n    sel1::PSY.NameComponentSelector =\n        make_selector(ThermalStandard, \"Component1\"; name = \"oldname\")\n    sel2::PSY.TypeComponentSelector =\n        make_selector(ThermalStandard; groupby = :all)\n    sel3::PSY.TopologyComponentSelector =\n        make_selector(ThermalStandard, Area, \"1\"; groupby = :all)\n    # TODO include sel3 when get_components is fixed -- see below\n    sel4::IS.ListComponentSelector = make_selector(sel1, sel2; name = \"oldname\")\n\n    @test rebuild_selector(sel1; name = \"newname\") ==\n          make_selector(ThermalStandard, \"Component1\"; name = \"newname\")\n    @test_throws Exception rebuild_selector(sel1; groupby = :each)\n\n    @test rebuild_selector(sel2; name = \"newname\") ==\n          make_selector(ThermalStandard; name = \"newname\", groupby = :all)\n    @test rebuild_selector(sel2; name = \"newname\", groupby = :each) ==\n          make_selector(ThermalStandard; name = \"newname\", groupby = :each)\n\n    @test rebuild_selector(sel3; name = \"newname\") ==\n          make_selector(ThermalStandard, Area, \"1\"; name = \"newname\", groupby = :all)\n    @test rebuild_selector(sel3; name = \"newname\", groupby = :each) ==\n          make_selector(ThermalStandard, Area, \"1\"; name = \"newname\", groupby = :each)\n\n    @test rebuild_selector(sel4; name = \"newname\") ==\n          make_selector(sel1, sel2; name = \"newname\")\n    regrouped = rebuild_selector(sel4; name = \"newname\", groupby = :all)\n    @test Set(collect(get_components_rt(regrouped, test_sys))) ==\n          Set(collect(get_components_rt(sel4, test_sys)))\n    @test length(get_groups(regrouped, test_sys)) == 1\nend\n\n@testset \"Test special cases\" begin\n    # Can error if the `PSY.get_components` vs. `IS.get_components` stuff is not functioning correctly\n    agg_selectors = [make_selector(ThermalStandard, Area, \"1\"),\n        make_selector(ThermalStandard, Area, \"1\")]\n    get_components_rt(make_selector(agg_selectors...), test_sys)\nend\n"
  },
  {
    "path": "test/test_constructors.jl",
    "content": "@testset \"Bus Constructors\" begin\n    tBus = ACBus(nothing)\n    tLoadZone = LoadZone(nothing)\n\n    bus = ACBus(\n        1,\n        \"test\",\n        true,\n        ACBusTypes.SLACK,\n        0.0,\n        0.0,\n        (min = 0.0, max = 0.0),\n        nothing,\n        nothing,\n        nothing,\n    )\n\n    @test PowerSystems.get_bustype(bus) == ACBusTypes.REF\nend\n\n@testset \"Generation Constructors\" begin\n    for T in InteractiveUtils.subtypes(PSY.OperationalCost)\n        isabstracttype(T) || (@test T(nothing) isa IS.InfrastructureSystemsType)\n    end\n    # TODO add concrete subtypes of ProductionVariableCostCurve?\n\n    tThermalGen = ThermalStandard(nothing)\n    @test tThermalGen isa PowerSystems.Component\n    tHydroDispatch = HydroDispatch(nothing)\n    @test tHydroDispatch isa PowerSystems.Component\n    tRenewableNonDispatch = RenewableNonDispatch(nothing)\n    @test tRenewableNonDispatch isa PowerSystems.Component\n    tRenewableDispatch = RenewableDispatch(nothing)\n    @test tRenewableDispatch isa PowerSystems.Component\n    tRenewableDispatch = RenewableDispatch(nothing)\n    @test tRenewableDispatch isa PowerSystems.Component\n    tTurbine = HydroTurbine(nothing)\n    @test tTurbine isa PowerSystems.Component\n    tReservoir = HydroReservoir(nothing)\n    @test tReservoir isa PowerSystems.Component\nend\n\n@testset \"Source Constructors\" begin\n    tSource = Source(nothing)\n    @test tSource isa PowerSystems.Component\nend\n\n@testset \"Storage Constructors\" begin\n    tStorage = EnergyReservoirStorage(nothing)\n    @test tStorage isa PowerSystems.Component\nend\n\n@testset \"Load Constructors\" begin\n    tPowerLoad = PowerLoad(nothing)\n    @test tPowerLoad isa PowerSystems.Component\n    tStandardLoad = StandardLoad(nothing)\n    @test tStandardLoad isa PowerSystems.Component\n    tPowerLoad = PowerLoad(\"init\", true, ACBus(nothing), 0.0, 0.0, 100.0, 0.0, 0.0)\n    @test tPowerLoad isa PowerSystems.Component\n    tLoad = InterruptiblePowerLoad(nothing)\n    @test tLoad isa PowerSystems.Component\n    tShiftableLoad = ShiftablePowerLoad(nothing)\n    @test tShiftableLoad isa PowerSystems.Component\n    tInterruptibleStandardLoad = InterruptibleStandardLoad(nothing)\n    @test tInterruptibleStandardLoad isa PowerSystems.Component\nend\n\n@testset \"Branch Constructors\" begin\n    tLine = Line(nothing)\n    @test tLine isa PowerSystems.Component\n    tMonitoredLine = MonitoredLine(nothing)\n    @test tMonitoredLine isa PowerSystems.Component\n    tTwoTerminalGenericHVDCLine = TwoTerminalGenericHVDCLine(nothing)\n    @test tTwoTerminalGenericHVDCLine isa PowerSystems.Component\n    tTwoTerminalLCCLine = TwoTerminalLCCLine(nothing)\n    @test tTwoTerminalLCCLine isa PowerSystems.Component\n    tTwoTerminalVSCLine = TwoTerminalVSCLine(nothing)\n    @test tTwoTerminalVSCLine isa PowerSystems.Component\n    tTransformer2W = Transformer2W(nothing)\n    @test tTransformer2W isa PowerSystems.Component\n    tTapTransformer = TapTransformer(nothing)\n    @test tTapTransformer isa PowerSystems.Component\n    tPhaseShiftingTransformer = PhaseShiftingTransformer(nothing)\n    @test tPhaseShiftingTransformer isa PowerSystems.Component\n    tTransformer3W = Transformer3W(nothing)\n    @test tTransformer3W isa PowerSystems.Component\n    tPhaseShiftingTransformer3W = PhaseShiftingTransformer3W(nothing)\n    @test tPhaseShiftingTransformer3W isa PowerSystems.Component\n    tGenericArcImpedance = GenericArcImpedance(nothing)\n    @test tGenericArcImpedance isa PowerSystems.Component\nend\n\n@testset \"Service Constructors\" begin\n    tConstantReserve = ConstantReserve{ReserveUp}(nothing)\n    @test tConstantReserve isa PowerSystems.Service\n    tVariableReserve = VariableReserve{ReserveDown}(nothing)\n    @test tVariableReserve isa PowerSystems.Service\nend\n\n@testset \"TimeSeriesData Constructors\" begin\n    tg = RenewableNonDispatch(nothing)\n    data = PowerSystems.TimeSeries.TimeArray(\n        [DateTime(\"01-01-01\"), DateTime(\"01-01-01\") + Hour(1)],\n        [1.0, 1.0],\n    )\n    #SingleTimeSeries Tests\n    ts = SingleTimeSeries(\"scalingfactor\", Hour(1), DateTime(\"01-01-01\"), 24)\n    @test ts isa PowerSystems.TimeSeriesData\n    ts = SingleTimeSeries(; name = \"scalingfactor\", data = data)\n    @test ts isa PowerSystems.TimeSeriesData\n\n    #Probabilistic Tests\n    data = SortedDict(\n        DateTime(\"01-01-01\") => [1.0 1.0; 2.0 2.0],\n        DateTime(\"01-01-01\") + Hour(1) => [1.0 1.0; 2.0 2.0],\n    )\n    ts = Probabilistic(\"scalingfactor\", data, [0.5, 0.5], Hour(1))\n    @test ts isa PowerSystems.TimeSeriesData\n    ts = Probabilistic(;\n        name = \"scalingfactor\",\n        percentiles = [1.0, 1.0],\n        data = data,\n        resolution = Hour(1),\n    )\n    @test ts isa PowerSystems.TimeSeriesData\n    ##Scenario Tests\n    ts = Scenarios(\"scalingfactor\", data, Hour(1))\n    @test ts isa PowerSystems.TimeSeriesData\nend\n"
  },
  {
    "path": "test/test_cost_functions.jl",
    "content": "@testset \"Test scope-sensitive printing of IS cost functions\" begin\n    # Make sure the aliases get registered properly\n    @test sprint(show, \"text/plain\", QuadraticCurve) ==\n          \"QuadraticCurve (alias for InputOutputCurve{QuadraticFunctionData})\"\n\n    # Make sure there are no IS-related prefixes in the printouts\n    fc = FuelCurve(InputOutputCurve(IS.QuadraticFunctionData(1, 2, 3)), 4.0)\n    @test sprint(show, \"text/plain\", fc) ==\n          sprint(show, \"text/plain\", fc; context = :compact => false) ==\n          \"FuelCurve:\\n  value_curve: QuadraticCurve (a type of InputOutputCurve) where function is: f(x) = 1.0 x^2 + 2.0 x + 3.0\\n  power_units: UnitSystem.NATURAL_UNITS = 2\\n  fuel_cost: 4.0\\n  startup_fuel_offtake: LinearCurve (a type of InputOutputCurve) where function is: f(x) = 0.0 x + 0.0\\n  vom_cost: LinearCurve (a type of InputOutputCurve) where function is: f(x) = 0.0 x + 0.0\"\n    @test sprint(show, \"text/plain\", fc; context = :compact => true) ==\n          \"FuelCurve with power_units UnitSystem.NATURAL_UNITS = 2, fuel_cost 4.0, startup_fuel_offtake LinearCurve(0.0, 0.0), vom_cost LinearCurve(0.0, 0.0), and value_curve:\\n  QuadraticCurve (a type of InputOutputCurve) where function is: f(x) = 1.0 x^2 + 2.0 x + 3.0\"\nend\n\n@testset \"Test MarketBidCost direct struct creation and some scalar cost_function_timeseries interface\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    #Update generator cost to MarketBidCost using Natural Units\n    powers = [22.0, 33.0, 44.0, 55.0] # MW\n    marginal_costs = [25.0, 26.0, 28.0] # $/MWh\n    initial_input = 50.0 # $/h\n    cc = CostCurve(\n        PiecewiseIncrementalCurve(\n            initial_input,\n            powers,\n            marginal_costs,\n        ),\n    )\n    mbc = MarketBidCost(;\n        start_up = (hot = 0.0, warm = 0.0, cold = 0.0),\n        shut_down = 0.0,\n        incremental_offer_curves = cc,\n    )\n    set_operation_cost!(generator, mbc)\n    @test get_operation_cost(generator) isa MarketBidCost\n\n    @test get_incremental_offer_curves(generator, mbc) == cc\n    @test isnothing(get_decremental_offer_curves(generator, mbc))\n\n    @test get_variable_cost(generator, mbc) == cc\n    @test get_incremental_variable_cost(generator, mbc) == cc\n    @test isnothing(get_decremental_variable_cost(generator, mbc))\n\n    cc2 = CostCurve(\n        PiecewiseIncrementalCurve(\n            initial_input,\n            powers,\n            marginal_costs .* 1.5,\n        ),\n    )\n    set_incremental_variable_cost!(sys, generator, cc2, UnitSystem.NATURAL_UNITS)\n    @test get_incremental_variable_cost(generator, mbc) == cc2\nend\n\n@testset \"Test Make market bid curve interface\" begin\n    mbc = make_market_bid_curve(\n        [0.0, 100.0, 105.0, 120.0, 130.0],\n        [25.0, 26.0, 28.0, 30.0],\n        10.0,\n    )\n    @test is_market_bid_curve(mbc)\n    @test is_market_bid_curve(\n        make_market_bid_curve(get_function_data(mbc), get_initial_input(mbc)),\n    )\n    @test_throws ArgumentError make_market_bid_curve(\n        [100.0, 105.0, 120.0, 130.0], [26.0, 28.0, 30.0, 40.0], 10.0)\n\n    mbc2 = make_market_bid_curve([1.0, 2.0, 3.0], [4.0, 6.0], 10.0; input_at_zero = 2.0)\n    @test is_market_bid_curve(mbc2)\n    @test is_market_bid_curve(\n        make_market_bid_curve(get_function_data(mbc2), get_initial_input(mbc2)),\n    )\n\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    mbc3 = make_market_bid_curve([22.0, 33.0, 44.0, 55.0], [25.0, 26.0, 28.0], 50.0)\n    set_incremental_offer_curves!(market_bid, mbc3)\n    set_start_up!(market_bid, 0.0)\n    set_operation_cost!(generator, market_bid)\n    @test get_operation_cost(generator) isa MarketBidCost\nend\n\ntest_costs = Dict(\n    CostCurve{QuadraticCurve} =>\n        repeat([CostCurve(QuadraticCurve(999.0, 2.0, 1.0))], 24),\n    PiecewiseStepData =>\n        repeat(\n            [\n                PSY._make_market_bid_curve(\n                    PiecewiseStepData([0.0, 2.0, 3.0], [4.0, 6.0]),\n                ),\n            ],\n            24,\n        ),\n    PiecewiseIncrementalCurve =>\n        repeat(\n            [\n                make_market_bid_curve(\n                    [1.0, 2.0, 3.0],\n                    [4.0, 6.0],\n                    18.0;\n                    input_at_zero = 20.0,\n                ),\n            ],\n            24,\n        ),\n    Float64 =>\n        collect(11.0:34.0),\n    PSY.StartUpStages =>\n        repeat([(hot = PSY.START_COST, warm = PSY.START_COST, cold = PSY.START_COST)], 24),\n)\n\n@testset \"Test MarketBidCost with Quadratic Cost Timeseries\" begin\n    # Will throw TypeErrors because market bids must be piecewise, not quadratic and service\n    # bids must be piecewise, not scalar\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    name = \"test\"\n    horizon = 24\n    service_data = Dict(initial_time => rand(horizon))\n    data_quadratic =\n        SortedDict(initial_time => test_costs[CostCurve{QuadraticCurve}])\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n    forecast_fd = IS.Deterministic(\n        \"variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_quadratic)),\n        resolution,\n    )\n    power_units = UnitSystem.NATURAL_UNITS\n    @test_throws TypeError set_variable_cost!(sys, generator, forecast_fd, power_units)\n    for s in generator.services\n        forecast_fd = IS.Deterministic(get_name(s), service_data, resolution)\n        @test_throws TypeError set_service_bid!(sys, generator, s, forecast_fd, power_units)\n    end\nend\n\n@testset \"Test MarketBidCost with PiecewiseLinearData Cost Timeseries with Service Bid Forecast\" begin\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    name = \"test\"\n    horizon = 24\n    power_units = UnitSystem.NATURAL_UNITS\n    data_pwl = SortedDict(initial_time => test_costs[PiecewiseStepData])\n    service_data = data_pwl\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n    forecast_fd = Deterministic(\n        \"variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    @test_throws ArgumentError set_variable_cost!(\n        sys,\n        generator,\n        forecast_fd,\n        UnitSystem.SYSTEM_BASE,\n    )\n    set_variable_cost!(sys, generator, forecast_fd, power_units)\n\n    for s in generator.services\n        forecast_fd = Deterministic(\n            get_name(s),\n            Dict(k => get_function_data.(v) for (k, v) in pairs(service_data)),\n            resolution,\n        )\n        @test_throws ArgumentError set_service_bid!(\n            sys,\n            generator,\n            s,\n            forecast_fd,\n            UnitSystem.SYSTEM_BASE,\n        )\n        set_service_bid!(sys, generator, s, forecast_fd, power_units)\n    end\n\n    iocs = get_incremental_offer_curves(generator, market_bid)\n    @test isequal(\n        first(TimeSeries.values(iocs)),\n        get_function_data(first(data_pwl[initial_time])),\n    )\n    cost_forecast = get_variable_cost(generator, market_bid; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast)), first(data_pwl[initial_time]))\n\n    for s in generator.services\n        service_cost = get_services_bid(generator, market_bid, s; start_time = initial_time)\n        @test isequal(\n            first(TimeSeries.values(service_cost)),\n            first(service_data[initial_time]),\n        )\n    end\nend\n\n@testset \"Test MarketBidCost with PiecewiseLinearData Cost Timeseries, initial_input, and no_load_cost\" begin\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    name = \"test\"\n    horizon = 24\n    power_units = UnitSystem.NATURAL_UNITS\n    data_pwl = SortedDict(initial_time => test_costs[PiecewiseIncrementalCurve])\n    service_data = data_pwl\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n    forecast_fd = IS.Deterministic(\n        \"variable_cost_function_data\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    set_variable_cost!(sys, generator, forecast_fd, power_units)\n\n    forecast_ii = IS.Deterministic(\n        \"variable_cost_initial_input\",\n        Dict(k => get_initial_input.(get_value_curve.(v)) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    PSY.set_incremental_initial_input!(sys, generator, forecast_ii)\n\n    forecast_iaz = IS.Deterministic(\n        \"variable_cost_input_at_zero\",\n        Dict(k => get_input_at_zero.(get_value_curve.(v)) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    set_no_load_cost!(sys, generator, forecast_iaz)\n\n    iocs = get_incremental_offer_curves(generator, market_bid)\n    @test isequal(\n        first(TimeSeries.values(iocs)),\n        get_function_data(first(data_pwl[initial_time])),\n    )\n    cost_forecast = get_variable_cost(generator, market_bid; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast)), first(data_pwl[initial_time]))\nend\n\n@testset \"Test MarketBidCost with Decremental PiecewiseLinearData Cost Timeseries, initial_input, and no_load_cost\" begin\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    name = \"test\"\n    horizon = 24\n    power_units = UnitSystem.NATURAL_UNITS\n    data_pwl = SortedDict(initial_time => test_costs[PiecewiseIncrementalCurve])\n    service_data = data_pwl\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n    forecast_fd = IS.Deterministic(\n        \"decremental_variable_cost_function_data\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    set_decremental_variable_cost!(sys, generator, forecast_fd, power_units)\n\n    forecast_ii = IS.Deterministic(\n        \"decremental_variable_cost_initial_input\",\n        Dict(k => get_initial_input.(get_value_curve.(v)) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    PSY.set_decremental_initial_input!(sys, generator, forecast_ii)\n\n    forecast_iaz = IS.Deterministic(\n        \"variable_cost_input_at_zero\",\n        Dict(k => get_input_at_zero.(get_value_curve.(v)) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    set_no_load_cost!(sys, generator, forecast_iaz)\n\n    iocs = get_decremental_offer_curves(generator, market_bid)\n    isequal(first(TimeSeries.values(iocs)), first(data_pwl[initial_time]))\n    cost_forecast =\n        get_decremental_variable_cost(generator, market_bid; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast)), first(data_pwl[initial_time]))\nend\n\n@testset \"Test `MarketBidCost` with single `start_up` value\" begin\n    cost = MarketBidCost(0.0, 1.0, 2.0)\n    @test get_start_up(cost) == (hot = 1.0, warm = 0.0, cold = 0.0)\n\n    set_start_up!(cost, 2.0)\n    @test get_start_up(cost) == (hot = 2.0, warm = 0.0, cold = 0.0)\nend\n\n@testset \"Test ReserveDemandCurve with Cost Timeseries\" begin\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    other_time = initial_time + resolution\n    name = \"test\"\n    horizon = 24\n    data_pwl = SortedDict(initial_time => test_costs[PiecewiseStepData],\n        other_time => test_costs[PiecewiseStepData])\n    sys = System(100.0)\n    reserve = ReserveDemandCurve{ReserveUp}(nothing)\n    add_component!(sys, reserve)\n    forecast_fd = IS.Deterministic(\n        \"variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_pwl)),\n        resolution,\n    )\n    set_variable_cost!(sys, reserve, forecast_fd)\n    cost_forecast = get_variable_cost(reserve; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast)), first(data_pwl[initial_time]))\nend\n\n@testset \"Test ReserveDemandCurve with Time Varying PWL Cost\" begin\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    other_time = initial_time + resolution\n\n    # Create time varying PWL cost data using PiecewiseIncrementalCurve\n    data_pwl_incremental = SortedDict(\n        initial_time => test_costs[PiecewiseIncrementalCurve],\n        other_time => test_costs[PiecewiseIncrementalCurve],\n    )\n\n    # Create system and reserve product\n    sys = System(100.0)\n    reserve = ReserveDemandCurve{ReserveUp}(\n        nothing,  # variable - will be set via set_variable_cost!\n        \"TestReserveProduct\",\n        true,\n        10.0,  # time_frame\n        3600.0,  # sustained_time\n        1.0,  # max_participation_factor\n        0.0,  # deployed_fraction\n    )\n    add_component!(sys, reserve)\n\n    # Attach time varying cost to the reserve product\n    forecast_fd = IS.Deterministic(\n        \"variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(data_pwl_incremental)),\n        resolution,\n    )\n    set_variable_cost!(sys, reserve, forecast_fd)\n\n    # Retrieve and verify the time varying cost data\n    cost_forecast = get_variable_cost(reserve; start_time = initial_time)\n    retrieved_curve = first(TimeSeries.values(cost_forecast))\n    original_curve = first(data_pwl_incremental[initial_time])\n\n    # Compare function data (x and y coordinates)\n    @test get_function_data(retrieved_curve) == get_function_data(original_curve)\n\n    # Verify we can retrieve cost at the second time point\n    cost_forecast_second = get_variable_cost(reserve; start_time = other_time)\n    retrieved_curve_second = first(TimeSeries.values(cost_forecast_second))\n    original_curve_second = first(data_pwl_incremental[other_time])\n\n    # Compare function data\n    @test get_function_data(retrieved_curve_second) ==\n          get_function_data(original_curve_second)\n\n    # Verify the reserve has the time series attached\n    @test has_time_series(reserve)\n    @test length(get_time_series_keys(reserve)) == 1\nend\n\n@testset \"Test fuel cost (scalar and time series)\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generators = collect(get_components(ThermalStandard, sys))\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n\n    op_cost = get_operation_cost(generator)\n    value_curve = get_value_curve(get_variable(op_cost))\n    set_variable!(op_cost, FuelCurve(value_curve, 0.0))\n    @test get_fuel_cost(generator) == 0.0\n    @test_throws ArgumentError get_fuel_cost(generator; len = 2)\n\n    set_fuel_cost!(sys, generator, 1.23)\n    @test get_fuel_cost(generator) == 1.23\n\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    horizon = 24\n    data_float = SortedDict(initial_time => test_costs[Float64])\n    forecast_fd = IS.Deterministic(\"fuel_cost\", data_float, resolution)\n    set_fuel_cost!(sys, generator, forecast_fd)\n    fuel_forecast = get_fuel_cost(generator; start_time = initial_time)\n    @test first(TimeSeries.values(fuel_forecast)) == first(data_float[initial_time])\n    fuel_forecast = get_fuel_cost(generator)  # missing start_time filled in with initial time\n    @test first(TimeSeries.values(fuel_forecast)) == first(data_float[initial_time])\nend\n@testset \"Test MarketBidCost no-load cost (single number and time series)\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generators = collect(get_components(ThermalStandard, sys))\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n\n    op_cost = get_operation_cost(generator)\n    @test get_no_load_cost(generator, op_cost) === nothing\n\n    set_no_load_cost!(sys, generator, 1.23)\n    @test get_no_load_cost(generator, op_cost) == 1.23\n\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    horizon = 24\n    data_float = SortedDict(initial_time => test_costs[Float64])\n    forecast_fd = IS.Deterministic(\"no_load_cost\", data_float, resolution)\n\n    set_no_load_cost!(sys, generator, forecast_fd)\n    @test first(TimeSeries.values(get_no_load_cost(generator, op_cost))) ==\n          first(data_float[initial_time])\nend\n\n@testset \"Test MarketBidCost startup cost (single number, tuple, and time series)\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generators = collect(get_components(ThermalStandard, sys))\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n\n    op_cost = get_operation_cost(generator)\n    @test get_start_up(op_cost) ==\n          (hot = PSY.START_COST, warm = PSY.START_COST, cold = PSY.START_COST)\n    @test get_start_up(generator, op_cost) ==\n          (hot = PSY.START_COST, warm = PSY.START_COST, cold = PSY.START_COST)\n\n    set_start_up!(sys, generator, 3.14)\n    @test get_start_up(op_cost) == (hot = 3.14, warm = 0.0, cold = 0.0)\n    @test get_start_up(generator, op_cost) == (hot = 3.14, warm = 0.0, cold = 0.0)\n\n    set_start_up!(sys, generator, (hot = 1.23, warm = 2.34, cold = 3.45))\n    @test get_start_up(op_cost) == (hot = 1.23, warm = 2.34, cold = 3.45)\n    @test get_start_up(generator, op_cost) == (hot = 1.23, warm = 2.34, cold = 3.45)\n\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    horizon = 24\n    data_sus = SortedDict(initial_time => test_costs[PSY.StartUpStages])\n    forecast_fd = IS.Deterministic(\n        \"start_up\",\n        Dict(k => Tuple.(v) for (k, v) in pairs(data_sus)),\n        resolution,\n    )\n\n    set_start_up!(sys, generator, forecast_fd)\n    @test first(TimeSeries.values(get_start_up(generator, op_cost))) ==\n          first(data_sus[initial_time])\nend\n\n@testset \"Test MarketBidCost shutdown cost (single number and time series)\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generators = collect(get_components(ThermalStandard, sys))\n    generator = get_component(ThermalStandard, sys, \"322_CT_6\")\n    market_bid = MarketBidCost(nothing)\n    set_operation_cost!(generator, market_bid)\n\n    op_cost = get_operation_cost(generator)\n    @test get_shut_down(op_cost) == 0.0\n    @test get_shut_down(generator, op_cost) == 0.0\n\n    set_shut_down!(sys, generator, 3.14)\n    @test get_shut_down(op_cost) == 3.14\n    @test get_shut_down(generator, op_cost) == 3.14\n\n    initial_time = Dates.DateTime(\"2020-01-01\")\n    resolution = Dates.Hour(1)\n    horizon = 24\n    data_float = SortedDict(initial_time => test_costs[Float64])\n    forecast_fd = IS.Deterministic(\"fuel_cost\", data_float, resolution)\n\n    set_shut_down!(sys, generator, forecast_fd)\n    @test first(TimeSeries.values(get_shut_down(generator, op_cost))) ==\n          first(data_float[initial_time])\nend\n\nfunction build_iec_sys()\n    sys = PSB.build_system(PSITestSystems, \"c_sys5_uc\")\n\n    source = Source(;\n        name = \"source\",\n        available = true,\n        bus = get_component(ACBus, sys, \"nodeC\"),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        active_power_limits = (min = -2.0, max = 2.0),\n        reactive_power_limits = (min = -2.0, max = 2.0),\n        R_th = 0.01,\n        X_th = 0.02,\n        internal_voltage = 1.0,\n        internal_angle = 0.0,\n        base_power = 100.0,\n    )\n\n    source2 = Source(;\n        name = \"source2\",\n        available = true,\n        bus = get_component(ACBus, sys, \"nodeD\"),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        active_power_limits = (min = -2.0, max = 2.0),\n        reactive_power_limits = (min = -2.0, max = 2.0),\n        R_th = 0.01,\n        X_th = 0.02,\n        internal_voltage = 1.0,\n        internal_angle = 0.0,\n        base_power = 100.0,\n    )\n\n    import_curve = make_import_curve(;\n        power = [0.0, 100.0, 105.0, 120.0, 200.0],\n        price = [5.0, 10.0, 20.0, 40.0],\n    )\n\n    import_curve2 = make_import_curve(;\n        power = 200.0,\n        price = 25.0,\n    )\n\n    export_curve = make_export_curve(;\n        power = [0.0, 100.0, 105.0, 120.0, 200.0],\n        price = [40.0, 20.0, 10.0, 5.0],\n    )\n\n    export_curve2 = make_export_curve(;\n        power = 200.0,\n        price = 45.0,\n    )\n\n    ie_cost = ImportExportCost(;\n        import_offer_curves = import_curve,\n        export_offer_curves = export_curve,\n    )\n\n    ie_cost2 = ImportExportCost(;\n        import_offer_curves = import_curve2,\n        export_offer_curves = export_curve2,\n    )\n\n    set_operation_cost!(source, ie_cost)\n    set_operation_cost!(source2, ie_cost2)\n    add_component!(sys, source)\n    add_component!(sys, source2)\n\n    return sys,\n    source,\n    source2,\n    import_curve,\n    import_curve2,\n    export_curve,\n    export_curve2,\n    ie_cost,\n    ie_cost2\nend\n\n@testset \"ImportExportCost basic methods\" begin\n    sys,\n    source,\n    source2,\n    import_curve,\n    import_curve2,\n    export_curve,\n    export_curve2,\n    ie_cost,\n    ie_cost2 =\n        build_iec_sys()\n\n    @test PowerSystems.is_import_export_curve(import_curve)\n    @test PowerSystems.is_import_export_curve(import_curve2)\n    @test PowerSystems.is_import_export_curve(export_curve)\n    @test PowerSystems.is_import_export_curve(export_curve2)\n\n    @test get_operation_cost(source) isa ImportExportCost\n    @test get_operation_cost(source2) isa ImportExportCost\nend\n\n@testset \"ImportExportCost cost_function_timeseries scalar\" begin\n    sys,\n    source,\n    source2,\n    import_curve,\n    import_curve2,\n    export_curve,\n    export_curve2,\n    ie_cost,\n    ie_cost2 =\n        build_iec_sys()\n\n    @test get_import_offer_curves(source, ie_cost) == import_curve\n    @test get_export_offer_curves(source, ie_cost) == export_curve\n\n    @test get_import_variable_cost(source, ie_cost) == import_curve\n    @test get_export_variable_cost(source, ie_cost) == export_curve\nend\n\n@testset \"ImportExportCost cost_function_timeseries time series\" begin\n    initial_time = Dates.DateTime(\"2024-01-01\")\n    resolution = Dates.Hour(1)\n    other_time = initial_time + resolution\n    name = \"test\"\n    horizon = 24\n\n    sys,\n    source,\n    source2,\n    import_curve,\n    import_curve2,\n    export_curve,\n    export_curve2,\n    ie_cost,\n    ie_cost2 =\n        build_iec_sys()\n\n    import_fd_array = repeat(\n        [\n            make_import_curve(;\n                power = [0.0, 100.0, 105.0, 120.0, 200.0],\n                price = [5.0, 10.0, 20.0, 40.0])], 24)\n\n    export_fd_array = repeat(\n        [\n            make_export_curve(;\n                power = [0.0, 100.0, 105.0, 120.0, 200.0],\n                price = [40.0, 20.0, 10.0, 5.0])], 24)\n\n    import_sd = SortedDict(initial_time => import_fd_array,\n        other_time => import_fd_array)\n    export_sd = SortedDict(initial_time => export_fd_array,\n        other_time => export_fd_array)\n\n    import_curve = IS.Deterministic(\n        \"import_variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(import_sd)),\n        resolution,\n    )\n    export_curve = IS.Deterministic(\n        \"export_variable_cost\",\n        Dict(k => get_function_data.(v) for (k, v) in pairs(export_sd)),\n        resolution,\n    )\n\n    set_import_variable_cost!(sys, source, import_curve, UnitSystem.NATURAL_UNITS)\n    set_export_variable_cost!(sys, source, export_curve, UnitSystem.NATURAL_UNITS)\n\n    iocs = get_import_offer_curves(source, ie_cost)\n    @test isequal(\n        first(TimeSeries.values(iocs)),\n        get_function_data(first(import_sd[initial_time])),\n    )\n    cost_forecast_i = get_import_variable_cost(source, ie_cost; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast_i)), first(import_sd[initial_time]))\n\n    eocs = get_export_offer_curves(source, ie_cost)\n    @test isequal(\n        first(TimeSeries.values(eocs)),\n        get_function_data(first(export_sd[initial_time])),\n    )\n    cost_forecast_e = get_export_variable_cost(source, ie_cost; start_time = initial_time)\n    @test isequal(first(TimeSeries.values(cost_forecast_e)), first(export_sd[initial_time]))\nend\n\n@testset \"Test HydroReservoirCost getters and setters\" begin\n    cost = HydroReservoirCost(;\n        level_shortage_cost = 1.0,\n        level_surplus_cost = 2.0,\n        spillage_cost = 3.0,\n    )\n    @test get_level_shortage_cost(cost) == 1.0\n    @test get_level_surplus_cost(cost) == 2.0\n    @test get_spillage_cost(cost) == 3.0\n\n    set_level_shortage_cost!(cost, 10.0)\n    @test get_level_shortage_cost(cost) == 10.0\n    @test get_level_surplus_cost(cost) == 2.0\n    @test get_spillage_cost(cost) == 3.0\n\n    set_level_surplus_cost!(cost, 20.0)\n    @test get_level_surplus_cost(cost) == 20.0\n    @test get_level_shortage_cost(cost) == 10.0\n    @test get_spillage_cost(cost) == 3.0\n\n    set_spillage_cost!(cost, 30.0)\n    @test get_spillage_cost(cost) == 30.0\n    @test get_level_shortage_cost(cost) == 10.0\n    @test get_level_surplus_cost(cost) == 20.0\nend\n"
  },
  {
    "path": "test/test_devices.jl",
    "content": "@testset \"Test special accessors\" begin\n    cdmsys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    th = first(get_components(ThermalStandard, cdmsys))\n    re = first(get_components(RenewableDispatch, cdmsys))\n\n    @test get_max_active_power(th) == get_active_power_limits(th).max\n    @test get_max_active_power(re) <= get_rating(re)\n    @test isa(get_max_reactive_power(re), Float64)\n\n    @test_throws MethodError get_max_active_power(TestDevice(\"foo\"))\n    @test_throws ArgumentError get_max_active_power(TestInjector(\"foo\"))\n    @test_throws ArgumentError get_max_active_power(TestRenDevice(\"foo\"))\nend\n\n@testset \"Test Remove Area with Interchanges\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    area1 = get_component(Area, sys, \"1\")\n    area2 = get_component(Area, sys, \"2\")\n    area3 = get_component(Area, sys, \"3\")\n    area_interchange12 = AreaInterchange(;\n        name = \"interchange_a1_a2\",\n        available = true,\n        active_power_flow = 0.0,\n        from_area = area1,\n        to_area = area2,\n        flow_limits = (from_to = 100.0, to_from = 100.0),\n    )\n    area_interchange13 = AreaInterchange(;\n        name = \"interchange_a1_a3\",\n        available = true,\n        active_power_flow = 0.0,\n        from_area = area1,\n        to_area = area3,\n        flow_limits = (from_to = 100.0, to_from = 100.0),\n    )\n    add_component!(sys, area_interchange12)\n    add_component!(sys, area_interchange13)\n    @test_throws ArgumentError remove_component!(sys, area1)\n    remove_component!(sys, area_interchange12)\n    remove_component!(sys, area_interchange13)\n    remove_component!(sys, area1)\n    @test get_component(Area, sys, \"1\") === nothing\nend\n\n@testset \"Test Shiftable Power Loads and Interruptible PowerLoads\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    buses = collect(get_components(ACBus, sys))\n    add_component!(\n        sys,\n        InterruptiblePowerLoad(\n            \"IloadBus\",\n            true,\n            buses[1],\n            0.10,\n            0.0,\n            0.10,\n            0.0,\n            100.0,\n            LoadCost(CostCurve(LinearCurve(150.0)), 2400.0),\n        ),\n    )\n    add_component!(\n        sys,\n        ShiftablePowerLoad(\n            \"ShiftableLoadBus4\",\n            true,\n            buses[2],\n            0.10,\n            (min = 0.03, max = 0.10),\n            0.0,\n            0.10,\n            0.0,\n            100.0,\n            24,\n            LoadCost(CostCurve(LinearCurve(150.0)), 2400.0),\n        ),\n    )\n    dir_path = mktempdir()\n    to_json(sys, joinpath(dir_path, \"test_RTS_GMLC_sys.json\"))\n    sys2 = System(joinpath(dir_path, \"test_RTS_GMLC_sys.json\"))\n    @test get_active_power(get_component(ShiftablePowerLoad, sys2, \"ShiftableLoadBus4\")) ==\n          0.10\n    @test get_active_power(get_component(InterruptiblePowerLoad, sys2, \"IloadBus\")) == 0.10\n    @test get_active_power_limits(\n        get_component(ShiftablePowerLoad, sys2, \"ShiftableLoadBus4\"),\n    ).min == 0.03\n    @test get_active_power_limits(\n        get_component(ShiftablePowerLoad, sys2, \"ShiftableLoadBus4\"),\n    ).max == 0.10\nend\n"
  },
  {
    "path": "test/test_dynamic_generator.jl",
    "content": "nodes_OMIB = [\n    ACBus(\n        1, #number\n        \"Bus 1\", #Name\n        true, #available\n        \"REF\", #BusType (REF, PV, PQ)\n        0, #Angle in radians\n        1.06, #Voltage in pu\n        (min = 0.94, max = 1.06), #Voltage limits in pu\n        69,\n        nothing,\n        nothing,\n    ), #Base voltage in kV\n    ACBus(2, \"Bus 2\", true, \"PV\", 0, 1.045, (min = 0.94, max = 1.06), 69, nothing, nothing),\n]\n\nstatic_gen = ThermalStandard(;\n    name = \"TestGen\",\n    available = true,\n    status = true,\n    bus = nodes_OMIB[2],\n    active_power = 0.40,\n    reactive_power = 0.010,\n    rating = 0.5,\n    prime_mover_type = PrimeMovers.ST,\n    fuel = ThermalFuels.COAL,\n    active_power_limits = (min = 0.0, max = 0.40),\n    reactive_power_limits = (min = -0.30, max = 0.30),\n    time_limits = nothing,\n    ramp_limits = nothing,\n    operation_cost = ThermalGenerationCost(\n        CostCurve(LinearCurve(1400.0)),\n        0.0,\n        4.0,\n        2.0,\n    ),\n    base_power = 1.0,\n)\n\nbranch_OMIB = [\n    Line(\n        \"Line1\", #name\n        true, #available\n        0.0, #active power flow initial condition (from-to)\n        0.0, #reactive power flow initial condition (from-to)\n        Arc(; from = nodes_OMIB[1], to = nodes_OMIB[2]), #Connection between buses\n        0.01, #resistance in pu\n        0.05, #reactance in pu\n        (from = 0.0, to = 0.0), #susceptance in pu\n        1.14, #rate in MW\n        1.04,\n    ),\n]  #angle limits (-min and max)\n\n@testset \"Dynamic Machines\" begin\n    Basic = BaseMachine(; R = 0.0, Xd_p = 0.2995, eq_p = 1.05)\n    @test Basic isa PowerSystems.DynamicComponent\n\n    GENROU = RoundRotorQuadratic(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_p = 0.06,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.646,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    @test GENROU isa PowerSystems.DynamicComponent\n\n    GENROE = RoundRotorExponential(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_p = 0.06,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.646,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    @test GENROE isa PowerSystems.DynamicComponent\n\n    GENSAL = SalientPoleQuadratic(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    @test GENSAL isa PowerSystems.DynamicComponent\n\n    GENSAE = SalientPoleExponential(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    @test GENSAE isa PowerSystems.DynamicComponent\n\n    oneDoneQ = OneDOneQMachine(;\n        R = 0.0,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.04,\n        Td0_p = 7.4,\n        Tq0_p = 0.033,\n    )\n    @test oneDoneQ isa PowerSystems.DynamicComponent\n\n    SauerPai = SauerPaiMachine(;\n        R = 0.0,\n        Xd = 0.920,\n        Xq = 0.130,\n        Xd_p = 0.300,\n        Xq_p = 0.228,\n        Xd_pp = 0.220,\n        Xq_pp = 0.290,\n        Xl = 0.1,\n        Td0_p = 5.2,\n        Tq0_p = 0.85,\n        Td0_pp = 0.029,\n        Tq0_pp = 0.034,\n    )\n    @test SauerPai isa PowerSystems.DynamicComponent\n\n    AndersonFouad = AndersonFouadMachine(;\n        R = 0.0,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.646,\n        Xd_pp = 0.23,\n        Xq_pp = 0.4,\n        Td0_p = 7.4,\n        Tq0_p = 0.01, #Data not available in Milano: Used 0.01\n        Td0_pp = 0.03,\n        Tq0_pp = 0.033,\n    )\n    @test AndersonFouad isa PowerSystems.DynamicComponent\n\n    KundurMachine = SimpleFullMachine(;\n        R = 0.003, #Example 3.1 and 4.1 of Kundur\n        R_f = 0.0006,\n        R_1d = 0.0284, #RD in Machowski\n        R_1q = 0.0062, #RQ on Machowski\n        L_d = 1.81,\n        L_q = 1.76,\n        L_ad = 1.66, #k*M_f or k*M_D in Machowski\n        L_aq = 1.61, #k*M_Q in Machowski\n        L_f1d = 1.66, #L_fD in Machowski. Assumed to be equal to L_ad\n        L_ff = 1.825,\n        L_1d = 0.1713, #L_D in Machowski\n        L_1q = 0.7525, #L_Q in Machowski\n    )\n    @test KundurMachine isa PowerSystems.DynamicComponent\n\n    KundurFullMachine = FullMachine(;\n        R = 0.003, #Example 3.1 and 4.1 of Kundur\n        R_f = 0.0006,\n        R_1d = 0.0284, #RD in Machowski\n        R_1q = 0.0062, #RQ on Machowski\n        L_d = 1.81,\n        L_q = 1.76,\n        L_ad = 1.66, #k*M_f or k*M_D in Machowski\n        L_aq = 1.61, #k*M_Q in Machowski\n        L_f1d = 1.66, #L_fD in Machowski. Assumed to be equal to L_ad\n        L_ff = 1.825,\n        L_1d = 0.1713, #L_D in Machowski\n        L_1q = 0.7525, #L_Q in Machowski\n    )\n    @test KundurFullMachine isa PowerSystems.DynamicComponent\n\n    Mach2_benchmark = OneDOneQMachine(;\n        R = 0.0,\n        Xd = 1.3125,\n        Xq = 1.2578,\n        Xd_p = 0.1813,\n        Xq_p = 0.25,\n        Td0_p = 5.89,\n        Tq0_p = 0.6,\n    )\n    @test Mach2_benchmark isa PowerSystems.DynamicComponent\nend\n\n################ Shaft Data #####################\n@testset \"Dynamic Shaft\" begin\n    BaseShaft = SingleMass(; H = 5.148, D = 2.0)\n    @test BaseShaft isa PowerSystems.DynamicComponent\n\n    FiveShaft = FiveMassShaft(;\n        H = 5.148,\n        H_hp = 0.3348,\n        H_ip = 0.7306,\n        H_lp = 0.8154,\n        H_ex = 0.0452,\n        D = 2.0,\n        D_hp = 0.5180,\n        D_ip = 0.2240,\n        D_lp = 0.2240,\n        D_ex = 0.1450,\n        D_12 = 0.0518,\n        D_23 = 0.0224,\n        D_34 = 0.0224,\n        D_45 = 0.0145,\n        K_hp = 33.07,\n        K_ip = 28.59,\n        K_lp = 44.68,\n        K_ex = 21.984,\n    )\n    @test FiveShaft isa PowerSystems.DynamicComponent\nend\n\n################# PSS Data #####################\n@testset \"Dynamic PSS\" begin\n    no_pss = PSSFixed(; V_pss = 0.0)\n    @test no_pss isa PowerSystems.DynamicComponent\nend\n################ TG Data #####################\n@testset \"Dynamic Turbine Governor Constructors\" begin\n    fixed_tg = TGFixed(; efficiency = 1.0)\n    @test fixed_tg isa PowerSystems.DynamicComponent\n\n    typeI_tg = TGTypeI(;\n        R = 0.02,\n        Ts = 0.1,\n        Tc = 0.45,\n        T3 = 0.0,\n        T4 = 0.0,\n        T5 = 50.0,\n        valve_position_limits = (min = 0.3, max = 1.2),\n    )\n    @test typeI_tg isa PowerSystems.DynamicComponent\n    @test get_frequency_droop(typeI_tg) == 0.02\n\n    typeII_tg = TGTypeII(; R = 0.05, T1 = 0.3, T2 = 0.1, τ_limits = (min = 0.1, max = 1.0))\n    @test typeII_tg isa PowerSystems.DynamicComponent\n    @test get_frequency_droop(typeII_tg) == 0.05\n\n    gast_tg = GasTG(;\n        R = 0.05,\n        T1 = 0.40,\n        T2 = 0.10,\n        T3 = 2.0,\n        AT = 1.0,\n        Kt = 2.0,\n        V_lim = (0.417, 0.8),\n        D_turb = 0.0,\n    )\n    @test gast_tg isa PowerSystems.DynamicComponent\n    @test get_frequency_droop(gast_tg) == 0.05\n\n    degov_tg = PSY.DEGOV(;\n        T1 = 0.0,\n        T2 = 0.0,\n        T3 = 0.0,\n        K = 18.0,\n        T4 = 12.0,\n        T5 = 5.0,\n        T6 = 0.2,\n        Td = 0.0,\n        P_ref = 0.0,\n    )\n    @test degov_tg isa PowerSystems.DynamicComponent\n    @test get_frequency_droop(degov_tg) == (1/18.0)\nend\n\n################ AVR Data #####################\n@testset \"Dynamic AVR Constructors\" begin\n    proportional_avr = AVRSimple(; Kv = 5000.0)\n    @test proportional_avr isa PowerSystems.DynamicComponent\n\n    fixed_avr = AVRFixed(; Vf = 1.05, V_ref = 1.0)\n    @test fixed_avr isa PowerSystems.DynamicComponent\n\n    typeI_avr = AVRTypeI(;\n        Ka = 200.0,\n        Ke = 1.0,\n        Kf = 0.0012,\n        Ta = 0.02,\n        Te = 0.19,\n        Tf = 1.0,\n        Tr = 0.001,\n        Va_lim = (0.0, 0.0),\n        Ae = 0.0006,\n        Be = 0.9,\n    )\n    @test typeI_avr isa PowerSystems.DynamicComponent\n\n    ac1a_avr = ESAC1A(;\n        Tr = 0.0,\n        Tb = 0.0,\n        Tc = 0.0,\n        Ka = 200,\n        Ta = 0.5,\n        Va_lim = (-7.0, 7.0),\n        Te = 1.333,\n        Kf = 0.02,\n        Tf = 0.8,\n        Kc = 0.0,\n        Kd = 0.0,\n        Ke = 1.0,\n        E_sat = (0.0, 0.0),\n        Se = (0.0, 0.0),\n        Vr_lim = (-99.0, 99.0),\n    )\n    @test ac1a_avr isa PowerSystems.DynamicComponent\n\n    mod_ac1a_avr = EXAC1(;\n        Tr = 0.0,\n        Tb = 0.0,\n        Tc = 0.0,\n        Ka = 400,\n        Ta = 0.5,\n        Vr_lim = (-5.2477, 5.2477),\n        Te = 1.1,\n        Kf = 0.035,\n        Tf = 1.0,\n        Kc = 0.2469,\n        Kd = 0.5,\n        Ke = 1.0,\n        E_sat = (2.707, 3.6102),\n        Se = (0.0366, 0.1831),\n    )\n    @test mod_ac1a_avr isa PowerSystems.DynamicComponent\n\n    st1a_avr = ESST1A(;\n        UEL_flags = 1,\n        PSS_flags = 1,\n        Tr = 0.0,\n        Vi_lim = (-99.0, 99.0),\n        Tc = 2.5,\n        Tb = 13.25,\n        Tc1 = 0.0,\n        Tb1 = 0.0,\n        Ka = 200.0,\n        Ta = 0.1,\n        Va_lim = (-9.5, 9.5),\n        Vr_lim = (-9.5, 9.5),\n        Kc = 0.0,\n        Kf = 0.0,\n        Tf = 1.0,\n        K_lr = 0.0,\n        I_lr = 999.0,\n    )\n    @test st1a_avr isa PowerSystems.DynamicComponent\n\n    gen2_avr_benchmark = AVRTypeII(;\n        K0 = 20.0,\n        T1 = 0.2,\n        T2 = 0.063,\n        T3 = 0.35,\n        T4 = 0.01,\n        Te = 0.314,\n        Tr = 0.001,\n        Va_lim = (-5.0, 5.0),\n        Ae = 0.0039,\n        Be = 1.555,\n    )\n    @test gen2_avr_benchmark isa PowerSystems.DynamicComponent\nend\n######################### Generators ########################\n@testset \"Dynamic Generators\" begin\n    #Components for the test\n    Basic = BaseMachine(; R = 0.0, Xd_p = 0.2995, eq_p = 1.05)\n\n    BaseShaft = SingleMass(; H = 5.148, D = 2.0)\n\n    fixed_avr = AVRFixed(; Vf = 1.05, V_ref = 1.0)\n\n    proportional_avr = AVRSimple(; Kv = 5000.0)\n\n    sexs_avr = SEXS(; Ta_Tb = 0.1, Tb = 10.0, K = 100.0, Te = 0.1, V_lim = (-4.0, 5.0))\n\n    fixed_tg = TGFixed(; efficiency = 1.0)\n    typeI_tg = TGTypeI(;\n        R = 0.02,\n        Ts = 0.1,\n        Tc = 0.45,\n        T3 = 0.0,\n        T4 = 0.0,\n        T5 = 50.0,\n        valve_position_limits = (min = 0.3, max = 1.2),\n    )\n    no_pss = PSSFixed(; V_pss = 0.0)\n\n    oneDoneQ = OneDOneQMachine(;\n        R = 0.0,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.04,\n        Td0_p = 7.4,\n        Tq0_p = 0.033,\n    )\n\n    Gen1AVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = Basic,\n        shaft = BaseShaft,\n        avr = proportional_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n    @test Gen1AVR isa PowerSystems.Component\n    Gen1AVRnoAVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = Basic,\n        shaft = BaseShaft,\n        avr = fixed_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n    @test Gen1AVRnoAVR isa PowerSystems.Component\n\n    Gen2AVRnoAVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = oneDoneQ,\n        shaft = BaseShaft,\n        avr = fixed_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n    @test Gen2AVRnoAVR isa PowerSystems.Component\n\n    Gen2AVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = oneDoneQ,\n        shaft = BaseShaft,\n        avr = proportional_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n    @test Gen2AVR isa PowerSystems.Component\n\n    Gen3AVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = oneDoneQ,\n        shaft = BaseShaft,\n        avr = sexs_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n    @test Gen3AVR isa PowerSystems.Component\n\n    Gen4AVR = DynamicGenerator(;\n        name = get_name(static_gen),\n        ω_ref = 1.0,\n        machine = oneDoneQ,\n        shaft = BaseShaft,\n        avr = sexs_avr,\n        prime_mover = typeI_tg,\n        pss = no_pss,\n    )\n    @test get_frequency_droop(Gen4AVR) == 0.02\n\n    sys = System(100.0)\n    for bus in nodes_OMIB\n        add_component!(sys, bus)\n    end\n    for lines in branch_OMIB\n        add_component!(sys, lines)\n    end\n\n    # Names must be the same.\n    Gen1AVR.name = \"bad_name\"\n    @test_throws ArgumentError add_component!(sys, Gen1AVR, static_gen)\n\n    Gen1AVR.name = get_name(static_gen)\n    # static_injector must be passed.\n    @test_throws ArgumentError add_component!(sys, Gen1AVR)\n\n    # static_injector must be attached to the system.\n    @test_throws ArgumentError add_component!(sys, Gen1AVR, static_gen)\n\n    add_component!(sys, static_gen)\n    @test isnothing(get_dynamic_injector(static_gen))\n\n    add_component!(sys, Gen1AVR, static_gen)\n    dynamics = collect(get_components(DynamicGenerator, sys))\n    @test length(dynamics) == 1\n    @test dynamics[1] == Gen1AVR\n    @test get_dynamic_injector(static_gen) == Gen1AVR\n    @test get_base_power(static_gen) == get_base_power(Gen1AVR)\n    @test PSY.compare_values(static_gen, deepcopy(static_gen))\n\n    remove_component!(sys, Gen1AVR)\n    @test isnothing(get_dynamic_injector(static_gen))\n    add_component!(sys, Gen2AVR, static_gen)\n    @test get_dynamic_injector(static_gen) === Gen2AVR\n    @test get_base_power(static_gen) == get_base_power(Gen2AVR)\n\n    set_base_power!(static_gen, 1234.5)\n    @test get_base_power(static_gen) == 1234.5\n    @test PSY.get_system_base_power(static_gen) == get_base_power(sys)\n\n    # Rule: Can't set the pair injector if the current injector is already set.\n    @test_throws ArgumentError set_dynamic_injector!(static_gen, Gen1AVR)\n\n    # Rule: Can't remove a static injector if it is attached to a dynamic injector.\n    @test_throws ArgumentError remove_component!(sys, static_gen)\n\n    #Rule: Can't add saturation if Se(1.2) <= Se(1.0)\n    @test_throws IS.ConflictingInputsError PSY.get_quadratic_saturation((0.5, 0.1))\n    @test_throws IS.ConflictingInputsError PSY.get_quadratic_saturation((0.1, 0.1))\n    @test_throws IS.ConflictingInputsError PSY.get_avr_saturation((0.2, 0.1), (0.1, 0.1))\n\n    @test length(collect(get_dynamic_components(Gen2AVR))) == 5\n\n    remove_component!(sys, Gen2AVR)\n    @test isnothing(get_dynamic_injector(static_gen))\n    add_component!(sys, Gen3AVR, static_gen)\n\n    retrieved_gen = collect(get_components(DynamicGenerator, sys))\n    orig_dir = pwd()\n    temp_dir = mktempdir()\n    cd(temp_dir)\n    to_json(sys, \"sys.json\")\n    sys2 = System(\"sys.json\")\n    serialized_gen = collect(get_components(DynamicGenerator, sys2))\n    @test get_name(retrieved_gen[1]) == get_name(serialized_gen[1])\n    cd(orig_dir)\nend\n\n@testset \"Replace Dynamic Injector\" begin\n    nodes = [\n        ACBus(\n            1,\n            \"Bus 1\",\n            true,\n            \"REF\",\n            0,\n            1.06,\n            (min = 0.94, max = 1.06),\n            69,\n            nothing,\n            nothing,\n        ),\n        ACBus(\n            2,\n            \"Bus 2\",\n            true,\n            \"PV\",\n            0,\n            1.045,\n            (min = 0.94, max = 1.06),\n            69,\n            nothing,\n            nothing,\n        ),\n    ]\n\n    static = ThermalStandard(;\n        name = \"ReplaceTestGen\",\n        available = true,\n        status = true,\n        bus = nodes[2],\n        active_power = 0.40,\n        reactive_power = 0.010,\n        rating = 0.5,\n        prime_mover_type = PrimeMovers.ST,\n        fuel = ThermalFuels.COAL,\n        active_power_limits = (min = 0.0, max = 0.40),\n        reactive_power_limits = (min = -0.30, max = 0.30),\n        time_limits = nothing,\n        ramp_limits = nothing,\n        operation_cost = ThermalGenerationCost(\n            CostCurve(LinearCurve(1400.0)),\n            0.0,\n            4.0,\n            2.0,\n        ),\n        base_power = 1.0,\n    )\n\n    branches = [\n        Line(\n            \"ReplaceLine1\",\n            true,\n            0.0,\n            0.0,\n            Arc(; from = nodes[1], to = nodes[2]),\n            0.01,\n            0.05,\n            (from = 0.0, to = 0.0),\n            1.14,\n            (min = -0.7, max = 0.7),\n        ),\n    ]\n\n    Basic = BaseMachine(; R = 0.0, Xd_p = 0.2995, eq_p = 1.05)\n    BaseShaft = SingleMass(; H = 5.148, D = 2.0)\n    fixed_avr = AVRFixed(; Vf = 1.05, V_ref = 1.0)\n    proportional_avr = AVRSimple(; Kv = 5000.0)\n    fixed_tg = TGFixed(; efficiency = 1.0)\n    no_pss = PSSFixed(; V_pss = 0.0)\n\n    oneDoneQ = OneDOneQMachine(;\n        R = 0.0,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.04,\n        Td0_p = 7.4,\n        Tq0_p = 0.033,\n    )\n\n    Gen1 = DynamicGenerator(;\n        name = get_name(static),\n        ω_ref = 1.0,\n        machine = Basic,\n        shaft = BaseShaft,\n        avr = proportional_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n\n    Gen2 = DynamicGenerator(;\n        name = get_name(static),\n        ω_ref = 1.0,\n        machine = oneDoneQ,\n        shaft = BaseShaft,\n        avr = fixed_avr,\n        prime_mover = fixed_tg,\n        pss = no_pss,\n    )\n\n    sys = System(100.0)\n    for bus in nodes\n        add_component!(sys, bus)\n    end\n    for line in branches\n        add_component!(sys, line)\n    end\n    add_component!(sys, static)\n    add_component!(sys, Gen1, static)\n\n    @test get_dynamic_injector(static) === Gen1\n\n    # Replace the dynamic injector\n    replace_dynamic_injector!(sys, static, Gen2)\n    @test get_dynamic_injector(static) === Gen2\n    @test get_base_power(static) == get_base_power(Gen2)\n\n    # Old dynamic injector should be removed from the system\n    @test length(collect(get_components(DynamicGenerator, sys))) == 1\n\n    # Error: static injector has no dynamic injector\n    remove_component!(sys, Gen2)\n    @test isnothing(get_dynamic_injector(static))\n    @test_throws ArgumentError replace_dynamic_injector!(sys, static, Gen1)\n\n    # Error: name mismatch\n    add_component!(sys, Gen1, static)\n    bad_name_gen = DynamicGenerator(;\n        name = \"wrong_name\",\n        ω_ref = 1.0,\n        machine = BaseMachine(; R = 0.0, Xd_p = 0.2995, eq_p = 1.05),\n        shaft = SingleMass(; H = 5.148, D = 2.0),\n        avr = AVRSimple(; Kv = 5000.0),\n        prime_mover = TGFixed(; efficiency = 1.0),\n        pss = PSSFixed(; V_pss = 0.0),\n    )\n    @test_throws ArgumentError replace_dynamic_injector!(sys, static, bad_name_gen)\nend\n\n@testset \"Generic DER (DERD)\" begin\n    #valid (non-default) Qref_Flag\n    derd = GenericDER(;\n        name = \"init\",\n        Qref_Flag = 2,\n        PQ_Flag = 0,\n        Gen_Flag = 0,\n        PerOp_Flag = 0,\n        Recon_Flag = 0,\n        Trv = 0,\n        VV_pnts = (V1 = 0.0, V2 = 0.0, V3 = 0.0, V4 = 0.0),\n        Q_lim = (min = 0.0, max = 0.0),\n        Tp = 0,\n        e_lim = (min = 0.0, max = 0.0),\n        Kpq = 0,\n        Kiq = 0,\n        Iqr_lim = (min = 0.0, max = 0.0),\n        I_max = 0,\n        Tg = 0,\n        kWh_Cap = 0,\n        SOC_ini = 0,\n        SOC_lim = (min = 0.0, max = 0.0),\n        Trf = 0,\n        fdbd_pnts = (fdbd1 = 0.0, fdbd2 = 0.0),\n        D_dn = 0,\n        D_up = 0,\n        fe_lim = (min = 0.0, max = 0.0),\n        Kpp = 0,\n        Kip = 0,\n        P_lim = (min = 0.0, max = 0.0),\n        dP_lim = (min = 0.0, max = 0.0),\n        T_pord = 0,\n        rrpwr = 0,\n        VRT_pnts = (vrt1 = 0.0, vrt2 = 0.0, vrt3 = 0.0, vrt4 = 0.0, vrt5 = 0.0),\n        TVRT_pnts = (tvrt1 = 0.0, tvrt2 = 0.0, tvrt3 = 0.0),\n        tV_delay = 0,\n        VES_lim = (min = 0.0, max = 0.0),\n        FRT_pnts = (frt1 = 0.0, frt2 = 0.0, frt3 = 0.0, frt4 = 0.0),\n        TFRT_pnts = (tfrt1 = 0.0, tfrt2 = 0.0),\n        tF_delay = 0,\n        FES_lim = (min = 0.0, max = 0.0),\n        Pfa_ref = 0,\n        Q_ref = 0,\n        P_ref = 0,\n        base_power = 0,\n        ext = Dict{String, Any}(),\n    )\n    @test derd isa PowerSystems.Component\n\n    #invalid Qref_Flag\n    @test_throws ErrorException GenericDER(\n        name = \"init\",\n        Qref_Flag = 4,\n        PQ_Flag = 0,\n        Gen_Flag = 0,\n        PerOp_Flag = 0,\n        Recon_Flag = 0,\n        Trv = 0,\n        VV_pnts = (V1 = 0.0, V2 = 0.0, V3 = 0.0, V4 = 0.0),\n        Q_lim = (min = 0.0, max = 0.0),\n        Tp = 0,\n        e_lim = (min = 0.0, max = 0.0),\n        Kpq = 0,\n        Kiq = 0,\n        Iqr_lim = (min = 0.0, max = 0.0),\n        I_max = 0,\n        Tg = 0,\n        kWh_Cap = 0,\n        SOC_ini = 0,\n        SOC_lim = (min = 0.0, max = 0.0),\n        Trf = 0,\n        fdbd_pnts = (fdbd1 = 0.0, fdbd2 = 0.0),\n        D_dn = 0,\n        D_up = 0,\n        fe_lim = (min = 0.0, max = 0.0),\n        Kpp = 0,\n        Kip = 0,\n        P_lim = (min = 0.0, max = 0.0),\n        dP_lim = (min = 0.0, max = 0.0),\n        T_pord = 0,\n        rrpwr = 0,\n        VRT_pnts = (vrt1 = 0.0, vrt2 = 0.0, vrt3 = 0.0, vrt4 = 0.0, vrt5 = 0.0),\n        TVRT_pnts = (tvrt1 = 0.0, tvrt2 = 0.0, tvrt3 = 0.0),\n        tV_delay = 0,\n        VES_lim = (min = 0.0, max = 0.0),\n        FRT_pnts = (frt1 = 0.0, frt2 = 0.0, frt3 = 0.0, frt4 = 0.0),\n        TFRT_pnts = (tfrt1 = 0.0, tfrt2 = 0.0),\n        tF_delay = 0,\n        FES_lim = (min = 0.0, max = 0.0),\n        Pfa_ref = 0,\n        Q_ref = 0,\n        P_ref = 0,\n        base_power = 0,\n        ext = Dict{String, Any}(),\n    )\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_injector = ThermalStandard(nothing)\n    static_injector.bus = bus\n    add_component!(sys, static_injector)\n    add_component!(sys, derd, static_injector)\n    DERDs = collect(get_components(GenericDER, sys))\n    @test length(DERDs) == 1\nend\n\n@testset \"Aggregate Distributed Generation\" begin\n    #valid (non-default) Freq_Flag\n    dera = AggregateDistributedGenerationA(;\n        name = \"init\",\n        Pf_Flag = 0,\n        Freq_Flag = 1,\n        PQ_Flag = 0,\n        Gen_Flag = 0,\n        Vtrip_Flag = 0,\n        Ftrip_Flag = 0,\n        T_rv = 0,\n        Trf = 0,\n        dbd_pnts = (0.0, 0.0),\n        K_qv = 0,\n        Tp = 0,\n        T_iq = 0,\n        D_dn = 0,\n        D_up = 0,\n        fdbd_pnts = (0.0, 0.0),\n        fe_lim = (min = 0.0, max = 0.0),\n        P_lim = (min = 0.0, max = 0.0),\n        dP_lim = (min = 0.0, max = 0.0),\n        Tpord = 0,\n        Kpg = 0,\n        Kig = 0,\n        I_max = 0,\n        vl_pnts = [(0.0, 0.0), (0.0, 0.0)],\n        vh_pnts = [(0.0, 0.0), (0.0, 0.0)],\n        Vrfrac = 0,\n        fl = 0,\n        fh = 0,\n        tfl = 0,\n        tfh = 0,\n        Tg = 0,\n        rrpwr = 0,\n        Tv = 0,\n        Vpr = 0,\n        Iq_lim = (min = 0.0, max = 0.0),\n        V_ref = 0,\n        Pfa_ref = 0,\n        Q_ref = 0,\n        P_ref = 0,\n        base_power = 0,\n        ext = Dict{String, Any}(),\n    )\n    @test dera isa PowerSystems.Component\n\n    #invalid Freq_Flag\n    @test_throws ErrorException AggregateDistributedGenerationA(\n        name = \"init\",\n        Pf_Flag = 0,\n        Freq_Flag = 2,\n        PQ_Flag = 0,\n        Gen_Flag = 0,\n        Vtrip_Flag = 0,\n        Ftrip_Flag = 0,\n        T_rv = 0,\n        Trf = 0,\n        dbd_pnts = (0.0, 0.0),\n        K_qv = 0,\n        Tp = 0,\n        T_iq = 0,\n        D_dn = 0,\n        D_up = 0,\n        fdbd_pnts = (0.0, 0.0),\n        fe_lim = (min = 0.0, max = 0.0),\n        P_lim = (min = 0.0, max = 0.0),\n        dP_lim = (min = 0.0, max = 0.0),\n        Tpord = 0,\n        Kpg = 0,\n        Kig = 0,\n        I_max = 0,\n        vl_pnts = [(0.0, 0.0), (0.0, 0.0)],\n        vh_pnts = [(0.0, 0.0), (0.0, 0.0)],\n        Vrfrac = 0,\n        fl = 0,\n        fh = 0,\n        tfl = 0,\n        tfh = 0,\n        Tg = 0,\n        rrpwr = 0,\n        Tv = 0,\n        Vpr = 0,\n        Iq_lim = (min = 0.0, max = 0.0),\n        V_ref = 0,\n        Pfa_ref = 0,\n        Q_ref = 0,\n        P_ref = 0,\n        base_power = 0,\n        ext = Dict{String, Any}(),\n    )\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_injector = ThermalStandard(nothing)\n    static_injector.bus = bus\n    add_component!(sys, static_injector)\n    add_component!(sys, dera, static_injector)\n    DERAs = collect(get_components(AggregateDistributedGenerationA, sys))\n    @test length(DERAs) == 1\nend\n\n@testset \"Forward functions\" begin\n    GENROU = RoundRotorQuadratic(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_p = 0.06,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.646,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    test_accessors(GENROU)\n\n    GENROE = RoundRotorExponential(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_p = 0.06,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xq_p = 0.646,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    test_accessors(GENROE)\n\n    GENSAL = SalientPoleQuadratic(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    test_accessors(GENSAL)\n\n    GENSAE = SalientPoleExponential(;\n        R = 0.0,\n        Td0_p = 7.4,\n        Td0_pp = 0.03,\n        Tq0_pp = 0.033,\n        Xd = 0.8979,\n        Xq = 0.646,\n        Xd_p = 0.2995,\n        Xd_pp = 0.23,\n        Xl = 0.1,\n        Se = (0.1, 0.5),\n    )\n    test_accessors(GENSAE)\n\n    #Test GENROU\n    @test get_R(GENROU) == 0.0\n    @test get_Td0_p(GENROU) == 7.4\n    @test get_Td0_pp(GENROU) == 0.03\n    @test get_Tq0_p(GENROU) == 0.06\n    @test get_Tq0_pp(GENROU) == 0.033\n    @test get_Xd(GENROU) == 0.8979\n    @test get_Xq(GENROU) == 0.646\n    @test get_Xd_p(GENROU) == 0.2995\n    @test get_Xq_p(GENROU) == 0.646\n    @test get_Xd_pp(GENROU) == 0.23\n    @test get_Xl(GENROU) == 0.1\n    @test get_Se(GENROU) == (0.1, 0.5)\n    @test get_states(GENROU) == [:eq_p, :ed_p, :ψ_kd, :ψ_kq]\n    @test get_n_states(GENROU) == 4\n    @test get_saturation_coeffs(GENROU)[1] == 0.8620204102886728\n    @test get_saturation_coeffs(GENROU)[2] == 5.252551286084109\n\n    #Test GENROE\n    @test get_R(GENROE) == 0.0\n    @test get_Td0_p(GENROE) == 7.4\n    @test get_Td0_pp(GENROE) == 0.03\n    @test get_Tq0_p(GENROE) == 0.06\n    @test get_Tq0_pp(GENROE) == 0.033\n    @test get_Xd(GENROE) == 0.8979\n    @test get_Xq(GENROE) == 0.646\n    @test get_Xd_p(GENROE) == 0.2995\n    @test get_Xq_p(GENROE) == 0.646\n    @test get_Xd_pp(GENROE) == 0.23\n    @test get_Xl(GENROE) == 0.1\n    @test get_Se(GENROE) == (0.1, 0.5)\n    @test get_states(GENROE) == [:eq_p, :ed_p, :ψ_kd, :ψ_kq]\n    @test get_n_states(GENROE) == 4\n    @test abs(get_saturation_coeffs(GENROE)[1] - 8.827469119589406) <= 1e-6\n    @test abs(get_saturation_coeffs(GENROE)[2] - 0.1) <= 1e-6\n\n    #Test GENSAL\n    @test get_R(GENSAL) == 0.0\n    @test get_Td0_p(GENSAL) == 7.4\n    @test get_Td0_pp(GENSAL) == 0.03\n    @test get_Tq0_pp(GENSAL) == 0.033\n    @test get_Xd(GENSAL) == 0.8979\n    @test get_Xq(GENSAL) == 0.646\n    @test get_Xd_p(GENSAL) == 0.2995\n    @test get_Xd_pp(GENSAL) == 0.23\n    @test get_Xl(GENSAL) == 0.1\n    @test get_Se(GENSAL) == (0.1, 0.5)\n    @test get_states(GENSAL) == [:eq_p, :ψ_kd, :ψq_pp]\n    @test get_n_states(GENSAL) == 3\n    @test get_saturation_coeffs(GENSAL)[1] == 0.8620204102886728\n    @test get_saturation_coeffs(GENSAL)[2] == 5.252551286084109\n\n    #Test GENSAE\n    @test get_R(GENSAE) == 0.0\n    @test get_Td0_p(GENSAE) == 7.4\n    @test get_Td0_pp(GENSAE) == 0.03\n    @test get_Tq0_pp(GENSAE) == 0.033\n    @test get_Xd(GENSAE) == 0.8979\n    @test get_Xq(GENSAE) == 0.646\n    @test get_Xd_p(GENSAE) == 0.2995\n    @test get_Xd_pp(GENSAE) == 0.23\n    @test get_Xl(GENSAE) == 0.1\n    @test get_Se(GENSAE) == (0.1, 0.5)\n    @test get_states(GENSAE) == [:eq_p, :ψ_kd, :ψq_pp]\n    @test get_n_states(GENSAE) == 3\n    @test abs(get_saturation_coeffs(GENSAE)[1] - 8.827469119589406) <= 1e-6\n    @test abs(get_saturation_coeffs(GENSAE)[2] - 0.1) <= 1e-6\nend\n"
  },
  {
    "path": "test/test_dynamic_inverter.jl",
    "content": "@testset \"Inverter Components\" begin\n    converter = AverageConverter(690.0, 2750000.0) #S_rated goes in Watts\n    @test converter isa PowerSystems.DynamicComponent\n    dc_source = FixedDCSource(600.0) #Not in the original data, guessed.\n    @test dc_source isa PowerSystems.DynamicComponent\n    filter = LCLFilter(0.08, 0.003, 0.074, 0.2, 0.01)\n    @test filter isa PowerSystems.DynamicComponent\n    pll = KauraPLL(500.0, 0.084, 4.69)\n    @test pll isa PowerSystems.DynamicComponent\n    reduced_pll = ReducedOrderPLL(500.0, 0.084, 4.69)\n    @test reduced_pll isa PowerSystems.DynamicComponent\n    virtual_H = VirtualInertia(2.0, 400.0, 20.0, 2 * pi * 50.0)\n    @test virtual_H isa PowerSystems.DeviceParameter\n    P_control = ActivePowerDroop(0.2, 1000.0)\n    @test P_control isa PowerSystems.DeviceParameter\n    P_control_PI = ActivePowerPI(2.0, 20.0, 50.0)\n    @test P_control_PI isa PowerSystems.DeviceParameter\n    P_VOC = ActiveVirtualOscillator(0.0033, pi / 4)\n    @test P_VOC isa PowerSystems.DeviceParameter\n    Q_control = ReactivePowerDroop(0.2, 1000.0)\n    @test Q_control isa PowerSystems.DeviceParameter\n    Q_control_PI = ReactivePowerPI(2.0, 20.0, 50.0)\n    @test Q_control_PI isa PowerSystems.DeviceParameter\n    Q_VOC = ReactiveVirtualOscillator(0.0796)\n    @test Q_VOC isa PowerSystems.DeviceParameter\n    outer_control = OuterControl(virtual_H, Q_control)\n    @test outer_control isa PowerSystems.DynamicComponent\n    test_accessors(outer_control)\n    outer_control_droop = OuterControl(P_control, Q_control)\n    @test outer_control_droop isa PowerSystems.DynamicComponent\n    test_accessors(outer_control_droop)\n    outer_control_PI = OuterControl(P_control_PI, Q_control_PI)\n    @test outer_control_PI isa PowerSystems.DynamicComponent\n    test_accessors(outer_control_PI)\n    outer_control_VOC = OuterControl(P_VOC, Q_VOC)\n    @test outer_control_PI isa PowerSystems.DynamicComponent\n    test_accessors(outer_control_PI)\n    vsc = VoltageModeControl(0.59, 736.0, 0.0, 0.0, 0.2, 1.27, 14.3, 0.0, 50.0, 0.2)\n    @test vsc isa PowerSystems.DynamicComponent\n    vsc2 = VoltageModeControl(0.59, 736.0, 0.0, 0.0, 0.2, 1.27, 14.3, 0.0, 50.0, 0.2)\n    @test vsc2 isa PowerSystems.DynamicComponent\n    vsc3 = CurrentModeControl(1.27, 14.3, 0.0)\n    @test vsc3 isa PowerSystems.DynamicComponent\n    BESS_source = ZeroOrderBESS(\n        (sqrt(8) / sqrt(3)) * 690.0,\n        (sqrt(3) / sqrt(8)) * 2750000.0,\n        370.0,\n        0.001,\n        4.63,\n        3200.0,\n        0.6,\n        4.0,\n        0.39,\n        10.34,\n        1.08,\n    )\n    @test BESS_source isa PowerSystems.DynamicComponent\nend\n\n@testset \"Dynamic Inverter\" begin\n    sys = PSB.build_system(PSB.PSYTestSystems, \"dynamic_inverter_sys\")\n    inverters = collect(get_components(DynamicInverter, sys))\n    @test length(inverters) == 1\n    test_inverter = inverters[1]\n    @test test_inverter isa PowerSystems.Component\n    test_accessors(test_inverter)\nend\n\n@testset \"Dynamic Inverter Limiters\" begin\n    converter = AverageConverter(690.0, 2750000.0) #S_rated goes in Watts\n    dc_source = FixedDCSource(600.0) #Not in the original data, guessed.\n    filt = LCLFilter(0.08, 0.003, 0.074, 0.2, 0.01)\n    pll = KauraPLL(500.0, 0.084, 4.69)\n    virtual_H = VirtualInertia(2.0, 400.0, 20.0, 2 * pi * 50.0)\n    Q_control = ReactivePowerDroop(0.2, 1000.0)\n    outer_control = OuterControl(virtual_H, Q_control)\n    vsc = VoltageModeControl(0.59, 736.0, 0.0, 0.0, 0.2, 1.27, 14.3, 0.0, 50.0, 0.2)\n    inverter = DynamicInverter(\n        \"TestInverter\",\n        1.0,\n        converter,\n        outer_control,\n        vsc,\n        dc_source,\n        pll,\n        filt,\n    )\n    @test inverter isa PowerSystems.Component\n    test_accessors(inverter)\n    inv_magnitude = DynamicInverter(;\n        name = \"TestInverter\",\n        ω_ref = 1.0,\n        converter = converter,\n        outer_control = outer_control,\n        inner_control = vsc,\n        dc_source = dc_source,\n        freq_estimator = pll,\n        filter = filt,\n        limiter = MagnitudeOutputCurrentLimiter(; I_max = 1.0),\n    )\n    @test inv_magnitude isa PowerSystems.Component\n    test_accessors(inv_magnitude)\n    inv_inst = DynamicInverter(;\n        name = \"TestInverter\",\n        ω_ref = 1.0,\n        converter = converter,\n        outer_control = outer_control,\n        inner_control = vsc,\n        dc_source = dc_source,\n        freq_estimator = pll,\n        filter = filt,\n        limiter = InstantaneousOutputCurrentLimiter(;\n            Id_max = 1.0 / sqrt(2),\n            Iq_max = 1.0 / sqrt(2),\n        ),\n    )\n    @test inv_inst isa PowerSystems.Component\n    test_accessors(inv_inst)\n    inv_priority = DynamicInverter(;\n        name = \"TestInverter\",\n        ω_ref = 1.0,\n        converter = converter,\n        outer_control = outer_control,\n        inner_control = vsc,\n        dc_source = dc_source,\n        freq_estimator = pll,\n        filter = filt,\n        limiter = PriorityOutputCurrentLimiter(; I_max = 1.0, ϕ_I = 0.1),\n    )\n    @test inv_priority isa PowerSystems.Component\n    test_accessors(inv_priority)\nend\n\n@testset \"Generic Renewable Models\" begin\n    converter_regca1 = RenewableEnergyConverterTypeA(;\n        T_g = 0.02,\n        Rrpwr = 10.0,\n        Brkpt = 0.9,\n        Zerox = 0.4,\n        Lvpl1 = 1.22,\n        Vo_lim = 1.2,\n        Lv_pnts = (0.5, 0.9),\n        Io_lim = -1.3,\n        T_fltr = 0.2,\n        K_hv = 0.0,\n        Iqr_lims = (-100.0, 100.0),\n        Accel = 0.7,\n        Lvpl_sw = 0,\n    )\n    @test converter_regca1 isa PowerSystems.DynamicComponent\n    filt_current = RLFilter(; rf = 0.0, lf = 0.1)\n    @test filt_current isa PowerSystems.DynamicComponent\n    inner_ctrl_typeB = RECurrentControlB(;\n        Q_Flag = 0,\n        PQ_Flag = 0,\n        Vdip_lim = (-99.0, 99.0),\n        T_rv = 0.02,\n        dbd_pnts = (-1.0, 1.0),\n        K_qv = 0.0,\n        Iqinj_lim = (-1.1, 1.1),\n        V_ref0 = 0.0,\n        K_vp = 10.0,\n        K_vi = 60.0,\n        T_iq = 0.02,\n        I_max = 1.11,\n    )\n    @test inner_ctrl_typeB isa PowerSystems.DynamicComponent\n    # Creates 2^5 = 32 combinations of flags for an outer control\n    for (F_flag, VC_flag, R_flag, PF_flag, V_flag) in\n        reverse.(Iterators.product(fill(0:1, 5)...))[:]\n        P_control_typeAB = ActiveRenewableControllerAB(;\n            bus_control = 0,\n            from_branch_control = 0,\n            to_branch_control = 0,\n            branch_id_control = \"0\",\n            Freq_Flag = F_flag,\n            K_pg = 1.0,\n            K_ig = 0.05,\n            T_p = 0.25,\n            fdbd_pnts = (-1.0, 1.0),\n            fe_lim = (-99.0, 99.0),\n            P_lim = (0.0, 1.2),\n            T_g = 0.1,\n            D_dn = 0.0,\n            D_up = 0.0,\n            dP_lim = (-99.0, 99.0),\n            P_lim_inner = (0.0, 1.2),\n            T_pord = 0.02,\n        )\n        Q_control_typeAB = ReactiveRenewableControllerAB(;\n            bus_control = 0,\n            from_branch_control = 0,\n            to_branch_control = 0,\n            branch_id_control = \"0\",\n            VC_Flag = VC_flag,\n            Ref_Flag = R_flag,\n            PF_Flag = PF_flag,\n            V_Flag = V_flag,\n            T_fltr = 0.02,\n            K_p = 18.0,\n            K_i = 5.0,\n            T_ft = 0.0,\n            T_fv = 0.05,\n            V_frz = 0.0,\n            R_c = 0.0,\n            X_c = 0.0,\n            K_c = 0.0,\n            e_lim = (-0.1, 0.1),\n            dbd_pnts = (-1.0, 1.0),\n            Q_lim = (-0.43, 0.43),\n            T_p = 0.0,\n            Q_lim_inner = (-0.44, 0.44),\n            V_lim = (0.9, 1.05),\n            K_qp = 0.0,\n            K_qi = 0.01,\n        )\n        @test P_control_typeAB isa PowerSystems.DeviceParameter\n        @test Q_control_typeAB isa PowerSystems.DeviceParameter\n        outer_control_typeAB = OuterControl(P_control_typeAB, Q_control_typeAB)\n        @test outer_control_typeAB isa PowerSystems.DynamicComponent\n        test_accessors(outer_control_typeAB)\n    end\nend\n"
  },
  {
    "path": "test/test_dynamic_loads.jl",
    "content": "@testset \"Induction Motor\" begin\n    #valid (non-default) A and B\n    im = SingleCageInductionMachine(;\n        name = \"init\",\n        R_s = 0.0,\n        R_r = 0.018,\n        X_ls = 0.1,\n        X_lr = 0.18,\n        X_m = 3.2,\n        H = 0.5,\n        A = 0.2,\n        B = 0.0,\n        base_power = 100.0,\n    )\n    @test im isa PowerSystems.Component\n\n    #invalid A, B or C\n    @test_throws ErrorException SingleCageInductionMachine(\n        name = \"init\",\n        R_s = 0.0,\n        R_r = 0.018,\n        X_ls = 0.1,\n        X_lr = 0.18,\n        X_m = 3.2,\n        H = 0.5,\n        A = 0.2,\n        B = 0.9,\n        base_power = 100.0,\n    )\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_load = PowerLoad(nothing)\n    static_load.bus = bus\n    add_component!(sys, static_load)\n    add_component!(sys, im, static_load)\n    IMs = collect(get_components(SingleCageInductionMachine, sys))\n    @test length(IMs) == 1\n\n    im = SimplifiedSingleCageInductionMachine(;\n        name = \"init\",\n        R_s = 0.0,\n        R_r = 0.018,\n        X_ls = 0.1,\n        X_lr = 0.18,\n        X_m = 3.2,\n        H = 0.5,\n        A = 0.2,\n        B = 0.0,\n        base_power = 100.0,\n    )\n    @test im isa PowerSystems.Component\n\n    #invalid A, B or C\n    @test_throws ErrorException SimplifiedSingleCageInductionMachine(\n        name = \"init\",\n        R_s = 0.0,\n        R_r = 0.018,\n        X_ls = 0.1,\n        X_lr = 0.18,\n        X_m = 3.2,\n        H = 0.5,\n        A = 0.2,\n        B = 0.9,\n        base_power = 100.0,\n    )\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_load = PowerLoad(nothing)\n    static_load.bus = bus\n    add_component!(sys, static_load)\n    add_component!(sys, im, static_load)\n    IMs = collect(get_components(SimplifiedSingleCageInductionMachine, sys))\n    @test length(IMs) == 1\nend\n\n@testset \"Active Constant Power Load Model\" begin\n    #valid model\n    al = ActiveConstantPowerLoad(;\n        name = \"init\",\n        r_load = 70.0,\n        c_dc = 2040e-6,\n        rf = 0.1,\n        lf = 2.3e-3,\n        cf = 8.8e-6,\n        rg = 0.03,\n        lg = 0.93e-3,\n        kp_pll = 0.4,\n        ki_pll = 4.69,\n        kpv = 0.5,\n        kiv = 150.0,\n        kpc = 15.0,\n        kic = 30000.0,\n        base_power = 100.0,\n    )\n    @test al isa PowerSystems.Component\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_load = PowerLoad(nothing)\n    static_load.bus = bus\n    add_component!(sys, static_load)\n    add_component!(sys, al, static_load)\n    ALs = collect(get_components(ActiveConstantPowerLoad, sys))\n    @test length(ALs) == 1\nend\n\n@testset \"Dynamic Exponential Load Model\" begin\n    #valid model\n    al = DynamicExponentialLoad(;\n        name = \"init\",\n        a = 1.0,\n        b = 1.0,\n        α = 1.2,\n        β = 1.2,\n        T_p = 3.0,\n        T_q = 3.0,\n    )\n    @test al isa PowerSystems.Component\n\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    add_component!(sys, bus)\n    static_load = PowerLoad(nothing)\n    static_load.bus = bus\n    add_component!(sys, static_load)\n    add_component!(sys, al, static_load)\n    ALs = collect(get_components(DynamicExponentialLoad, sys))\n    @test length(ALs) == 1\nend\n"
  },
  {
    "path": "test/test_dynamics_source.jl",
    "content": "# Non functional system data. This code is just for testing.\n# Do not copy paste this code.\n@testset \"Test Dynamic Source\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    set_bustype!(bus, ACBusTypes.SLACK)\n    add_component!(sys, bus)\n    source = Source(nothing)\n    set_bus!(source, bus)\n    add_component!(sys, source)\n    pvs = PeriodicVariableSource(nothing)\n    add_component!(sys, pvs, source)\n    @test get_components(PeriodicVariableSource, sys) !== nothing\nend\n\n@testset \"Test Dynamic Source\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    set_bustype!(bus, ACBusTypes.REF)\n    add_component!(sys, bus)\n    source = Source(nothing)\n    set_bus!(source, bus)\n    add_component!(sys, source)\n    pvs = PeriodicVariableSource(nothing)\n    add_component!(sys, pvs, source)\n    @test get_components(PeriodicVariableSource, sys) !== nothing\n    sys2, result = validate_serialization(sys)\n    @test result\nend\n"
  },
  {
    "path": "test/test_generate_structs.jl",
    "content": "@testset \"Test generated structs\" begin\n    descriptor_file =\n        joinpath(@__DIR__, \"..\", \"src\", \"descriptors\", \"power_system_structs.json\")\n    existing_dir = joinpath(@__DIR__, \"..\", \"src\", \"models\", \"generated\")\n    @test IS.test_generated_structs(descriptor_file, existing_dir)\nend\n\n@testset \"Test generated structs from StructDefinition\" begin\n    orig_descriptor_file =\n        joinpath(@__DIR__, \"..\", \"src\", \"descriptors\", \"power_system_structs.json\")\n    output_directory = mktempdir()\n    descriptor_file = joinpath(output_directory, \"power_system_structs.json\")\n    cp(orig_descriptor_file, descriptor_file)\n    # This is necessary in cases where the package has been added through a GitHub branch\n    # where all source files are read-only.\n    chmod(descriptor_file, 0o644)\n    new_struct = StructDefinition(;\n        struct_name = \"MyThermalStandard\",\n        docstring = \"Custom ThermalStandard\",\n        supertype = \"ThermalGen\",\n        is_component = true,\n        fields = [\n            StructField(; name = \"name\", data_type = String, comment = \"name\"),\n            StructField(;\n                name = \"active_power\",\n                data_type = Float64,\n                valid_range = \"active_power_limits\",\n                validation_action = \"warn\",\n                null_value = 0.0,\n                comment = \"active power\",\n                needs_conversion = true,\n            ),\n            StructField(;\n                name = \"active_power_limits\",\n                needs_conversion = true,\n                data_type = \"NamedTuple{(:min, :max), Tuple{Float64, Float64}}\",\n                null_value = \"(min=0.0, max=0.0)\",\n            ),\n            StructField(;\n                name = \"rating\",\n                data_type = Float64,\n                valid_range = Dict(\"min\" => 0.0, \"max\" => nothing),\n                validation_action = \"error\",\n                comment = \"Thermal limited MVA Power Output of the unit. <= Capacity\",\n            ),\n        ],\n    )\n    redirect_stdout(devnull) do\n        generate_struct_file(\n            new_struct;\n            filename = descriptor_file,\n            output_directory = output_directory,\n        )\n    end\n    data = open(descriptor_file, \"r\") do io\n        JSON3.read(io, Dict)\n    end\n\n    @test data[\"auto_generated_structs\"][end][\"struct_name\"] == \"MyThermalStandard\"\n    @test isfile(joinpath(output_directory, \"MyThermalStandard.jl\"))\nend\n"
  },
  {
    "path": "test/test_hybrid_system.jl",
    "content": "@testset \"Hybrid System tests\" begin\n    test_sys = PSB.build_system(PSB.PSITestSystems, \"c_sys14\"; add_forecasts = false)\n\n    h_sys = HybridSystem(;\n        name = \"Test H\",\n        available = true,\n        status = true,\n        bus = get_component(ACBus, test_sys, \"Bus 1\"),\n        active_power = 1.0,\n        reactive_power = 1.0,\n        thermal_unit = ThermalStandard(nothing),\n        electric_load = PowerLoad(nothing),\n        storage = EnergyReservoirStorage(nothing),\n        renewable_unit = RenewableDispatch(nothing),\n        base_power = 100.0,\n        operation_cost = MarketBidCost(nothing),\n    )\n    add_component!(test_sys, h_sys)\n\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    resolution = Dates.Hour(1)\n    other_time = initial_time + resolution\n    name = \"test\"\n    horizon = 24\n    data = Dict(initial_time => ones(horizon), other_time => 5.0 * ones(horizon))\n    forecast = Deterministic(name, data, resolution)\n    add_time_series!(test_sys, h_sys, forecast)\n    ts = get_time_series(Deterministic, h_sys, \"test\")\n    @test isa(ts, Deterministic)\nend\n\n@testset \"Hybrid System from parsed files\" begin\n    sys = PSB.build_system(\n        PSB.PSITestSystems,\n        \"test_RTS_GMLC_sys_with_hybrid\";\n        add_forecasts = true,\n    )\n    hybrids = collect(get_components(HybridSystem, sys))\n    @test length(hybrids) == 1\n    h_sys = hybrids[1]\n\n    electric_load = nothing\n    thermal_unit = nothing\n    subcomponents = collect(get_subcomponents(h_sys))\n    @test length(subcomponents) == 4\n    expected_time_series_names = Set{String}()\n    num_time_series = 0\n    for subcomponent in subcomponents\n        @test !PSY.is_attached(subcomponent, sys)\n        @test IS.is_attached(subcomponent, sys.data.masked_components)\n        if subcomponent isa PowerLoad\n            electric_load = subcomponent\n        elseif subcomponent isa ThermalStandard\n            thermal_unit = subcomponent\n        end\n        for ts in get_time_series_multiple(subcomponent)\n            push!(\n                expected_time_series_names,\n                PSY.make_subsystem_time_series_name(subcomponent, ts),\n            )\n            num_time_series += 1\n        end\n    end\n    @test electric_load !== nothing\n    @test thermal_unit !== nothing\n\n    sts = collect(get_time_series_multiple(h_sys; type = SingleTimeSeries))\n    forecasts =\n        collect(get_time_series_multiple(h_sys; type = DeterministicSingleTimeSeries))\n    @test length(sts) == 2\n    @test length(forecasts) == 2\n    @test issubset((get_name(x) for x in sts), expected_time_series_names)\n    @test issubset((get_name(x) for x in forecasts), expected_time_series_names)\n\n    @test get_time_series(SingleTimeSeries, electric_load, \"max_active_power\") isa\n          SingleTimeSeries\n    @test get_time_series(Deterministic, electric_load, \"max_active_power\") isa\n          DeterministicSingleTimeSeries\n\n    @test !has_time_series(thermal_unit)\n    @test has_time_series(electric_load)\n    remove_time_series!(\n        sys,\n        DeterministicSingleTimeSeries,\n        electric_load,\n        \"max_active_power\",\n    )\n    @test !has_time_series(electric_load, DeterministicSingleTimeSeries, \"max_active_power\")\n\n    # Can't set the units when the HybridSystem is attached to system.\n    @test_throws ArgumentError PSY.set_thermal_unit!(h_sys, thermal_unit)\nend\n\n@testset \"Hybrid System from unattached subcomponents\" begin\n    sys = PSB.build_system(PSB.PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    thermal_unit = first(get_components(ThermalStandard, sys))\n    bus = get_bus(thermal_unit)\n    electric_load = first(get_components(PowerLoad, sys))\n    storage = first(get_components(EnergyReservoirStorage, sys))\n    renewable_unit = first(get_components(RenewableDispatch, sys))\n\n    for subcomponent in (thermal_unit, electric_load, storage, renewable_unit)\n        remove_component!(sys, subcomponent)\n    end\n\n    name = \"Test H\"\n    h_sys = HybridSystem(;\n        name = name,\n        available = true,\n        status = true,\n        bus = bus,\n        active_power = 1.0,\n        reactive_power = 1.0,\n        thermal_unit = thermal_unit,\n        electric_load = electric_load,\n        storage = storage,\n        renewable_unit = renewable_unit,\n        base_power = 100.0,\n        operation_cost = MarketBidCost(nothing),\n    )\n    add_component!(sys, h_sys)\n\n    for subcomponent in (thermal_unit, electric_load, storage, renewable_unit)\n        @test !PSY.is_attached(subcomponent, sys)\n        @test !has_time_series(subcomponent)\n        @test IS.is_attached(subcomponent, sys.data.masked_components)\n    end\n\n    @test length(IS.get_masked_components(Component, sys.data)) == 4\n\n    # Add time series for a subcomponent.\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    resolution = Dates.Hour(1)\n    other_time = initial_time + resolution\n    name = \"test\"\n    horizon = 24\n    data = Dict(initial_time => rand(horizon), other_time => 5.0 * ones(horizon))\n\n    forecast = Deterministic(name, data, resolution)\n    add_time_series!(sys, thermal_unit, forecast)\n    @test get_time_series(Deterministic, thermal_unit, name) isa Deterministic\n    copy_subcomponent_time_series!(h_sys, thermal_unit)\n    @test get_time_series(\n        Deterministic,\n        h_sys,\n        PSY.make_subsystem_time_series_name(thermal_unit, forecast),\n    ) isa Deterministic\nend\n\n@testset \"get_fuel_cost for HybridSystem delegates to thermal subunit\" begin\n    # Hybrid with thermal: get_fuel_cost delegates to thermal subunit\n    sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5_uc\"; add_forecasts = false)\n    thermal = first(get_components(ThermalStandard, sys))\n    # Ensure thermal has ThermalGenerationCost with FuelCurve\n    fc = FuelCurve(InputOutputCurve(IS.QuadraticFunctionData(1, 2, 3)), 2.5)\n    set_operation_cost!(thermal, ThermalGenerationCost(fc, 0.0, 0.0, 0.0))\n    expected_fuel_cost = get_fuel_cost(thermal)\n\n    bus = get_bus(thermal)\n    remove_component!(sys, thermal)\n    h_sys = HybridSystem(;\n        name = \"HybridWithThermal\",\n        available = true,\n        status = true,\n        bus = bus,\n        active_power = 1.0,\n        reactive_power = 0.0,\n        thermal_unit = thermal,\n        electric_load = nothing,\n        storage = nothing,\n        renewable_unit = nothing,\n        base_power = 100.0,\n        operation_cost = MarketBidCost(nothing),\n    )\n    add_component!(sys, h_sys)\n    @test get_fuel_cost(h_sys) == expected_fuel_cost\nend\n\n@testset \"get_fuel_cost for HybridSystem without thermal throws\" begin\n    sys = PSB.build_system(PSB.PSITestSystems, \"c_sys14\"; add_forecasts = false)\n    bus = get_component(ACBus, sys, \"Bus 1\")\n    h_sys = HybridSystem(;\n        name = \"HybridNoThermal\",\n        available = true,\n        status = true,\n        bus = bus,\n        active_power = 1.0,\n        reactive_power = 0.0,\n        thermal_unit = nothing,\n        electric_load = nothing,\n        storage = nothing,\n        renewable_unit = nothing,\n        base_power = 100.0,\n        operation_cost = MarketBidCost(nothing),\n    )\n    add_component!(sys, h_sys)\n    @test_throws ArgumentError get_fuel_cost(h_sys)\nend\n"
  },
  {
    "path": "test/test_hydro_reservoir.jl",
    "content": "@testset \"Test Hydro Turbine constructors\" begin\n    turbine = HydroTurbine(; name = \"TestTurbine\",\n        available = true,\n        bus = ACBus(nothing),\n        active_power = 0.0,\n        reactive_power = 0.0,\n        rating = 1,\n        base_power = 100,\n        active_power_limits = (min = 0, max = 1),\n        reactive_power_limits = nothing,\n        outflow_limits = nothing,\n        powerhouse_elevation = 0.0,\n        ramp_limits = nothing,\n        time_limits = nothing,\n    )\n\n    set_powerhouse_elevation!(turbine, 10.0)\n    @test get_powerhouse_elevation(turbine) == 10.0\nend\n\n@testset \"Test Hydro Reservoir constructors and getters\" begin\n    reservoir = HydroReservoir(;\n        name = \"init\",\n        available = false,\n        initial_level = 1.0,\n        storage_level_limits = (min = 0.0, max = 1.0),\n        spillage_limits = nothing,\n        inflow = 0.0,\n        outflow = 0.0,\n        level_targets = 0.0,\n        intake_elevation = 0.0,\n        head_to_volume_factor = LinearCurve(0.0),\n    )\n    @test get_storage_level_limits(reservoir) == (min = 0.0, max = 1.0)\n    @test get_initial_level(reservoir) == 1.0\n    @test get_level_data_type(reservoir) == ReservoirDataType.USABLE_VOLUME\n    @test get_inflow(reservoir) == 0.0\n    @test get_outflow(reservoir) == 0.0\n    @test get_intake_elevation(reservoir) == 0.0\n    @test get_head_to_volume_factor(reservoir) == LinearCurve(0.0)\n    set_intake_elevation!(reservoir, 10.0)\n    @test get_intake_elevation(reservoir) == 10.0\nend\n\n@testset \"Test Hydro Reservoir constructors and setters\" begin\n    reservoir = HydroReservoir(nothing)\n    @test set_storage_level_limits!(reservoir, (min = 0.0, max = 0.0)) ==\n          (min = 0.0, max = 0.0)\n    @test set_level_data_type!(reservoir, ReservoirDataType.HEAD) == ReservoirDataType.HEAD\n    @test set_inflow!(reservoir, 10.0) == 10.0\n    @test set_outflow!(reservoir, 10.0) == 10.0\nend\n\n@testset \"Test single `HydroTurbine` with single `HydroReservoir`\" begin\n    sys = System(100.0)\n\n    bus = nodes5()[4]\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n\n    reservoir = HydroReservoir(nothing)\n    add_component!(sys, reservoir)\n    turbine = HydroTurbine(nothing)\n    turbine.bus = bus\n    add_component!(sys, turbine)\n    set_downstream_turbine!(reservoir, turbine)\n\n    @test !has_upstream_turbine(reservoir)\n    @test has_downstream_turbine(reservoir)\n    @test !has_upstream_turbine(reservoir, turbine)\n    @test has_downstream_turbine(reservoir, turbine)\n    @test length(get_components(HydroTurbine, sys)) == 1\n    @test length(get_connected_head_reservoirs(sys, turbine)) == 1\n\n    remove_turbine!(reservoir, turbine)\n    @test_throws ArgumentError remove_turbine!(reservoir, turbine)\n    @test !has_downstream_turbine(reservoir)\n    @test !has_downstream_turbine(reservoir, turbine)\n    @test length(get_connected_head_reservoirs(sys, turbine)) == 0\n\n    remove_component!(sys, turbine)\n    @test_throws ArgumentError get_connected_head_reservoirs(sys, turbine)\n\n    _, result = validate_serialization(sys)\n    @test result\nend\n\n@testset \"Test multiple `HydroTurbine` with single `HydroReservoir`\" begin\n    sys = System(100.0)\n\n    bus = nodes5()[4]\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n\n    hydro_reservoir = HydroReservoir(nothing)\n    add_component!(sys, hydro_reservoir)\n    turbines = []\n    for i in 1:5\n        turbine = HydroTurbine(nothing)\n        turbine.name = \"Turbine\" * string(i)\n        turbine.bus = bus\n        add_component!(sys, turbine)\n        push!(turbines, turbine)\n    end\n    set_downstream_turbines!(hydro_reservoir, turbines)\n\n    collected_turbines = collect(get_components(HydroTurbine, sys))\n    @test length(turbines) == length(collected_turbines)\n    @test !has_upstream_turbine(hydro_reservoir)\n    @test has_downstream_turbine(hydro_reservoir)\n    @test length(get_downstream_turbines(hydro_reservoir)) == 5\n    @test isempty(get_upstream_turbines(hydro_reservoir))\n\n    mapping = get_turbine_head_reservoirs_mapping(sys)\n    @test mapping isa TurbineConnectedDevicesMapping\n    @test length(get_connected_head_reservoirs(sys, turbines[1])) == 1\n\n    _, result = validate_serialization(sys)\n    @test result\n\n    remove_turbine!(hydro_reservoir, turbines[1])\n    @test length(get_downstream_turbines(hydro_reservoir)) == 4\n    clear_turbines!(hydro_reservoir)\n    @test isempty(get_downstream_turbines(hydro_reservoir))\nend\n\n@testset \"Test single `HydroTurbine` with multiple `HydroReservoir`\" begin\n    sys = System(100.0)\n\n    bus = nodes5()[4]\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n\n    hydro_reservoir_01 = HydroReservoir(nothing)\n    hydro_reservoir_02 = HydroReservoir(nothing)\n    hydro_reservoir_02.name = \"reservoir02\"\n    add_component!(sys, hydro_reservoir_01)\n    add_component!(sys, hydro_reservoir_02)\n    turbine = HydroTurbine(nothing)\n    turbine.bus = bus\n    add_component!(sys, turbine)\n    set_downstream_turbine!(hydro_reservoir_01, turbine)\n    set_downstream_turbine!(hydro_reservoir_02, turbine)\n    @test length(get_connected_head_reservoirs(sys, turbine)) == 2\n    @test isempty(get_connected_tail_reservoirs(sys, turbine))\n\n    _, result = validate_serialization(sys)\n    @test result\nend\n"
  },
  {
    "path": "test/test_internal.jl",
    "content": "import UUIDs\n\n\"\"\"Recursively validates that the object and fields have UUIDs.\"\"\"\nfunction validate_uuids(obj::T) where {T}\n    if !(obj isa Component)\n        return true\n    end\n\n    result = true\n    if !(IS.get_uuid(obj) isa Base.UUID)\n        result = false\n        @error \"object does not have a UUID\" obj\n    end\n\n    for fieldname in fieldnames(T)\n        val = getfield(obj, fieldname)\n        if !validate_uuids(val)\n            result = false\n        end\n    end\n\n    return result\nend\n\nfunction validate_uuids(obj::T) where {T <: AbstractArray}\n    result = true\n    for elem in obj\n        if !validate_uuids(elem)\n            result = false\n        end\n    end\n\n    return result\nend\n\nfunction validate_uuids(obj::T) where {T <: AbstractDict}\n    result = true\n    for elem in values(obj)\n        if !validate_uuids(elem)\n            result = false\n        end\n    end\n    return result\nend\n\n@testset \"Test internal values\" begin\n    sys_rts = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    @test validate_uuids(sys_rts)\nend\n"
  },
  {
    "path": "test/test_logging.jl",
    "content": "\nTEST_MSG = \"test log message\"\n\n@testset \"Test configure_logging\" begin\n    # Verify logging to a file.\n    logfile = \"testlog.txt\"\n    isfile(logfile) && rm(logfile)\n\n    orig_logger = global_logger()\n    try\n        logger = configure_logging(;\n            console_level = Logging.Warn,\n            file_level = Logging.Debug,\n            filename = logfile,\n        )\n        with_logger(logger) do\n            @info TEST_MSG\n        end\n\n        close(logger)\n        @test isfile(logfile)\n        lines = readlines(logfile)\n        @test length(lines) == 2  # two lines per message\n        @test occursin(TEST_MSG, lines[1])\n    finally\n        rm(logfile)\n        global_logger(orig_logger)\n    end\n\n    # Verify logging with no file.\n    try\n        logger = configure_logging(;\n            console_level = Logging.Warn,\n            file_level = Logging.Info,\n            filename = nothing,\n        )\n        with_logger(logger) do\n            @info TEST_MSG\n        end\n\n        close(logger)\n        @test !isfile(logfile)\n    finally\n        global_logger(orig_logger)\n    end\nend\n"
  },
  {
    "path": "test/test_outages.jl",
    "content": "@testset \"Test outages\" begin\n    sys = create_system_with_outages()\n    gens = collect(get_components(ThermalStandard, sys))\n    gen1 = gens[1]\n    gen2 = gens[2]\n    @test length(get_supplemental_attributes(Outage, sys)) == 4\n    forced_outages =\n        collect(get_supplemental_attributes(GeometricDistributionForcedOutage, sys))\n    @test length(forced_outages) == 2\n    @test get_supplemental_attribute(sys, IS.get_uuid(forced_outages[1])) ==\n          forced_outages[1]\n    planned_outages = collect(get_supplemental_attributes(PlannedOutage, sys))\n    @test length(planned_outages) == 2\n    @test get_supplemental_attribute(sys, IS.get_uuid(planned_outages[1])) ==\n          planned_outages[1]\n\n    geos = get_supplemental_attributes(GeographicInfo, sys)\n    for geo in geos\n        @test length(get_associated_components(sys, geo)) == 2\n        @test length(\n            get_associated_components(sys, geo; component_type = ThermalStandard),\n        ) == 1\n        # This method is deprecated for now...will be deleted later.\n        @test length(get_components(sys, geo)) == 2\n    end\n\n    associated_components = get_associated_components(sys, GeographicInfo)\n    @test length(associated_components) == 4\n    @test Set([typeof(x) for x in associated_components]) == Set([ACBus, ThermalStandard])\n\n    associated_components =\n        get_associated_components(sys, GeographicInfo; component_type = ThermalGen)\n    @test length(associated_components) == 2\n\n    for gen in (gen1, gen2)\n        for type in (GeometricDistributionForcedOutage, PlannedOutage, GeographicInfo)\n            attributes = get_supplemental_attributes(type, gen)\n            @test length(attributes) == 1\n            uuid = IS.get_uuid(attributes[1])\n            get_supplemental_attribute(sys, uuid)\n            get_supplemental_attribute(gen, uuid)\n            @test get_supplemental_attribute(gen, uuid) ==\n                  get_supplemental_attribute(sys, uuid)\n        end\n    end\n\n    @test length(\n        get_supplemental_attributes(\n            x -> get_mean_time_to_recovery(x) == 2.0,\n            GeometricDistributionForcedOutage,\n            sys,\n        ),\n    ) == 1\n    @test length(\n        get_supplemental_attributes(\n            x -> get_mean_time_to_recovery(x) == 2.0,\n            GeometricDistributionForcedOutage,\n            gen1,\n        ),\n    ) == 0\n    @test length(\n        get_supplemental_attributes(\n            x -> get_mean_time_to_recovery(x) == 2.0,\n            GeometricDistributionForcedOutage,\n            gen2,\n        ),\n    ) == 1\n    @test length(\n        get_supplemental_attributes(x -> get_outage_schedule(x) == \"1\", PlannedOutage, sys),\n    ) == 1\n    @test length(\n        get_supplemental_attributes(\n            x -> get_outage_schedule(x) == \"1\",\n            PlannedOutage,\n            gen1,\n        ),\n    ) == 1\n    @test length(\n        get_supplemental_attributes(\n            x -> get_outage_schedule(x) == \"1\",\n            PlannedOutage,\n            gen2,\n        ),\n    ) == 0\n    planned_outages = collect(get_supplemental_attributes(PlannedOutage, gen2))\n    @test !isempty(planned_outages)\n    for outage in planned_outages\n        ts_keys = get_time_series_keys(outage)\n        @test !isempty(ts_keys)\n        for key in ts_keys\n            remove_time_series!(sys, key.time_series_type, outage, key.name)\n        end\n        @test isempty(get_time_series_keys(outage))\n    end\nend\n\n@testset \"Test get_component_supplemental_attribute_pairs\" begin\n    sys = create_system_with_outages()\n    # This function is properly tested in InfrastructureSystems.\n    for (gen, outage) in get_component_supplemental_attribute_pairs(\n        ThermalStandard,\n        GeometricDistributionForcedOutage,\n        sys,\n    )\n        @test gen isa ThermalStandard\n        @test outage isa GeometricDistributionForcedOutage\n    end\nend\n\n@testset \"Test get_supplemental_attributes with component type\" begin\n    # the create_system_with_outages function creates a system with only ThermalStandard\n    # components, so we need a different system for this test.\n    c_sys5_bat = PSB.build_system(PSITestSystems, \"c_sys5_bat\")\n    renewables = collect(get_components(PSY.RenewableDispatch, c_sys5_bat))\n    thermals = collect(get_components(PSY.ThermalStandard, c_sys5_bat))\n\n    attr1 = IS.TestSupplemental(; value = 1.0)\n    attr2 = IS.TestSupplemental(; value = 2.0)\n    geo_attr1 = IS.GeographicInfo()\n    geo_attr2 = IS.GeographicInfo(; geo_json = Dict{String, Any}(\"foo\" => 5))\n\n    comp_to_attributes = Dict{PSY.Component, Vector{IS.SupplementalAttribute}}(\n        renewables[1] => [geo_attr1],\n        renewables[2] => [geo_attr1, attr1],\n        thermals[1] => [geo_attr2],\n        thermals[2] => [geo_attr2, attr2],\n        thermals[3] => [geo_attr1],\n    )\n    for (comp, attrs) in comp_to_attributes\n        for attr in attrs\n            add_supplemental_attribute!(c_sys5_bat, comp, attr)\n        end\n    end\n\n    renewable_attrs =\n        get_associated_supplemental_attributes(c_sys5_bat, PSY.RenewableDispatch)\n    @test length(renewable_attrs) == 2 && geo_attr1 in renewable_attrs &&\n          attr1 in renewable_attrs\n\n    thermal_attrs = get_associated_supplemental_attributes(c_sys5_bat, PSY.ThermalStandard)\n    @test length(thermal_attrs) == 3 && geo_attr2 in thermal_attrs &&\n          attr2 in thermal_attrs && geo_attr1 in thermal_attrs\n\n    thermal_geo_attrs = get_associated_supplemental_attributes(\n        c_sys5_bat,\n        PSY.ThermalStandard;\n        attribute_type = IS.GeographicInfo,\n    )\n    @test length(thermal_geo_attrs) == 2 && geo_attr1 in thermal_geo_attrs &&\n          geo_attr2 in thermal_geo_attrs\nend\n\n@testset \"Test remove_supplemental_attributes! by type\" begin\n    sys = create_system_with_outages()\n    # Verify initial state\n    @test length(get_supplemental_attributes(GeometricDistributionForcedOutage, sys)) == 2\n    @test length(get_supplemental_attributes(PlannedOutage, sys)) == 2\n    @test length(get_supplemental_attributes(GeographicInfo, sys)) == 2\n\n    # Remove all GeometricDistributionForcedOutage attributes\n    remove_supplemental_attributes!(GeometricDistributionForcedOutage, sys)\n    @test length(get_supplemental_attributes(GeometricDistributionForcedOutage, sys)) == 0\n    # Other types should be unaffected\n    @test length(get_supplemental_attributes(PlannedOutage, sys)) == 2\n    @test length(get_supplemental_attributes(GeographicInfo, sys)) == 2\n\n    # Remove all PlannedOutage attributes\n    remove_supplemental_attributes!(PlannedOutage, sys)\n    @test length(get_supplemental_attributes(PlannedOutage, sys)) == 0\n    @test length(get_supplemental_attributes(GeographicInfo, sys)) == 2\n\n    # Remove all GeographicInfo attributes\n    remove_supplemental_attributes!(GeographicInfo, sys)\n    @test length(get_supplemental_attributes(GeographicInfo, sys)) == 0\nend\n"
  },
  {
    "path": "test/test_parse_dynamics.jl",
    "content": "\n@testset \"2-area, 11-bus, 4-generator benchmark system Parsing \" begin\n    test_dir = mktempdir()\n    ger4_raw_file = joinpath(PSSE_RAW_DIR, \"Benchmark_4ger_33_2015.RAW\")\n    ger4_dyr_file = joinpath(PSSE_DYR_DIR, \"Benchmark_4ger_33_2015.dyr\")\n    sys = PSB.build_system(PSYTestSystems, \"psse_Benchmark_4ger_33_2015_sys\")\n    @test_throws PSY.DataFormatError System(ger4_raw_file, ger4_raw_file)\n    @test_throws PSY.DataFormatError System(ger4_dyr_file, ger4_raw_file)\n    dyn_injectors = get_components(DynamicInjection, sys)\n    @test length(dyn_injectors) == 4\n    for g in dyn_injectors\n        m = PSY.get_machine(g)\n        @test typeof(m) <: RoundRotorExponential\n    end\n    path = joinpath(test_dir, \"test_dyn_system_serialization.json\")\n    to_json(sys, path)\n    parsed_sys = System(path)\n    dyn_injectors = get_components(DynamicInjection, parsed_sys)\n    @test length(dyn_injectors) == 4\n    for g in dyn_injectors\n        m = PSY.get_machine(g)\n        @test typeof(m) <: RoundRotorExponential\n    end\nend\n\n@testset \"2-area, 11-bus, 4-generator with renewables benchmark system Parsing \" begin\n    test_dir = mktempdir()\n    sys = PSB.build_system(PSYTestSystems, \"psse_renewable_parsing_1\")\n    dyn_injectors = get_components(DynamicInjection, sys)\n    @test length(dyn_injectors) == 5\n    for g in dyn_injectors\n        if isa(g, DynamicGenerator)\n            m = PSY.get_machine(g)\n            @test typeof(m) <: RoundRotorExponential\n        elseif isa(g, DynamicInverter)\n            ic = PSY.get_inner_control(g)\n            @test typeof(ic) <: RECurrentControlB\n        else\n            @error(\"Generator $g not supported\")\n        end\n    end\n    path = joinpath(test_dir, \"test_dyn_system_serialization.json\")\n    to_json(sys, path)\n    parsed_sys = System(path)\n    dyn_injectors = get_components(DynamicInjection, parsed_sys)\n    @test length(dyn_injectors) == 5\n    for g in dyn_injectors\n        if isa(g, DynamicGenerator)\n            m = PSY.get_machine(g)\n            @test typeof(m) <: RoundRotorExponential\n        elseif isa(g, DynamicInverter)\n            ic = PSY.get_inner_control(g)\n            @test typeof(ic) <: RECurrentControlB\n        else\n            @error(\"Generator $g not supported\")\n        end\n    end\nend\n\n@testset \"240 Bus WECC system Parsing \" begin\n    test_dir = mktempdir()\n    sys = PSB.build_system(PSYTestSystems, \"psse_240_parsing_sys\")\n    dyn_injectors = get_components(DynamicInjection, sys)\n    @test length(dyn_injectors) == 146\n    for g in dyn_injectors\n        if isa(g, DynamicGenerator)\n            m = PSY.get_machine(g)\n            @test typeof(m) <: RoundRotorQuadratic\n        elseif isa(g, DynamicInverter)\n            ic = PSY.get_inner_control(g)\n            @test typeof(ic) <: RECurrentControlB\n        else\n            @error(\"Generator $g not supported\")\n        end\n    end\n    path = joinpath(test_dir, \"test_dyn_system_serialization.json\")\n    to_json(sys, path)\n    parsed_sys = System(path)\n    dyn_injectors = get_components(DynamicInjection, parsed_sys)\n    @test length(dyn_injectors) == 146\n    for g in dyn_injectors\n        if isa(g, DynamicGenerator)\n            m = PSY.get_machine(g)\n            @test typeof(m) <: RoundRotorQuadratic\n        elseif isa(g, DynamicInverter)\n            ic = PSY.get_inner_control(g)\n            @test typeof(ic) <: RECurrentControlB\n        else\n            @error(\"Generator $g not supported\")\n        end\n    end\n    all_gens = collect(get_components(ThermalStandard, sys))\n    sort!(all_gens, by = get_name)\n    static_injector = first(all_gens)\n    @test get_frequency_droop(static_injector) ==\n          static_injector.dynamic_injector.prime_mover.R\nend\n\n@testset \"GENCLS dyr parsing\" begin\n    threebus_raw_file = joinpath(PSSE_TEST_DIR, \"ThreeBusNetwork.raw\")\n    gencls_dyr_file = joinpath(PSSE_TEST_DIR, \"TestGENCLS.dyr\")\n    nogencls_dyr_file = joinpath(PSSE_TEST_DIR, \"Test-NoCLS.dyr\")\n    sexs_dyr_file = joinpath(PSSE_TEST_DIR, \"Test_SEXS.dyr\")\n    sys_gencls = PSB.build_system(PSYTestSystems, \"psse_3bus_gen_cls_sys\")\n    sys_nogencls = PSB.build_system(PSYTestSystems, \"psse_3bus_no_cls_sys\")\n    sys_sexs = PSB.build_system(PSYTestSystems, \"psse_3bus_SEXS_sys\")\n\n    #Check that generator at bus 102 (H = 0) is a Source, and not ThermalStandard.\n    @test isnothing(get_component(ThermalStandard, sys_gencls, \"generator-102-1\"))\n    @test typeof(get_component(StaticInjection, sys_gencls, \"generator-102-1\")) <: Source\n    #Check that generator at bus 102 (not provided in dyr data) is a Source.\n    @test isnothing(get_component(ThermalStandard, sys_nogencls, \"generator-102-1\"))\n    @test typeof(get_component(StaticInjection, sys_nogencls, \"generator-102-1\")) <: Source\n\n    #Check Parameters of GENROE raw file\n    genroe_gen = get_component(DynamicInjection, sys_gencls, \"generator-101-1\")\n    m = PSY.get_machine(genroe_gen)\n    s = PSY.get_shaft(genroe_gen)\n    @test typeof(m) <: RoundRotorExponential\n\n    @test get_R(m) == 0.0\n    @test get_Td0_p(m) == 8.0\n    @test get_Td0_pp(m) == 0.03\n    @test get_Tq0_p(m) == 0.4\n    @test get_Tq0_pp(m) == 0.05\n    @test get_Xd(m) == 1.8\n    @test get_Xq(m) == 1.7\n    @test get_Xd_p(m) == 0.3\n    @test get_Xd_pp(m) == 0.25\n    @test get_Xl(m) == 0.2\n    @test get_H(s) == 6.5\n    @test get_D(s) == 0.0\n\n    #Check Parameters of other GENCLS file\n    gencls_gen = get_component(DynamicInjection, sys_gencls, \"generator-103-1\")\n    m = PSY.get_machine(gencls_gen)\n    s = PSY.get_shaft(gencls_gen)\n    @test typeof(m) <: BaseMachine\n\n    @test get_R(m) == 0.0\n    @test get_Xd_p(m) == 0.2\n    @test get_H(s) == 3.1\n    @test get_D(s) == 2.0\n\n    #Check Parameters of other GENCLS file\n    gencls_gen = get_component(DynamicInjection, sys_nogencls, \"generator-103-1\")\n    m = PSY.get_machine(gencls_gen)\n    s = PSY.get_shaft(gencls_gen)\n    @test typeof(m) <: BaseMachine\n\n    @test get_R(m) == 0.0\n    @test get_Xd_p(m) == 0.2\n    @test get_H(s) == 3.1\n    @test get_D(s) == 2.0\n\n    #Check Parameters of SEXS file\n    genroe_sexs = get_component(DynamicInjection, sys_sexs, \"generator-101-1\")\n    a = PSY.get_avr(genroe_sexs)\n    @test typeof(a) <: AVR\n    @test get_Ta_Tb(a) == 0.4\n    @test get_Tb(a) == 5.0\n    @test get_K(a) == 20.0\n    @test get_Te(a) == 1.0\n    E_min, E_max = get_V_lim(a)\n    @test E_min == -50.0\n    @test E_max == 50.0\nend\n\n@testset \"2000-Bus Parsing\" begin\n    test_dir = mktempdir()\n    sys = build_system(PSSEParsingTestSystems, \"psse_ACTIVSg2000_sys\")\n    for g in get_components(ThermalStandard, sys)\n        if isnothing(get_dynamic_injector(g))\n            @error \"ThermalStandard $(get_name(g)) should have a dynamic injector\"\n        end\n        @test !isnothing(get_dynamic_injector(g))\n    end\n    for g in get_components(SynchronousCondenser, sys)\n        if isnothing(get_dynamic_injector(g))\n            @error \"SynchronousCondenser $(get_name(g)) should have a dynamic injector\"\n        end\n        @test !isnothing(get_dynamic_injector(g))\n    end\n    path = joinpath(test_dir, \"test_dyn_system_serialization_2000.json\")\n    to_json(sys, path)\n    parsed_sys = System(path)\n    dyn_injectors = get_components(DynamicInjection, parsed_sys)\n    @test length(dyn_injectors) == 435\n    for g in get_components(ThermalStandard, parsed_sys)\n        @test !isnothing(get_dynamic_injector(g))\n    end\nend\n"
  },
  {
    "path": "test/test_parse_matpower.jl",
    "content": "# TODO: Reviewers: Is this a correct list of keys to verify?\nPOWER_MODELS_KEYS = [\n    \"baseMVA\",\n    \"branch\",\n    \"bus\",\n    \"dcline\",\n    \"gen\",\n    \"load\",\n    \"name\",\n    \"per_unit\",\n    \"shunt\",\n    \"source_type\",\n    \"source_version\",\n    \"storage\",\n]\n\nbadfiles = Dict(\"case30.m\" => PSY.InvalidValue)\nvoltage_inconsistent_files = [\"RTS_GMLC_original.m\", \"case5_re.m\", \"case5_re_uc.m\"]\nerror_log_files = [\"ACTIVSg2000.m\", \"case_ACTIVSg10k.m\"]\n\n@testset \"Parse Matpower data files\" begin\n    files = [x for x in readdir(joinpath(MATPOWER_DIR)) if splitext(x)[2] == \".m\"]\n    if length(files) == 0\n        @error \"No test files in the folder\"\n    end\n\n    for f in files\n        @info \"Parsing $f...\"\n        path = joinpath(MATPOWER_DIR, f)\n\n        if f in voltage_inconsistent_files\n            continue\n        else\n            pm_dict = PowerSystems.parse_file(path)\n        end\n\n        for key in POWER_MODELS_KEYS\n            @test haskey(pm_dict, key)\n        end\n        @info \"Successfully parsed $path to PowerModels dict\"\n\n        if f in keys(badfiles)\n            @test_logs(\n                (:error, r\"cannot create Line\"),\n                match_mode = :any,\n                @test_throws(badfiles[f], System(PowerSystems.PowerModelsData(pm_dict)))\n            )\n        else\n            sys = System(PowerSystems.PowerModelsData(pm_dict))\n            @info \"Successfully parsed $path to System struct\"\n        end\n    end\nend\n\n@testset \"Parse PowerModel Matpower data files\" begin\n    files = [\n        x for x in readdir(MATPOWER_DIR) if\n              splitext(x)[2] == \".m\"\n    ]\n    if length(files) == 0\n        @error \"No test files in the folder\"\n    end\n\n    for f in files\n        @info \"Parsing $f...\"\n        path = joinpath(MATPOWER_DIR, f)\n\n        if f in voltage_inconsistent_files\n            continue\n        else\n            pm_dict = PowerSystems.parse_file(path)\n        end\n\n        for key in POWER_MODELS_KEYS\n            @test haskey(pm_dict, key)\n        end\n        @info \"Successfully parsed $path to PowerModels dict\"\n\n        if f in keys(badfiles)\n            @test_logs(\n                (:error, r\"cannot create Line\"),\n                match_mode = :any,\n                @test_throws(badfiles[f], System(PowerSystems.PowerModelsData(pm_dict)))\n            )\n        else\n            sys = System(PowerSystems.PowerModelsData(pm_dict))\n            @info \"Successfully parsed $path to System struct\"\n        end\n    end\nend\n\n@testset \"Parse Matpower files with voltage inconsistencies\" begin\n    test_parse = (path) -> begin\n        pm_dict = PowerSystems.parse_file(path)\n\n        for key in POWER_MODELS_KEYS\n            @test haskey(pm_dict, key)\n        end\n        @info \"Successfully parsed $path to PowerModels dict\"\n        sys = System(PowerSystems.PowerModelsData(pm_dict))\n        @info \"Successfully parsed $path to System struct\"\n        @test isa(sys, System)\n    end\n    for f in voltage_inconsistent_files\n        @info \"Parsing $f...\"\n        path = joinpath(BAD_DATA, f)\n        @test_logs (:error,) match_mode = :any test_parse(path)\n    end\nend\n"
  },
  {
    "path": "test/test_parse_psse.jl",
    "content": "@testset \"PSSE Parsing\" begin\n    files = readdir(PSSE_RAW_DIR)\n    if length(files) == 0\n        error(\"No test files in the folder\")\n    end\n\n    for f in files[1:1]\n        @info \"Parsing $f ...\"\n        pm_data = PowerSystems.PowerModelsData(joinpath(PSSE_RAW_DIR, f))\n        @info \"Successfully parsed $f to PowerModelsData\"\n        sys = System(pm_data)\n        for g in get_components(Generator, sys)\n            @test haskey(get_ext(g), \"r\")\n            @test haskey(get_ext(g), \"x\")\n        end\n        @info \"Successfully parsed $f to System struct\"\n    end\n\n    # Test bad input\n    pm_data = PowerSystems.PowerModelsData(joinpath(PSSE_RAW_DIR, files[1]))\n    pm_data.data[\"bus\"] = Dict{String, Any}()\n    @test_throws PowerSystems.DataFormatError System(pm_data)\nend\n\n@testset \"PSSE Component Parsing\" begin\n    @info \"Testing Load Parsing\"\n    mp_sys = build_system(MatpowerTestSystems, \"matpower_case24_sys\")\n    @test get_active_power(get_component(PowerLoad, mp_sys, \"bus14\")) == 1.94\n    @test get_max_reactive_power(get_component(PowerLoad, mp_sys, \"bus14\")) == 0.39\n    @test get_conformity(get_component(PowerLoad, mp_sys, \"bus14\")) ==\n          LoadConformity.CONFORMING\n\n    sys = build_system(PSYTestSystems, \"psse_240_parsing_sys\") # current/imedance_power read in natural units during parsing\n    @test get_current_active_power(get_component(StandardLoad, sys, \"load10021\")) == 2.2371\n    @test get_impedance_reactive_power(get_component(StandardLoad, sys, \"load10021\")) ==\n          -5.83546\n    @test get_conformity(get_component(StandardLoad, sys, \"load10021\")) ==\n          LoadConformity.CONFORMING\n\n    sys2 = build_system(PSYTestSystems, \"psse_Benchmark_4ger_33_2015_sys\")  # Constant_active/reactive_power read in pu during parsing\n    @test get_constant_active_power(get_component(StandardLoad, sys2, \"load71\")) == 9.67\n    @test get_constant_reactive_power(get_component(StandardLoad, sys2, \"load71\")) == 1.0\n    @test get_conformity(get_component(StandardLoad, sys2, \"load71\")) ==\n          LoadConformity.CONFORMING\n\n    @info \"Testing ZIP Load Parsing\"\n    wecc_sys = build_system(PSYTestSystems, \"psse_240_parsing_sys\")\n    test_load1 = get_component(StandardLoad, wecc_sys, \"load24091\")\n    impedance_q = get_impedance_reactive_power(test_load1)\n    # Negative for capacitive loads\n    @test impedance_q < 0\n    @test isapprox(impedance_q, -0.75; atol = 1e-4)\n\n    test_load2 = get_component(StandardLoad, wecc_sys, \"load10031\")\n    impedance_q = get_impedance_reactive_power(test_load2)\n    # Positive for inductance loads\n    @test impedance_q > 0\n    @test isapprox(impedance_q, 3.873; atol = 1e-3)\n\n    @info \"Testing Generator Parsing\"\n    @test get_status(get_component(ThermalStandard, sys, \"generator-2438-ND\")) == 0\n    @test get_available(get_component(ThermalStandard, sys, \"generator-2438-ND\")) == 0\n    @test get_status(get_component(ThermalStandard, sys, \"generator-2438-EG\")) == 1\n    @test get_available(get_component(ThermalStandard, sys, \"generator-2438-EG\")) == 1\n\n    sys3 = build_system(PSSEParsingTestSystems, \"psse_ACTIVSg2000_sys\")\n    sys4 = build_system(PSSEParsingTestSystems, \"pti_frankenstein_70_sys\")\n\n    base_dir = string(dirname(@__FILE__))\n    file_dir = joinpath(base_dir, \"test_data\", \"5circuit_3w.raw\")\n    sys5 = System(file_dir)\n\n    @info \"Testing Three-Winding Transformer Parsing\"\n\n    @test isnothing(get_component(Transformer3W, sys3, \"1\"))\n    @test haskey(\n        get_ext(get_component(Transformer2W, sys3, \"DALLAS 1 3-DALLAS 1 0-i_1\")),\n        \"psse_name\",\n    )\n    @test get_available(\n        get_component(Transformer3W, sys4, \"FAV PLACE 07-FAV SPOT 06-FAV SPOT 03-i_1\"),\n    ) == true\n    tw3s = get_components(Transformer3W, sys4)\n    @test length(tw3s) == 1\n    tw3 = only(tw3s)\n    @test isapprox(get_b(tw3), 0.0036144)\n    @test get_primary_turns_ratio(tw3) == 1.5\n    @test get_rating(tw3) == 0.0\n\n    @test get_available(\n        get_component(Transformer3W, sys5, \"FAV SPOT 01-FAV SPOT 02-FAV SPOT 03-i_A\"),\n    ) == false\n\n    @test get_r_primary(\n        get_component(Transformer3W, sys5, \"FAV SPOT 01-FAV SPOT 02-FAV SPOT 03-i_C\"),\n    ) == 0.00225\n    @test haskey(\n        get_ext(\n            get_component(Transformer3W, sys5, \"FAV SPOT 01-FAV SPOT 02-FAV SPOT 03-i_C\"),\n        ),\n        \"psse_name\",\n    )\n\n    @test length(get_components(Transformer3W, sys5)) == 5\n\n    @info \"Testing Phase Shifting Three-Winding Transformer Parsing\"\n    sys_pst3w = build_system(PSSEParsingTestSystems, \"pti_case14_with_pst3w_sys\")\n\n    pst3w_1, pst3w_2 = sort(\n        collect(get_components(PhaseShiftingTransformer3W, sys_pst3w)),\n        by = get_name,\n    )\n\n    @test get_available(pst3w_1) == true\n    @test get_available(pst3w_2) == true\n\n    @test isapprox(get_α_primary(pst3w_1), -0.5236; atol = 1e-4)\n    @test isapprox(get_α_secondary(pst3w_1), 2.6179; atol = 1e-4)\n    @test isapprox(get_α_tertiary(pst3w_1), -1.3962; atol = 1e-4)\n\n    @test isapprox(get_α_primary(pst3w_2), 1.0471; atol = 1e-4)\n    @test isapprox(get_α_secondary(pst3w_2), 0.0; atol = 1e-4)\n    @test isapprox(get_α_tertiary(pst3w_2), -2.0943; atol = 1e-4)\n\n    @test length(get_components(PhaseShiftingTransformer3W, sys_pst3w)) == 2\n\n    @info \"Testing Switched Shunt Parsing\"\n    @test get_available(get_component(SwitchedAdmittance, sys3, \"1030-9\")) == false\n    @test only(\n        get_Y_increase(get_component(SwitchedAdmittance, sys3, \"3147-42\")),\n    ).im ==\n          0.35\n    @test get_admittance_limits(\n        get_component(SwitchedAdmittance, sys3, \"3147-42\"),\n    ).min ==\n          1.03\n    @test only(\n        get_number_of_steps(\n            get_component(SwitchedAdmittance, sys3, \"7075-119\"),\n        ),\n    ) ==\n          1\n    @test only(\n        get_Y_increase(get_component(SwitchedAdmittance, sys3, \"7075-119\")),\n    ).im ==\n          3.425\n\n    @test get_available(get_component(SwitchedAdmittance, sys4, \"1005-2\")) ==\n          true\n    @test get_Y(get_component(SwitchedAdmittance, sys4, \"1005-2\")) == 0.06im\n    @test get_admittance_limits(\n        get_component(SwitchedAdmittance, sys4, \"1005-2\"),\n    ).max ==\n          1.045\n    @test only(\n        get_Y_increase(get_component(SwitchedAdmittance, sys4, \"1005-2\")),\n    ).im == 0.06\n\n    @test length(get_components(SwitchedAdmittance, sys4)) == 2\n    @test get_available(get_component(SwitchedAdmittance, sys4, \"1003-1\")) ==\n          true\n    @test get_Y(get_component(SwitchedAdmittance, sys4, \"1003-1\")) == 0.038im\n    @test get_admittance_limits(\n        get_component(SwitchedAdmittance, sys4, \"1003-1\"),\n    ).min ==\n          0.95\n\n    @info \"Testing VSC Parser\"\n    vsc = only(get_components(TwoTerminalVSCLine, sys4))\n    @test get_active_power_flow(vsc) == -0.2\n    @test get_dc_setpoint_to(vsc) == -20.0\n\n    @info \"Testing Load Zone Formatter\"\n    PSB.clear_serialized_systems(\"psse_Benchmark_4ger_33_2015_sys\")\n    sys3 = build_system(\n        PSYTestSystems,\n        \"psse_Benchmark_4ger_33_2015_sys\";\n        loadzone_name_formatter = x -> string(3 * x),\n    )\n    lz_original = only(get_components(LoadZone, sys2))\n    lz_new = only(get_components(LoadZone, sys3))\n    @test parse(Int, get_name(lz_new)) == 3 * parse(Int, get_name(lz_original))\nend\n\n@testset \"PSSE FACTS Control Devices Parsing\" begin\n    sys = build_system(PSSEParsingTestSystems, \"pti_case14_sys\")\n    bus2 = get_component(ACBus, sys, \"Bus 2     HV\")\n    facts_1 = FACTSControlDevice(;\n        name = \"FACTS 1\",\n        available = true,\n        bus = bus2,\n        control_mode = 1,\n        max_shunt_current = 9999.0,\n        reactive_power_required = 100.0,\n        voltage_setpoint = 1.0,\n    )\n    add_component!(sys, facts_1)\n\n    facts = only(get_components(FACTSControlDevice, sys))\n    @test get_available(facts) == true\n    @test get_voltage_setpoint(facts) == 1.0\n    @test get_max_shunt_current(facts) == 9999.0\n    @test get_reactive_power_required(facts) > 0\n    @test get_control_mode(facts) == FACTSOperationModes.NML\nend\n\n@testset \"PSSE Generators as Synchronous Condensers\" begin\n    sys = build_system(PSSEParsingTestSystems, \"pti_case11_with_synchronous_condensers_sys\")\n    sc_gen1 = collect(get_components(SynchronousCondenser, sys))[1]\n\n    @test !hasproperty(sc_gen1, :active_power)\n    @test get_rating(sc_gen1) >= 0.0\n    @test get_reactive_power(sc_gen1) != 0.0\n    @test get_available(sc_gen1) == true\n    @test get_bustype(get_bus(sc_gen1)) == ACBusTypes.PV\nend\n\n@testset \"PSSE Switches & Breakers Parsing\" begin\n    sys = build_system(PSSEParsingTestSystems, \"pti_case24_sys\")\n    line1 = first(get_components(Line, sys))\n    sw_1 = DiscreteControlledACBranch(;\n        name = \"SWITCH 1\",\n        available = true,\n        arc = line1.arc,\n        active_power_flow = 0.0,\n        reactive_power_flow = 0.0,\n        r = 0.0,\n        x = line1.x,\n        rating = line1.rating,\n        discrete_branch_type = 0,\n        branch_status = 1,\n    )\n    add_component!(sys, sw_1)\n    line2 = get_component(Line, sys, \"15-16-i_1\")\n    br_1 = DiscreteControlledACBranch(;\n        name = \"BREAKER 1\",\n        available = true,\n        arc = line2.arc,\n        active_power_flow = 0.0,\n        reactive_power_flow = 0.0,\n        r = 0.0,\n        x = line2.x,\n        rating = line2.rating,\n        discrete_branch_type = 1,\n        branch_status = 1,\n    )\n    add_component!(sys, br_1)\n    line3 = get_component(Line, sys, \"20-23-i_1\")\n    otr_1 = DiscreteControlledACBranch(;\n        name = \"OTHER 1\",\n        available = true,\n        arc = line3.arc,\n        active_power_flow = 0.0,\n        reactive_power_flow = 0.0,\n        r = line3.r,\n        x = line3.x,\n        rating = line3.rating,\n        discrete_branch_type = 2,\n        branch_status = 1,\n    )\n    add_component!(sys, otr_1)\n\n    switch = get_component(DiscreteControlledACBranch, sys, \"SWITCH 1\")\n    breaker = get_component(DiscreteControlledACBranch, sys, \"BREAKER 1\")\n    other = get_component(DiscreteControlledACBranch, sys, \"OTHER 1\")\n\n    @test get_available(switch) == true\n    @test get_available(breaker) == true\n    @test get_available(other) == true\n\n    @test get_discrete_branch_type(switch) == DiscreteControlledBranchType.SWITCH\n    @test get_discrete_branch_type(breaker) == DiscreteControlledBranchType.BREAKER\n\n    @test get_branch_status(switch) == DiscreteControlledBranchStatus.CLOSED\n    @test get_branch_status(other) == DiscreteControlledBranchStatus.CLOSED\nend\n\n@testset \"PSSE default branch name counter\" begin\n    sys = build_system(PSSEParsingTestSystems, \"pti_case24_sys\")\n    buses = collect(get_components(ACBus, sys))\n    bus_f = buses[1]\n    bus_t = buses[2]\n\n    branch_pair_counts = Dict{Tuple{String, String}, Int}()\n    d1 = Dict{String, Any}(\"source_id\" => Any[\"transformer\", 1, 2, 0, \" 1\", 0])\n    d2 = Dict{String, Any}(\"source_id\" => Any[\"transformer\", 1, 2, 0, \"1 \", 0])\n\n    n1 =\n        PowerSystems._get_pm_branch_name_with_counter!(d1, bus_f, bus_t, branch_pair_counts)\n    n2 =\n        PowerSystems._get_pm_branch_name_with_counter!(d2, bus_f, bus_t, branch_pair_counts)\n\n    @test n1 != n2\n    @test endswith(n1, \"-i_1\")\n    @test endswith(n2, \"-i_2\")\nend\n\n@testset \"PSSE LCC Parsing\" begin\n    sys = build_system(PSSEParsingTestSystems, \"pti_two_terminal_hvdc_test_sys\")\n\n    lccs = get_components(TwoTerminalLCCLine, sys)\n    @test length(lccs) == 1\n    lcc = only(lccs)\n    @test get_transfer_setpoint(lcc) == 20.0\n    @test get_active_power_flow(lcc) == 0.2\n    @test isapprox(get_rectifier_delay_angle_limits(lcc).max, pi / 2)\n    @test isapprox(get_inverter_extinction_angle_limits(lcc).max, pi / 2)\n    @test get_power_mode(lcc)\nend\n\n@testset \"PSSE Impedance Correction Table Parsing\" begin\n    base_dir = string(dirname(@__FILE__))\n    file_dir = joinpath(base_dir, \"test_data\", \"modified_14bus_system.raw\")\n    sys = System(file_dir)\n\n    tr2w_1 = get_component(Transformer2W, sys, \"BUS 110-BUS 109-i_1\")\n    suppl_attr_tr2w_1 = only(get_supplemental_attributes(tr2w_1))\n    @test get_table_number(suppl_attr_tr2w_1) == 3\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_1))[1] ==\n          (x = -24.1, y = 1.27)\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_1))[end] ==\n          (x = 24.1, y = 1.27)\n    @test get_transformer_winding(suppl_attr_tr2w_1) == WindingCategory.TR2W_WINDING\n    @test get_transformer_control_mode(suppl_attr_tr2w_1) ==\n          ImpedanceCorrectionTransformerControlMode.PHASE_SHIFT_ANGLE\n\n    tr2w_2 = get_component(Transformer2W, sys, \"BUS 109-BUS 104-i_1\")\n    suppl_attr_tr2w_2 = only(get_supplemental_attributes(tr2w_2))\n    @test get_table_number(suppl_attr_tr2w_2) == 4\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_2))[1] ==\n          (x = 0.88, y = 1.093)\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_2))[end] ==\n          (x = 1.17, y = 0.916)\n    @test get_transformer_winding(suppl_attr_tr2w_2) == WindingCategory.TR2W_WINDING\n    @test get_transformer_control_mode(suppl_attr_tr2w_2) ==\n          ImpedanceCorrectionTransformerControlMode.TAP_RATIO\n\n    tr2w_3 = get_component(Transformer2W, sys, \"BUS 106-BUS 105-i_1\")\n    suppl_attr_tr2w_3 = only(get_supplemental_attributes(tr2w_3))\n    @test get_table_number(suppl_attr_tr2w_3) == 7\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_3))[1] ==\n          (x = -45.0, y = 2.073)\n    @test get_points(get_impedance_correction_curve(suppl_attr_tr2w_3))[end] ==\n          (x = 45.0, y = 2.073)\n    @test get_transformer_winding(suppl_attr_tr2w_3) == WindingCategory.TR2W_WINDING\n    @test get_transformer_control_mode(suppl_attr_tr2w_3) ==\n          ImpedanceCorrectionTransformerControlMode.PHASE_SHIFT_ANGLE\n\n    tr3w_1 = get_component(Transformer3W, sys, \"BUS 109-BUS 104-BUS 107-i_1\")\n    suppl_attr_tr3w_1 = collect(get_supplemental_attributes(tr3w_1))\n\n    filtered_tertiary_tr3w_1 = only(\n        filter(\n            x -> get_transformer_winding(x) == WindingCategory.TERTIARY_WINDING,\n            suppl_attr_tr3w_1,\n        ),\n    )\n    @test get_table_number(filtered_tertiary_tr3w_1) == 4\n    @test get_points(get_impedance_correction_curve(filtered_tertiary_tr3w_1))[1] ==\n          (x = 0.88, y = 1.093)\n    @test get_points(get_impedance_correction_curve(filtered_tertiary_tr3w_1))[end] ==\n          (x = 1.17, y = 0.916)\n    @test get_transformer_control_mode(filtered_tertiary_tr3w_1) ==\n          ImpedanceCorrectionTransformerControlMode.TAP_RATIO\n\n    filtered_secondary_tr3w_2 = only(\n        filter(\n            x -> get_transformer_winding(x) == WindingCategory.SECONDARY_WINDING,\n            suppl_attr_tr3w_1,\n        ),\n    )\n    @test get_table_number(filtered_secondary_tr3w_2) == 8\n    @test get_points(get_impedance_correction_curve(filtered_secondary_tr3w_2))[1] ==\n          (x = -60.0, y = 1.5718)\n    @test get_points(get_impedance_correction_curve(filtered_secondary_tr3w_2))[end] ==\n          (x = 60.0, y = 1.5718)\n    @test get_transformer_control_mode(filtered_secondary_tr3w_2) ==\n          ImpedanceCorrectionTransformerControlMode.PHASE_SHIFT_ANGLE\n\n    tr3w_2 = get_component(Transformer3W, sys, \"BUS 113-BUS 110-BUS 114-i_1\")\n    suppl_attr_tr3w_2 = collect(get_supplemental_attributes(tr3w_2))\n\n    filtered_primary_tr3w_2 = only(\n        filter(\n            x -> get_transformer_winding(x) == WindingCategory.PRIMARY_WINDING,\n            suppl_attr_tr3w_2,\n        ),\n    )\n    @test get_table_number(filtered_primary_tr3w_2) == 9\n    @test get_points(get_impedance_correction_curve(filtered_primary_tr3w_2))[1] ==\n          (x = -40.0, y = 1.4)\n    @test get_points(get_impedance_correction_curve(filtered_primary_tr3w_2))[end] ==\n          (x = 40.0, y = 1.4)\n    @test get_transformer_control_mode(filtered_primary_tr3w_2) ==\n          ImpedanceCorrectionTransformerControlMode.PHASE_SHIFT_ANGLE\nend\n\n@testset \"PSSE System Serialization/Desearialization\" begin\n    original_sys =\n        build_system(PSSEParsingTestSystems, \"pti_case30_sys\"; force_build = true)\n    serialize_sys_path = joinpath(tempdir(), \"test_system.json\")\n    to_json(original_sys, serialize_sys_path; force = true)\n    deserialized_sys = System(serialize_sys_path)\n\n    @test get_base_power(original_sys) == get_base_power(deserialized_sys)\n    @test get_frequency(original_sys) == get_frequency(deserialized_sys)\n    @test get_num_components(original_sys) ==\n          get_num_components(deserialized_sys)\n\n    gen1_names = sort(get_name.(get_components(ThermalStandard, original_sys)))\n    gen2_names = sort(get_name.(get_components(ThermalStandard, deserialized_sys)))\n    @test gen1_names == gen2_names\n\n    sa1_y = get_Y.(get_components(SwitchedAdmittance, original_sys))\n    sa2_y = get_Y.(get_components(SwitchedAdmittance, deserialized_sys))\n    @test sa1_y == sa2_y\n\n    @test IS.compare_values(original_sys, deserialized_sys)\nend\n\n@testset \"PSSE transformer tap position correction testing\" begin\n    sys = build_system(\n        PSSEParsingTestSystems,\n        \"psse_14_tap_correction_test_system\";\n        force_build = true,\n    )\n    #test 2W correction matches PSSE\n    trf = get_component(TapTransformer, sys, \"BUS 104-BUS 107-i_1\")\n    tap = get_tap(trf)\n    @test isapprox(tap, 0.979937; atol = 1e-6)\n\n    #test 3W correction matches PSSE\n    trf_3w = get_component(Transformer3W, sys, \"BUS 109-BUS 104-BUS 107-i_1\")\n    tap1 = get_primary_turns_ratio(trf_3w)\n    tap2 = get_secondary_turns_ratio(trf_3w)\n    tap3 = get_tertiary_turns_ratio(trf_3w)\n    @test isapprox(tap1, 0.98750; atol = 1e-6)\n    @test isapprox(tap2, 0.97500; atol = 1e-6)\n    @test isapprox(tap3, 0.96250; atol = 1e-6)\n\n    sys2 = build_system(\n        PSSEParsingTestSystems,\n        \"pti_case8_voltage_winding_correction_sys\";\n        force_build = true,\n    )\n    trf_3w_v = get_component(Transformer3W, sys2, \"NODE F-NODE G-NODE D-i_1\")\n    @test get_available_primary(trf_3w_v) == true\n    @test get_available_secondary(trf_3w_v) == true\n    @test get_available_tertiary(trf_3w_v) == true\n\n    #test 3W correction matches PSSE\n    tap1 = get_primary_turns_ratio(trf_3w_v)\n    tap2 = get_secondary_turns_ratio(trf_3w_v)\n    tap3 = get_tertiary_turns_ratio(trf_3w_v)\n    @test isapprox(tap1, 0.988; atol = 1e-6)\n    @test isapprox(tap2, 0.9807518; atol = 1e-6)\n    @test isapprox(tap3, 0.992; atol = 1e-6)\n\n    sys3 = build_system(\n        PSSEParsingTestSystems,\n        \"pti_case10_voltage_winding_correction_sys\";\n        force_build = true,\n    )\n\n    trf_3w_v1 = get_component(Transformer3W, sys3, \"BUS 108-BUS 110-BUS 109-i_1\")\n    tap1 = get_primary_turns_ratio(trf_3w_v1)\n    tap2 = get_secondary_turns_ratio(trf_3w_v1)\n    tap3 = get_tertiary_turns_ratio(trf_3w_v1)\n    @test isapprox(tap1, 1.05; atol = 1e-6)\n    @test isapprox(tap2, 0.956; atol = 1e-6)\n    @test isapprox(tap3, 0.95625; atol = 1e-6)\n\n    trf_3w_v2 = get_component(Transformer3W, sys3, \"BUS 104-BUS 109-BUS 111-i_1\")\n    tap1 = get_primary_turns_ratio(trf_3w_v2)\n    tap2 = get_secondary_turns_ratio(trf_3w_v2)\n    tap3 = get_tertiary_turns_ratio(trf_3w_v2)\n    @test isapprox(tap1, 1.0; atol = 1e-6)\n    @test isapprox(tap2, 1.0; atol = 1e-6)\n    @test isapprox(tap3, 1.0; atol = 1e-6)\n\n    trf_3w_v3 = get_component(Transformer3W, sys3, \"BUS 102-BUS 104-BUS 103-i_1\")\n    tap1 = get_primary_turns_ratio(trf_3w_v3)\n    tap2 = get_secondary_turns_ratio(trf_3w_v3)\n    tap3 = get_tertiary_turns_ratio(trf_3w_v3)\n    @test isapprox(tap1, 1.0250; atol = 1e-6)\n    @test isapprox(tap2, 0.9256; atol = 1e-6)\n    @test isapprox(tap3, 0.9150; atol = 1e-6)\nend\n\n@testset \"PSSE isolated bus handling (unavailable vs topologically isolated)\" begin\n    sys = @test_logs (:error,) min_level = Logging.Error match_mode = :any build_system(\n        PSSEParsingTestSystems,\n        \"isolated_bus_test_system\";\n        force_build = true,\n    )\n    @test length(get_components(x -> get_available(x), ACBus, sys)) == 2   #Bus 1 and 2\n    @test length(get_components(x -> get_available(x), StandardLoad, sys)) == 1 # Load at Bus 2\n    @test length(get_components(x -> get_available(x), SwitchedAdmittance, sys)) == 0\n    @test length(get_components(x -> get_available(x), Generator, sys)) == 2  #Gens at Bus 1 and 2\n    @test length(get_components(x -> get_available(x), Branch, sys)) == 1\n    @test length(get_components(x -> get_available(x), TapTransformer, sys)) == 0\n\n    @test length(get_components(x -> get_bustype(x) == ACBusTypes.ISOLATED, ACBus, sys)) ==\n          14\n    @test length(get_components(x -> get_bustype(x) == ACBusTypes.REF, ACBus, sys)) == 1\n    @test length(get_components(x -> get_bustype(x) == ACBusTypes.PV, ACBus, sys)) == 1\n    @test length(get_components(x -> get_bustype(x) == ACBusTypes.PQ, ACBus, sys)) == 0\nend\n\n@testset \"Test PSSE interruptible loads parsing\" begin\n    sys = build_system(\n        PSSEParsingTestSystems,\n        \"pti_case14_with_interruptible_loads_sys\";\n        force_build = true,\n    )\n    all_isl = collect(get_components(InterruptibleStandardLoad, sys))\n    sort!(all_isl, by = get_name)\n    isl = first(all_isl)  # should be named \"load10LD\"\n    @test length(all_isl) == 4\n    @test get_available(isl) == true\n    @test isl isa InterruptibleStandardLoad\n    @test get_constant_active_power(isl) == 0.11485\n    @test get_max_active_power(isl) == 0.11485\nend\n\n@testset \"Test conversion zero impedance branch to switch\" begin\n    sys = build_system(\n        PSSEParsingTestSystems,\n        \"psse_14_zero_impedance_branch_test_system\";\n        force_build = true,\n    )\n    @test length(get_components(DiscreteControlledACBranch, sys)) == 6\n    @test length(\n        get_components(x -> get_r(x) == get_x(x) == 0.0, DiscreteControlledACBranch, sys),\n    ) == 4\nend\n\n@testset \"Test threshold setting for zero impedance 3WT winding\" begin\n    sys = build_system(\n        PSSEParsingTestSystems,\n        \"psse_4_zero_impedance_3wt_test_system\";\n        force_build = true,\n    )\n    trf_3w = collect(get_components(Transformer3W, sys))[1]\n    @test get_available(trf_3w) == true\n    @test get_available_tertiary(trf_3w) == true\n    @test get_x_tertiary(trf_3w) == 1e-4\nend\n\n@testset \"Test GeoJSON RFC 7946 Compliance\" begin\n    # Test that GeographicInfo uses proper GeoJSON Point format\n    # According to RFC 7946, section 3.1.2, a Point should have:\n    # {\"type\": \"Point\", \"coordinates\": [longitude, latitude]}\n\n    # Create a simple test using the common.jl helper\n    sys = System(100.0)\n    bus1 = ACBus(;\n        number = 1,\n        name = \"test_bus\",\n        available = true,\n        bustype = ACBusTypes.REF,\n        angle = 0.0,\n        magnitude = 1.0,\n        voltage_limits = (min = 0.9, max = 1.1),\n        base_voltage = 230.0,\n    )\n    add_component!(sys, bus1)\n\n    # Create GeographicInfo with proper GeoJSON format\n    geo = IS.GeographicInfo(;\n        geo_json = Dict(\"type\" => \"Point\", \"coordinates\" => [-105.0, 40.0]),\n    )\n\n    add_supplemental_attribute!(sys, bus1, geo)\n\n    # Retrieve and verify the GeoJSON format\n    geo_attrs = get_supplemental_attributes(IS.GeographicInfo, sys)\n    @test length(geo_attrs) == 1\n\n    retrieved_geo = first(geo_attrs)\n    geo_json = IS.get_geo_json(retrieved_geo)\n\n    # Verify RFC 7946 compliance\n    @test haskey(geo_json, \"type\")\n    @test geo_json[\"type\"] == \"Point\"\n    @test haskey(geo_json, \"coordinates\")\n    @test isa(geo_json[\"coordinates\"], Vector)\n    @test length(geo_json[\"coordinates\"]) == 2\n    @test geo_json[\"coordinates\"][1] == -105.0  # longitude\n    @test geo_json[\"coordinates\"][2] == 40.0    # latitude\n\n    # Verify old format is NOT present\n    @test !haskey(geo_json, \"x\")\n    @test !haskey(geo_json, \"y\")\nend\n"
  },
  {
    "path": "test/test_plant_attributes.jl",
    "content": "using Test\nusing PowerSystems\nusing InfrastructureSystems\nimport InfrastructureSystems as IS\nimport JSON3\nimport PowerSystemCaseBuilder as PSB\nconst PSY = PowerSystems\n\ninclude(\"common.jl\")\n\n@testset \"Test plant attributes\" begin\n    @testset \"ThermalPowerPlant construction and basic accessors\" begin\n        plant = ThermalPowerPlant(name = \"Coal Plant A\")\n        @test get_name(plant) == \"Coal Plant A\"\n    end\n\n    @testset \"HydroPowerPlant construction and basic accessors\" begin\n        plant = HydroPowerPlant(name = \"Hydro Dam 1\")\n        @test get_name(plant) == \"Hydro Dam 1\"\n    end\n\n    @testset \"RenewablePowerPlant construction and basic accessors\" begin\n        plant = RenewablePowerPlant(name = \"Wind Farm A\")\n        @test get_name(plant) == \"Wind Farm A\"\n    end\n\n    @testset \"CombinedCycleBlock construction and basic accessors\" begin\n        cc_block = CombinedCycleBlock(\n            name = \"CC Block 1\",\n            configuration = CombinedCycleConfiguration.SingleShaftCombustionSteam,\n            heat_recovery_to_steam_factor = 0.85,\n        )\n        @test get_name(cc_block) == \"CC Block 1\"\n        @test get_configuration(cc_block) ==\n              CombinedCycleConfiguration.SingleShaftCombustionSteam\n        @test get_heat_recovery_to_steam_factor(cc_block) == 0.85\n    end\n\n    @testset \"Add and remove ThermalGen to/from ThermalPowerPlant\" begin\n        sys = System(100.0)\n\n        # Create buses\n        bus1 = ACBus(nothing)\n        bus1.name = \"bus1\"\n        bus1.number = 1\n        bus1.bustype = ACBusTypes.REF\n        add_component!(sys, bus1)\n\n        bus2 = ACBus(nothing)\n        bus2.name = \"bus2\"\n        bus2.number = 2\n        add_component!(sys, bus2)\n\n        # Create thermal generators\n        gen1 = ThermalStandard(nothing)\n        gen1.bus = bus1\n        gen1.name = \"thermal_gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = ThermalStandard(nothing)\n        gen2.bus = bus2\n        gen2.name = \"thermal_gen2\"\n        add_component!(sys, gen2)\n\n        # Create thermal power plant\n        plant = ThermalPowerPlant(name = \"Coal Plant\")\n\n        # Add generators to plant with shaft numbers\n        add_supplemental_attribute!(sys, gen1, plant; shaft_number = 1)\n        add_supplemental_attribute!(sys, gen2, plant; shaft_number = 2)\n\n        # Verify shaft mappings\n        shaft_map = get_shaft_map(plant)\n        @test length(shaft_map) == 2\n        @test length(shaft_map[1]) == 1\n        @test length(shaft_map[2]) == 1\n        @test shaft_map[1][1] == IS.get_uuid(gen1)\n        @test shaft_map[2][1] == IS.get_uuid(gen2)\n\n        # Verify reverse mappings\n        reverse_map = get_reverse_shaft_map(plant)\n        @test reverse_map[IS.get_uuid(gen1)] == 1\n        @test reverse_map[IS.get_uuid(gen2)] == 2\n\n        # Verify supplemental attributes are attached\n        @test has_supplemental_attributes(gen1)\n        @test has_supplemental_attributes(gen2)\n        attrs1 = get_supplemental_attributes(ThermalPowerPlant, gen1)\n        @test length(collect(attrs1)) == 1\n        @test collect(attrs1)[1] == plant\n\n        # Test multiple generators on same shaft\n        gen3 = ThermalStandard(nothing)\n        gen3.bus = bus1\n        gen3.name = \"thermal_gen3\"\n        add_component!(sys, gen3)\n        add_supplemental_attribute!(sys, gen3, plant; shaft_number = 1)\n\n        @test length(shaft_map[1]) == 2\n        @test shaft_map[1][2] == IS.get_uuid(gen3)\n\n        # Remove generator from plant\n        remove_supplemental_attribute!(sys, gen1, plant)\n        @test !haskey(reverse_map, IS.get_uuid(gen1))\n        @test length(shaft_map[1]) == 1\n        @test shaft_map[1][1] == IS.get_uuid(gen3)\n\n        # Remove last generator from shaft\n        remove_supplemental_attribute!(sys, gen3, plant)\n        @test !haskey(shaft_map, 1)\n        @test !haskey(reverse_map, IS.get_uuid(gen3))\n\n        # Test error when removing non-existent generator\n        @test_throws IS.ArgumentError remove_supplemental_attribute!(sys, gen1, plant)\n    end\n\n    @testset \"Get components in shaft\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        # Create thermal generators\n        gen1 = ThermalStandard(nothing)\n        gen1.bus = bus\n        gen1.name = \"gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = ThermalStandard(nothing)\n        gen2.bus = bus\n        gen2.name = \"gen2\"\n        add_component!(sys, gen2)\n\n        gen3 = ThermalStandard(nothing)\n        gen3.bus = bus\n        gen3.name = \"gen3\"\n        add_component!(sys, gen3)\n\n        # Create plant with generators on different shafts\n        plant = ThermalPowerPlant(name = \"Test Plant\")\n        add_supplemental_attribute!(sys, gen1, plant; shaft_number = 1)\n        add_supplemental_attribute!(sys, gen2, plant; shaft_number = 1)\n        add_supplemental_attribute!(sys, gen3, plant; shaft_number = 2)\n\n        # Test getting components in shaft 1\n        shaft1_components = get_components_in_shaft(sys, plant, 1)\n        @test length(shaft1_components) == 2\n        shaft1_names = Set([get_name(c) for c in shaft1_components])\n        @test \"gen1\" in shaft1_names\n        @test \"gen2\" in shaft1_names\n\n        # Test getting components in shaft 2\n        shaft2_components = get_components_in_shaft(sys, plant, 2)\n        @test length(shaft2_components) == 1\n        @test get_name(shaft2_components[1]) == \"gen3\"\n\n        # Test error for non-existent shaft\n        @test_throws IS.ArgumentError get_components_in_shaft(sys, plant, 99)\n    end\n\n    @testset \"Get components in penstock\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        # Create hydro generators\n        turb1 = HydroTurbine(nothing)\n        turb1.bus = bus\n        turb1.name = \"turb1\"\n        add_component!(sys, turb1)\n\n        turb2 = HydroTurbine(nothing)\n        turb2.bus = bus\n        turb2.name = \"turb2\"\n        add_component!(sys, turb2)\n\n        pump = HydroPumpTurbine(nothing)\n        pump.bus = bus\n        pump.name = \"pump1\"\n        add_component!(sys, pump)\n\n        # Create plant with generators on different penstocks\n        plant = HydroPowerPlant(name = \"Hydro Plant\")\n        add_supplemental_attribute!(sys, turb1, plant, 1)\n        add_supplemental_attribute!(sys, turb2, plant, 1)\n        add_supplemental_attribute!(sys, pump, plant, 2)\n\n        # Test getting components in penstock 1\n        penstock1_components = get_components_in_penstock(sys, plant, 1)\n        @test length(penstock1_components) == 2\n        penstock1_names = Set([get_name(c) for c in penstock1_components])\n        @test \"turb1\" in penstock1_names\n        @test \"turb2\" in penstock1_names\n\n        # Test getting components in penstock 2\n        penstock2_components = get_components_in_penstock(sys, plant, 2)\n        @test length(penstock2_components) == 1\n        @test get_name(penstock2_components[1]) == \"pump1\"\n\n        # Test error for non-existent penstock\n        @test_throws IS.ArgumentError get_components_in_penstock(sys, plant, 99)\n    end\n\n    @testset \"Get components in PCC\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        # Create renewable generators and storage\n        wind1 = RenewableDispatch(nothing)\n        wind1.bus = bus\n        wind1.name = \"wind1\"\n        add_component!(sys, wind1)\n\n        solar = RenewableNonDispatch(nothing)\n        solar.bus = bus\n        solar.name = \"solar1\"\n        add_component!(sys, solar)\n\n        battery = EnergyReservoirStorage(nothing)\n        battery.bus = bus\n        battery.name = \"battery1\"\n        add_component!(sys, battery)\n\n        # Create plant with components on different PCCs\n        plant = RenewablePowerPlant(name = \"Renewable Plant\")\n        add_supplemental_attribute!(sys, wind1, plant, 1)\n        add_supplemental_attribute!(sys, battery, plant, 1)\n        add_supplemental_attribute!(sys, solar, plant, 2)\n\n        # Test getting components in PCC 1\n        pcc1_components = get_components_in_pcc(sys, plant, 1)\n        @test length(pcc1_components) == 2\n        pcc1_names = Set([get_name(c) for c in pcc1_components])\n        @test \"wind1\" in pcc1_names\n        @test \"battery1\" in pcc1_names\n\n        # Test getting components in PCC 2\n        pcc2_components = get_components_in_pcc(sys, plant, 2)\n        @test length(pcc2_components) == 1\n        @test get_name(pcc2_components[1]) == \"solar1\"\n\n        # Test error for non-existent PCC\n        @test_throws IS.ArgumentError get_components_in_pcc(sys, plant, 99)\n    end\n\n    @testset \"Add and remove HydroGen to/from HydroPowerPlant\" begin\n        sys = System(100.0)\n\n        # Create buses\n        bus1 = ACBus(nothing)\n        bus1.name = \"bus1\"\n        bus1.number = 1\n        bus1.bustype = ACBusTypes.REF\n        add_component!(sys, bus1)\n\n        bus2 = ACBus(nothing)\n        bus2.name = \"bus2\"\n        bus2.number = 2\n        add_component!(sys, bus2)\n\n        # Create hydro generators\n        gen1 = HydroTurbine(nothing)\n        gen1.bus = bus1\n        gen1.name = \"hydro_gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = HydroPumpTurbine(nothing)\n        gen2.bus = bus2\n        gen2.name = \"hydro_gen2\"\n        add_component!(sys, gen2)\n\n        # Create hydro power plant\n        plant = HydroPowerPlant(name = \"Hydro Dam\")\n\n        # Add generators to plant with penstock numbers\n        add_supplemental_attribute!(sys, gen1, plant, 1)\n        add_supplemental_attribute!(sys, gen2, plant, 2)\n\n        # Verify penstock mappings\n        penstock_map = get_penstock_map(plant)\n        @test length(penstock_map) == 2\n        @test penstock_map[1][1] == IS.get_uuid(gen1)\n        @test penstock_map[2][1] == IS.get_uuid(gen2)\n\n        # Verify reverse mappings\n        reverse_map = get_reverse_penstock_map(plant)\n        @test reverse_map[IS.get_uuid(gen1)] == 1\n        @test reverse_map[IS.get_uuid(gen2)] == 2\n\n        # Remove generator from plant\n        remove_supplemental_attribute!(sys, gen1, plant)\n        @test !haskey(reverse_map, IS.get_uuid(gen1))\n        @test !haskey(penstock_map, 1)\n\n        # Test error for HydroDispatch\n        hydro_dispatch = HydroDispatch(nothing)\n        hydro_dispatch.bus = bus1\n        hydro_dispatch.name = \"hydro_dispatch\"\n        add_component!(sys, hydro_dispatch)\n\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys,\n            hydro_dispatch,\n            plant,\n            1,\n        )\n    end\n\n    @testset \"Add and remove RenewableGen to/from RenewablePowerPlant\" begin\n        sys = System(100.0)\n\n        # Create buses\n        bus1 = ACBus(nothing)\n        bus1.name = \"bus1\"\n        bus1.number = 1\n        bus1.bustype = ACBusTypes.REF\n        add_component!(sys, bus1)\n\n        bus2 = ACBus(nothing)\n        bus2.name = \"bus2\"\n        bus2.number = 2\n        add_component!(sys, bus2)\n\n        # Create renewable generators\n        gen1 = RenewableDispatch(nothing)\n        gen1.bus = bus1\n        gen1.name = \"wind_gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = RenewableNonDispatch(nothing)\n        gen2.bus = bus2\n        gen2.name = \"solar_gen2\"\n        add_component!(sys, gen2)\n\n        # Create storage\n        storage = EnergyReservoirStorage(nothing)\n        storage.bus = bus1\n        storage.name = \"battery1\"\n        add_component!(sys, storage)\n\n        # Create renewable power plant\n        plant = RenewablePowerPlant(name = \"Renewable Farm\")\n\n        # Add generators to plant with PCC numbers\n        add_supplemental_attribute!(sys, gen1, plant, 1)\n        add_supplemental_attribute!(sys, gen2, plant, 2)\n        add_supplemental_attribute!(sys, storage, plant, 1)\n\n        # Verify PCC mappings\n        pcc_map = get_pcc_map(plant)\n        @test length(pcc_map) == 2\n        @test length(pcc_map[1]) == 2  # gen1 and storage on same PCC\n        @test length(pcc_map[2]) == 1\n        @test IS.get_uuid(gen1) in pcc_map[1]\n        @test IS.get_uuid(storage) in pcc_map[1]\n        @test pcc_map[2][1] == IS.get_uuid(gen2)\n\n        # Verify reverse mappings\n        reverse_map = get_reverse_pcc_map(plant)\n        @test reverse_map[IS.get_uuid(gen1)] == 1\n        @test reverse_map[IS.get_uuid(gen2)] == 2\n        @test reverse_map[IS.get_uuid(storage)] == 1\n\n        # Remove generator from plant\n        remove_supplemental_attribute!(sys, gen1, plant)\n        @test !haskey(reverse_map, IS.get_uuid(gen1))\n        @test length(pcc_map[1]) == 1\n        @test pcc_map[1][1] == IS.get_uuid(storage)\n\n        # Remove storage\n        remove_supplemental_attribute!(sys, storage, plant)\n        @test !haskey(pcc_map, 1)\n        @test !haskey(reverse_map, IS.get_uuid(storage))\n    end\n\n    @testset \"Serialization and deserialization of ThermalPowerPlant\" begin\n        sys = System(100.0)\n\n        # Create bus and generator\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen1 = ThermalStandard(nothing)\n        gen1.bus = bus\n        gen1.name = \"thermal_gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = ThermalStandard(nothing)\n        gen2.bus = bus\n        gen2.name = \"thermal_gen2\"\n        add_component!(sys, gen2)\n\n        # Create and add plant\n        plant = ThermalPowerPlant(name = \"Coal Plant\")\n        add_supplemental_attribute!(sys, gen1, plant; shaft_number = 1)\n        add_supplemental_attribute!(sys, gen2, plant; shaft_number = 2)\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify plant is preserved\n        gen1_restored = get_component(ThermalStandard, sys2, \"thermal_gen1\")\n        gen2_restored = get_component(ThermalStandard, sys2, \"thermal_gen2\")\n        @test has_supplemental_attributes(gen1_restored)\n        @test has_supplemental_attributes(gen2_restored)\n\n        attrs = get_supplemental_attributes(ThermalPowerPlant, gen1_restored)\n        plant_restored = collect(attrs)[1]\n        @test get_name(plant_restored) == \"Coal Plant\"\n\n        # Verify mappings are preserved\n        shaft_map = get_shaft_map(plant_restored)\n        reverse_map = get_reverse_shaft_map(plant_restored)\n        @test length(shaft_map) == 2\n        @test length(reverse_map) == 2\n        @test reverse_map[IS.get_uuid(gen1_restored)] == 1\n        @test reverse_map[IS.get_uuid(gen2_restored)] == 2\n    end\n\n    @testset \"Serialization and deserialization of HydroPowerPlant\" begin\n        sys = System(100.0)\n\n        # Create bus and generator\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen1 = HydroTurbine(nothing)\n        gen1.bus = bus\n        gen1.name = \"hydro_gen1\"\n        add_component!(sys, gen1)\n\n        gen2 = HydroTurbine(nothing)\n        gen2.bus = bus\n        gen2.name = \"hydro_gen2\"\n        add_component!(sys, gen2)\n\n        # Create and add plant\n        plant = HydroPowerPlant(name = \"Hydro Dam\")\n        add_supplemental_attribute!(sys, gen1, plant, 1)\n        add_supplemental_attribute!(sys, gen2, plant, 2)\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify plant is preserved\n        gen1_restored = get_component(HydroTurbine, sys2, \"hydro_gen1\")\n        attrs = get_supplemental_attributes(HydroPowerPlant, gen1_restored)\n        plant_restored = collect(attrs)[1]\n        @test get_name(plant_restored) == \"Hydro Dam\"\n\n        # Verify mappings are preserved\n        penstock_map = get_penstock_map(plant_restored)\n        reverse_map = get_reverse_penstock_map(plant_restored)\n        @test length(penstock_map) == 2\n        @test length(reverse_map) == 2\n    end\n\n    @testset \"Serialization and deserialization of RenewablePowerPlant\" begin\n        sys = System(100.0)\n\n        # Create bus and generator\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen1 = RenewableDispatch(nothing)\n        gen1.bus = bus\n        gen1.name = \"wind_gen1\"\n        add_component!(sys, gen1)\n\n        storage = EnergyReservoirStorage(nothing)\n        storage.bus = bus\n        storage.name = \"battery1\"\n        add_component!(sys, storage)\n\n        # Create and add plant\n        plant = RenewablePowerPlant(name = \"Wind Farm\")\n        add_supplemental_attribute!(sys, gen1, plant, 1)\n        add_supplemental_attribute!(sys, storage, plant, 1)\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify plant is preserved\n        gen1_restored = get_component(RenewableDispatch, sys2, \"wind_gen1\")\n        attrs = get_supplemental_attributes(RenewablePowerPlant, gen1_restored)\n        plant_restored = collect(attrs)[1]\n        @test get_name(plant_restored) == \"Wind Farm\"\n\n        # Verify mappings are preserved\n        pcc_map = get_pcc_map(plant_restored)\n        reverse_map = get_reverse_pcc_map(plant_restored)\n        @test length(pcc_map) == 1\n        @test length(pcc_map[1]) == 2  # Both generator and storage on same PCC\n        @test length(reverse_map) == 2\n    end\n\n    @testset \"Add and remove ThermalGen to/from CombinedCycleBlock\" begin\n        sys = System(100.0)\n\n        bus1 = ACBus(nothing)\n        bus1.name = \"bus1\"\n        bus1.number = 1\n        bus1.bustype = ACBusTypes.REF\n        add_component!(sys, bus1)\n\n        bus2 = ACBus(nothing)\n        bus2.name = \"bus2\"\n        bus2.number = 2\n        add_component!(sys, bus2)\n\n        # Create thermal generators with appropriate prime mover types\n        ct_gen = ThermalStandard(nothing)\n        ct_gen.bus = bus1\n        ct_gen.name = \"ct_gen1\"\n        ct_gen.prime_mover_type = PrimeMovers.CT\n        add_component!(sys, ct_gen)\n\n        ca_gen = ThermalStandard(nothing)\n        ca_gen.bus = bus2\n        ca_gen.name = \"ca_gen1\"\n        ca_gen.prime_mover_type = PrimeMovers.CA\n        add_component!(sys, ca_gen)\n\n        # Create combined cycle block\n        cc_block = CombinedCycleBlock(\n            name = \"CC Block 1\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n            heat_recovery_to_steam_factor = 0.75,\n        )\n\n        # Add generators with HRSG numbers (prime mover type is read from component)\n        add_supplemental_attribute!(\n            sys, ct_gen, cc_block; hrsg_number = 1,\n        )\n        add_supplemental_attribute!(\n            sys, ca_gen, cc_block; hrsg_number = 1,\n        )\n\n        # Verify HRSG CT mappings\n        hrsg_ct_map = get_hrsg_ct_map(cc_block)\n        @test length(hrsg_ct_map) == 1\n        @test length(hrsg_ct_map[1]) == 1\n        @test hrsg_ct_map[1][1] == IS.get_uuid(ct_gen)\n\n        # Verify HRSG CA mappings\n        hrsg_ca_map = get_hrsg_ca_map(cc_block)\n        @test length(hrsg_ca_map) == 1\n        @test length(hrsg_ca_map[1]) == 1\n        @test hrsg_ca_map[1][1] == IS.get_uuid(ca_gen)\n\n        # Verify reverse CT mapping\n        ct_hrsg_map = get_ct_hrsg_map(cc_block)\n        @test ct_hrsg_map[IS.get_uuid(ct_gen)] == [1]\n\n        # Verify reverse CA mapping\n        ca_hrsg_map = get_ca_hrsg_map(cc_block)\n        @test ca_hrsg_map[IS.get_uuid(ca_gen)] == [1]\n\n        # Verify supplemental attributes are attached\n        @test has_supplemental_attributes(ct_gen)\n        @test has_supplemental_attributes(ca_gen)\n\n        # Test multiple CTs on same HRSG\n        ct_gen2 = ThermalStandard(nothing)\n        ct_gen2.bus = bus1\n        ct_gen2.name = \"ct_gen2\"\n        ct_gen2.prime_mover_type = PrimeMovers.CT\n        add_component!(sys, ct_gen2)\n        add_supplemental_attribute!(\n            sys, ct_gen2, cc_block; hrsg_number = 1,\n        )\n        @test length(hrsg_ct_map[1]) == 2\n        @test hrsg_ct_map[1][2] == IS.get_uuid(ct_gen2)\n\n        # Remove generator from block\n        remove_supplemental_attribute!(sys, ct_gen, cc_block)\n        @test !haskey(ct_hrsg_map, IS.get_uuid(ct_gen))\n        @test length(hrsg_ct_map[1]) == 1\n        @test hrsg_ct_map[1][1] == IS.get_uuid(ct_gen2)\n\n        # Remove last CT generator from HRSG 1\n        remove_supplemental_attribute!(sys, ct_gen2, cc_block)\n        @test !haskey(hrsg_ct_map, 1)\n        @test !haskey(ct_hrsg_map, IS.get_uuid(ct_gen2))\n\n        # Test error when removing non-existent generator\n        @test_throws IS.ArgumentError remove_supplemental_attribute!(\n            sys, ct_gen, cc_block,\n        )\n    end\n\n    @testset \"CombinedCycleBlock rejects invalid PrimeMover types\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        cc_block = CombinedCycleBlock(\n            name = \"CC Block Invalid\",\n            configuration = CombinedCycleConfiguration.SingleShaftCombustionSteam,\n        )\n\n        # Invalid prime mover types should throw (only CT and CA are valid)\n        for (i, pm) in enumerate([\n            PrimeMovers.GT,\n            PrimeMovers.ST,\n            PrimeMovers.WT,\n            PrimeMovers.CC,\n            PrimeMovers.CS,\n        ])\n            gen = ThermalStandard(nothing)\n            gen.bus = bus\n            gen.name = \"gen_invalid_$i\"\n            gen.prime_mover_type = pm\n            add_component!(sys, gen)\n            @test_throws IS.ArgumentError add_supplemental_attribute!(\n                sys, gen, cc_block; hrsg_number = 1,\n            )\n        end\n\n        # Valid prime mover types should not throw (CT and CA only)\n        ct_gen = ThermalStandard(nothing)\n        ct_gen.bus = bus\n        ct_gen.name = \"gen_ct\"\n        ct_gen.prime_mover_type = PrimeMovers.CT\n        add_component!(sys, ct_gen)\n        add_supplemental_attribute!(\n            sys, ct_gen, cc_block; hrsg_number = 1,\n        )\n\n        ca_gen = ThermalStandard(nothing)\n        ca_gen.bus = bus\n        ca_gen.name = \"gen_ca\"\n        ca_gen.prime_mover_type = PrimeMovers.CA\n        add_component!(sys, ca_gen)\n        add_supplemental_attribute!(\n            sys, ca_gen, cc_block; hrsg_number = 1,\n        )\n\n        @test length(get_hrsg_ct_map(cc_block)) == 1\n        @test length(get_hrsg_ca_map(cc_block)) == 1\n    end\n\n    @testset \"Serialization and deserialization of CombinedCycleBlock\" begin\n        sys = System(100.0)\n\n        # Create bus and generators with appropriate prime mover types\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        ct_gen = ThermalStandard(nothing)\n        ct_gen.bus = bus\n        ct_gen.name = \"cc_ct_gen1\"\n        ct_gen.prime_mover_type = PrimeMovers.CT\n        add_component!(sys, ct_gen)\n\n        ca_gen = ThermalStandard(nothing)\n        ca_gen.bus = bus\n        ca_gen.name = \"cc_ca_gen1\"\n        ca_gen.prime_mover_type = PrimeMovers.CA\n        add_component!(sys, ca_gen)\n\n        # Create and add combined cycle block with HRSG mappings\n        cc_block = CombinedCycleBlock(\n            name = \"CC Block 1\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n            heat_recovery_to_steam_factor = 0.75,\n        )\n        add_supplemental_attribute!(\n            sys, ct_gen, cc_block; hrsg_number = 1,\n        )\n        add_supplemental_attribute!(\n            sys, ca_gen, cc_block; hrsg_number = 1,\n        )\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify block is preserved\n        ct_gen_restored = get_component(ThermalStandard, sys2, \"cc_ct_gen1\")\n        @test has_supplemental_attributes(ct_gen_restored)\n        attrs = get_supplemental_attributes(CombinedCycleBlock, ct_gen_restored)\n        cc_block_restored = collect(attrs)[1]\n        @test get_name(cc_block_restored) == \"CC Block 1\"\n        @test get_configuration(cc_block_restored) ==\n              CombinedCycleConfiguration.SeparateShaftCombustionSteam\n        @test get_heat_recovery_to_steam_factor(cc_block_restored) == 0.75\n\n        # Verify HRSG mappings are preserved\n        hrsg_ct_map = get_hrsg_ct_map(cc_block_restored)\n        hrsg_ca_map = get_hrsg_ca_map(cc_block_restored)\n        ct_hrsg_map = get_ct_hrsg_map(cc_block_restored)\n        ca_hrsg_map = get_ca_hrsg_map(cc_block_restored)\n        @test length(hrsg_ct_map) == 1\n        @test length(hrsg_ca_map) == 1\n        @test length(ct_hrsg_map) == 1\n        @test length(ca_hrsg_map) == 1\n\n        ct_gen_restored_uuid = IS.get_uuid(ct_gen_restored)\n        ca_gen_restored = get_component(ThermalStandard, sys2, \"cc_ca_gen1\")\n        ca_gen_restored_uuid = IS.get_uuid(ca_gen_restored)\n\n        @test ct_hrsg_map[ct_gen_restored_uuid] == [1]\n        @test ca_hrsg_map[ca_gen_restored_uuid] == [1]\n        @test ct_gen_restored_uuid in hrsg_ct_map[1]\n        @test ca_gen_restored_uuid in hrsg_ca_map[1]\n    end\n\n    @testset \"Duplicate generator rejection for ThermalPowerPlant\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen1\"\n        add_component!(sys, gen)\n\n        plant = ThermalPowerPlant(name = \"Plant\")\n        add_supplemental_attribute!(sys, gen, plant; shaft_number = 1)\n\n        # Adding the same generator again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, gen, plant; shaft_number = 1,\n        )\n        # Also rejects with a different shaft number\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, gen, plant; shaft_number = 2,\n        )\n\n        # Maps should be unchanged after rejected adds\n        @test length(get_shaft_map(plant)) == 1\n        @test length(get_shaft_map(plant)[1]) == 1\n        @test get_reverse_shaft_map(plant)[IS.get_uuid(gen)] == 1\n    end\n\n    @testset \"Duplicate generator rejection for HydroPowerPlant\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        turb = HydroTurbine(nothing)\n        turb.bus = bus\n        turb.name = \"turb1\"\n        add_component!(sys, turb)\n\n        plant = HydroPowerPlant(name = \"Hydro Plant\")\n        add_supplemental_attribute!(sys, turb, plant, 1)\n\n        # Adding the same turbine again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(sys, turb, plant, 1)\n        @test_throws IS.ArgumentError add_supplemental_attribute!(sys, turb, plant, 2)\n\n        # Maps should be unchanged\n        @test length(get_penstock_map(plant)) == 1\n        @test length(get_penstock_map(plant)[1]) == 1\n        @test get_reverse_penstock_map(plant)[IS.get_uuid(turb)] == 1\n    end\n\n    @testset \"Duplicate generator rejection for RenewablePowerPlant\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        wind = RenewableDispatch(nothing)\n        wind.bus = bus\n        wind.name = \"wind1\"\n        add_component!(sys, wind)\n\n        plant = RenewablePowerPlant(name = \"Renewable Plant\")\n        add_supplemental_attribute!(sys, wind, plant, 1)\n\n        # Adding the same generator again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(sys, wind, plant, 1)\n        @test_throws IS.ArgumentError add_supplemental_attribute!(sys, wind, plant, 2)\n\n        # Maps should be unchanged\n        @test length(get_pcc_map(plant)) == 1\n        @test length(get_pcc_map(plant)[1]) == 1\n        @test get_reverse_pcc_map(plant)[IS.get_uuid(wind)] == 1\n    end\n\n    @testset \"Duplicate generator rejection for CombinedCycleBlock\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        ct_gen = ThermalStandard(nothing)\n        ct_gen.bus = bus\n        ct_gen.name = \"ct_gen1\"\n        ct_gen.prime_mover_type = PrimeMovers.CT\n        add_component!(sys, ct_gen)\n\n        ca_gen = ThermalStandard(nothing)\n        ca_gen.bus = bus\n        ca_gen.name = \"ca_gen1\"\n        ca_gen.prime_mover_type = PrimeMovers.CA\n        add_component!(sys, ca_gen)\n\n        cc_block = CombinedCycleBlock(\n            name = \"CC Block\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n        )\n\n        add_supplemental_attribute!(sys, ct_gen, cc_block; hrsg_number = 1)\n        add_supplemental_attribute!(sys, ca_gen, cc_block; hrsg_number = 1)\n\n        # Adding the same CT again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, ct_gen, cc_block; hrsg_number = 1,\n        )\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, ct_gen, cc_block; hrsg_number = 2,\n        )\n\n        # Adding the same CA again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, ca_gen, cc_block; hrsg_number = 1,\n        )\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, ca_gen, cc_block; hrsg_number = 2,\n        )\n\n        # Maps should be unchanged after rejected adds\n        hrsg_ct_map = get_hrsg_ct_map(cc_block)\n        hrsg_ca_map = get_hrsg_ca_map(cc_block)\n        ct_hrsg_map = get_ct_hrsg_map(cc_block)\n        ca_hrsg_map = get_ca_hrsg_map(cc_block)\n        @test length(hrsg_ct_map) == 1\n        @test length(hrsg_ct_map[1]) == 1\n        @test length(hrsg_ca_map) == 1\n        @test length(hrsg_ca_map[1]) == 1\n        @test ct_hrsg_map[IS.get_uuid(ct_gen)] == [1]\n        @test ca_hrsg_map[IS.get_uuid(ca_gen)] == [1]\n    end\n\n    @testset \"Multiple plants per generator\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"thermal_gen1\"\n        add_component!(sys, gen)\n\n        # Add multiple plant attributes to same generator\n        plant1 = ThermalPowerPlant(name = \"Plant A\")\n        plant2 = ThermalPowerPlant(name = \"Plant B\")\n\n        add_supplemental_attribute!(sys, gen, plant1; shaft_number = 1)\n        add_supplemental_attribute!(sys, gen, plant2; shaft_number = 1)\n\n        # Verify both plants are attached\n        attrs = get_supplemental_attributes(ThermalPowerPlant, gen)\n        plants = collect(attrs)\n        @test length(plants) == 2\n        plant_names = Set([get_name(p) for p in plants])\n        @test \"Plant A\" in plant_names\n        @test \"Plant B\" in plant_names\n\n        # Remove one plant\n        remove_supplemental_attribute!(sys, gen, plant1)\n        attrs = get_supplemental_attributes(ThermalPowerPlant, gen)\n        @test length(collect(attrs)) == 1\n        @test get_name(collect(attrs)[1]) == \"Plant B\"\n    end\n\n    @testset \"Empty plant serialization\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"thermal_gen1\"\n        add_component!(sys, gen)\n\n        # Create empty plant (no generators added yet)\n        plant = ThermalPowerPlant(name = \"Empty Plant\")\n        IS.add_supplemental_attribute!(sys.data, gen, plant)\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify empty plant is preserved\n        gen_restored = get_component(ThermalStandard, sys2, \"thermal_gen1\")\n        attrs = get_supplemental_attributes(ThermalPowerPlant, gen_restored)\n        plant_restored = collect(attrs)[1]\n        @test get_name(plant_restored) == \"Empty Plant\"\n        @test isempty(get_shaft_map(plant_restored))\n        @test isempty(get_reverse_shaft_map(plant_restored))\n    end\n\n    @testset \"Plant attributes with case builder system and full serialization cycle\" begin\n        # Load a system from case builder\n        sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5\")\n\n        # Get thermal generators\n        thermal_gens = collect(get_components(ThermalStandard, sys))\n        @test length(thermal_gens) >= 2\n\n        # Create thermal power plant and add generators\n        thermal_plant = ThermalPowerPlant(name = \"Test Coal Plant\")\n        add_supplemental_attribute!(sys, thermal_gens[1], thermal_plant; shaft_number = 1)\n        add_supplemental_attribute!(sys, thermal_gens[2], thermal_plant; shaft_number = 2)\n\n        # Verify plant is attached\n        @test has_supplemental_attributes(thermal_gens[1])\n        attrs = get_supplemental_attributes(ThermalPowerPlant, thermal_gens[1])\n        @test length(collect(attrs)) == 1\n        @test get_name(collect(attrs)[1]) == \"Test Coal Plant\"\n\n        # Get renewable generators if available\n        renewable_gens = collect(get_components(RenewableGen, sys))\n        if length(renewable_gens) >= 1\n            # Create renewable power plant\n            renewable_plant = RenewablePowerPlant(name = \"Test Wind Farm\")\n            add_supplemental_attribute!(sys, renewable_gens[1], renewable_plant, 1)\n\n            # Verify plant is attached\n            @test has_supplemental_attributes(renewable_gens[1])\n        end\n\n        # Test to_json serialization\n        test_dir = mktempdir()\n        json_path = joinpath(test_dir, \"system_with_plants.json\")\n\n        try\n            # Serialize using to_json\n            to_json(sys, json_path; force = true)\n            @test isfile(json_path)\n\n            # Verify JSON file contains plant data\n            json_data = open(json_path, \"r\") do io\n                JSON3.read(io)\n            end\n            @test haskey(json_data, \"data_format_version\")\n            @test json_data[\"data_format_version\"] == PSY.DATA_FORMAT_VERSION\n\n            # Test System(file) constructor\n            sys_loaded = System(json_path)\n\n            # Verify system loaded correctly\n            @test get_base_power(sys_loaded) == get_base_power(sys)\n            @test length(get_components(ThermalStandard, sys_loaded)) ==\n                  length(thermal_gens)\n\n            # Verify thermal power plant is preserved\n            gen1_loaded = get_component(\n                ThermalStandard,\n                sys_loaded,\n                get_name(thermal_gens[1]),\n            )\n            @test gen1_loaded !== nothing\n            @test has_supplemental_attributes(gen1_loaded)\n\n            attrs_loaded = get_supplemental_attributes(ThermalPowerPlant, gen1_loaded)\n            plant_loaded = collect(attrs_loaded)[1]\n            @test get_name(plant_loaded) == \"Test Coal Plant\"\n\n            # Verify shaft mappings are preserved\n            shaft_map = get_shaft_map(plant_loaded)\n            reverse_map = get_reverse_shaft_map(plant_loaded)\n            @test length(shaft_map) == 2\n            @test length(reverse_map) == 2\n\n            gen1_uuid = IS.get_uuid(gen1_loaded)\n            gen2_loaded = get_component(\n                ThermalStandard,\n                sys_loaded,\n                get_name(thermal_gens[2]),\n            )\n            gen2_uuid = IS.get_uuid(gen2_loaded)\n\n            @test reverse_map[gen1_uuid] == 1\n            @test reverse_map[gen2_uuid] == 2\n            @test gen1_uuid in shaft_map[1]\n            @test gen2_uuid in shaft_map[2]\n\n            # Verify renewable plant if it was added\n            if length(renewable_gens) >= 1\n                ren1_loaded = get_component(\n                    RenewableGen,\n                    sys_loaded,\n                    get_name(renewable_gens[1]),\n                )\n                @test has_supplemental_attributes(ren1_loaded)\n\n                ren_attrs = get_supplemental_attributes(RenewablePowerPlant, ren1_loaded)\n                ren_plant_loaded = collect(ren_attrs)[1]\n                @test get_name(ren_plant_loaded) == \"Test Wind Farm\"\n\n                pcc_map = get_pcc_map(ren_plant_loaded)\n                @test length(pcc_map) == 1\n                @test IS.get_uuid(ren1_loaded) in pcc_map[1]\n            end\n\n            # Test that we can serialize the loaded system again (round-trip)\n            json_path2 = joinpath(test_dir, \"system_roundtrip.json\")\n            to_json(sys_loaded, json_path2; force = true)\n            @test isfile(json_path2)\n\n            # Load the round-trip system\n            sys_roundtrip = System(json_path2)\n            @test get_base_power(sys_roundtrip) == get_base_power(sys)\n\n            # Verify plant still exists after round-trip\n            gen1_rt = get_component(\n                ThermalStandard,\n                sys_roundtrip,\n                get_name(thermal_gens[1]),\n            )\n            @test has_supplemental_attributes(gen1_rt)\n            attrs_rt = get_supplemental_attributes(ThermalPowerPlant, gen1_rt)\n            @test get_name(collect(attrs_rt)[1]) == \"Test Coal Plant\"\n\n        finally\n            # Clean up temporary files\n            rm(test_dir; recursive = true, force = true)\n        end\n    end\n\n    @testset \"CombinedCycleFractional construction and basic accessors\" begin\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac 1\",\n            configuration = CombinedCycleConfiguration.SingleShaftCombustionSteam,\n        )\n        @test get_name(cc_frac) == \"CC Frac 1\"\n        @test get_configuration(cc_frac) ==\n              CombinedCycleConfiguration.SingleShaftCombustionSteam\n        @test isempty(get_operation_exclusion_map(cc_frac))\n        @test isempty(get_inverse_operation_exclusion_map(cc_frac))\n    end\n\n    @testset \"Add and remove ThermalGen to/from CombinedCycleFractional\" begin\n        sys = System(100.0)\n\n        bus1 = ACBus(nothing)\n        bus1.name = \"bus1\"\n        bus1.number = 1\n        bus1.bustype = ACBusTypes.REF\n        add_component!(sys, bus1)\n\n        bus2 = ACBus(nothing)\n        bus2.name = \"bus2\"\n        bus2.number = 2\n        add_component!(sys, bus2)\n\n        # Create thermal generators with CC prime mover type\n        cc_gen1 = ThermalStandard(nothing)\n        cc_gen1.bus = bus1\n        cc_gen1.name = \"cc_gen1\"\n        cc_gen1.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen1)\n\n        cc_gen2 = ThermalStandard(nothing)\n        cc_gen2.bus = bus2\n        cc_gen2.name = \"cc_gen2\"\n        cc_gen2.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen2)\n\n        # Create combined cycle fractional plant\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac 1\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n        )\n\n        # Add generators with exclusion group numbers\n        add_supplemental_attribute!(\n            sys, cc_gen1, cc_frac; exclusion_group = 1,\n        )\n        add_supplemental_attribute!(\n            sys, cc_gen2, cc_frac; exclusion_group = 1,\n        )\n\n        # Verify exclusion mappings\n        excl_map = get_operation_exclusion_map(cc_frac)\n        @test length(excl_map) == 1\n        @test length(excl_map[1]) == 2\n        @test IS.get_uuid(cc_gen1) in excl_map[1]\n        @test IS.get_uuid(cc_gen2) in excl_map[1]\n\n        # Verify inverse mappings\n        inv_map = get_inverse_operation_exclusion_map(cc_frac)\n        @test length(inv_map) == 2\n        @test inv_map[IS.get_uuid(cc_gen1)] == 1\n        @test inv_map[IS.get_uuid(cc_gen2)] == 1\n\n        # Verify supplemental attributes are attached\n        @test has_supplemental_attributes(cc_gen1)\n        @test has_supplemental_attributes(cc_gen2)\n\n        # Test multiple exclusion groups\n        cc_gen3 = ThermalStandard(nothing)\n        cc_gen3.bus = bus1\n        cc_gen3.name = \"cc_gen3\"\n        cc_gen3.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen3)\n        add_supplemental_attribute!(\n            sys, cc_gen3, cc_frac; exclusion_group = 2,\n        )\n        @test length(excl_map) == 2\n        @test length(excl_map[2]) == 1\n        @test excl_map[2][1] == IS.get_uuid(cc_gen3)\n\n        # Remove generator from plant\n        remove_supplemental_attribute!(sys, cc_gen1, cc_frac)\n        @test length(excl_map[1]) == 1\n        @test excl_map[1][1] == IS.get_uuid(cc_gen2)\n\n        # Remove last generator from group 1\n        remove_supplemental_attribute!(sys, cc_gen2, cc_frac)\n        @test !haskey(excl_map, 1)\n\n        # Test error when removing non-existent generator\n        @test_throws IS.ArgumentError remove_supplemental_attribute!(\n            sys, cc_gen1, cc_frac,\n        )\n    end\n\n    @testset \"CombinedCycleFractional rejects invalid PrimeMover types\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac Invalid\",\n            configuration = CombinedCycleConfiguration.SingleShaftCombustionSteam,\n        )\n\n        # Invalid prime mover types should throw (only CC is valid)\n        for (i, pm) in enumerate([\n            PrimeMovers.GT,\n            PrimeMovers.ST,\n            PrimeMovers.WT,\n            PrimeMovers.CT,\n            PrimeMovers.CA,\n        ])\n            gen = ThermalStandard(nothing)\n            gen.bus = bus\n            gen.name = \"gen_invalid_$i\"\n            gen.prime_mover_type = pm\n            add_component!(sys, gen)\n            @test_throws IS.ArgumentError add_supplemental_attribute!(\n                sys, gen, cc_frac; exclusion_group = 1,\n            )\n        end\n\n        # Valid prime mover type (CC only)\n        cc_gen = ThermalStandard(nothing)\n        cc_gen.bus = bus\n        cc_gen.name = \"gen_cc\"\n        cc_gen.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen)\n        add_supplemental_attribute!(\n            sys, cc_gen, cc_frac; exclusion_group = 1,\n        )\n        @test length(get_operation_exclusion_map(cc_frac)) == 1\n    end\n\n    @testset \"Get components in exclusion group\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        # Create CC generators\n        gen1 = ThermalStandard(nothing)\n        gen1.bus = bus\n        gen1.name = \"cc_gen1\"\n        gen1.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, gen1)\n\n        gen2 = ThermalStandard(nothing)\n        gen2.bus = bus\n        gen2.name = \"cc_gen2\"\n        gen2.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, gen2)\n\n        gen3 = ThermalStandard(nothing)\n        gen3.bus = bus\n        gen3.name = \"cc_gen3\"\n        gen3.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, gen3)\n\n        # Create plant with generators in different exclusion groups\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac Test\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n        )\n        add_supplemental_attribute!(sys, gen1, cc_frac; exclusion_group = 1)\n        add_supplemental_attribute!(sys, gen2, cc_frac; exclusion_group = 1)\n        add_supplemental_attribute!(sys, gen3, cc_frac; exclusion_group = 2)\n\n        # Test getting components in exclusion group 1\n        group1_components = get_components_in_exclusion_group(sys, cc_frac, 1)\n        @test length(group1_components) == 2\n        group1_names = Set([get_name(c) for c in group1_components])\n        @test \"cc_gen1\" in group1_names\n        @test \"cc_gen2\" in group1_names\n\n        # Test getting components in exclusion group 2\n        group2_components = get_components_in_exclusion_group(sys, cc_frac, 2)\n        @test length(group2_components) == 1\n        @test get_name(group2_components[1]) == \"cc_gen3\"\n\n        # Test error for non-existent exclusion group\n        @test_throws IS.ArgumentError get_components_in_exclusion_group(sys, cc_frac, 99)\n    end\n\n    @testset \"Duplicate generator rejection for CombinedCycleFractional\" begin\n        sys = System(100.0)\n\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        cc_gen = ThermalStandard(nothing)\n        cc_gen.bus = bus\n        cc_gen.name = \"cc_gen1\"\n        cc_gen.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen)\n\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n        )\n\n        add_supplemental_attribute!(sys, cc_gen, cc_frac; exclusion_group = 1)\n\n        # Adding the same generator again should throw\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, cc_gen, cc_frac; exclusion_group = 1,\n        )\n        # Also rejects with a different exclusion group\n        @test_throws IS.ArgumentError add_supplemental_attribute!(\n            sys, cc_gen, cc_frac; exclusion_group = 2,\n        )\n\n        # Maps should be unchanged after rejected adds\n        excl_map = get_operation_exclusion_map(cc_frac)\n        @test length(excl_map) == 1\n        @test length(excl_map[1]) == 1\n    end\n\n    @testset \"Serialization and deserialization of CombinedCycleFractional\" begin\n        sys = System(100.0)\n\n        # Create bus and generators with CC prime mover type\n        bus = ACBus(nothing)\n        bus.name = \"bus1\"\n        bus.number = 1\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n\n        cc_gen1 = ThermalStandard(nothing)\n        cc_gen1.bus = bus\n        cc_gen1.name = \"cc_frac_gen1\"\n        cc_gen1.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen1)\n\n        cc_gen2 = ThermalStandard(nothing)\n        cc_gen2.bus = bus\n        cc_gen2.name = \"cc_frac_gen2\"\n        cc_gen2.prime_mover_type = PrimeMovers.CC\n        add_component!(sys, cc_gen2)\n\n        # Create and add combined cycle fractional plant\n        cc_frac = CombinedCycleFractional(\n            name = \"CC Frac 1\",\n            configuration = CombinedCycleConfiguration.SeparateShaftCombustionSteam,\n        )\n        add_supplemental_attribute!(sys, cc_gen1, cc_frac; exclusion_group = 1)\n        add_supplemental_attribute!(sys, cc_gen2, cc_frac; exclusion_group = 2)\n\n        # Serialize and deserialize\n        sys2, result = validate_serialization(sys)\n        @test result\n\n        # Verify plant is preserved\n        gen1_restored = get_component(ThermalStandard, sys2, \"cc_frac_gen1\")\n        @test has_supplemental_attributes(gen1_restored)\n        attrs = get_supplemental_attributes(CombinedCycleFractional, gen1_restored)\n        cc_frac_restored = collect(attrs)[1]\n        @test get_name(cc_frac_restored) == \"CC Frac 1\"\n        @test get_configuration(cc_frac_restored) ==\n              CombinedCycleConfiguration.SeparateShaftCombustionSteam\n\n        # Verify exclusion mappings are preserved\n        excl_map = get_operation_exclusion_map(cc_frac_restored)\n        inv_map = get_inverse_operation_exclusion_map(cc_frac_restored)\n        @test length(excl_map) == 2\n        @test length(inv_map) == 2\n\n        gen1_restored_uuid = IS.get_uuid(gen1_restored)\n        gen2_restored = get_component(ThermalStandard, sys2, \"cc_frac_gen2\")\n        gen2_restored_uuid = IS.get_uuid(gen2_restored)\n\n        @test gen1_restored_uuid in excl_map[1]\n        @test gen2_restored_uuid in excl_map[2]\n    end\nend\n"
  },
  {
    "path": "test/test_power_system_table_data.jl",
    "content": "import PowerSystems: LazyDictFromIterator\n\n@testset \"PowerSystemTableData parsing\" begin\n    resolutions = (\n        (resolution = Dates.Minute(5), len = 288),\n        (resolution = Dates.Minute(60), len = 24),\n    )\n\n    for (resolution, len) in resolutions\n        sys = create_rts_system(resolution)\n        for time_series in get_time_series_multiple(sys)\n            @test length(time_series) == len\n        end\n    end\nend\n\n@testset \"PowerSystemTableData parsing invalid directory\" begin\n    @test_throws ErrorException PowerSystemTableData(DATA_DIR, 100.0, DESCRIPTORS)\nend\n\n@testset \"Consistency between PowerSystemTableData and standardfiles\" begin\n    # This signature is used to capture expected error logs from parsing matpower\n    consistency_test =\n        () -> begin\n            mpsys = System(joinpath(BAD_DATA, \"RTS_GMLC_original.m\"))\n            cdmsys = PSB.build_system(\n                PSB.PSITestSystems,\n                \"test_RTS_GMLC_sys\";\n                force_build = true,\n            )\n            mp_iter = get_components(HydroGen, mpsys)\n            mp_generators = LazyDictFromIterator(String, HydroGen, mp_iter, get_name)\n            for cdmgen in get_components(HydroGen, cdmsys)\n                mpgen = get(mp_generators, uppercase(get_name(cdmgen)))\n                if isnothing(mpgen)\n                    error(\"did not find $cdmgen\")\n                end\n                @test cdmgen.available == mpgen.available\n                @test lowercase(cdmgen.bus.name) == lowercase(mpgen.bus.name)\n                gen_dat = (\n                    structname = nothing,\n                    fields = (\n                        :active_power,\n                        :reactive_power,\n                        :rating,\n                        :active_power_limits,\n                        :reactive_power_limits,\n                        :ramp_limits,\n                    ),\n                )\n                function check_fields(chk_dat)\n                    for field in chk_dat.fields\n                        n = get(chk_dat, :structname, nothing)\n                        (cdmd, mpd) =\n                            if isnothing(n)\n                                (cdmgen, mpgen)\n                            else\n                                (getfield(cdmgen, n), getfield(mpgen, n))\n                            end\n                        cdmgen_val = getfield(cdmd, field)\n                        mpgen_val = getfield(mpd, field)\n                        if isnothing(cdmgen_val) || isnothing(mpgen_val)\n                            @warn \"Skip value with nothing\" repr(cdmgen_val) repr(mpgen_val)\n                            continue\n                        end\n                        @test cdmgen_val == mpgen_val\n                    end\n                end\n                check_fields(gen_dat)\n            end\n\n            mp_iter = get_components(ThermalGen, mpsys)\n            mp_generators = LazyDictFromIterator(String, ThermalGen, mp_iter, get_name)\n            for cdmgen in get_components(ThermalGen, cdmsys)\n                if isnothing(cdmgen)\n                    # Skips generators parsed from Matpower as SynchCondensers in PSY5\n                    # The fields are different so those aren't valiated in this loop\n                    continue\n                end\n                mpgen = get(mp_generators, uppercase(get_name(cdmgen)))\n                @test cdmgen.available == mpgen.available\n                @test lowercase(cdmgen.bus.name) == lowercase(mpgen.bus.name)\n                for field in (:active_power_limits, :reactive_power_limits, :ramp_limits)\n                    cdmgen_val = getfield(cdmgen, field)\n                    mpgen_val = getfield(mpgen, field)\n                    if isnothing(cdmgen_val) || isnothing(mpgen_val)\n                        @warn \"Skip value with nothing\" repr(cdmgen_val) repr(mpgen_val)\n                        continue\n                    end\n                    @test cdmgen_val == mpgen_val\n                end\n\n                mpgen_cost = get_operation_cost(mpgen)\n                # Currently true; this is likely to change in the future and then we'd have to change the test\n                @assert get_variable(mpgen_cost) isa\n                        CostCurve{InputOutputCurve{PiecewiseLinearData}}\n                mp_points = get_points(\n                    get_function_data(get_value_curve(\n                        get_variable(mpgen_cost))),\n                )\n                if length(mp_points) == 4\n                    cdm_op_cost = get_operation_cost(cdmgen)\n                    @test get_fixed(cdm_op_cost) == 0.0\n                    fuel_curve = get_variable(cdm_op_cost)\n                    fuel_cost = get_fuel_cost(fuel_curve)\n                    mp_fixed = get_fixed(mpgen_cost)\n                    io_curve = InputOutputCurve(get_value_curve(fuel_curve))\n                    cdm_points = get_points(io_curve)\n                    @test all(\n                        isapprox.(\n                            [p.y * fuel_cost for p in cdm_points],\n                            [p.y + mp_fixed for p in mp_points],\n                            atol = 0.1),\n                    )\n                    @test all(\n                        isapprox.(\n                            [p.x for p in cdm_points],\n                            [p.x * get_base_power(mpgen) for p in mp_points],\n                            atol = 0.1),\n                    )\n                end\n            end\n\n            mp_iter = get_components(RenewableGen, mpsys)\n            mp_generators =\n                LazyDictFromIterator(String, RenewableGen, mp_iter, get_name)\n            for cdmgen in get_components(RenewableGen, cdmsys)\n                mpgen = get(mp_generators, uppercase(get_name(cdmgen)))\n                # Disabled since data is inconsisten between sources\n                #@test cdmgen.available == mpgen.available\n                @test lowercase(cdmgen.bus.name) == lowercase(mpgen.bus.name)\n                for field in (:rating, :power_factor)\n                    cdmgen_val = getfield(cdmgen, field)\n                    mpgen_val = getfield(mpgen, field)\n                    if isnothing(cdmgen_val) || isnothing(mpgen_val)\n                        @warn \"Skip value with nothing\" repr(cdmgen_val) repr(mpgen_val)\n                        continue\n                    end\n                    @test cdmgen_val == mpgen_val\n                end\n                #@test compare_values_without_uuids(cdmgen.operation_cost, mpgen.operation_cost)\n            end\n\n            cdm_ac_branches = collect(get_components(ACBranch, cdmsys))\n            @test get_rating(cdm_ac_branches[2]) ==\n                  get_rating(get_branch(mpsys, cdm_ac_branches[2]))\n            @test get_rating(cdm_ac_branches[6]) ==\n                  get_rating(get_branch(mpsys, cdm_ac_branches[6]))\n            @test get_rating(cdm_ac_branches[120]) ==\n                  get_rating(get_branch(mpsys, cdm_ac_branches[120]))\n\n            cdm_dc_branches =\n                collect(get_components(TwoTerminalGenericHVDCLine, cdmsys))\n            @test get_active_power_limits_from(cdm_dc_branches[1]) ==\n                  get_active_power_limits_from(get_branch(mpsys, cdm_dc_branches[1]))\n        end\n    @test_logs (:error,) match_mode = :any min_level = Logging.Error consistency_test()\nend\n\n@testset \"Test reserve direction\" begin\n    @test PSY.get_reserve_direction(\"Up\") == ReserveUp\n    @test PSY.get_reserve_direction(\"Down\") == ReserveDown\n    @test PSY.get_reserve_direction(\"up\") == ReserveUp\n    @test PSY.get_reserve_direction(\"down\") == ReserveDown\n\n    for invalid in (\"right\", \"left\")\n        @test_throws PSY.DataFormatError PSY.get_reserve_direction(invalid)\n    end\nend\n\n@testset \"Test consistency between variable cost and heat rate parsing\" begin\n    fivebus_dir = joinpath(DATA_DIR, \"5-Bus\")\n    rawsys_hr = PowerSystemTableData(\n        fivebus_dir,\n        100.0,\n        joinpath(fivebus_dir, \"user_descriptors_var_cost.yaml\");\n        generator_mapping_file = joinpath(fivebus_dir, \"generator_mapping.yaml\"),\n    )\n    rawsys = PowerSystemTableData(\n        fivebus_dir,\n        100.0,\n        joinpath(fivebus_dir, \"user_descriptors_var_cost.yaml\");\n        generator_mapping_file = joinpath(fivebus_dir, \"generator_mapping.yaml\"),\n    )\n    sys_hr = System(rawsys_hr)\n    sys = System(rawsys)\n\n    g_hr = get_components(ThermalStandard, sys_hr)\n    g = get_components(ThermalStandard, sys)\n    @test get_variable.(get_operation_cost.(g)) == get_variable.(get_operation_cost.(g))\nend\n\n@testset \"Test create_poly_cost function\" begin\n    cost_colnames = [\"heat_rate_a0\", \"heat_rate_a1\", \"heat_rate_a2\"]\n\n    # Coefficients for a CC using natural gas\n    a2 = -0.000531607\n    a1 = 0.060554675\n    a0 = 8.951100118\n\n    # First test that return quadratic if all coefficients are provided.\n    # We convert the coefficients to string to mimic parsing from csv\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = string(a0),\n        heat_rate_a1 = string(a1),\n        heat_rate_a2 = string(a2),\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa QuadraticCurve\n    @assert isapprox(get_quadratic_term(cost_curve), a2, atol = 0.01)\n    @assert isapprox(get_proportional_term(cost_curve), a1, atol = 0.01)\n    @assert isapprox(get_constant_term(cost_curve), a0, atol = 0.01)\n\n    # Test return linear with both proportional and constant term\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = string(a0),\n        heat_rate_a1 = string(a1),\n        heat_rate_a2 = nothing,\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa LinearCurve\n    @assert isapprox(get_proportional_term(cost_curve), a1, atol = 0.01)\n    @assert isapprox(get_constant_term(cost_curve), a0, atol = 0.01)\n\n    # Test return linear with just proportional term\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = nothing,\n        heat_rate_a1 = string(a1),\n        heat_rate_a2 = nothing,\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa LinearCurve\n    @assert isapprox(get_proportional_term(cost_curve), a1, atol = 0.01)\n\n    # Test raises error if a2 is passed but other coefficients are nothing\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = nothing,\n        heat_rate_a1 = nothing,\n        heat_rate_a2 = string(a2),\n    )\n    @test_throws IS.DataFormatError create_poly_cost(example_generator, cost_colnames)\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = nothing,\n        heat_rate_a1 = string(a1),\n        heat_rate_a2 = string(a2),\n    )\n    @test_throws IS.DataFormatError create_poly_cost(example_generator, cost_colnames)\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = string(a0),\n        heat_rate_a1 = nothing,\n        heat_rate_a2 = string(a2),\n    )\n    @test_throws IS.DataFormatError create_poly_cost(example_generator, cost_colnames)\n\n    # Test that it works with zero proportional and constant term\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = string(0.0),\n        heat_rate_a1 = string(0.0),\n        heat_rate_a2 = string(a2),\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa QuadraticCurve\n    @assert isapprox(get_quadratic_term(cost_curve), a2, atol = 0.01)\n    @assert isapprox(get_proportional_term(cost_curve), 0.0, atol = 0.01)\n    @assert isapprox(get_constant_term(cost_curve), 0.0, atol = 0.01)\n\n    # Test that create_poly_cost works with numeric values (not just strings)\n    # Some CSV parsers return numeric types directly instead of strings\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = a0,  # Float64\n        heat_rate_a1 = a1,  # Float64\n        heat_rate_a2 = a2,  # Float64\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa QuadraticCurve\n    @assert isapprox(get_quadratic_term(cost_curve), a2, atol = 0.01)\n    @assert isapprox(get_proportional_term(cost_curve), a1, atol = 0.01)\n    @assert isapprox(get_constant_term(cost_curve), a0, atol = 0.01)\n\n    # Test with Int64 values (another common numeric type from CSV parsers)\n    example_generator = (\n        name = \"test-gen\",\n        heat_rate_a0 = Int64(9),\n        heat_rate_a1 = Int64(0),\n        heat_rate_a2 = Int64(0),\n    )\n    cost_curve, fixed_cost = create_poly_cost(example_generator, cost_colnames)\n    @assert cost_curve isa QuadraticCurve\n    @assert isapprox(get_quadratic_term(cost_curve), 0.0, atol = 0.01)\n    @assert isapprox(get_proportional_term(cost_curve), 0.0, atol = 0.01)\n    @assert isapprox(get_constant_term(cost_curve), 9.0, atol = 0.01)\nend\n\n@testset \"Test parsing with ThermalMultiStart generators\" begin\n    # Test that ThermalMultiStart generators parse correctly with multi-start costs\n    # This exercises the multi-start cost fallback logic in make_thermal_generator_multistart\n    rawsys = PowerSystemTableData(\n        RTS_GMLC_DIR,\n        100.0,\n        DESCRIPTORS;\n        generator_mapping_file = joinpath(\n            RTS_GMLC_DIR,\n            \"generator_mapping_multi_start.yaml\",\n        ),\n    )\n    sys = System(rawsys; time_series_resolution = Dates.Hour(1))\n\n    # Verify ThermalMultiStart generators were created\n    ms_gens = collect(get_components(ThermalMultiStart, sys))\n    @test length(ms_gens) > 0\n\n    # Check that startup costs were parsed correctly\n    for gen in ms_gens\n        op_cost = get_operation_cost(gen)\n        startup_costs = get_start_up(op_cost)\n        # Startup costs should be non-negative\n        @test startup_costs.hot >= 0.0\n        @test startup_costs.warm >= 0.0\n        @test startup_costs.cold >= 0.0\n    end\nend\n\n@testset \"Test Reservoirs and Turbines\" begin\n    cdmsys = PSB.build_system(\n        PSB.PSITestSystems,\n        \"test_RTS_GMLC_sys\";\n        force_build = true,\n    )\n    @test !isempty(get_components(HydroTurbine, cdmsys))\n    for turbine in get_components(HydroTurbine, cdmsys)\n        reservoir = get_connected_head_reservoirs(cdmsys, turbine)\n        @test !isempty(reservoir)\n        reservoir = get_connected_tail_reservoirs(cdmsys, turbine)\n        @test isempty(reservoir)\n    end\n\n    @test !isempty(get_components(HydroReservoir, cdmsys))\n\n    for reservoir in get_components(HydroReservoir, cdmsys)\n        turbines = get_downstream_turbines(reservoir)\n        @test !isempty(turbines)\n        @test isempty(get_upstream_turbines(reservoir))\n    end\nend\n"
  },
  {
    "path": "test/test_powersystemconstructors.jl",
    "content": "checksys = false\n\n@testset \"Test System constructors from .jl files\" begin\n    tPowerSystem = System(nothing)\n    nodes_5_nodes = nodes5()\n    nodes_14_nodes = nodes14()\n\n    for node in nodes_5_nodes\n        node.angle = deg2rad(node.angle)\n    end\n\n    # Components with time_series cannot be added to multiple systems, so clear them on each\n    # test.\n\n    sys5 = System(\n        100.0,\n        nodes_5_nodes,\n        thermal_generators5(nodes_5_nodes),\n        loads5(nodes_5_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys5)\n\n    sys5b = System(\n        100.0,\n        nodes_5_nodes,\n        thermal_generators5(nodes_5_nodes),\n        loads5(nodes_5_nodes),\n        battery5(nodes_5_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys5b)\n\n    sys5f = System(\n        100.0,\n        nodes_5_nodes,\n        thermal_generators5(nodes_5_nodes),\n        loads5(nodes_5_nodes),\n        shiftable5(nodes_5_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys5f)\n\n    # GitHub issue #234 - fix time_series5 in data file, use new format\n    #_sys5b = PowerSystems._System(nodes_5, thermal_generators5(nodes_5), loads5(nodes_5), nothing, battery5(nodes_5),\n    #                              100.0, time_series5, nothing, nothing)\n    #sys5b = System(_sys5b)\n\n    sys5bh = System(\n        100.0,\n        nodes_5_nodes,\n        thermal_generators5(nodes_5_nodes),\n        hydro_generators5(nodes_5_nodes),\n        loads5(nodes_5_nodes),\n        branches5(nodes_5_nodes),\n        battery5(nodes_5_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys5bh)\n\n    # Test Data for 14 Bus\n\n    # GitHub issue #234 - fix time_series5 in data file, use new format\n    #_sys14 = PowerSystems._System(nodes_14, thermal_generators14, loads14, nothing, nothing,\n    #                            100.0, Dict{Symbol,Vector{<:TimeSeriesData}}(),nothing,nothing)\n    #sys14 = System(_sys14)\n\n    for node in nodes_14_nodes\n        node.angle = deg2rad(node.angle)\n    end\n\n    sys14b = PowerSystems.System(\n        100.0,\n        nodes_14_nodes,\n        thermal_generators14(nodes_14_nodes),\n        loads14(nodes_14_nodes),\n        battery14(nodes_14_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys14b)\n    sys14b = PowerSystems.System(\n        100.0,\n        nodes_14_nodes,\n        thermal_generators14(nodes_14_nodes),\n        loads14(nodes_14_nodes),\n        branches14(nodes_14_nodes),\n        battery14(nodes_14_nodes);\n        runchecks = checksys,\n    )\n    clear_components!(sys14b)\nend\n\n@testset \"Test System constructor from Matpower\" begin\n    # Include a System kwarg to make sure it doesn't get forwarded to PM functions.\n    kwarg_test =\n        () -> begin\n            sys = System(\n                joinpath(BAD_DATA,\n                    \"case5_re.m\");\n                runchecks = true,\n            )\n        end\n    @test_logs (:error,) min_level = Logging.Error match_mode = :any kwarg_test()\nend\n\n@testset \"Test accessor functions of PowerSystems auto-generated types\" begin\n    # If this test fails because a type doesn't have a constructor that takes nothing,\n    # it's because not all fields in that type are defined in power_system_structs.json\n    # with nullable values. Consider adding them so that this \"demo-constructor\" works.\n    # If that isn't appropriate for this type, add it to types_to_skip below.\n    # You can also call test_accessors wherever an instance has been created.\n\n    types_to_skip = (TestDevice, TestRenDevice, TestInjector, NonexistentComponent)\n    types = vcat(\n        IS.get_all_concrete_subtypes(Component),\n        IS.get_all_concrete_subtypes(DynamicComponent),\n        IS.get_all_concrete_subtypes(PowerSystems.ActivePowerControl),\n        IS.get_all_concrete_subtypes(PowerSystems.ReactivePowerControl),\n    )\n    sort!(types; by = x -> string(x))\n    for ps_type in types\n        ps_type in types_to_skip && continue\n        component = ps_type(nothing)\n        test_accessors(component)\n    end\nend\n\n@testset \"Test required accessor functions of subtypes of Component \" begin\n    types = IS.get_all_concrete_subtypes(Component)\n    types_to_skip = (TestDevice, TestRenDevice, NonexistentComponent, TestInjector)\n    sort!(types; by = x -> string(x))\n    for ps_type in types\n        ps_type in types_to_skip && continue\n        component = ps_type(nothing)\n        @test get_name(component) isa String\n        @test IS.get_internal(component) isa IS.InfrastructureSystemsInternal\n    end\nend\n\n@testset \"Test component conversion\" begin\n    test_line_conversion =\n        () -> begin\n            sys = System(joinpath(BAD_DATA, \"case5_re.m\"))\n            l = get_component(Line, sys, \"bus2-bus3-i_4\")\n            initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n            dates = collect(\n                initial_time:Dates.Hour(1):Dates.DateTime(\"2020-01-01T23:00:00\"),\n            )\n            data = collect(1:24)\n            ta = TimeSeries.TimeArray(dates, data, [get_name(l)])\n            name = \"active_power_flow\"\n            time_series = SingleTimeSeries(; name = name, data = ta)\n            add_time_series!(sys, l, time_series)\n            @test get_time_series(SingleTimeSeries, l, name) isa SingleTimeSeries\n            PSY.convert_component!(sys, l, MonitoredLine)\n            @test isnothing(get_component(Line, sys, \"bus2-bus3-i_4\"))\n            mline = get_component(MonitoredLine, sys, \"bus2-bus3-i_4\")\n            @test !isnothing(mline)\n            @test get_name(mline) == \"bus2-bus3-i_4\"\n            @test get_time_series(SingleTimeSeries, mline, name) isa SingleTimeSeries\n            @test_throws ErrorException convert_component!(\n                sys,\n                get_component(MonitoredLine, sys, \"bus2-bus3-i_4\"),\n                Line,\n            )\n            convert_component!(\n                sys,\n                get_component(MonitoredLine, sys, \"bus2-bus3-i_4\"),\n                Line;\n                force = true,\n            )\n            line = get_component(Line, sys, \"bus2-bus3-i_4\")\n            @test !isnothing(mline)\n            @test get_time_series(SingleTimeSeries, line, name) isa SingleTimeSeries\n        end\n\n    test_load_conversion =\n        () -> begin\n            sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5\")\n            component_name = \"Bus2\"\n            # We use this name to avoid conflicts with the existing time series in the system\n            ts_name = \"max_active_power_test\"\n            old_component = get_component(PowerLoad, sys, component_name)\n            dates = collect(\n                Dates.DateTime(\"2020-01-01T00:00:00\"):Dates.Hour(1):Dates.DateTime(\n                    \"2020-01-01T23:00:00\",\n                ),\n            )\n            data = collect(1:24)\n            ta = TimeSeries.TimeArray(dates, data, [component_name])\n            time_series = SingleTimeSeries(; name = ts_name, data = ta)\n            add_time_series!(sys, old_component, time_series)\n            @test get_time_series(SingleTimeSeries, old_component, ts_name) isa\n                  SingleTimeSeries\n\n            convert_component!(sys, old_component, StandardLoad)\n            @test isnothing(get_component(typeof(old_component), sys, component_name))\n            new_component = get_component(StandardLoad, sys, component_name)\n            @test !isnothing(new_component)\n            @test get_name(new_component) == component_name\n            @test get_time_series(SingleTimeSeries, new_component, ts_name) isa\n                  SingleTimeSeries\n            # Conversion back is not implemented\n        end\n\n    @test_logs (:error,) min_level = Logging.Error match_mode = :any test_line_conversion()\n    test_load_conversion()\nend\n"
  },
  {
    "path": "test/test_printing.jl",
    "content": "\nfunction are_type_and_fields_in_output(obj::T) where {T <: Component}\n    match = true\n    normal = repr(obj)\n    io = IOBuffer()\n    show(io, \"text/plain\", obj)\n    custom = String(take!(io))\n    fields = fieldnames(T)\n\n    # Type must always be present. name should be also, if the type defines it.\n    #for text in (normal, custom)\n    for text in (custom,)\n        if !occursin(string(T), text)\n            @error \"type name is not in output\" string(T) text\n            match = false\n        end\n        if :name in fields\n            if !occursin(obj.name, text)\n                @error \"name is not in output\" name text\n                match = false\n            end\n        end\n    end\n\n    for (name, type) in zip(fields, fieldtypes(T))\n        val = getfield(obj, name)\n        if val === nothing || type <: IS.InfrastructureSystemsInternal\n            continue\n        end\n\n        # Account for the fact that type may be abstract.\n        actual_type = typeof(val)\n        if actual_type <: IS.InfrastructureSystemsType\n            expected = string(actual_type)\n        elseif actual_type <: Vector{<:Service}\n            expected = string(actual_type)\n        elseif actual_type <: Vector{<:IS.InfrastructureSystemsType}\n            expected = string(actual_type)\n        else\n            expected = string(val)\n        end\n\n        if !occursin(expected, custom)\n            @error \"field's value is not in custom output\" name custom\n            match = false\n        end\n    end\n\n    return match\nend\n\n@testset \"Test printing of system and components\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    @test are_type_and_fields_in_output(iterate(get_components(ACBus, sys))[1])\n    @test are_type_and_fields_in_output(iterate(get_components(Generator, sys))[1])\n    @test are_type_and_fields_in_output(iterate(get_components(ThermalGen, sys))[1])\n    @test are_type_and_fields_in_output(iterate(get_components(Branch, sys))[1])\n    @test are_type_and_fields_in_output(iterate(get_components(ElectricLoad, sys))[1])\n\n    io = IOBuffer()\n    component = first(get_components(ThermalGen, sys))\n    show(io, \"text/plain\", component)\n    text = String(take!(io))\n    expected_sa = string(has_supplemental_attributes(component))\n    expected_ts = string(has_time_series(component))\n    @test occursin(\"has_supplemental_attributes: $expected_sa\", text)\n    @test occursin(\"has_time_series: $expected_ts\", text)\n\n    # Just make sure nothing blows up.\n    for component in iterate_components(sys)\n        print(devnull, component)\n        print(devnull, MIME\"text/plain\")\n        @test !isempty(summary(component))\n    end\n    for time_series in get_time_series_multiple(sys)\n        show(devnull, time_series)\n        show(devnull, MIME\"text/plain\")\n        @test !isempty(summary(time_series))\n    end\n\n    @test !isempty(summary(sys))\n\n    @test isnothing(\n        show(\n            IOBuffer(),\n            \"text/plain\",\n            PowerSystemTableData(RTS_GMLC_DIR, 100.0, DESCRIPTORS),\n        ),\n    )\n\n    @test isnothing(show(IOBuffer(), \"text/plain\", sys))\n    @test isnothing(show(IOBuffer(), \"text/html\", sys))\n    @test isnothing(show_components(IOBuffer(), sys, RenewableNonDispatch))\n    @test isnothing(show_components(IOBuffer(), sys, RenewableNonDispatch, [:rating]))\n    @test isnothing(\n        show_components(\n            IOBuffer(),\n            sys,\n            RenewableNonDispatch,\n            Dict(\"ts\" => x -> has_time_series(x)),\n        ),\n    )\nend\n\n@testset \"Test printing of non-PowerSystems struct\" begin\n    struct MyComponent <: Component\n        name::String\n        internal::IS.InfrastructureSystemsInternal\n    end\n\n    PSY.get_internal(x::MyComponent) = x.internal\n    PSY.get_name(x::MyComponent) = string(x.name)\n\n    component = MyComponent(\"component1\", IS.InfrastructureSystemsInternal())\n    @test isnothing(show(IOBuffer(), component))\n    @test isnothing(show(IOBuffer(), \"text/plain\", component))\nend\n"
  },
  {
    "path": "test/test_read_time_series.jl",
    "content": "import DataFrames\nimport Dates\nimport TimeSeries\n\nfunction verify_time_series(sys::System, num_initial_times, num_time_series, len)\n    total_time_series = 0\n    all_time_series = get_time_series_multiple(sys)\n    for time_series in all_time_series\n        if length(time_series) != len\n            @error \"length doesn't match\" length(time_series) len\n            return false\n        end\n        total_time_series += 1\n    end\n\n    if num_time_series != total_time_series\n        @error \"num_time_series doesn't match\" num_time_series total_time_series\n        return false\n    end\n\n    return true\nend\n\n@testset \"Test read_time_series_file_metadata\" begin\n    for file in [\"timeseries_pointers.json\", \"timeseries_pointers.csv\"]\n        filename = joinpath(RTS_GMLC_DIR, file)\n        all_time_series = IS.read_time_series_file_metadata(filename)\n        @test length(all_time_series) == 260\n\n        for time_series in all_time_series\n            @test isfile(time_series.data_file)\n        end\n    end\nend\n\n@testset \"Test time_series normalization\" begin\n    component_name = \"122_HYDRO_1\"\n    timeseries_file = joinpath(\n        RTS_GMLC_DIR,\n        \"RTS_GMLC_forecasts\",\n        \"gen\",\n        \"Hydro\",\n        \"DAY_AHEAD_hydro.csv\",\n    )\n    gen = ThermalStandard(nothing)\n    gen.name = component_name\n    resolution = Dates.Hour(1)\n\n    # Parse the file directly in order to compare values.\n    ts_base = SingleTimeSeries(component_name, timeseries_file, gen, resolution)\n    timeseries = get_data(ts_base)\n    max_value = maximum(TimeSeries.values(timeseries))\n\n    file_metadata = IS.TimeSeriesFileMetadata(;\n        simulation = \"DAY_AHEAD\",\n        category = \"Generator\",\n        component_name = \"122_HYDRO_1\",\n        name = \"active_power\",\n        normalization_factor = 1.0,\n        data_file = timeseries_file,\n        percentiles = [],\n        resolution = resolution,\n        time_series_type_module = \"InfrastructureSystems\",\n        time_series_type = \"SingleTimeSeries\",\n    )\n\n    # Test code path where no normalization occurs.\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    add_time_series!(sys, [file_metadata])\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\n    @test TimeSeries.values(time_series.data) == TimeSeries.values(timeseries)\n\n    # Test code path where timeseries is normalized by dividing by the max value.\n    file_metadata.normalization_factor = \"Max\"\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    add_time_series!(sys, [file_metadata])\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\n    @test TimeSeries.values(time_series.data) == TimeSeries.values(timeseries ./ max_value)\n\n    # Test code path where timeseries is normalized by dividing by a custom value.\n    nf = 95.0\n    file_metadata.normalization_factor = nf\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    add_time_series!(sys, [file_metadata])\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\n    @test TimeSeries.values(time_series.data) == TimeSeries.values(timeseries ./ nf)\nend\n\n@testset \"Test single time_series addition\" begin\n    component_name = \"122_HYDRO_1\"\n    name = \"active_power\"\n    timeseries_file = joinpath(\n        RTS_GMLC_DIR,\n        \"RTS_GMLC_forecasts\",\n        \"gen\",\n        \"Hydro\",\n        \"DAY_AHEAD_hydro.csv\",\n    )\n    resolution = Dates.Hour(1)\n\n    # Test with a filename.\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    component = get_component(HydroDispatch, sys, component_name)\n    ts = SingleTimeSeries(\n        name,\n        timeseries_file,\n        component,\n        resolution;\n        normalization_factor = 1.0,\n    )\n    ta = get_data(ts)\n    add_time_series!(sys, component, ts)\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\n    @test TimeSeries.timestamp(get_data(time_series)) == TimeSeries.timestamp(ta)\n    @test TimeSeries.values(get_data(time_series)) == TimeSeries.values(ta)\n\n    # Test with TimeSeries.TimeArray.\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    component = get_component(HydroDispatch, sys, component_name)\n    ts = SingleTimeSeries(name, ta; normalization_factor = 1.0)\n    add_time_series!(sys, component, ts)\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\n    @test TimeSeries.values(get_data(time_series)) == TimeSeries.values(ta)\n\n    # Test with DataFrames.DataFrame.\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    component = get_component(HydroDispatch, sys, component_name)\n    df = DataFrames.DataFrame(ta)\n    ts = SingleTimeSeries(name, df; normalization_factor = 1.0)\n    add_time_series!(sys, component, ts)\n    verify_time_series(sys, 1, 1, 24)\n    time_series = collect(get_time_series_multiple(sys))[1]\nend\n\n@testset \"TimeSeriesData data matpower\" begin\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n    file_metadata = joinpath(DATA_DIR, \"5-Bus\", \"5bus_ts\", \"timeseries_pointers_da.json\")\n    add_time_series!(sys, file_metadata)\n    @test verify_time_series(sys, 1, 5, 24)\n\n    # Add the same files.\n    # This will fail because the component-name pairs will be duplicated.\n    @test_throws ArgumentError add_time_series!(sys, file_metadata)\n\n    file_metadata = joinpath(DATA_DIR, \"5-Bus\", \"5bus_ts\", \"timeseries_pointers_rt.json\")\n\n    # sys = System(PowerSystems.PowerModelsData(joinpath(MATPOWER_DIR, \"case5_re.m\")))\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n    add_time_series!(sys, file_metadata)\n    @test verify_time_series(sys, 1, 5, 288)\nend\n"
  },
  {
    "path": "test/test_serialization.jl",
    "content": "@testset \"Test JSON serialization of RTS data with immutable time series\" begin\n    sys =\n        PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; time_series_read_only = true)\n    sys2, result = validate_serialization(sys; time_series_read_only = true)\n    @test result\n    @test_throws ArgumentError clear_time_series!(sys2)\n    # Full error checking is done in IS.\nend\n\n@testset \"Test JSON serialization of matpower data\" begin\n    sys = PSB.build_system(PSB.MatpowerTestSystems, \"matpower_case5_re_sys\")\n\n    # Add a Probabilistic time_series to get coverage serializing it.\n    bus = ACBus(nothing)\n    bus.name = \"Bus1234\"\n    add_component!(sys, bus)\n    tg = RenewableNonDispatch(nothing)\n    tg.bus = bus\n    add_component!(sys, tg)\n    # TODO 1.0\n    #ts = PSY.Probabilistic(\"scalingfactor\", Hour(1), DateTime(\"01-01-01\"), [0.5, 0.5], 24)\n    #add_time_series!(sys, tg, ts)\n\n    _, result = validate_serialization(sys)\n    @test result\nend\n\n@testset \"Test JSON serialization of dynamic inverter\" begin\n    sys = PSB.build_system(PSB.PSYTestSystems, \"dynamic_inverter_sys\")\n\n    # Add a dynamic branch to test that code.\n    branch = collect(get_components(Branch, sys))[1]\n    dynamic_branch = DynamicBranch(branch)\n    add_component!(sys, dynamic_branch)\n    _, result = validate_serialization(sys)\n    @test result\n\n    test_accessors(dynamic_branch)\nend\n\n@testset \"Test JSON serialization of StaticGroupReserve\" begin\n    sys = System(100.0)\n    devices = []\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        # This prevents an error log message.\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n    end\n\n    service = ConstantReserve{ReserveDown}(nothing)\n    add_service!(sys, service, devices)\n\n    groupservice = ConstantReserveGroup{ReserveDown}(nothing)\n    add_service!(sys, groupservice)\n    members = Vector{Service}()\n    push!(members, service)\n    set_contributing_services!(sys, groupservice, members)\n    _, result = validate_serialization(sys)\n    @test result\nend\n\n@testset \"Test deepcopy of a system\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    sys2 = deepcopy(sys)\n    clear_time_series!(sys2)\n    @test !isempty(collect(get_time_series_multiple(sys)))\nend\n\n@testset \"Test JSON serialization of MarketBidCost\" begin\n    sys = System(100.0)\n    generators = [ThermalStandard(nothing), ThermalMultiStart(nothing)]\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        # This prevents an error log message.\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n        gen = generators[i]\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n        end_time = Dates.DateTime(\"2020-01-01T23:00:00\")\n        dates = collect(initial_time:Dates.Hour(1):end_time)\n        data =\n            PiecewiseStepData.(\n                [[i, i + 1, i + 2] for i in 1.0:24.0],\n                [[i, i + 1] for i in 1.0:24.0],\n            )\n        market_bid = MarketBidCost(nothing)\n        set_operation_cost!(gen, market_bid)\n        add_component!(sys, gen)\n        ta = TimeSeries.TimeArray(dates, data)\n        time_series = IS.SingleTimeSeries(; name = \"variable_cost\", data = ta)\n        power_units = UnitSystem.NATURAL_UNITS\n        set_variable_cost!(sys, gen, time_series, power_units)\n        service = ConstantReserve{ReserveDown}(;\n            name = \"init_$i\",\n            available = false,\n            time_frame = 0.0,\n            requirement = 0.0,\n            sustained_time = 0.0,\n            max_output_fraction = 1.0,\n            max_participation_factor = 1.0,\n            deployed_fraction = 0.0,\n            ext = Dict{String, Any}(),\n        )\n        add_component!(sys, service)\n        add_service!(gen, service, sys)\n        set_service_bid!(\n            sys,\n            gen,\n            service,\n            IS.SingleTimeSeries(; name = \"init_$i\", data = ta),\n            power_units,\n        )\n    end\n    _, result = validate_serialization(sys)\n    @test result\nend\n\n@testset \"Test JSON serialization of ReserveDemandCurve\" begin\n    sys = System(100.0)\n    devices = []\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        # This prevents an error log message.\n        bus.bustype = ACBusTypes.REF\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n    end\n    initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n    end_time = Dates.DateTime(\"2020-01-01T23:00:00\")\n    dates = collect(initial_time:Dates.Hour(1):end_time)\n    data = collect(1:24)\n\n    service = ReserveDemandCurve{ReserveDown}(nothing)\n    add_service!(sys, service, devices)\n    ta = TimeSeries.TimeArray(dates, data)\n    time_series = IS.SingleTimeSeries(; name = \"variable_cost\", data = ta)\n    set_variable_cost!(sys, service, time_series)\n\n    _, result = validate_serialization(sys)\n    @test result\nend\n\n@testset \"Test JSON serialization of HybridSystem\" begin\n    sys = PSB.build_system(\n        PSB.PSITestSystems,\n        \"test_RTS_GMLC_sys_with_hybrid\";\n        add_forecasts = true,\n    )\n    h_sys = first(get_components(HybridSystem, sys))\n    subcomponents = collect(get_subcomponents(h_sys))\n    @test length(subcomponents) == 4\n    sys2, result = validate_serialization(sys)\n    @test result\n    subcomponent = subcomponents[1]\n    @test IS.get_masked_component(\n        typeof(subcomponent),\n        sys2.data,\n        get_name(subcomponent),\n    ) !== nothing\nend\n\n@testset \"Test deserialization with new UUIDs\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    sys2, result = validate_serialization(sys; assign_new_uuids = true)\n    @test result\n    @test IS.get_uuid(sys) != IS.get_uuid(sys2)\n    for component1 in get_components(Component, sys)\n        component2 = get_component(typeof(component1), sys2, get_name(component1))\n        @test IS.get_uuid(component1) != IS.get_uuid(component2)\n    end\nend\n\n@testset \"Test serialization of supplemental attributes\" begin\n    sys = create_system_with_outages()\n    sys2, result = validate_serialization(sys; assign_new_uuids = true)\n    @test result\nend\n\n@testset \"Test verification of invalid ext fields\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    gen = first(get_components(ThermalStandard, sys))\n    ext = get_ext(gen)\n\n    struct MyType\n        func::Function\n    end\n    val = MyType(println)\n    ext[\"val\"] = val\n\n    tmpdir = mktempdir()\n    filename = joinpath(tmpdir, \"invalid_sys.json\")\n    @test_logs(\n        (:error, r\"only basic types are allowed\"),\n        match_mode = :any,\n        @test_throws(\n            ErrorException,\n            to_json(sys, filename, force = true),\n        ),\n    )\nend\n\n@testset \"Test serialization of System fields\" begin\n    frequency = 50.0\n    name = \"my_system\"\n    description = \"test\"\n    sys = System(100; frequency = frequency, name = name, description = description)\n    bus = ACBus(nothing)\n    bus.name = \"bus1\"\n    bus.number = 1\n    # This prevents an error log message.\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.bus = bus\n    gen.name = \"gen1\"\n    add_component!(sys, gen)\n\n    sys2, result = validate_serialization(sys)\n    @test result\n    @test sys2.frequency == frequency\n    @test sys2.metadata.name == name\n    @test sys2.metadata.description == description\nend\n\n@testset \"Test serialization of subsystems\" begin\n    sys = create_system_with_subsystems()\n    sys2, result = validate_serialization(sys)\n    @test result\n    @test sort!(collect(get_subsystems(sys))) == [\"subsystem_1\"]\nend\n\n@testset \"Test serialization to JSON string\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    set_name!(sys, \"test_RTS_GMLC_sys\")\n    set_description!(sys, \"test description\")\n    @test !isempty(collect(IS.iterate_components_with_time_series(sys.data)))\n    text = to_json(sys)\n    sys2 = from_json(text, System)\n    exclude = Set([:time_series_manager])\n    @test PSY.compare_values(sys2, sys, exclude = exclude)\n    @test isempty(collect(IS.iterate_components_with_time_series(sys2.data)))\nend\n\n@testset \"Test serialization of component with shared time series\" begin\n    for use_scaling_factor in (true, false)\n        for in_memory in (true, false)\n            sys = System(100.0)\n            bus = ACBus(nothing)\n            bus.bustype = ACBusTypes.REF\n            add_component!(sys, bus)\n            gen = ThermalStandard(nothing)\n            gen.name = \"gen1\"\n            gen.bus = bus\n            gen.base_power = 1.0\n            gen.active_power = 1.2\n            gen.reactive_power = 2.3\n            gen.active_power_limits = (0.0, 5.0)\n            add_component!(sys, gen)\n\n            initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n            end_time = Dates.DateTime(\"2020-01-01T23:00:00\")\n            dates = collect(initial_time:Dates.Hour(1):end_time)\n            data = rand(length(dates))\n            ta = TimeSeries.TimeArray(dates, data, [\"1\"])\n            sfm1 = use_scaling_factor ? get_max_active_power : nothing\n            sfm2 = use_scaling_factor ? get_max_reactive_power : nothing\n            ts1a = SingleTimeSeries(;\n                name = \"max_active_power\",\n                data = ta,\n                scaling_factor_multiplier = sfm1,\n            )\n            add_time_series!(sys, gen, ts1a)\n            ts2a = SingleTimeSeries(\n                ts1a,\n                \"max_reactive_power\";\n                scaling_factor_multiplier = sfm2,\n            )\n            add_time_series!(sys, gen, ts2a)\n\n            sys2, result = validate_serialization(sys)\n            @test result\n\n            @test IS.get_num_time_series(sys2.data) == 1\n            gen2 = get_component(ThermalStandard, sys2, \"gen1\")\n            ts1b = get_time_series(SingleTimeSeries, gen2, \"max_active_power\")\n            ts2b = get_time_series(SingleTimeSeries, gen2, \"max_reactive_power\")\n            @test ts1b.data == ts2b.data\n            ta_vals = TimeSeries.values(ta)\n            expected1 = use_scaling_factor ? ta_vals * get_max_active_power(gen) : ta_vals\n            expected2 = use_scaling_factor ? ta_vals * get_max_reactive_power(gen) : ta_vals\n            @test get_time_series_values(\n                gen2,\n                ts1b,\n                start_time = initial_time;\n            ) == expected1\n            @test get_time_series_values(\n                gen2,\n                ts2b,\n                start_time = initial_time,\n            ) == expected2\n        end\n    end\nend\n\n@testset \"Test serialization of GenericArcImpedance\" begin\n    sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5\")\n    arc = first(get_components(Arc, sys))\n    generic_arc_impedance = GenericArcImpedance(;\n        name = \"test_impedance\",\n        available = true,\n        active_power_flow = 0.0,\n        reactive_power_flow = 0.0,\n        max_flow = 0.0,\n        arc = arc,\n        r = 0.01,\n        x = 0.1,\n    )\n    add_component!(sys, generic_arc_impedance)\n    _, result = validate_serialization(sys)\n    @test result\nend\n"
  },
  {
    "path": "test/test_services.jl",
    "content": "@testset \"Test add/remove services\" begin\n    @testset \"Case: $direction\" for direction in [ReserveDown; ReserveUp; ReserveSymmetric]\n        sys = System(100.0)\n        devices = []\n        for i in 1:2\n            bus = ACBus(nothing)\n            bus.name = \"bus\" * string(i)\n            bus.number = i\n            add_component!(sys, bus)\n            gen = ThermalStandard(nothing)\n            gen.bus = bus\n            gen.name = \"gen\" * string(i)\n            add_component!(sys, gen)\n            push!(devices, gen)\n        end\n\n        service = ConstantReserve{direction}(nothing)\n        add_service!(sys, service, devices)\n\n        for device in devices\n            services = get_services(device)\n            @test length(services) == 1\n            @test services[1] isa Service\n            @test services[1] == service\n        end\n\n        services = collect(get_components(Service, sys))\n        @test length(services) == 1\n        @test services[1] == service\n\n        remove_component!(sys, service)\n\n        for device in devices\n            @test length(get_services(device)) == 0\n        end\n\n        sys = System(100.0)\n        devices = []\n        for i in 1:2\n            bus = ACBus(nothing)\n            bus.name = \"bus\" * string(i)\n            bus.number = i\n            add_component!(sys, bus)\n            gen = ThermalStandard(nothing)\n            gen.bus = bus\n            gen.name = \"gen\" * string(i)\n            add_component!(sys, gen)\n            push!(devices, gen)\n        end\n\n        service = ConstantReserve{direction}(nothing)\n        add_component!(sys, service)\n        test_device = get_component(ThermalStandard, sys, \"gen1\")\n        add_service!(test_device, service, sys)\n        @test PowerSystems.has_service(test_device, service)\n    end\nend\n\n@testset \"Test add_component Service\" begin\n    sys = System(100.0)\n    static_reserve = ConstantReserve{ReserveDown}(nothing)\n    add_component!(sys, static_reserve)\n    services = get_components(ConstantReserve{ReserveDown}, sys)\n    @test length(services) == 1\n    @test iterate(services)[1] == static_reserve\nend\n\n@testset \"Test add_service errors\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    service = ConstantReserve{ReserveDown}(nothing)\n    # Bus is not a Device.\n    @test_throws ArgumentError add_service!(sys, service, [bus])\n\n    gen = ThermalStandard(nothing)\n    # gen is not in sys.\n    @test_throws ArgumentError add_service!(sys, service, [bus])\nend\n\n@testset \"Test remove service from device\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.bus = bus\n    gen.name = \"gen\"\n    add_component!(sys, gen)\n\n    service = ConstantReserve{ReserveDown}(nothing)\n    add_service!(sys, service, [gen])\n    @test length(get_services(gen)) == 1\n\n    remove_service!(gen, service)\n    @test length(get_services(gen)) == 0\nend\n\n@testset \"Test has service\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.bus = bus\n    gen.name = \"gen\"\n    add_component!(sys, gen)\n\n    service = ConstantReserve{ReserveDown}(nothing)\n    add_service!(sys, service, [gen])\n    @test has_service(gen, service)\n    @test has_service(gen, typeof(service))\n\n    remove_service!(gen, service)\n    @test !has_service(gen, service)\n    @test !has_service(gen, typeof(service))\nend\n\n@testset \"Test remove device with service\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.bus = bus\n    gen.name = \"gen\"\n    add_component!(sys, gen)\n\n    service = ConstantReserve{ReserveDown}(nothing)\n    add_service!(sys, service, [gen])\n    @test length(get_services(gen)) == 1\n\n    remove_component!(sys, gen)\n    @test length(get_services(gen)) == 0\nend\n\n@testset \"Test clear_services\" begin\n    gen = ThermalStandard(nothing)\n    service = ConstantReserve{ReserveDown}(nothing)\n    PSY.add_service_internal!(gen, service)\n    @test length(get_services(gen)) == 1\n\n    remove_service!(gen, service)\n    @test length(get_services(gen)) == 0\nend\n\n@testset \"Test add device with service\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.name = \"bus1\"\n    bus.number = 1\n    add_component!(sys, bus)\n\n    gen = ThermalStandard(nothing)\n    gen.bus = bus\n    gen.name = \"gen\"\n\n    service = ConstantReserve{ReserveDown}(nothing)\n    PSY.add_service_internal!(gen, service)\n    @test length(get_services(gen)) == 1\n\n    @test_throws ArgumentError add_component!(sys, gen)\nend\n\n@testset \"Test get_contributing_devices\" begin\n    sys = System(100.0)\n    devices = []\n    services = []\n    for i in 1:5\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n\n        service = ConstantReserve{ReserveUp}(nothing)\n        service.name = \"ConstantReserve\" * string(i)\n        push!(services, service)\n        add_component!(sys, service)\n    end\n\n    PSY.add_service_internal!(devices[1], services[1])\n    PSY.add_service_internal!(devices[2], services[1])\n    PSY.add_service_internal!(devices[3], services[2])\n    PSY.add_service_internal!(devices[4], services[2])\n    PSY.add_service_internal!(devices[5], services[2])\n\n    expected_contributing_devices1 = [devices[1], devices[2]]\n    expected_contributing_devices2 = [devices[3], devices[4], devices[5]]\n\n    contributing_devices1 = get_contributing_devices(sys, services[1])\n    contributing_devices2 = get_contributing_devices(sys, services[2])\n\n    # Order of contributing_devices isn't guaranteed, sort them to test.\n    sort!(contributing_devices1; by = x -> get_name(x))\n    sort!(contributing_devices2; by = x -> get_name(x))\n    @test contributing_devices1 == expected_contributing_devices1\n    @test contributing_devices2 == expected_contributing_devices2\n\n    mapping = get_contributing_device_mapping(sys)\n    @test length(mapping) == length(services)\n    key1 =\n        ServiceContributingDevicesKey((ConstantReserve{ReserveUp}, get_name(services[1])))\n    key2 =\n        ServiceContributingDevicesKey((ConstantReserve{ReserveUp}, get_name(services[2])))\n    key3 =\n        ServiceContributingDevicesKey((ConstantReserve{ReserveUp}, get_name(services[3])))\n    @test haskey(mapping, key1)\n    @test haskey(mapping, key2)\n    @test haskey(mapping, key3)\n    @test length(mapping[key1].contributing_devices) == 2\n    @test length(mapping[key2].contributing_devices) == 3\n    @test length(mapping[key3].contributing_devices) == 0\n\n    sort!(mapping[key1].contributing_devices; by = x -> get_name(x))\n    sort!(mapping[key2].contributing_devices; by = x -> get_name(x))\n    @test mapping[key1].contributing_devices == expected_contributing_devices1\n    @test mapping[key2].contributing_devices == expected_contributing_devices2\nend\n\n@testset \"Test get_component combinations\" begin\n    sys = System(100.0)\n    reserves = (\n        ConstantReserve{ReserveUp}(nothing),\n        ConstantReserve{ReserveDown}(nothing),\n        VariableReserve{ReserveUp}(nothing),\n        VariableReserve{ReserveDown}(nothing),\n        ReserveDemandCurve{ReserveUp}(nothing),\n        ReserveDemandCurve{ReserveDown}(nothing),\n    )\n\n    for reserve in reserves\n        add_component!(sys, reserve)\n    end\n\n    @test length(get_components(Service, sys)) == length(reserves)\n    @test length(get_components(Reserve, sys)) == length(reserves)\n    @test length(get_components(ConstantReserve, sys)) == 2\n    @test length(get_components(VariableReserve, sys)) == 2\n    @test length(get_components(ConstantReserve{ReserveUp}, sys)) == 1\n    @test length(get_components(ConstantReserve{ReserveDown}, sys)) == 1\n    @test length(get_components(VariableReserve{ReserveUp}, sys)) == 1\n    @test length(get_components(VariableReserve{ReserveDown}, sys)) == 1\n    @test length(get_components(ReserveDemandCurve{ReserveUp}, sys)) == 1\n    @test length(get_components(ReserveDemandCurve{ReserveDown}, sys)) == 1\nend\n\n@testset \"Test struct type collections\" begin\n    concrete_types = IS.get_all_concrete_subtypes(Service)\n    reserve_types = InteractiveUtils.subtypes(Reserve)\n    reserve_parametric_types = InteractiveUtils.subtypes(ReserveDirection)\n\n    actual_count = length(concrete_types)\n    for reserve in reserve_types\n        for parametric in reserve_parametric_types\n            actual_count += 1\n        end\n    end\n    # Changed 14 to 13 as we eliminated the Transfer Service\n    @test 13 == actual_count\nend\n\n@testset \"Test ConstantReserveGroup\" begin\n    # create system\n    sys = System(100.0)\n    # add buses and generators\n    devices = []\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n    end\n\n    # add ConstantReserve\n    service = ConstantReserve{ReserveDown}(nothing)\n    add_service!(sys, service, devices)\n\n    # add ConstantReserve\n    groupservice = ConstantReserveGroup{ReserveDown}(nothing)\n    add_service!(sys, groupservice)\n\n    # add ConstantReserveGroup\n    groupservices = collect(get_components(ConstantReserveGroup, sys))\n    # test if ConstantReserveGroup was added\n    @test length(groupservices) == 1\n    @test groupservices[1] == groupservice\n\n    # add contributing services\n    expected_contributing_services = Vector{Service}()\n    push!(expected_contributing_services, service)\n    set_contributing_services!(sys, groupservice, expected_contributing_services)\n    # get contributing services\n    contributing_services = get_contributing_services(groupservice)\n\n    # check if expected contributing services is iqual to contributing services\n    sort!(contributing_services; by = x -> get_name(x))\n    @test contributing_services == expected_contributing_services\nend\n\n@testset \"Test ConstantReserveGroup errors\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    groupservice = ConstantReserveGroup{ReserveDown}(nothing)\n\n    # Bus is not a Service.\n    @test_throws MethodError set_contributing_services!(sys, groupservice, [bus])\n\n    # Service not in System\n    service = ConstantReserve{ReserveDown}(nothing)\n    contributing_services = Vector{Service}()\n    push!(contributing_services, service)\n    @test_throws ArgumentError add_service!(sys, groupservice, contributing_services)\n\n    # Service in a ConstantReserveGroup\n    devices = []\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n    end\n    add_service!(sys, service, devices)\n    add_service!(sys, groupservice, contributing_services)\n    @test_throws ArgumentError remove_component!(sys, service)\nend\n\n@testset \"Test ReserveNonSpinning\" begin\n    # create system\n    sys = System(100.0)\n    # add buses and generators\n    devices = []\n    for i in 1:2\n        bus = ACBus(nothing)\n        bus.name = \"bus\" * string(i)\n        bus.number = i\n        add_component!(sys, bus)\n        gen = ThermalStandard(nothing)\n        gen.bus = bus\n        gen.name = \"gen\" * string(i)\n        add_component!(sys, gen)\n        push!(devices, gen)\n    end\n\n    # add ConstantReserve\n    service = ConstantReserveNonSpinning(nothing)\n    add_service!(sys, service, devices)\n\n    for device in devices\n        services = get_services(device)\n        @test length(services) == 1\n        @test services[1] isa Service\n        @test services[1] == service\n    end\n\n    services = collect(get_components(Service, sys))\n    @test length(services) == 1\n    @test services[1] == service\n\n    remove_component!(sys, service)\n\n    for device in devices\n        @test length(get_services(device)) == 0\n    end\nend\n\n@testset \"Test Service Removal\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    res_up = PSY.get_component(PSY.VariableReserve{PSY.ReserveUp}, sys, \"Flex_Up\")\n    res_dn = PSY.get_component(PSY.VariableReserve{PSY.ReserveDown}, sys, \"Flex_Down\")\n    PSY.remove_component!(sys, res_dn)\n    PSY.remove_component!(sys, res_up)\n    @test isnothing(PSY.get_component(PSY.VariableReserve{PSY.ReserveUp}, sys, \"Flex_Up\"))\n    @test isnothing(\n        PSY.get_component(PSY.VariableReserve{PSY.ReserveDown}, sys, \"Flex_Down\"),\n    )\nend\n\n@testset \"Test TransmissionInterface\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    lines = get_components(Line, sys)\n    xfr = get_components(TapTransformer, sys)\n    hvdc = collect(get_components(TwoTerminalGenericHVDCLine, sys))\n    some_lines = collect(lines)[1:2]\n    other_lines_and_hvdc = vcat(collect(lines)[10:14], hvdc)\n    lines_and_transformers = [some_lines; collect(xfr)[1:2]]\n\n    interface1 = TransmissionInterface(\"foo1\", true, (min = -10.0, max = 10.0))\n    interface2 = TransmissionInterface(\"foo2\", true, (min = -10.0, max = 10.0))\n    interface3 = TransmissionInterface(\"foo3\", true, (min = -10.0, max = 10.0))\n    add_service!(sys, interface1, some_lines)\n    add_service!(sys, interface2, other_lines_and_hvdc)\n    add_service!(sys, interface3, lines_and_transformers)\n    for br in get_contributing_devices(sys, interface1)\n        @test br ∈ some_lines\n    end\n    for br in get_contributing_devices(sys, interface2)\n        @test br ∈ other_lines_and_hvdc\n    end\n    for br in get_contributing_devices(sys, interface3)\n        @test br ∈ lines_and_transformers\n    end\n    tmp_path = joinpath(mktempdir(), \"sys_with_interfaces.json\")\n    to_json(sys, tmp_path)\n    sys = System(tmp_path)\n    @test length(get_components(TransmissionInterface, sys)) == 3\n\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    area1 = get_component(Area, sys, \"1\")\n    area2 = get_component(Area, sys, \"2\")\n    area3 = get_component(Area, sys, \"3\")\n    area_interchange12 = AreaInterchange(;\n        name = \"interchange_a1_a2\",\n        available = true,\n        active_power_flow = 0.0,\n        from_area = area1,\n        to_area = area2,\n        flow_limits = (from_to = 100.0, to_from = 100.0),\n    )\n    area_interchange13 = AreaInterchange(;\n        name = \"interchange_a1_a3\",\n        available = true,\n        active_power_flow = 0.0,\n        from_area = area1,\n        to_area = area3,\n        flow_limits = (from_to = 100.0, to_from = 100.0),\n    )\n    line = first(get_components(Line, sys))\n    add_component!(sys, area_interchange12)\n    add_component!(sys, area_interchange13)\n    area_level_interface = TransmissionInterface(\"foo3\", true, (min = -10.0, max = 10.0))\n    area_level_mixed = TransmissionInterface(\"foo4\", true, (min = -10.0, max = 10.0))\n    add_service!(sys, area_level_interface, [area_interchange12, area_interchange13])\n    @test_throws ArgumentError add_service!(\n        sys,\n        area_level_mixed,\n        [area_interchange12, area_interchange13, line],\n    )\nend\n\n@testset \"Test AGC\" begin\n    sys = PSB.build_system(PSITestSystems, \"c_sys5_uc\"; add_reserves = true)\n    thermals = get_components(ThermalStandard, sys)\n    reserves = get_components(VariableReserve{ReserveUp}, sys)\n    agc = AGC(;\n        name = \"agc\",\n        available = true,\n        bias = 0.0,\n        K_p = 1.0,\n        K_i = 1.0,\n        K_d = 1.0,\n        delta_t = 1.0,\n    )\n    @test_throws ArgumentError add_service!(sys, agc, thermals)\n    add_service!(sys, agc, reserves)\n    mapping = get_contributing_reserve_mapping(sys)\n    @test length(mapping) == 1\n    @test_throws ArgumentError add_service!(sys, agc, reserves)\n\n    #Test serialization of system with AGC + contributing reserves\n    sys = PSB.build_system(PSITestSystems, \"c_sys5_uc\"; add_reserves = true)\n    reserves = get_components(VariableReserve{ReserveUp}, sys)\n    agc = AGC(;\n        name = \"agc\",\n        available = true,\n        bias = 0.0,\n        K_p = 1.0,\n        K_i = 1.0,\n        K_d = 1.0,\n        delta_t = 1.0,\n    )\n    add_service!(sys, agc, reserves)\n    _, result = validate_serialization(sys)\n    @test result\nend\n"
  },
  {
    "path": "test/test_subsystems.jl",
    "content": "function create_system_with_test_subsystems()\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"c_sys5_uc\";\n        add_forecasts = false,\n        time_series_read_only = false,\n    )\n\n    components = collect(get_components(ThermalStandard, sys))\n    @test length(components) >= 5\n\n    subsystems = String[]\n    for i in 1:3\n        name = \"subsystem_$i\"\n        add_subsystem!(sys, name)\n        push!(subsystems, name)\n    end\n\n    add_component_to_subsystem!(sys, subsystems[1], components[1])\n    add_component_to_subsystem!(sys, subsystems[1], components[2])\n    add_component_to_subsystem!(sys, subsystems[2], components[2])\n    add_component_to_subsystem!(sys, subsystems[2], components[3])\n    add_component_to_subsystem!(sys, subsystems[3], components[3])\n    add_component_to_subsystem!(sys, subsystems[3], components[4])\n    return (sys, components)\nend\n\nfunction create_system_with_2_test_subsystems()\n    c_sys5 = PSB.build_system(PSISystems, \"2Area 5 Bus System\")\n\n    components = collect(get_components(Component, c_sys5))\n    #@test length(components) == 52\n\n    subsystems = String[]\n    for i in 1:2\n        name = \"subsystem_$i\"\n        add_subsystem!(c_sys5, name)\n        push!(subsystems, name)\n    end\n\n    #name of components solely belonging to subsystem 2 ends with 2\n    suffix = \"2\"\n\n    for component in get_components(Component, c_sys5)\n        if (endswith(get_name(component), suffix))\n            add_component_to_subsystem!(c_sys5, subsystems[2], component)\n        else\n            add_component_to_subsystem!(c_sys5, subsystems[1], component)\n        end\n    end\n\n    #components connecting the subsystems are shared\n    add_component_to_subsystem!(\n        c_sys5,\n        subsystems[1],\n        get_component(TwoTerminalGenericHVDCLine, c_sys5, \"nodeC-nodeC2\"),\n    )\n    add_component_to_subsystem!(\n        c_sys5,\n        subsystems[1],\n        get_component(Arc, c_sys5, \"nodeC -> nodeC2\"),\n    )\n    add_component_to_subsystem!(\n        c_sys5,\n        subsystems[1],\n        get_component(ACBus, c_sys5, \"nodeC2\"),\n    )\n    add_component_to_subsystem!(\n        c_sys5,\n        subsystems[2],\n        get_component(ACBus, c_sys5, \"nodeC\"),\n    )\n    PSY.check(c_sys5)\n    PSY.check_components(c_sys5)\n    return (c_sys5, components)\nend\n\n@testset \"Test get subsystems and components\" begin\n    sys, components = create_system_with_test_subsystems()\n    @test sort!(collect(get_subsystems(sys))) ==\n          [\"subsystem_1\", \"subsystem_2\", \"subsystem_3\"]\n    @test has_component(sys, \"subsystem_1\", components[1])\n    @test has_component(sys, \"subsystem_1\", components[2])\n    @test has_component(sys, \"subsystem_2\", components[2])\n    @test has_component(sys, \"subsystem_2\", components[3])\n    @test has_component(sys, \"subsystem_3\", components[3])\n    @test has_component(sys, \"subsystem_3\", components[4])\n    @test !has_component(sys, \"subsystem_3\", components[5])\n    @test sort!(get_name.(get_subsystem_components(sys, \"subsystem_2\"))) ==\n          sort!([get_name(components[2]), get_name(components[3])])\n    @test get_assigned_subsystems(sys, components[1]) == [\"subsystem_1\"]\n    @test is_assigned_to_subsystem(sys, components[1])\n    @test !is_assigned_to_subsystem(sys, components[5])\n    @test is_assigned_to_subsystem(sys, components[1], \"subsystem_1\")\n    @test !is_assigned_to_subsystem(sys, components[5], \"subsystem_1\")\n    @test_throws ArgumentError add_subsystem!(sys, \"subsystem_1\")\nend\n\n@testset \"Test get_components\" begin\n    sys, components = create_system_with_test_subsystems()\n    @test length(\n        get_components(ThermalStandard, sys; subsystem_name = \"subsystem_1\"),\n    ) == 2\n    name = get_name(components[1])\n    @test collect(\n        get_components(\n            x -> x.name == name,\n            ThermalStandard,\n            sys;\n            subsystem_name = \"subsystem_1\",\n        ),\n    )[1].name == name\nend\n\n@testset \"Test subsystem after remove_component\" begin\n    sys, components = create_system_with_test_subsystems()\n    remove_component!(sys, components[3])\n    @test !has_component(sys, \"subsystem_2\", components[3])\n    @test !has_component(sys, \"subsystem_3\", components[3])\n    @test has_component(sys, \"subsystem_2\", components[2])\n    @test has_component(sys, \"subsystem_3\", components[4])\nend\n\n@testset \"Test removal of subsystem\" begin\n    sys, components = create_system_with_test_subsystems()\n    remove_subsystem!(sys, \"subsystem_2\")\n    @test sort!(collect(get_subsystems(sys))) == [\"subsystem_1\", \"subsystem_3\"]\n    @test get_assigned_subsystems(sys, components[2]) == [\"subsystem_1\"]\n    @test_throws ArgumentError remove_subsystem!(sys, \"subsystem_2\")\nend\n\n@testset \"Test removal of subsystem component\" begin\n    sys, components = create_system_with_test_subsystems()\n    remove_component_from_subsystem!(sys, \"subsystem_2\", components[2])\n    @test get_name.(get_subsystem_components(sys, \"subsystem_2\")) ==\n          [get_name(components[3])]\n    @test_throws ArgumentError remove_component_from_subsystem!(\n        sys,\n        \"subsystem_2\",\n        components[2],\n    )\nend\n\n@testset \"Test addition of component to invalid subsystem\" begin\n    sys, components = create_system_with_test_subsystems()\n    @test_throws ArgumentError add_component_to_subsystem!(sys, \"invalid\", components[1])\nend\n\n@testset \"Test addition of duplicate component to subsystem\" begin\n    sys, components = create_system_with_test_subsystems()\n    @test_throws ArgumentError add_component_to_subsystem!(\n        sys,\n        \"subsystem_1\",\n        components[1],\n    )\nend\n\n@testset \"Test addition of non-system component\" begin\n    sys, components = create_system_with_test_subsystems()\n    remove_component!(sys, components[1])\n    @test_throws ArgumentError add_component_to_subsystem!(\n        sys,\n        \"subsystem_1\",\n        components[1],\n    )\nend\n\n@testset \"Test invalid subsystem count\" begin\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"c_sys5_uc\";\n        add_forecasts = false,\n        time_series_read_only = true,\n    )\n    num_buses = length(get_components(Bus, sys))\n    for i in 1:num_buses\n        add_subsystem!(sys, \"subsystem_$i\")\n    end\n    @test_throws \"cannot exceed the number of buses\" add_subsystem!(sys, \"subsystem\")\nend\n\n@testset \"Test valid subsystem\" begin\n    sys = create_system_with_subsystems()\n    check_components(sys)\nend\n\n@testset \"Test inconsistent component-subsystem membership\" begin\n    sys, components = create_system_with_test_subsystems()\n    @test_throws IS.InvalidValue check_components(sys)\nend\n\n@testset \"Test mismatch component-topological membership\" begin\n    sys = create_system_with_subsystems()\n    add_subsystem!(sys, \"incomplete_subsystem\")\n    gen = first(get_components(ThermalStandard, sys))\n    bus = get_bus(gen)\n    remove_component_from_subsystem!(sys, \"subsystem_1\", bus)\n    add_component_to_subsystem!(sys, \"incomplete_subsystem\", bus)\n    @test_throws IS.InvalidValue PSY._check_topological_consistency(sys, gen)\nend\n\n@testset \"Test mismatch branch-arc membership\" begin\n    sys = create_system_with_subsystems()\n    add_subsystem!(sys, \"incomplete_subsystem\")\n    branch = first(get_components(Branch, sys))\n    arc = get_arc(branch)\n    remove_component_from_subsystem!(sys, \"subsystem_1\", arc)\n    add_component_to_subsystem!(sys, \"incomplete_subsystem\", arc)\n    @test_throws IS.InvalidValue PSY._check_branch_consistency(sys, branch)\nend\n\n@testset \"Test service-contributing-device consistency\" begin\n    sys = create_system_with_subsystems()\n    add_subsystem!(sys, \"incomplete_subsystem\")\n    device = nothing\n    service = nothing\n    for dev in get_components(Device, sys)\n        if !PSY.supports_services(dev)\n            continue\n        end\n        services = get_services(dev)\n        if !isempty(services)\n            device = dev\n            service = first(services)\n            break\n        end\n    end\n    @test !isnothing(device) && !isnothing(service)\n\n    remove_component_from_subsystem!(sys, \"subsystem_1\", device)\n    add_subsystem!(sys, \"subsystem_2\")\n    add_component_to_subsystem!(sys, \"subsystem_2\", device)\n\n    @test_throws IS.InvalidValue PSY._check_device_service_consistency(sys, device)\nend\n\n@testset \"Test subsystems with HybridSystem\" begin\n    sys = PSB.build_system(PSB.PSITestSystems, \"test_RTS_GMLC_sys_with_hybrid\")\n    h_sys = first(get_components(HybridSystem, sys))\n    subcomponents = collect(get_subcomponents(h_sys))\n\n    subsystem_name = \"subsystem_1\"\n    add_subsystem!(sys, subsystem_name)\n    add_component_to_subsystem!(sys, subsystem_name, h_sys)\n    # Ensure that subcomponents get added automatically.\n    for subcomponent in subcomponents\n        @test is_assigned_to_subsystem(sys, subcomponent, subsystem_name)\n    end\n\n    remove_component_from_subsystem!(sys, subsystem_name, subcomponents[1])\n    @test_throws IS.InvalidValue PSY._check_subcomponent_consistency(sys, h_sys)\n\n    add_component_to_subsystem!(sys, subsystem_name, subcomponents[1])\n    remove_component_from_subsystem!(sys, subsystem_name, h_sys)\n    # Ensure that subcomponents get removed automatically.\n    for subcomponent in subcomponents\n        @test !is_assigned_to_subsystem(sys, subcomponent, subsystem_name)\n    end\nend\n\n@testset \"Test get subsystems and components for c_sys5\" begin\n    bus_c = ACBus(\n        3,\n        \"nodeC\",\n        true,\n        \"PV\",\n        0,\n        1.0,\n        (min = 0.9, max = 1.05),\n        230,\n        nothing,\n        nothing,\n    )\n    bus_d = ACBus(\n        4,\n        \"nodeD\",\n        true,\n        \"REF\",\n        0,\n        1.0,\n        (min = 0.9, max = 1.05),\n        230,\n        nothing,\n        nothing,\n    )\n    bus_d2 =\n        ACBus(\n            9,\n            \"nodeD2\",\n            true,\n            \"REF\",\n            0,\n            1.0,\n            (min = 0.9, max = 1.05),\n            230,\n            nothing,\n            nothing,\n        )\n\n    d_d2 = Line(\n        \"nodeD-nodeD2\",\n        true,\n        0.0,\n        0.0,\n        Arc(; from = bus_d, to = bus_d2),\n        0.00108,\n        0.0108,\n        (from = 0.00926, to = 0.00926),\n        11.1480,\n        (min = -0.7, max = 0.7),\n    )\n\n    c_d2 = Line(\n        \"nodeC-nodeD2\",\n        true,\n        0.0,\n        0.0,\n        Arc(; from = bus_c, to = bus_d2),\n        0.00297,\n        0.0297,\n        (from = 0.00337, to = 0.00337),\n        40.530,\n        (min = -0.7, max = 0.7),\n    )\n\n    c_sys5, components = create_system_with_2_test_subsystems()\n    @test sort!(collect(get_subsystems(c_sys5))) ==\n          [\"subsystem_1\", \"subsystem_2\"]\n\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeA -> nodeB\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeA -> nodeD\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeA -> nodeE\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeB -> nodeC\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeC -> nodeD\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeD -> nodeE\"))\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(Arc, c_sys5, \"nodeC -> nodeC2\"),\n    )\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeA2 -> nodeB2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeA2 -> nodeD2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeA2 -> nodeE2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeB2 -> nodeC2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeC2 -> nodeD2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeD2 -> nodeE2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeC -> nodeC2\"),\n    )\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ThermalStandard, c_sys5, \"Solitude\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ThermalStandard, c_sys5, \"Park City\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ThermalStandard, c_sys5, \"Alta\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ThermalStandard, c_sys5, \"Brighton\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ThermalStandard, c_sys5, \"Sundance\"),\n    )\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(ThermalStandard, c_sys5, \"Park City-2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(ThermalStandard, c_sys5, \"Solitude-2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(ThermalStandard, c_sys5, \"Alta-2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(ThermalStandard, c_sys5, \"Sundance-2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(ThermalStandard, c_sys5, \"Brighton-2\"),\n    )\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeB\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeC\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeD\"),\n    )\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeB2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeC2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(PowerLoad, c_sys5, \"Load-nodeD2\"),\n    )\n\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeA-nodeB\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeA-nodeD\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeA-nodeE\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeB-nodeC\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeC-nodeD\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Line, c_sys5, \"nodeD-nodeE\"))\n\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeA2-nodeB2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeA2-nodeD2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeA2-nodeE2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeB2-nodeC2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeC2-nodeD2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(Line, c_sys5, \"nodeD2-nodeE2\"))\n\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeA\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeB\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeC\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeD\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeE\"))\n    @test has_component(c_sys5, \"subsystem_1\", get_component(ACBus, c_sys5, \"nodeC2\"))\n\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeA2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeB2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeC2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeD2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeE2\"))\n    @test has_component(c_sys5, \"subsystem_2\", get_component(ACBus, c_sys5, \"nodeC\"))\n\n    @test has_component(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(TwoTerminalGenericHVDCLine, c_sys5, \"nodeC-nodeC2\"),\n    )\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(TwoTerminalGenericHVDCLine, c_sys5, \"nodeC-nodeC2\"),\n    )\n\n    @test sort!(get_name.(get_subsystem_components(c_sys5, \"subsystem_1\"))) ==\n          sort!([\n        get_name(get_component(Arc, c_sys5, \"nodeA -> nodeB\")),\n        get_name(get_component(Arc, c_sys5, \"nodeA -> nodeD\")),\n        get_name(get_component(Arc, c_sys5, \"nodeA -> nodeE\")),\n        get_name(get_component(Arc, c_sys5, \"nodeB -> nodeC\")),\n        get_name(get_component(Arc, c_sys5, \"nodeC -> nodeD\")),\n        get_name(get_component(Arc, c_sys5, \"nodeD -> nodeE\")),\n        get_name(get_component(Arc, c_sys5, \"nodeC -> nodeC2\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Solitude\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Park City\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Alta\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Brighton\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Sundance\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeB\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeC\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeB\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeE\")),\n        get_name(get_component(Line, c_sys5, \"nodeB-nodeC\")),\n        get_name(get_component(Line, c_sys5, \"nodeC-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeD-nodeE\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeA\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeB\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeC\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeD\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeE\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeC2\")),\n        get_name(get_component(TwoTerminalGenericHVDCLine, c_sys5, \"nodeC-nodeC2\")),\n    ])\n\n    @test get_assigned_subsystems(c_sys5, get_component(ACBus, c_sys5, \"nodeD\")) ==\n          [\"subsystem_1\"]\n    @test get_assigned_subsystems(c_sys5, get_component(ACBus, c_sys5, \"nodeD2\")) ==\n          [\"subsystem_2\"]\n    @test sort!(get_assigned_subsystems(c_sys5, get_component(ACBus, c_sys5, \"nodeC2\"))) ==\n          [\"subsystem_1\", \"subsystem_2\"]\n    @test sort!(get_assigned_subsystems(c_sys5, get_component(ACBus, c_sys5, \"nodeC\"))) ==\n          [\"subsystem_1\", \"subsystem_2\"]\n    @test is_assigned_to_subsystem(c_sys5, get_component(ACBus, c_sys5, \"nodeC\"))\n    @test !is_assigned_to_subsystem(c_sys5, d_d2)\n    @test !is_assigned_to_subsystem(c_sys5, c_d2)\n    @test is_assigned_to_subsystem(\n        c_sys5,\n        get_component(ACBus, c_sys5, \"nodeC\"),\n        \"subsystem_1\",\n    )\n    @test is_assigned_to_subsystem(\n        c_sys5,\n        get_component(ACBus, c_sys5, \"nodeC\"),\n        \"subsystem_2\",\n    )\n    @test is_assigned_to_subsystem(\n        c_sys5,\n        get_component(ACBus, c_sys5, \"nodeD\"),\n        \"subsystem_1\",\n    )\n    @test is_assigned_to_subsystem(\n        c_sys5,\n        get_component(ACBus, c_sys5, \"nodeD2\"),\n        \"subsystem_2\",\n    )\n    @test !is_assigned_to_subsystem(\n        c_sys5,\n        get_component(ACBus, c_sys5, \"nodeD2\"),\n        \"subsystem_1\",\n    )\n    @test_throws ArgumentError add_subsystem!(c_sys5, \"subsystem_1\")\nend\n\n@testset \"Test get_components for c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    @test length(\n        get_components(ThermalStandard, c_sys5; subsystem_name = \"subsystem_1\"),\n    ) == 5\n    name = get_name(get_component(PowerLoad, c_sys5, \"Load-nodeB2\"))\n    @test collect(\n        get_components(\n            x -> x.name == name,\n            PowerLoad,\n            c_sys5;\n            subsystem_name = \"subsystem_2\",\n        ),\n    )[1].name == name\nend\n\n@testset \"Test c_sys5 subsystem after remove_component\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    comp = get_component(Arc, c_sys5, \"nodeB -> nodeC\")\n    remove_component!(c_sys5, comp)\n    @test !has_component(c_sys5, \"subsystem_1\", comp)\n    @test !has_component(c_sys5, \"subsystem_2\", comp)\n    @test has_component(c_sys5, \"subsystem_1\", get_component(Arc, c_sys5, \"nodeA -> nodeB\"))\n    @test has_component(\n        c_sys5,\n        \"subsystem_2\",\n        get_component(Arc, c_sys5, \"nodeA2 -> nodeB2\"),\n    )\nend\n\n@testset \"Test removal of subsystem from c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    remove_subsystem!(c_sys5, \"subsystem_2\")\n    @test sort!(collect(get_subsystems(c_sys5))) == [\"subsystem_1\"]\n    @test get_assigned_subsystems(c_sys5, get_component(Arc, c_sys5, \"nodeA -> nodeB\")) ==\n          [\"subsystem_1\"]\n    @test_throws ArgumentError remove_subsystem!(c_sys5, \"subsystem_2\")\nend\n\n@testset \"Test removal of subsystem component\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    comp = get_component(Arc, c_sys5, \"nodeA -> nodeB\")\n    remove_component_from_subsystem!(c_sys5, \"subsystem_1\", comp)\n    @test sort!(get_name.(get_subsystem_components(c_sys5, \"subsystem_1\"))) ==\n          sort!([\n        get_name(get_component(Arc, c_sys5, \"nodeA -> nodeD\")),\n        get_name(get_component(Arc, c_sys5, \"nodeA -> nodeE\")),\n        get_name(get_component(Arc, c_sys5, \"nodeB -> nodeC\")),\n        get_name(get_component(Arc, c_sys5, \"nodeC -> nodeD\")),\n        get_name(get_component(Arc, c_sys5, \"nodeD -> nodeE\")),\n        get_name(get_component(Arc, c_sys5, \"nodeC -> nodeC2\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Solitude\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Park City\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Alta\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Brighton\")),\n        get_name(get_component(ThermalStandard, c_sys5, \"Sundance\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeB\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeC\")),\n        get_name(get_component(PowerLoad, c_sys5, \"Load-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeB\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeA-nodeE\")),\n        get_name(get_component(Line, c_sys5, \"nodeB-nodeC\")),\n        get_name(get_component(Line, c_sys5, \"nodeC-nodeD\")),\n        get_name(get_component(Line, c_sys5, \"nodeD-nodeE\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeA\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeB\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeC\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeD\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeE\")),\n        get_name(get_component(ACBus, c_sys5, \"nodeC2\")),\n        get_name(get_component(TwoTerminalGenericHVDCLine, c_sys5, \"nodeC-nodeC2\")),\n    ])\n    @test_throws ArgumentError remove_component_from_subsystem!(\n        c_sys5,\n        \"subsystem_1\",\n        comp,\n    )\nend\n\n@testset \"Test addition of component to invalid subsystem for c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    @test_throws ArgumentError add_component_to_subsystem!(c_sys5, \"invalid\", components[1])\nend\n\n@testset \"Test addition of duplicate component to subsystem for c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    @test_throws ArgumentError add_component_to_subsystem!(\n        c_sys5,\n        \"subsystem_1\",\n        get_component(ACBus, c_sys5, \"nodeD\"),\n    )\nend\n\n@testset \"Test addition of non-system component to c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    comp = get_component(ACBus, c_sys5, \"nodeD\")\n    remove_component!(c_sys5, comp)\n    @test_throws ArgumentError add_component_to_subsystem!(\n        c_sys5,\n        \"subsystem_1\",\n        comp,\n    )\nend\n\n@testset \"Test invalid subsystem count\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    num_buses = length(get_components(Bus, c_sys5))\n    for i in 3:num_buses\n        add_subsystem!(c_sys5, \"subsystem_$i\")\n    end\n    @test_throws \"cannot exceed the number of buses\" add_subsystem!(\n        c_sys5,\n        \"subsystem134523\",\n    )\nend\n\n@testset \"Test service-contributing-device consistency for c_sys5\" begin\n    c_sys5, components = create_system_with_2_test_subsystems()\n    device = nothing\n    service = nothing\n    for dev in get_components(Device, c_sys5; subsystem_name = \"subsystem_1\")\n        res = VariableReserve{ReserveUp}(\"REG1\", true, 5.0, 0.1)\n        add_service!(c_sys5, res, dev)\n        services = get_services(dev)\n        if !isempty(services)\n            device = dev\n            service = first(services)\n            break\n        end\n    end\n    @test !isnothing(device) && !isnothing(service)\n\n    remove_component_from_subsystem!(c_sys5, \"subsystem_1\", device)\n    add_subsystem!(c_sys5, \"incomplete_subsystem\")\n    add_component_to_subsystem!(c_sys5, \"incomplete_subsystem\", device)\n\n    @test_throws IS.InvalidValue PSY._check_device_service_consistency(c_sys5, device)\nend\n\n@testset \"Test construct system from subsystem\" begin\n    base_sys = create_system_with_2_test_subsystems()[1]\n    ts_counts = get_time_series_counts(base_sys)\n    @test ts_counts.components_with_time_series == 6\n    @test ts_counts.forecast_count == 6\n    subsystem1_uuids = get_component_uuids(base_sys, \"subsystem_1\")\n    subsystem2_uuids = get_component_uuids(base_sys, \"subsystem_2\")\n\n    sys1 = from_subsystem(base_sys, \"subsystem_1\")\n    sys2 = from_subsystem(base_sys, \"subsystem_2\")\n\n    base_sys_components = get_components(Component, base_sys)\n\n    sys1_components = get_components(Component, sys1)\n    sys2_components = get_components(Component, sys2)\n    @test length(sys1_components) < length(base_sys_components)\n    @test length(sys2_components) < length(base_sys_components)\n\n    for (components, uuids) in\n        ((sys1_components, subsystem1_uuids), (sys2_components, subsystem2_uuids))\n        for component in components\n            base_component = get_component(typeof(component), base_sys, get_name(component))\n            @test IS.get_uuid(base_component) in uuids\n        end\n    end\n\n    for sys in (sys1, sys2)\n        ts_counts = get_time_series_counts(sys)\n        @test ts_counts.components_with_time_series == 3\n        @test ts_counts.forecast_count == 3\n    end\nend\n"
  },
  {
    "path": "test/test_supplemental_accessors.jl",
    "content": "@testset \"Test supplemental voltage accessors\" begin\n    @testset \"get_base_voltage for Line - matching voltages\" begin\n        sys = PSB.build_system(PSB.PSITestSystems, \"c_sys5\")\n        lines = collect(get_components(Line, sys))\n        @test !isempty(lines)\n        for line in lines\n            from_bus = get_from(get_arc(line))\n            expected = get_base_voltage(from_bus)\n            @test get_base_voltage(line) == expected\n            @test get_base_voltage(line) isa Float64\n        end\n    end\n\n    @testset \"get_base_voltage for Line - within tolerance picks rounder value\" begin\n        bus_from = ACBus(nothing)\n        bus_from.name = \"bus_from\"\n        bus_from.number = 1\n        bus_from.bustype = ACBusTypes.PV\n        bus_from.base_voltage = 230.0\n\n        bus_to = ACBus(nothing)\n        bus_to.name = \"bus_to\"\n        bus_to.number = 2\n        bus_to.bustype = ACBusTypes.PQ\n        bus_to.base_voltage = 229.5  # within 1% of 230.0\n\n        arc = Arc(; from = bus_from, to = bus_to)\n        line = Line(\n            \"test_line\",\n            true,\n            0.0,\n            0.0,\n            arc,\n            0.01,\n            0.05,\n            (from = 0.0, to = 0.0),\n            100.0,\n            (min = -0.7, max = 0.7),\n        )\n        # 230.0 has fewer significant figures than 229.5\n        @test get_base_voltage(line) == 230.0\n\n        # Reverse: from has more digits, to has fewer\n        bus_from2 = ACBus(nothing)\n        bus_from2.name = \"bus_from2\"\n        bus_from2.number = 3\n        bus_from2.bustype = ACBusTypes.PV\n        bus_from2.base_voltage = 229.5\n\n        bus_to2 = ACBus(nothing)\n        bus_to2.name = \"bus_to2\"\n        bus_to2.number = 4\n        bus_to2.bustype = ACBusTypes.PQ\n        bus_to2.base_voltage = 230.0\n\n        arc2 = Arc(; from = bus_from2, to = bus_to2)\n        line2 = Line(\n            \"test_line2\",\n            true,\n            0.0,\n            0.0,\n            arc2,\n            0.01,\n            0.05,\n            (from = 0.0, to = 0.0),\n            100.0,\n            (min = -0.7, max = 0.7),\n        )\n        @test get_base_voltage(line2) == 230.0\n    end\n\n    @testset \"get_base_voltage for Line - exceeds tolerance throws error\" begin\n        bus_from = ACBus(nothing)\n        bus_from.name = \"bus_hi\"\n        bus_from.number = 5\n        bus_from.bustype = ACBusTypes.PV\n        bus_from.base_voltage = 230.0\n\n        bus_to = ACBus(nothing)\n        bus_to.name = \"bus_lo\"\n        bus_to.number = 6\n        bus_to.bustype = ACBusTypes.PQ\n        bus_to.base_voltage = 115.0  # 50% difference\n\n        arc = Arc(; from = bus_from, to = bus_to)\n        line = Line(\n            \"bad_line\",\n            true,\n            0.0,\n            0.0,\n            arc,\n            0.01,\n            0.05,\n            (from = 0.0, to = 0.0),\n            100.0,\n            (min = -0.7, max = 0.7),\n        )\n        @test_throws ErrorException get_base_voltage(line)\n    end\n\n    @testset \"get_high_voltage and get_low_voltage for TapTransformer\" begin\n        sys = PSB.build_system(PSB.PSITestSystems, \"c_sys14\")\n        taps = collect(get_components(TapTransformer, sys))\n        @test !isempty(taps)\n        for t in taps\n            v_primary = get_base_voltage_primary(t)\n            v_secondary = get_base_voltage_secondary(t)\n            @test get_high_voltage(t) == max(v_primary, v_secondary)\n            @test get_low_voltage(t) == min(v_primary, v_secondary)\n            @test get_high_voltage(t) >= get_low_voltage(t)\n            @test get_high_voltage(t) isa Float64\n            @test get_low_voltage(t) isa Float64\n        end\n    end\n\n    @testset \"get_high_voltage and get_low_voltage for Transformer2W\" begin\n        sys = PSB.build_system(PSB.PSITestSystems, \"c_sys14\")\n        t2ws = collect(get_components(Transformer2W, sys))\n        @test !isempty(t2ws)\n        for t in t2ws\n            v_primary = get_base_voltage_primary(t)\n            v_secondary = get_base_voltage_secondary(t)\n            @test get_high_voltage(t) == max(v_primary, v_secondary)\n            @test get_low_voltage(t) == min(v_primary, v_secondary)\n            @test get_high_voltage(t) >= get_low_voltage(t)\n        end\n    end\nend\n"
  },
  {
    "path": "test/test_system.jl",
    "content": "@testset \"Test functionality of System\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    summary(devnull, sys)\n    @test get_frequency(sys) == PSY.DEFAULT_SYSTEM_FREQUENCY\n\n    generators = collect(get_components(ThermalStandard, sys))\n    generator = get_component(ThermalStandard, sys, get_name(generators[1]))\n    @test IS.get_uuid(generator) == IS.get_uuid(generators[1])\n    @test_throws(IS.ArgumentError, add_component!(sys, generator))\n    @test get_available_component(ThermalStandard, sys, get_name(generators[1])) ===\n          generator\n    set_available!(generator, false)\n    @test isnothing(get_available_component(ThermalStandard, sys, get_name(generators[1])))\n    set_available!(generator, true)\n\n    generators2 = get_components_by_name(ThermalGen, sys, get_name(generators[1]))\n    @test length(generators2) == 1\n    @test IS.get_uuid(generators2[1]) == IS.get_uuid(generators[1])\n    @test !has_time_series(generators2[1])\n\n    @test isnothing(get_component(ThermalStandard, sys, \"not-a-name\"))\n    @test isempty(get_components_by_name(ThermalGen, sys, \"not-a-name\"))\n    @test_throws(\n        IS.ArgumentError,\n        get_components_by_name(ThermalStandard, sys, \"not-a-name\")\n    )\n    @test isempty(get_components(x -> (!get_available(x)), ThermalStandard, sys))\n    @test !isempty(get_available_components(ThermalStandard, sys))\n    @test !isempty(get_available_components(x -> true, ThermalStandard, sys))\n    # Test get_bus* functionality.\n    bus_numbers = Vector{Int}()\n    for bus in get_components(ACBus, sys)\n        push!(bus_numbers, bus.number)\n        if length(bus_numbers) >= 2\n            break\n        end\n    end\n\n    bus = PowerSystems.get_bus(sys, bus_numbers[1])\n    @test bus.number == bus_numbers[1]\n\n    buses = PowerSystems.get_buses(sys, Set(bus_numbers))\n    sort!(bus_numbers)\n    sort!(buses; by = x -> x.number)\n    @test length(bus_numbers) == length(buses)\n    for (bus_number, bus) in zip(bus_numbers, buses)\n        @test bus_number == bus.number\n    end\n\n    @test get_forecast_initial_times(sys) == []\n    @test get_time_series_resolutions(sys)[1] == Dates.Hour(1)\n\n    # Get time_series with a name and without.\n    components = collect(get_components(HydroTurbine, sys))\n    @test !isempty(components)\n    component = components[1]\n    ts = get_time_series(SingleTimeSeries, component, \"max_active_power\")\n    @test ts isa SingleTimeSeries\n\n    components = collect(get_components(HydroReservoir, sys))\n    @test !isempty(components)\n\n    returned_it, returned_len = check_time_series_consistency(sys, SingleTimeSeries)\n    @test returned_it == first(TimeSeries.timestamp(get_data(ts)))\n    @test returned_len == length(get_data(ts))\n\n    # Test all versions of get_time_series_[array|timestamps|values]\n    values1 = get_time_series_array(component, ts)\n    values2 = get_time_series_array(SingleTimeSeries, component, \"max_active_power\")\n    @test values1 == values2\n    values3 = get_time_series_array(SingleTimeSeries, component, \"max_active_power\")\n    @test values1 == values3\n\n    val = get_time_series_array(SingleTimeSeries, component, \"max_active_power\")\n    @test val isa TimeSeries.TimeArray\n    val = get_time_series_timestamps(SingleTimeSeries, component, \"max_active_power\")\n    @test val isa Array\n    @test val[1] isa Dates.DateTime\n    val = get_time_series_values(SingleTimeSeries, component, \"max_active_power\")\n    @test val isa Array\n    @test val[1] isa AbstractFloat\n\n    val = get_time_series_array(component, ts)\n    @test val isa TimeSeries.TimeArray\n    val = get_time_series_timestamps(component, ts)\n    @test val isa Array\n    @test val[1] isa Dates.DateTime\n    val = get_time_series_values(component, ts)\n    @test val isa Array\n    @test val[1] isa AbstractFloat\n\n    clear_time_series!(sys)\n    @test length(collect(get_time_series_multiple(sys))) == 0\n    @test IS.get_internal(sys) isa IS.InfrastructureSystemsInternal\nend\n\n@testset \"Test get_componets filter_func\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    gen = first(get_components(ThermalStandard, sys))\n    name = get_name(gen)\n    generators = get_components(ThermalStandard, sys) do gen\n        get_name(gen) == name && get_available(gen)\n    end\n\n    @test length(generators) == 1 && get_name(first(generators)) == name\nend\n\n@testset \"Test handling of bus_numbers\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n\n    @test length(sys.bus_numbers) > 0\n    buses = get_components(ACBus, sys)\n    bus_numbers = sort!([get_number(bus) for bus in buses])\n    @test bus_numbers == get_bus_numbers(sys)\n\n    # Remove some components\n    remove_components!(x -> get_number(x) ∈ [101, 201], sys, ACBus)\n    @test length(sys.bus_numbers) == length(bus_numbers) - 2\n\n    # Remove entire type\n    remove_components!(sys, ACBus)\n    @test length(sys.bus_numbers) == 0\n\n    # Remove individually.\n    for bus in buses\n        add_component!(sys, bus)\n    end\n    @test length(sys.bus_numbers) > 0\n    for bus in buses\n        remove_component!(sys, bus)\n    end\n    @test length(sys.bus_numbers) == 0\n\n    # Remove by name.\n    for bus in buses\n        add_component!(sys, bus)\n    end\n    @test length(sys.bus_numbers) > 0\n    for bus in buses\n        remove_component!(ACBus, sys, get_name(bus))\n    end\n    @test length(sys.bus_numbers) == 0\nend\n\n@testset \"Test System iterators\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n\n    i = 0\n    for component in iterate_components(sys)\n        i += 1\n    end\n\n    components = get_components(Component, sys)\n    @test i == length(components)\n\n    # Test debugging functions.\n    component = first(components)\n    uuid = IS.get_uuid(component)\n    @test get_name(get_component(sys, uuid)) == get_name(component)\n    @test get_name(get_component(sys, string(uuid))) == get_name(component)\nend\n\n@testset \"Test remove_component\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    generators = get_components(ThermalStandard, sys)\n    initial_length = length(generators)\n    @assert initial_length > 0\n    gen = collect(generators)[1]\n\n    remove_component!(sys, gen)\n\n    @test isnothing(get_component(typeof(gen), sys, get_name(gen)))\n    generators = get_components(typeof(gen), sys)\n    @test length(generators) == initial_length - 1\n\n    @test_throws(IS.ArgumentError, remove_component!(sys, gen))\n\n    add_component!(sys, gen)\n    remove_component!(typeof(gen), sys, get_name(gen))\n    @test isnothing(get_component(typeof(gen), sys, get_name(gen)))\n\n    @assert length(get_components(typeof(gen), sys)) > 0\n    remove_components!(sys, typeof(gen))\n    @test_throws(IS.ArgumentError, remove_components!(sys, typeof(gen)))\n\n    remove_components!(sys, Area)\n    @test isempty(get_components(Area, sys))\n    @test isnothing(get_area(collect(get_components(ACBus, sys))[1]))\nend\n\n@testset \"Test missing Arc bus\" begin\n    sys = System(100.0)\n    line = Line(nothing)\n    @test_throws(IS.ArgumentError, add_component!(sys, line))\nend\n\n@testset \"Test frequency set\" begin\n    sys = System(100; frequency = 50.0)\n    @test get_frequency(sys) == 50.0\nend\n\n@testset \"Test exported names\" begin\n    @test IS.validate_exported_names(PowerSystems)\nend\n\n@testset \"Test system ext\" begin\n    sys = System(100.0)\n    ext = get_ext(sys)\n    ext[\"data\"] = 2\n    @test get_ext(sys)[\"data\"] == 2\n    clear_ext!(sys)\n    @test isempty(get_ext(sys))\nend\n\n@testset \"Test system checks\" begin\n    sys = System(100.0)\n    @test_logs (:warn, r\"There are no .* Components in the System\") match_mode = :any check(\n        sys,\n    )\nend\n\n@testset \"Test system units\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    set_units_base_system!(sys, \"DEVICE_BASE\")\n    @test get_units_base(sys) == \"DEVICE_BASE\"\n    set_units_base_system!(sys, \"SYSTEM_BASE\")\n    @test get_units_base(sys) == \"SYSTEM_BASE\"\n\n    gen = get_component(ThermalStandard, sys, \"322_CT_6\")\n    active_power_mw = with_units_base(sys, UnitSystem.NATURAL_UNITS) do\n        get_active_power(gen)\n    end\n    @test get_units_base(sys) == \"SYSTEM_BASE\"\n    set_units_base_system!(sys, UnitSystem.NATURAL_UNITS)\n    @test active_power_mw == get_active_power(gen)\nend\n\n@testset \"Test with_units_base on component\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    set_units_base_system!(sys, \"SYSTEM_BASE\")\n    gen = get_component(ThermalStandard, sys, \"322_CT_6\")\n    base_power = get_base_power(sys)\n\n    # Component shares system's units_settings initially\n    @test sys.units_settings === PSY.get_internal(gen).units_info\n\n    # with_units_base on component should work and preserve reference after\n    P_pu = get_active_power(gen)\n    P_natural = with_units_base(gen, \"NATURAL_UNITS\") do\n        get_active_power(gen)\n    end\n    @test P_natural ≈ P_pu * base_power\n\n    # Reference should be preserved after with_units_base(component, ...)\n    @test sys.units_settings === PSY.get_internal(gen).units_info\n\n    # System-level with_units_base should still work after component-level call\n    P_natural_via_sys = with_units_base(sys, UnitSystem.NATURAL_UNITS) do\n        get_active_power(gen)\n    end\n    @test P_natural ≈ P_natural_via_sys\nend\n\n@testset \"Test with_units_base on component removed during block\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    set_units_base_system!(sys, \"SYSTEM_BASE\")\n    line = first(get_components(Line, sys))\n\n    # Component shares system's units_settings initially\n    @test sys.units_settings === PSY.get_internal(line).units_info\n\n    # Remove component during with_units_base block\n    @test_throws ErrorException begin\n        with_units_base(line, \"NATURAL_UNITS\") do\n            remove_component!(sys, line)\n        end\n    end\n\n    # After removal, units_info should be nothing (not restored to system's)\n    @test isnothing(PSY.get_internal(line).units_info)\nend\n\n@testset \"Test add_time_series multiple components\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    components = []\n    len = 2\n    for i in 1:len\n        gen = ThermalStandard(nothing)\n        gen.name = string(i)\n        gen.bus = bus\n        add_component!(sys, gen)\n        push!(components, gen)\n    end\n\n    initial_time = Dates.DateTime(\"2020-01-01T00:00:00\")\n    end_time = Dates.DateTime(\"2020-01-01T23:00:00\")\n    dates = collect(initial_time:Dates.Hour(1):end_time)\n    data = collect(1:24)\n    ta = TimeSeries.TimeArray(dates, data, [\"1\"])\n    name = \"max_active_power\"\n    ts = SingleTimeSeries(; name = name, data = ta)\n    res = add_time_series!(sys, components, ts)\n\n    for i in 1:len\n        component = get_component(ThermalStandard, sys, string(i))\n        ts = get_time_series(SingleTimeSeries, component, name)\n        @test ts isa SingleTimeSeries\n    end\nend\n\n@testset \"Test bulk add of time series\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    components = []\n    len = 2\n    component = ThermalStandard(nothing)\n    component.name = \"gen\"\n    component.bus = bus\n    add_component!(sys, component)\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    resolution = Dates.Hour(1)\n    len = 24\n    timestamps = range(initial_time; length = len, step = resolution)\n    arrays = [TimeSeries.TimeArray(timestamps, rand(len)) for _ in 1:5]\n    ts_name = \"test\"\n\n    open_time_series_store!(sys, \"r+\") do\n        for (i, ta) in enumerate(arrays)\n            ts = SingleTimeSeries(; data = ta, name = \"$(ts_name)_$(i)\")\n            add_time_series!(sys, component, ts)\n        end\n    end\n\n    open_time_series_store!(sys, \"r\") do\n        for (i, expected_array) in enumerate(arrays)\n            ts = IS.get_time_series(IS.SingleTimeSeries, component, \"$(ts_name)_$(i)\")\n            @test ts.data == expected_array\n        end\n    end\nend\n\n@testset \"Test begin_time_series_update\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    components = []\n    len = 2\n    component = ThermalStandard(nothing)\n    component.name = \"gen\"\n    component.bus = bus\n    add_component!(sys, component)\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    resolution = Dates.Hour(1)\n    len = 24\n    timestamps = range(initial_time; length = len, step = resolution)\n    arrays = [TimeSeries.TimeArray(timestamps, rand(len)) for _ in 1:5]\n    ts_name = \"test\"\n\n    begin_time_series_update(sys) do\n        for (i, ta) in enumerate(arrays)\n            ts = SingleTimeSeries(; data = ta, name = \"$(ts_name)_$(i)\")\n            add_time_series!(sys, component, ts)\n        end\n    end\n\n    open_time_series_store!(sys, \"r\") do\n        for (i, expected_array) in enumerate(arrays)\n            ts = IS.get_time_series(IS.SingleTimeSeries, component, \"$(ts_name)_$(i)\")\n            @test ts.data == expected_array\n        end\n    end\nend\n\n@testset \"Test set_name! of system component\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    set_name!(sys, bus, \"new_name\")\n    @test get_component(ACBus, sys, \"new_name\") === bus\n\n    @test_throws ErrorException set_name!(bus, \"new_name2\")\n    remove_component!(sys, bus)\n    set_name!(bus, \"new_name2\")\n    @test get_name(bus) == \"new_name2\"\nend\n\n@testset \"Test forecast parameters\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.name = \"gen\"\n    gen.bus = bus\n    add_component!(sys, gen)\n\n    resolution = Dates.Hour(1)\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    second_time = initial_time + resolution\n    name = \"test\"\n    horizon = Hour(24)\n    horizon_count = 24\n    data =\n        SortedDict(initial_time => ones(horizon_count), second_time => ones(horizon_count))\n\n    forecast = Deterministic(; data = data, name = name, resolution = resolution)\n    add_time_series!(sys, gen, forecast)\n\n    @test get_time_series_resolutions(sys)[1] == resolution\n    @test get_forecast_horizon(sys) == horizon\n    @test get_forecast_initial_timestamp(sys) == initial_time\n    @test get_forecast_interval(sys) == Dates.Millisecond(second_time - initial_time)\n    @test get_forecast_window_count(sys) == 2\n    @test get_forecast_initial_times(sys) == [initial_time, second_time]\n\n    remove_time_series!(sys, typeof(forecast), gen, get_name(forecast))\n    @test_throws ArgumentError get_time_series(typeof(forecast), gen, get_name(forecast))\nend\n\n@testset \"Test multi-interval DeterministicSingleTimeSeries\" begin\n    sys = System(100.0)\n    bus = ACBus(nothing)\n    bus.bustype = ACBusTypes.REF\n    add_component!(sys, bus)\n    gen = ThermalStandard(nothing)\n    gen.name = \"gen\"\n    gen.bus = bus\n    add_component!(sys, gen)\n\n    initial_time = Dates.DateTime(\"2020-09-01\")\n    resolution = Dates.Minute(5)\n    sts_length = 288  # 24 hours at 5-min resolution\n    data = TimeSeries.TimeArray(\n        range(initial_time; length = sts_length, step = resolution),\n        rand(sts_length),\n    )\n    sts_name = \"max_active_power\"\n    sts = SingleTimeSeries(; data = data, name = sts_name)\n    add_time_series!(sys, gen, sts)\n\n    horizon = Dates.Hour(1)\n    interval1 = Dates.Minute(30)\n    interval2 = Dates.Hour(1)\n\n    transform_single_time_series!(\n        sys,\n        horizon,\n        interval1;\n        delete_existing = false,\n    )\n    transform_single_time_series!(\n        sys,\n        horizon,\n        interval2;\n        delete_existing = false,\n    )\n\n    @test has_time_series(\n        gen,\n        DeterministicSingleTimeSeries,\n        sts_name;\n        interval = interval1,\n    )\n    @test has_time_series(\n        gen,\n        DeterministicSingleTimeSeries,\n        sts_name;\n        interval = interval2,\n    )\n\n    ts1 = get_time_series(\n        DeterministicSingleTimeSeries,\n        gen,\n        sts_name;\n        interval = interval1,\n    )\n    @test ts1 isa DeterministicSingleTimeSeries\n    @test IS.get_interval(ts1) == interval1\n\n    ts2 = get_time_series(\n        DeterministicSingleTimeSeries,\n        gen,\n        sts_name;\n        interval = interval2,\n    )\n    @test ts2 isa DeterministicSingleTimeSeries\n    @test IS.get_interval(ts2) == interval2\n\n    @test_throws ArgumentError get_time_series(\n        DeterministicSingleTimeSeries,\n        gen,\n        sts_name,\n    )\n\n    @test get_forecast_interval(sys; interval = interval1) == interval1\n    @test get_forecast_interval(sys; interval = interval2) == interval2\n    @test get_forecast_horizon(sys; interval = interval1) == horizon\n    @test get_forecast_window_count(sys; interval = interval1) > 0\n    @test get_forecast_window_count(sys; interval = interval2) > 0\n\n    ts_interval1 = collect(\n        get_time_series_multiple(\n            sys;\n            type = DeterministicSingleTimeSeries,\n            interval = interval1,\n        ),\n    )\n    @test length(ts_interval1) > 0\n    for ts in ts_interval1\n        @test IS.get_interval(ts) == interval1\n    end\n\n    remove_time_series!(\n        sys,\n        DeterministicSingleTimeSeries,\n        gen,\n        sts_name;\n        interval = interval1,\n    )\n    @test !has_time_series(\n        gen,\n        DeterministicSingleTimeSeries,\n        sts_name;\n        interval = interval1,\n    )\n    @test has_time_series(\n        gen,\n        DeterministicSingleTimeSeries,\n        sts_name;\n        interval = interval2,\n    )\n\n    @test has_time_series(gen, SingleTimeSeries, sts_name)\nend\n\n@testset \"Invalid constructor\" begin\n    @test_throws IS.DataFormatError System(\"data.invalid\")\nend\n\n@testset \"Test deepcopy with runchecks\" begin\n    sys = System(100.0)\n    @test get_runchecks(sys)\n    @test get_runchecks(deepcopy(sys))\nend\n\n@testset \"Test deepcopy with runchecks disabled\" begin\n    sys = System(100.0; runchecks = false)\n    @test !get_runchecks(sys)\n    sys2 = deepcopy(sys)\n    @test sys2 isa System\n    @test !get_runchecks(sys)\nend\n\n@testset \"Test deepcopy with custom time_series_directory\" begin\n    ts_dir = mktempdir()\n    sys = System(100.0; time_series_directory = ts_dir)\n    sys2 = deepcopy(sys)\n    @test dirname(sys2.data.time_series_manager.data_store.file_path) == ts_dir\nend\n\n@testset \"Test time series counts\" begin\n    # The system has both single and deterministic forecasts time series\n    c_sys5 = PSB.build_system(\n        PSITestSystems,\n        \"c_sys5_uc\";\n        add_forecasts = true,\n        skip_serialization = true,\n    )\n    counts = get_time_series_counts(c_sys5)\n    @test counts.static_time_series_count == 0\n    @test counts.forecast_count == 3\n\n    # The system has both single and deterministic forecasts time series\n    c_sys5 = PSB.build_system(\n        PSITestSystems,\n        \"c_sys5_uc\";\n        add_single_time_series = true,\n        skip_serialization = true,\n    )\n    counts = get_time_series_counts(c_sys5)\n    @test counts.static_time_series_count == 3\n    @test counts.forecast_count == 0\nend\n\n@testset \"Test deepcopy with time series options\" begin\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"test_RTS_GMLC_sys\";\n        time_series_in_memory = true,\n        force_build = true,\n    )\n    @test sys.data.time_series_manager.data_store isa IS.InMemoryTimeSeriesStorage\n    sys2 = deepcopy(sys)\n    @test sys2.data.time_series_manager.data_store isa IS.InMemoryTimeSeriesStorage\n    @test IS.compare_values(sys, sys2)\n    # Ensure that the storage references got updated correctly.\n    for component in get_components(x -> has_time_series(x), Component, sys2)\n        @test component.internal.shared_system_references.time_series_manager ===\n              sys2.data.time_series_manager\n    end\n\n    sys = PSB.build_system(\n        PSITestSystems,\n        \"test_RTS_GMLC_sys\";\n        time_series_in_memory = false,\n        force_build = true,\n    )\n    @test sys.data.time_series_manager.data_store isa IS.Hdf5TimeSeriesStorage\n    sys2 = deepcopy(sys)\n    @test sys2.data.time_series_manager.data_store isa IS.Hdf5TimeSeriesStorage\n    @test sys.data.time_series_manager.data_store.file_path !=\n          sys2.data.time_series_manager.data_store.file_path\n    @test IS.compare_values(sys, sys2)\n    for component in get_components(x -> has_time_series(x), Component, sys2)\n        @test component.internal.shared_system_references.time_series_manager ===\n              sys2.data.time_series_manager\n    end\nend\n\n@testset \"Test fast deepcopy of system\" begin\n    systems = Dict(\n        in_memory => PSB.build_system(\n            PSITestSystems,\n            \"test_RTS_GMLC_sys\";\n            time_series_in_memory = in_memory,\n            force_build = true,\n        ) for in_memory in (true, false)\n    )\n    @testset for (in_memory, skip_ts, skip_sa) in  # Iterate over all permutations\n                 Iterators.product(repeat([(true, false)], 3)...)\n        sys = systems[in_memory]\n\n        sys2 = IS.fast_deepcopy_system(sys;\n            skip_time_series = skip_ts, skip_supplemental_attributes = skip_sa)\n        @test IS.compare_values(\n            sys,\n            sys2;\n            exclude = Set(\n                [:time_series_manager, :supplemental_attribute_manager][[skip_ts, skip_sa]],\n            ),\n        )\n\n        # We copy the SystemData separately from the other System fields, so the egal-ity of these references could get broken\n        generator = get_component(ThermalStandard, sys2, \"322_CT_6\")\n        @test sys2.units_settings === generator.internal.units_info\n    end\nend\n\n@testset \"Test with compression enabled\" begin\n    @test get_compression_settings(System(100.0)) == CompressionSettings(; enabled = false)\n\n    settings = CompressionSettings(; enabled = true, type = CompressionTypes.BLOSC)\n    @test get_compression_settings(System(100.0; compression = settings)) == settings\n    @test get_compression_settings(System(100.0; enable_compression = true)) ==\n          CompressionSettings(; enabled = true)\nend\n\n@testset \"Test compare_values\" begin\n    sys1 = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    sys2 = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    gen1 = first(get_components(ThermalStandard, sys1))\n    gen2 = first(get_components(ThermalStandard, sys2))\n    @test IS.compare_values(gen1, gen2)\n    @test IS.compare_values(sys1, sys2)\n\n    set_active_power!(gen1, get_active_power(gen1) + 0.1)\n    @test(\n        @test_logs(\n            (:error, r\"not match\"),\n            match_mode = :any,\n            !IS.compare_values(gen1, gen2),\n        )\n    )\n    @test(\n        @test_logs(\n            (:error, r\"not match\"),\n            match_mode = :any,\n            !IS.compare_values(sys1, sys2)\n        )\n    )\n\n    my_match_fn(a::Float64, b::Float64) =\n        isapprox(a, b; atol = 0.2) || IS.isequivalent(a, b)\n    my_match_fn(a, b) = IS.isequivalent(a, b)\n    @test IS.compare_values(my_match_fn, gen1, gen2)\n    @test IS.compare_values(my_match_fn, sys1, sys2)\nend\n\n@testset \"Test check_components\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    check_components(sys)\n    check_components(sys, Component)\n    check_components(sys, Generator)\n    check_components(sys, ThermalStandard)\n    check_components(sys, get_components(ThermalStandard, sys))\n    components = get_components(ThermalStandard, sys)\n    gen = first(components)\n    check_components(sys, components)\n    check_component(sys, gen)\n\n    # Invalid Bus base_voltage values throw errors.\n    # Invalid ThermalStandard active_power logs warning messages.\n\n    bus = first(get_components(ACBus, sys))\n    check_component(sys, bus)\n    orig = get_base_voltage(bus)\n    set_base_voltage!(bus, -1.0)\n    try\n        @test_logs(\n            (:error, \"Invalid range\"),\n            match_mode = :any,\n            @test_throws IS.InvalidValue check_component(sys, bus)\n        )\n    finally\n        set_base_voltage!(bus, orig)\n    end\n\n    gen.active_power = 100.0\n    @test_logs :warn, \"Invalid range\" match_mode = :any check_component(sys, gen)\n    @test_logs :warn, \"Invalid range\" match_mode = :any check_components(\n        sys,\n        ThermalStandard,\n    )\n\n    # @test !(@test_logs :warn, r\"is larger than the max expected in the\" match_mode = :any check_ac_transmission_rate_values(\n    #     sys,\n    # ))\n    @test check_ac_transmission_rate_values(sys)\nend\n\n@testset \"Test system name and description\" begin\n    name = \"test_system\"\n    description = \"a system description\"\n    sys = System(100.0)\n    @test get_name(sys) === nothing\n    @test get_description(sys) === nothing\n    set_name!(sys, name)\n    set_description!(sys, description)\n\n    sys = System(100.0; name = name, description = description)\n    @test get_name(sys) == name\n    @test get_description(sys) == description\nend\n\n@testset \"Test system metadata\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    name = \"test_system\"\n    description = \"a system description\"\n    set_name!(sys, name)\n    set_description!(sys, description)\n\n    tempdir = mktempdir()\n    sys_file = joinpath(tempdir, \"sys.json\")\n    to_json(sys, sys_file; user_data = Dict(\"author\" => \"test\"))\n\n    sys2 = System(sys_file)\n    @test get_name(sys2) == name\n    @test get_description(sys2) == description\n\n    metadata_file = joinpath(tempdir, \"sys_metadata.json\")\n    metadata = open(metadata_file) do io\n        JSON3.read(io, Dict)\n    end\n\n    @test metadata[\"name\"] == name\n    @test metadata[\"description\"] == description\n    found_component_thermal = false\n    found_component_condenser = false\n    for item in metadata[\"component_counts\"]\n        if item[\"type\"] == \"ThermalStandard\"\n            @test item[\"count\"] == 73\n            found_component_thermal = true\n        end\n        if item[\"type\"] == \"SynchronousCondenser\"\n            @test item[\"count\"] == 3\n            found_component_condenser = true\n        end\n    end\n    @test found_component_thermal\n    @test found_component_condenser\n    @test metadata[\"time_series_counts\"][1][\"type\"] == \"DeterministicSingleTimeSeries\"\n    @test metadata[\"time_series_counts\"][1][\"count\"] == 182\n    @test metadata[\"time_series_counts\"][2][\"type\"] == \"SingleTimeSeries\"\n    @test metadata[\"time_series_counts\"][2][\"count\"] == 182\n    @test metadata[\"user_data\"][\"author\"] == \"test\"\nend\n\n@testset \"Test addition of service to the wrong system\" begin\n    sys1 = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    sys2 = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    service1 = first(get_components(VariableReserve{ReserveDown}, sys1))\n    device2 = first(get_components(ThermalStandard, sys2))\n    @test_throws ArgumentError add_service!(device2, service1, sys2)\nend\n\n@testset \"Test has_components\" begin\n    sys1 = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    @test has_components(sys1, ThermalStandard)\n    @test !has_components(sys1, TransmissionInterface)\nend\n\n@testset \"Test set_bus_number!\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\")\n    buses = collect(get_components(ACBus, sys))\n    bus1 = buses[1]\n    bus2 = buses[2]\n    orig = get_number(bus1)\n    new_number = 9999999\n    @test orig != new_number\n    set_bus_number!(sys, bus1, new_number)\n    @test get_number(bus1) == new_number\n    bus_numbers = get_bus_numbers(sys)\n    @test new_number in bus_numbers\n    @test !(orig in bus_numbers)\n\n    # Ensure that the no-op case works.\n    set_bus_number!(sys, bus1, new_number)\n    @test get_number(bus1) == new_number\n    @test new_number in get_bus_numbers(sys)\n\n    # Ensure that duplicate numbers are blocked.\n    @test_throws ArgumentError set_bus_number!(sys, bus1, get_number(bus2))\n\n    # Ensure that you can't change an unattached bus.\n    remove_component!(sys, bus1)\n    @test_throws ArgumentError set_bus_number!(sys, bus1, new_number + 1)\n\n    # Ensure that this is exported. This can be deleted in PSY5.\n    set_number!(bus1, new_number + 2)\n    @test get_number(bus1) == new_number + 2\nend\n"
  },
  {
    "path": "test/test_topology.jl",
    "content": "\nfunction get_expected_buses(::Type{T}, sys::System) where {T <: AggregationTopology}\n    expected_buses = Dict{String, Vector{String}}()\n    for bus in get_components(ACBus, sys)\n        agg = get_aggregation_topology_accessor(T)(bus)\n        name = get_name(agg)\n        if !haskey(expected_buses, name)\n            expected_buses[name] = Vector{String}()\n        end\n        push!(expected_buses[name], get_name(bus))\n    end\n\n    return expected_buses\nend\n\nfunction test_aggregation_topologies(sys::System, expected_areas, expected_zones)\n    expected_buses_by_area = get_expected_buses(Area, sys)\n    expected_buses_by_zone = get_expected_buses(LoadZone, sys)\n\n    areas = collect(get_components(Area, sys))\n    @test length(areas) == expected_areas\n    area_mapping = get_aggregation_topology_mapping(Area, sys)\n    for area in areas\n        area_name = get_name(area)\n        buses = sort!([get_name(x) for x in get_buses(sys, area)])\n        @test buses == sort(expected_buses_by_area[area_name])\n        @test buses == sort!([get_name(x) for x in area_mapping[area_name]])\n    end\n\n    zones = collect(get_components(LoadZone, sys))\n    zone_mapping = get_aggregation_topology_mapping(LoadZone, sys)\n    @test length(zones) == expected_zones\n    for zone in zones\n        zone_name = get_name(zone)\n        buses = sort!([get_name(x) for x in get_buses(sys, zone)])\n        @test buses == sort(expected_buses_by_zone[zone_name])\n        @test buses == sort!([get_name(x) for x in zone_mapping[zone_name]])\n    end\nend\n\n@testset \"Test topology mappings\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    test_aggregation_topologies(sys, 3, 3)\nend\n\n@testset \"Test PM areas and load zones\" begin\n    sys = PSB.build_system(MatpowerTestSystems, \"matpower_RTS_GMLC_sys\")\n    test_aggregation_topologies(sys, 3, 21)\nend\n\n@testset \"Test get_components_in_aggregation_topology and is_component_in_aggregation_topology\" begin\n    sys = PSB.build_system(PSITestSystems, \"test_RTS_GMLC_sys\"; add_forecasts = false)\n    areas = collect(get_components(Area, sys))\n    @test !isempty(areas)\n    zones = collect(get_components(LoadZone, sys))\n    @test !isempty(zones)\n\n    for (agg, accessor) in [(first(areas), get_area), (first(zones), get_load_zone)]\n        all_generators = get_components(ThermalStandard, sys)\n        in_generators = get_components_in_aggregation_topology(ThermalStandard, sys, agg)\n        covered_in = covered_out = false  # Invalid test if agg is empty or includes everything\n\n        for gen in all_generators\n            bus = get_bus(gen)\n            if gen in in_generators\n                @test IS.get_uuid(accessor(bus)) == IS.get_uuid(agg)\n                @test is_component_in_aggregation_topology(gen, agg)\n                covered_in = true\n            else\n                @test IS.get_uuid(accessor(bus)) != IS.get_uuid(agg)\n                @test !is_component_in_aggregation_topology(gen, agg)\n                covered_out = true\n            end\n        end\n        @test covered_in && covered_out\n    end\nend\n"
  },
  {
    "path": "test/test_validation.jl",
    "content": "import YAML\n\nconst WRONG_FORMAT_CONFIG_FILE =\n    joinpath(dirname(pathof(PowerSystems)), \"descriptors\", \"config.yml\")\n\n@testset \"Test reading in config data\" begin\n    data = IS.read_validation_descriptor(PSY.POWER_SYSTEM_STRUCT_DESCRIPTOR_FILE)\n    @test data isa Vector\n    @test !isempty(data)\n    function find_struct()\n        for item in data\n            if item[\"struct_name\"] == \"ThermalStandard\"\n                return true\n            end\n        end\n        return false\n    end\n    @test find_struct()\n    @test_throws(ErrorException, IS.read_validation_descriptor(\"badfile.toml\"))\nend\n\n@testset \"Test adding custom validation YAML file to System\" begin\n    nodes = nodes5()\n    sys_no_config =\n        System(100.0, nodes, thermal_generators5(nodes), loads5(nodes); runchecks = true)\n    @test !isempty(sys_no_config.data.validation_descriptors)\n\n    nodes = nodes5()\n    sys_no_runchecks =\n        System(100.0, nodes, thermal_generators5(nodes), loads5(nodes); runchecks = false)\n    @test !isempty(sys_no_runchecks.data.validation_descriptors)\nend\n\n@testset \"Test extracting struct info from validation_descriptor vector\" begin\n    data = [\n        Dict(\n            \"fields\" => Dict{Any, Any}[\n                Dict(\n                    \"name\" => \"curtailpenalty\",\n                    \"valid_range\" => Dict{Any, Any}(\"max\" => nothing, \"min\" => 0.0),\n                ),\n                Dict(\n                    \"name\" => \"variablecost\",\n                    \"valid_range\" => Dict{Any, Any}(\"max\" => nothing, \"min\" => 0.0),\n                ),\n                Dict(\"name\" => \"internal\"),\n            ],\n            \"struct_name\" => \"EconHydro\",\n        ),\n        Dict(\n            \"fields\" => Dict{Any, Any}[\n                Dict(\n                    \"name\" => \"curtailpenalty\",\n                    \"valid_range\" => Dict{Any, Any}(\"max\" => nothing, \"min\" => 0.0),\n                ),\n                Dict(\n                    \"name\" => \"variablecost\",\n                    \"valid_range\" => Dict{Any, Any}(\"max\" => nothing, \"min\" => 0.0),\n                ),\n                Dict(\"name\" => \"internal\"),\n            ],\n            \"struct_name\" => \"EconLoad\",\n        ),\n    ]\n    struct_name = \"EconHydro\"\n    descriptor = IS.get_config_descriptor(data, struct_name)\n    @test descriptor isa Dict{String, Any}\n    @test haskey(descriptor, \"struct_name\")\n    @test haskey(descriptor, \"fields\")\n    @test descriptor[\"struct_name\"] == struct_name\nend\n\n@testset \"Test extracting field info from struct descriptor dictionary\" begin\n    config = Dict{Any, Any}(\n        \"fields\" => Dict{Any, Any}[\n            Dict(\"name\" => \"name\", \"data_type\" => \"String\"),\n            Dict(\"name\" => \"available\", \"data_type\" => \"Bool\"),\n            Dict(\"name\" => \"bus\", \"data_type\" => \"ACBus\"),\n            Dict(\"name\" => \"tech\", \"data_type\" => \"Union{Nothing, TechThermal}\"),\n            Dict(\"name\" => \"econ\", \"data_type\" => \"Union{Nothing, EconThermal}\"),\n            Dict(\"name\" => \"internal\", \"data_type\" => \"IS.InfrastructureSystemsInternal\"),\n        ],\n        \"struct_name\" => \"ThermalStandard\",\n    )\n    field_name = \"econ\"\n    field_descriptor = IS.get_field_descriptor(config, field_name)\n    @test field_descriptor isa Dict{Any, Any}\n    @test haskey(field_descriptor, \"name\")\n    @test field_descriptor[\"name\"] == field_name\nend\n\n@testset \"Test retrieving validation action\" begin\n    warn_descriptor = Dict{Any, Any}(\n        \"name\" => \"ramp_limits\",\n        \"valid_range\" => Dict{Any, Any}(\"max\" => 5, \"min\" => 0),\n        \"validation_action\" => \"warn\",\n    )\n    error_descriptor = Dict{Any, Any}(\n        \"name\" => \"ramp_limits\",\n        \"valid_range\" => Dict{Any, Any}(\"max\" => 5, \"min\" => 0),\n        \"validation_action\" => \"error\",\n    )\n    typo_descriptor = Dict{Any, Any}(\n        \"name\" => \"ramp_limits\",\n        \"valid_range\" => Dict{Any, Any}(\"max\" => 5, \"min\" => 0),\n        \"validation_action\" => \"asdfasdfsd\",\n    )\n    @test IS.get_validation_action(warn_descriptor) == IS.validation_warning\n    @test IS.get_validation_action(error_descriptor) == IS.validation_error\n    @test_throws(ErrorException, IS.get_validation_action(typo_descriptor))\nend\n\n@testset \"Test field validation\" begin\n    #test recursive call of validate_fields and a regular valid range\n    nodes = nodes5()\n    bad_therm_gen_rating = thermal_generators5(nodes)\n    bad_therm_gen_rating[1].rating = -10\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        @test_throws(\n            PSY.InvalidValue,\n            System(100.0, nodes, bad_therm_gen_rating, loads5(nodes); runchecks = true)\n        )\n    )\n\n    #test custom range (active_power and active_power_limits)\n    nodes = nodes5()\n    bad_therm_gen_act_power = thermal_generators5(nodes)\n    bad_therm_gen_act_power[1].active_power = 10\n    # This is an explicit check for one error message.\n    @test_logs (:warn, r\"Invalid range\") System(\n        100.0,\n        nodes,\n        bad_therm_gen_act_power,\n        loads5(nodes);\n        runchecks = true,\n    )\n\n    #test validating named tuple\n    nodes = nodes5()\n    bad_therm_gen_ramp_lim = thermal_generators5(nodes)\n    bad_therm_gen_ramp_lim[1].ramp_limits = (up = -10, down = -3)\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        match_mode = :any,\n        @test_throws(\n            PSY.InvalidValue,\n            System(100.0, nodes, bad_therm_gen_ramp_lim, loads5(nodes); runchecks = true)\n        )\n    )\nend\n\n@testset \"Test field validation\" begin\n    nodes = nodes5()\n    sys = System(100.0, nodes, thermal_generators5(nodes), loads5(nodes); runchecks = true)\n\n    add_component!(\n        sys,\n        ACBus(\n            11,\n            \"11\",\n            true,\n            ACBusTypes.PQ,\n            1,\n            1,\n            (min = 0.9, max = 1.1),\n            123,\n            nothing,\n            nothing,\n        ),\n    )\n    B = collect(get_components(ACBus, sys))\n    sort!(B, by = get_number)\n    a = Arc(B[1], B[6])\n    badline = Line(\n        \"badline\",\n        true,\n        0.01,\n        0.01,\n        a,\n        0.002,\n        0.014,\n        (from = 0.015, to = 0.015),\n        5.0,\n        (min = -1, max = 1),\n    )\n    @test_logs(\n        (:error, r\"cannot create Line\"),\n        match_mode = :any,\n        @test_throws(PSY.InvalidValue, add_component!(sys, badline))\n    )\nend\n\n# disabled until serialization is updated\n@testset \"Test field validation after deserialization\" begin\n    nodes = nodes5()\n    sys = System(100.0, nodes, thermal_generators5(nodes), loads5(nodes))\n\n    add_component!(\n        sys,\n        ACBus(\n            11,\n            \"11\",\n            true,\n            ACBusTypes.PQ,\n            1,\n            1,\n            (min = 0.9, max = 1.1),\n            123,\n            nothing,\n            nothing,\n        ),\n    )\n    path = joinpath(mktempdir(), \"test_validation.json\")\n    try\n        PSY.to_json(sys, path)\n    catch\n        rm(path)\n        rethrow()\n    end\n\n    try\n        sys2 = PSY.System(path)\n\n        B = collect(get_components(ACBus, sys2))\n        sort!(B, by = get_number)\n        a = Arc(B[1], B[6])\n        badline = Line(\n            \"badline\",\n            true,\n            0.01,\n            0.01,\n            a,\n            0.002,\n            0.014,\n            (from = 0.015, to = 0.015),\n            5.0,\n            (min = -1, max = 1),\n        )\n        @test_logs(\n            (:error, r\"cannot create Line\"),\n            match_mode = :any,\n            @test_throws(PSY.InvalidValue, add_component!(sys2, badline))\n        )\n    finally\n        rm(path)\n    end\nend\n\nfunction _make_bus()\n    return ACBus(;\n        number = 1,\n        name = \"bus1\",\n        available = true,\n        bustype = ACBusTypes.REF,\n        angle = 0.0,\n        magnitude = 0.0,\n        voltage_limits = (min = 0.0, max = 0.0),\n        base_voltage = nothing,\n        area = nothing,\n        load_zone = nothing,\n    )\nend\n\n@testset \"Test add_component with runchecks enabled\" begin\n    sys = System(100.0; runchecks = true)\n    @test get_runchecks(sys)\n    bus = _make_bus()\n    add_component!(sys, bus)\n    remove_component!(sys, bus)\n\n    # Make the bus invalid.\n    set_base_voltage!(bus, -1000.0)\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        match_mode = :any,\n        @test_throws IS.InvalidValue add_component!(sys, bus)\n    )\n\n    # Allowed with skip_validation.\n    add_component!(sys, bus; skip_validation = true)\n    @test !get_runchecks(sys)\nend\n\n@testset \"Test add_component with runchecks disabled\" begin\n    sys = System(100.0; runchecks = false)\n    bus = _make_bus()\n\n    # Make the bus invalid.\n    set_base_voltage!(bus, -1000.0)\n    add_component!(sys, bus)\nend\n\n@testset \"Test serialization and range checks\" begin\n    sys = System(100.0; runchecks = false)\n    bus = _make_bus()\n\n    # Make the bus invalid.\n    set_base_voltage!(bus, -1000.0)\n    add_component!(sys, bus)\n\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        match_mode = :any,\n        @test_throws(IS.InvalidValue, validate_serialization(sys, runchecks = true)),\n    )\nend\n\n@testset \"Test serialization and system checks\" begin\n    # Serialize/deserialize an invalid system.\n    sys = System(100.0; runchecks = false)\n    @test !get_runchecks(sys)\n    bus = _make_bus()\n    set_bustype!(bus, ACBusTypes.PQ)\n    add_component!(sys, bus)\n\n    @test_logs(\n        (:error, r\"Model doesn't contain a slack bus\"),\n        match_mode = :any,\n        validate_serialization(sys, runchecks = true)\n    )\n\n    sys, result = validate_serialization(sys; runchecks = false)\n    @test result\n    @test !get_runchecks(sys)\nend\n\n@testset \"Test runchecks\" begin\n    sys = System(100.0)\n    @test get_runchecks(sys)\n    sys = System(100.0; runchecks = false)\n    @test !get_runchecks(sys)\n    set_runchecks!(sys, true)\n    @test get_runchecks(sys)\n    set_runchecks!(sys, false)\n    @test !get_runchecks(sys)\nend\n\n@testset \"Test check_component\" begin\n    sys = System(100.0; runchecks = false)\n    bus = _make_bus()\n\n    # Make the bus invalid.\n    set_base_voltage!(bus, -1000.0)\n    add_component!(sys, bus)\n\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        match_mode = :any,\n        @test_throws(IS.InvalidValue, check_component(sys, bus)),\n    )\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        match_mode = :any,\n        @test_throws(IS.InvalidValue, check_components(sys)),\n    )\nend\n\n@testset \"Test check at serialization\" begin\n    nodes = nodes5()\n    bad_therm_gen_rating = thermal_generators5(nodes)\n    bad_therm_gen_rating[1].rating = -10\n    sys = System(100.0, nodes, bad_therm_gen_rating, loads5(nodes); runchecks = false)\n    @test_logs(\n        (:error, r\"Invalid range\"),\n        (:warn, r\"exceeds total capacity capability\"),\n        match_mode = :any,\n        @test_throws(\n            IS.InvalidValue,\n            to_json(sys, \"sys.json\", force = true, runchecks = true)\n        ),\n    )\nend\n"
  }
]