-
Notifications
You must be signed in to change notification settings - Fork 9
Feature/rename on off to status #500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
## Parameters Class (`OnOffParameters` → `StatusParameters`) | Current Name | Recommended Name | Rationale | |--------------|------------------|-----------| | `OnOffParameters` | **`StatusParameters`** | Aligns with PyPSA, clearer semantics | | `effects_per_switch_on` | **`effects_per_startup`** | Standard UC terminology | | `effects_per_running_hour` | **`effects_per_active_hour`** | Clear, concise, matches "active" state | | `on_hours_total_min` | **`active_hours_min`** | Total (not consecutive) active hours | | `on_hours_total_max` | **`active_hours_max`** | Total (not consecutive) active hours | | `consecutive_on_hours_min` | **`min_uptime`** | Standard UC term (consecutive) | | `consecutive_on_hours_max` | **`max_uptime`** | Standard UC term (consecutive) | | `consecutive_off_hours_min` | **`min_downtime`** | Standard UC term (consecutive) | | `consecutive_off_hours_max` | **`max_downtime`** | Standard UC term (consecutive) | | `switch_on_total_max` | **`startup_limit`** | Clearer intent, matches "startup" | | `force_switch_on` | **`force_startup_tracking`** | More explicit about what is forced | ## Model Class (`OnOffModel` → `StatusModel`) ### Class Name | Current Name | Recommended Name | |--------------|------------------| | `OnOffModel` | **`StatusModel`** | ### Constructor Parameters | Current Name | Recommended Name | Rationale | |--------------|------------------|-----------| | `on_variable` | **`status`** | Aligns with PyPSA and literature | | `previous_states` | **`previous_status`** | Consistency with status variable | ### Variables (short_name in add_variables/expression_tracking_variable) | Current Name | Recommended Name | Type | Notes | |--------------|------------------|------|-------| | `self.on` | **`self.status`** | Input variable | Main binary state variable | | `'off'` | **Remove variable** | Binary variable | Replace with expression `1 - status` | | `'switch\|on'` | **`'startup'`** | Binary variable | Startup event indicator | | `'switch\|off'` | **`'shutdown'`** | Binary variable | Shutdown event indicator | | `'switch\|count'` | **`'startup_count'`** | Integer variable | Number of startups | | `'on_hours_total'` | **`'active_hours'`** | Continuous variable | Total active duration | | `'consecutive_on_hours'` | **`'uptime'`** | Continuous variable | Consecutive active hours | | `'consecutive_off_hours'` | **`'downtime'`** | Continuous variable | Consecutive inactive hours | ### Properties | Current Name | Recommended Name | Returns | Meaning | |--------------|------------------|---------|---------| | `on_hours_total` | **`active_hours`** | `linopy.Variable` | Total active hours | | `off` | **Remove property** | — | Use `1 - status` expression | | `switch_on` | **`startup`** | `linopy.Variable \| None` | Startup events | | `switch_off` | **`shutdown`** | `linopy.Variable \| None` | Shutdown events | | `switch_on_nr` | **`startup_count`** | `linopy.Variable \| None` | Number of startups | | `consecutive_on_hours` | **`uptime`** | `linopy.Variable \| None` | Consecutive active hours | | `consecutive_off_hours` | **`downtime`** | `linopy.Variable \| None` | Consecutive inactive hours | ### Internal Methods | Current Name | Recommended Name | |--------------|------------------| | `_get_previous_on_duration()` | **`_get_previous_uptime()`** | | `_get_previous_off_duration()` | **`_get_previous_downtime()`** | ### Internal Properties/Flags (in parameters) | Current Name | Recommended Name | |--------------|------------------| | `use_off` | **Remove** (use expression instead) | | `use_switch_on` | **`use_startup_tracking`** | | `use_consecutive_on_hours` | **`use_uptime_tracking`** | | `use_consecutive_off_hours` | **`use_downtime_tracking`** | ## Constraint Names (short_name in add_constraints) | Current Name | Recommended Name | |--------------|------------------| | `'complementary'` | **Remove** (no off variable) | | `'on_hours_total'` | **`'active_hours'`** | | `'switch\|on'`, `'switch\|off'` | **`'startup'`, `'shutdown'`** | | `'switch\|count'` | **`'startup_count'`** | | `'consecutive_on_hours'` | **`'uptime'`** | | `'consecutive_off_hours'` | **`'downtime'`** | ## Complete Terminology Summary (Option A) **State:** - `status` (binary): 1 = active, 0 = inactive **Events:** - `startup` (binary): transition from inactive to active - `shutdown` (binary): transition from active to inactive **Durations:** - `active_hours` (continuous): **total** hours in active state across time horizon - `uptime` (continuous): **consecutive** hours currently active (UC standard) - `downtime` (continuous): **consecutive** hours currently inactive (UC standard) **Parameter Bounds:** - `active_hours_min/max`: limits on **total** active hours - `min_uptime/max_uptime`: limits on **consecutive** active hours (UC standard) - `min_downtime/max_downtime`: limits on **consecutive** inactive hours (UC standard) - `startup_limit`: maximum number of startup events **Effects:** - `effects_per_startup`: costs/impacts per startup event - `effects_per_active_hour`: costs/impacts per active hour This aligns perfectly with PyPSA and the unit commitment literature! 🎯
1. interface.py - Module docstring now references "Status decisions"
2. components.py - Updated all docstrings:
- status_parameters parameter descriptions
- Example code updated with new parameter names (effects_per_startup, min_uptime, startup_limit)
- Fixed incorrect "OnOff feature" docstring to "Investment feature"
- Updated TODO comment to reference StatusParameters
3. linear_converters.py - All docstrings updated:
- Import statement updated to StatusParameters
- All parameter descriptions updated
- All example code updated with new terminology
4. flow_system.py - Updated references from "consecutive_on_hours" to "uptime and downtime" and on_off_parameters to status_parameters
5. modeling.py - Updated docstring from "switch-on/off variables" to "state transition constraints for binary switching variables"
Documentation Markdown Files Updated:
1. Flow.md - All references updated:
- Links to StatusParameters
- "on/off state" → "active/inactive state"
- Parameter names updated
2. StatusParameters.md (renamed from OnOffParameters.md) - Comprehensive updates:
- Title changed to "StatusParameters"
- All terminology updated: on/off → active/inactive
- Mathematical notation updated: s^on/s^off → s^startup/s^shutdown
- Duration variables: d^on/d^off → d^uptime/d^downtime
- Parameter names updated in all examples
- All Python code examples updated with new API
3. Other modeling pattern docs - Updated all references to StatusParameters and active/inactive terminology
4. mkdocs.yml - Navigation updated to reference StatusParameters.md
All docstrings and documentation now consistently use the new Status terminology aligned with PyPSA and unit commitment standards!
Changes Made:
1. Fixed error message in modeling.py
- Corrected ModelingPrimitives.state_transition_bounds() → BoundingPatterns.state_transition_bounds() in error message (flixopt/modeling.py:591)
2. Fixed Transmission type hint (flixopt/components.py:667)
- Changed status_parameters: StatusParameters = None → status_parameters: StatusParameters | None = None
3. Fixed absolute_losses=0 edge case (flixopt/components.py:768)
- Added np.any(self.element.absolute_losses != 0) check in create_transmission_equation to match the initialization logic
- This prevents AttributeError when absolute_losses is explicitly set to 0
4. Updated test assertion messages (tests/test_component.py)
- Changed "On does not work properly" → "Status does not work properly"
5. Fixed effects_per_startup type (examples/02_Complex/complex_example.py)
- Changed scalar effects_per_startup=0.01 → dict effects_per_startup={Costs.label: 0.01} in all 3 occurrences
- Now consistent with the StatusParameters API which expects a dict mapping effect names to values
6. Updated test_functional.py docstring
- Removed reference to non-existent TestStatus class
- Updated to accurately describe the status-related test functions
7. Consistent unbounded upper bounds (flixopt/features.py:191)
- Changed np.inf → None for unbounded active_hours_max
- Now consistent with FlowModel's total_flow_hours pattern
All changes maintain backward compatibility and align with the codebase's existing patterns. The documentation in index.md was already correct (BoundingPatterns is
the right class for state_transition_bounds).
1. CHANGELOG.md - Fixed parameter rename documentation (lines 89-90) - Changed incorrect status_parameters → status_parameters - To correct: on_off_parameters → status_parameters 2. CHANGELOG.md - Removed duplicate logger warning (line 803 in v2.1.0) - Removed duplicate entry that was already documented in v2.0.1 - Fixed v2.0.1 entry to say on_off_parameters (the name at that time) 3. StatusParameters.md - Aligned flow bounds formulation (line 229) - Updated summary to include max(ε, rel_lower) like the main text - Now consistent: s(t) · P · max(ε, rel_lower) ≤ p(t) ≤ s(t) · P · rel_upper 4. features.py - Narrowed previous_status type hint (line 155) - Changed from Numeric_TPS | None to xr.DataArray | None - Added import xarray as xr (line 12) - This accurately reflects that _get_previous_uptime() and _get_previous_downtime() use xarray APIs All changes are verified to compile correctly and maintain consistency with the codebase patterns!
1. Constraint naming in tests (tests/test_component.py:126-127, 158, 168,
338, 348):
- Updated test expectations from 'TestComponent|on|lb' and
'TestComponent|on|ub' to 'TestComponent|status|lb' and
'TestComponent|status|ub' to match the actual constraint names
2. Added 'off' property to StatusModel (flixopt/features.py:284-287):
- Added a new property that returns 1 - self.status for backward
compatibility with tests expecting an off attribute
3. Fixed deprecated parameter name (tests/test_functional.py:435):
- Changed force_switch_on=True to force_startup_tracking=True in
StatusParameters
4. Fixed property name (tests/test_functional.py:466):
- Changed switch_off to shutdown to match the actual property name in
StatusModel
switch_on -> activate switch_off -> deactivate
switch_on -> activate switch_off -> deactivate state_variable -> state
switch_on -> activate switch_off -> deactivate state_variable -> state
✅ All Parameters Now Documented
Each primitive now has complete parameter documentation with:
- Clear description of what each parameter does
- Type expectations
- Default values where applicable
✅ Focused on Math & Parameters
Removed:
- Excessive examples at low level
- Use case lists that belong at higher levels
Enhanced:
- Mathematical formulations (using proper · symbol for multiplication)
- Clear behavior descriptions
- Precise return value documentation
Updated Functions:
ModelingPrimitives:
1. expression_tracking_variable
- All 6 parameters documented
- Clear math formulation
2. consecutive_duration_tracking
- All 9 parameters documented
- Explained Big-M value
- Clear what constraints are returned
3. mutual_exclusivity_constraint
- All 4 parameters documented
- Simplified, focused on math
BoundingPatterns:
4. basic_bounds
- All 4 parameters documented
- Concise formulation
5. bounds_with_state
- All 5 parameters documented
- Explained epsilon (ε) usage
6. scaled_bounds
- All 5 parameters documented
- Clear scaling relationship
7. scaled_bounds_with_state
- All 7 parameters documented
- Explained Big-M formulation
8. state_transition_bounds
- All 7 parameters documented
- Removed verbose examples, kept math focus
9. continuous_transition_bounds
- All 8 parameters documented
- Clear Big-M constraint explanation
Result
✅ All parameters documented
✅ Math-focused docstrings
✅ Consistent format across all primitives
✅ Tests still passing
The modeling primitives now have professional, complete documentation!
# Conflicts: # docs/user-guide/mathematical-notation/features/OnOffParameters.md # examples/02_Complex/complex_example.py # examples/03_Calculation_types/example_calculation_types.py # examples/04_Scenarios/scenario_example.py # examples/05_Two-stage-optimization/two_stage_optimization.py # flixopt/components.py # flixopt/elements.py # flixopt/features.py # flixopt/flow_system.py # flixopt/interface.py # flixopt/linear_converters.py # tests/conftest.py # tests/test_flow.py # tests/test_functional.py # tests/test_linear_converter.py # tests/test_scenarios.py
# Conflicts: # flixopt/interface.py
# Conflicts: # docs/user-guide/mathematical-notation/effects-penalty-objective.md
…r=inf when active_hours_max is not specified
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis pull request implements a comprehensive terminology rebranding across the codebase, renaming binary on/off state concepts to active/inactive status-based concepts. OnOffParameters becomes StatusParameters, with cascading renames of related fields, variables, methods, and constraints throughout the library, documentation, examples, and tests. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
docs/user-guide/mathematical-notation/effects-penalty-objective.md (1)
157-159: Code example uses deprecated API terminology that no longer exists in the codebase.Lines 157-159 show
fx.OnOffParametersandeffects_per_switch_on, which were renamed as breaking changes:
OnOffParameters→StatusParameterseffects_per_switch_on→effects_per_startupThe entire codebase has been migrated to the new terminology (verified across tests, examples, and implementation files). This documentation example will fail at runtime.
-on_off = fx.OnOffParameters( - effects_per_switch_on={'Penalty': 1} # Add bias against switching on this component, without adding costs +on_off = fx.StatusParameters( + effects_per_startup={'Penalty': 1} # Add bias against startup of this component, without adding costs )flixopt/linear_converters.py (1)
643-672: Based on my verification, I have confirmed that the review comment is accurate and identifies a real issue in the codebase. Here is my rewritten review comment:
Docstring range notation conflicts with exclusive bounds enforcement
check_bounds()enforces exclusive limits (value_arr > lower_boundand< upper_bound), but multiple parameter docstrings use standard range notation that conventionally implies inclusive endpoints:
- Line 222, 542: "
cop...typically 1–20 range" (suggests 1 and 20 are valid, but code enforces1 < cop < 20)- Line 34, 126, 412, 414: "
thermal_efficiency factor (0–1 range)" (suggests 0 and 1 are valid, but code enforces0 < eff < 1)- Line 318: "
specific_electricity_demand...0.01–0.05 range" (paired with exclusive bounds validation)- Line 460: "
Total efficiency...should be ≤ 1.0" but code enforces< 1.0(exclusive)To align expectations with implementation, either:
- Allow endpoints by changing
>to>=and<to<=, or- Tighten docstrings to explicitly state exclusive bounds (e.g., "0–1 (exclusive)" or "COP > 1, < 20")
Note: Some docstrings (e.g., line 261–262, 592) already correctly state "
COP should be greater than 1", which aligns with the exclusive check.
🧹 Nitpick comments (12)
flixopt/features.py (3)
149-252: StatusModel core modeling looks coherent; consider a small robustness improvementThe construction of
inactive,startup/shutdown,active_hours, and uptime/downtime using the shared primitives and bounding patterns is internally consistent, and the dimension handling (time/period/scenario) appears correct.One thing to harden:
_add_effectslater assumesself.startupexists wheneffects_per_startupis set. If a caller ever configureseffects_per_startupwithout enablinguse_startup_tracking,self.startupwill beNoneandself.startup * factorwill fail. You could defensively either:
- implicitly require/enable
use_startup_trackingwheneffects_per_startupis non‑empty, or- guard on
self.startup is not Nonewhen adding those effects.
255-312: Accessor properties are thin wrappers over Submodel storage
active_hours,inactive,startup,shutdown,startup_count,uptime, anddowntimeall delegate to__getitem__/get, matching how variables are registered in_do_modeling. The “deprecated” note forinactiveis a bit confusing given it is still used for downtime tracking; consider clarifying that the property is mainly for backward compatibility while users should prefer1 - statusin custom expressions.
313-328: Previous uptime/downtime helpers mostly align with semantics; docstring nitThe
_get_previous_uptime/_get_previous_downtimehelpers useModelingUtilities.compute_consecutive_hours_in_statewith complementary encodings and scalarhours_per_step, which is consistent with howconsecutive_duration_trackingexpectsprevious_duration.Minor nit:
_get_previous_uptime’s docstring (“Previously inactive by default, for one timestep”) doesn’t match the implementation (return 0when no previous status, i.e., zero prior active duration). You may want to reword the docstring to avoid confusion.flixopt/modeling.py (1)
245-352: consecutive_duration_tracking docs improved; consider fixing the return annotationThe updated docstring correctly explains the active-state duration logic, Big‑M construction, and the contents of the
constraintsdict. The implementation still returns(variables_dict, constraints_dict), but the return type is annotated astuple[linopy.Variable, tuple[...]], which is now misleading.If you rely on static typing, it would be good to update the annotation to reflect the actual
(dict[str, linopy.Variable], dict[str, linopy.Constraint])structure.docs/user-guide/mathematical-notation/index.md (1)
59-62: Align feature label wording with status-based terminologyThe Features Cross-Reference table still uses the older “On/off operation” label, while the surrounding docs and PR intent use “binary active/inactive status”.
To keep terminology consistent, consider updating that row:
-| **On/off operation** | [StatusParameters](features/StatusParameters.md) | [`StatusParameters`][flixopt.interface.StatusParameters] | +| **Binary active/inactive operation** | [StatusParameters](features/StatusParameters.md) | [`StatusParameters`][flixopt.interface.StatusParameters] |The
status_parametersmention in the user API paragraph and the Python Class Lookup entry otherwise look correct.Also applies to: 100-100, 122-122
docs/user-guide/mathematical-notation/features/StatusParameters.md (1)
125-127: Clarify parameter names and tighten wording in StatusParameters docThe formulation and examples look solid; a couple of small wording tweaks would improve clarity:
- Min‑uptime behavior bullet
Current text:
- When shutting down at time $t$: enforces equipment was on for at least $h^\text{uptime}_\text{min}$ prior to the switchTo avoid the “prior to” wording and keep it simple:
-- When shutting down at time $t$: enforces equipment was on for at least $h^\text{uptime}_\text{min}$ prior to the switch +- When shutting down at time $t$: enforces equipment was on for at least $h^\text{uptime}_\text{min}$ before the switch
- Time series boundary note
The current phrasing:
**Time Series Boundary:** The final time period constraints for min_uptime/max and min_downtime/max are not enforced ...can be misread and doesn’t match the parameter names. Consider:
-**Time Series Boundary:** The final time period constraints for min_uptime/max and min_downtime/max are not enforced at the end of the planning horizon. +**Time Series Boundary:** The final time period constraints for `min_uptime`/`max_uptime` and `min_downtime`/`max_downtime` are not enforced at the end of the planning horizon.This makes the mapping to the actual
StatusParametersarguments unambiguous.Also applies to: 317-317
tests/test_component.py (1)
72-177: Status-based component tests look consistent with the new modelThe component tests now:
- Construct components/flows with
status_parameters=fx.StatusParameters(...).- Expect per-flow and component-level variables named
...|statusand...|active_hours.- Assert that flow bounds are correctly scaled by corresponding
statusbinaries.- Check initial uptime behavior via
TestComponent|uptime|initialin the parameterized previous-state test.These updates align with the StatusParameters design and preserve the original structural coverage.
As a low-priority clean-up, you might eventually want to rename the test methods and parameters from
test_on_*/previous_on_hourstotest_status_*/previous_active_hoursfor consistency with the new terminology, but the current naming doesn’t affect correctness.Also applies to: 178-238, 239-417
CHANGELOG.md (1)
149-151: Clarify: These removals are from a previous version, not this PR.The "Removed" section at Lines 149-151 references
OnOffParameterswith old deprecated names (on_hours_total_min,on_hours_total_max,switch_on_total_max). This appears to document removals from v4.0.0 deprecations, but sinceOnOffParametersis being renamed toStatusParametersin this PR, this entry may cause confusion.Consider either:
- Updating these references to use
StatusParameterswith a note about the class rename, or- Adding a clarifying note that these were the deprecated names in the old
OnOffParametersclass (nowStatusParameters)examples/02_Complex/complex_example.py (1)
50-50: Minor terminology inconsistency in comment.The comment says "on-inactive parameters" but the new terminology is "status parameters" representing "active/inactive" states. Consider updating to:
- # A gas boiler that converts fuel into thermal output, with investment and on-inactive parameters + # A gas boiler that converts fuel into thermal output, with investment and status parameterstests/conftest.py (1)
125-180: Fixture StatusParameters use may create more binaries than necessarySeveral fixtures (e.g.,
Converters.Boilers.complex,Converters.CHPs.base,Converters.LinearConverters.*, long-system boiler/CHP inflow_system_long) attachStatusParametersboth at the component level and on individualFlowobjects. This is functionally fine but multiplies the number of status binaries and related constraints, which can slow MIP solves for larger systems.If these tests don’t rely on both flow-level and component-level status behavior simultaneously, consider simplifying to a single
StatusParametersattachment point (either on the key flow or on the component) to keep the fixture systems lighter.Also applies to: 181-207, 209-253, 596-615
flixopt/interface.py (1)
1008-1260: StatusParameters API looks coherent; only minor doc polish possibleThe class definition,
transform_data, and the tracking properties align well with how StatusParameters is consumed in flows/components and tests (startup, active-hour, uptime/downtime, and startup_limit behavior).Two small doc nits you may want to adjust later:
startup_limitdescription ends with a double period (per period..).- The docstring emphasizes dicts for
effects_per_startup/effects_per_active_hour, while the type hints also allow numeric/time-series. If scalar/array inputs are intentionally supported, mentioning that explicitly would make the API clearer.tests/test_flow.py (1)
518-1070: Status-related flow tests are thorough; consider future extensibility of name-based checksThe updated tests around
status_parameters(status/active_hours, uptime/downtime, startup_limit, effects_per_active_hour, active_hours_min/max, and the invest+status combinations) exercise the new StatusModel wiring in detail and look consistent with the modeling logic inFlowModelandStatusParameters.One thing to keep in mind long-term: many assertions compare
set(flow.submodel.variables)/set(flow.submodel.constraints)to exact hard-coded sets. That’s excellent for locking down the current formulation, but it will force test updates for any future enhancement that adds auxiliary status-related constraints or variables. If you later extend StatusModel, you may want to relax some checks to require a superset (or at least focus on the most important names) instead of strict equality.Also applies to: 1076-1273
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (37)
-
.github/workflows/test.yaml(1 hunks) -
CHANGELOG.md(1 hunks) -
docs/user-guide/core-concepts.md(1 hunks) -
docs/user-guide/mathematical-notation/dimensions.md(1 hunks) -
docs/user-guide/mathematical-notation/effects-penalty-objective.md(4 hunks) -
docs/user-guide/mathematical-notation/elements/Flow.md(3 hunks) -
docs/user-guide/mathematical-notation/elements/Storage.md(2 hunks) -
docs/user-guide/mathematical-notation/features/InvestParameters.md(8 hunks) -
docs/user-guide/mathematical-notation/features/OnOffParameters.md(0 hunks) -
docs/user-guide/mathematical-notation/features/StatusParameters.md(1 hunks) -
docs/user-guide/mathematical-notation/index.md(3 hunks) -
docs/user-guide/mathematical-notation/modeling-patterns/bounds-and-states.md(9 hunks) -
docs/user-guide/mathematical-notation/modeling-patterns/duration-tracking.md(8 hunks) -
docs/user-guide/mathematical-notation/modeling-patterns/index.md(2 hunks) -
docs/user-guide/mathematical-notation/modeling-patterns/state-transitions.md(10 hunks) -
docs/user-guide/recipes/index.md(1 hunks) -
examples/02_Complex/complex_example.py(4 hunks) -
examples/02_Complex/complex_example_results.py(1 hunks) -
examples/03_Optimization_modes/example_optimization_modes.py(2 hunks) -
examples/04_Scenarios/scenario_example.py(2 hunks) -
examples/05_Two-stage-optimization/two_stage_optimization.py(1 hunks) -
flixopt/__init__.py(2 hunks) -
flixopt/components.py(13 hunks) -
flixopt/elements.py(25 hunks) -
flixopt/features.py(3 hunks) -
flixopt/flow_system.py(2 hunks) -
flixopt/interface.py(5 hunks) -
flixopt/linear_converters.py(25 hunks) -
flixopt/modeling.py(17 hunks) -
mkdocs.yml(1 hunks) -
tests/conftest.py(8 hunks) -
tests/test_component.py(16 hunks) -
tests/test_flow.py(20 hunks) -
tests/test_functional.py(19 hunks) -
tests/test_linear_converter.py(7 hunks) -
tests/test_scenarios.py(3 hunks) -
tests/test_storage.py(2 hunks)
💤 Files with no reviewable changes (1)
- docs/user-guide/mathematical-notation/features/OnOffParameters.md
🧰 Additional context used
🧬 Code graph analysis (14)
flixopt/__init__.py (1)
flixopt/interface.py (1)
StatusParameters(1009-1261)
examples/03_Optimization_modes/example_optimization_modes.py (1)
flixopt/interface.py (1)
StatusParameters(1009-1261)
tests/test_storage.py (2)
flixopt/results.py (2)
variables(332-336)variables(1168-1176)flixopt/structure.py (1)
variables(1499-1505)
tests/test_functional.py (2)
flixopt/elements.py (2)
Flow(310-597)status(828-832)flixopt/interface.py (1)
StatusParameters(1009-1261)
examples/04_Scenarios/scenario_example.py (1)
flixopt/interface.py (1)
StatusParameters(1009-1261)
flixopt/interface.py (1)
flixopt/structure.py (4)
Interface(279-956)transform_data(297-311)_fit_effect_coords(364-382)_fit_coords(349-362)
tests/test_component.py (3)
flixopt/interface.py (1)
StatusParameters(1009-1261)tests/conftest.py (2)
assert_var_equal(753-787)assert_conequal(734-750)flixopt/elements.py (1)
status(828-832)
tests/test_flow.py (1)
flixopt/interface.py (1)
StatusParameters(1009-1261)
flixopt/components.py (2)
flixopt/interface.py (1)
StatusParameters(1009-1261)flixopt/elements.py (1)
status(828-832)
tests/test_linear_converter.py (5)
flixopt/results.py (6)
flow_system(353-372)size(2002-2010)variables(332-336)variables(1168-1176)constraints(339-343)constraints(1179-1187)flixopt/structure.py (5)
flow_system(329-347)variables(1499-1505)constraints(1490-1496)hours_per_step(184-185)hours_per_step(1531-1532)flixopt/elements.py (1)
Flow(310-597)flixopt/interface.py (1)
StatusParameters(1009-1261)flixopt/components.py (1)
LinearConverter(30-245)
flixopt/elements.py (2)
flixopt/features.py (2)
StatusModel(149-327)size(137-139)flixopt/interface.py (7)
StatusParameters(1009-1261)transform_data(77-80)transform_data(229-231)transform_data(461-463)transform_data(680-683)transform_data(908-965)transform_data(1214-1237)
flixopt/linear_converters.py (1)
flixopt/interface.py (1)
StatusParameters(1009-1261)
tests/conftest.py (2)
flixopt/interface.py (1)
StatusParameters(1009-1261)flixopt/linear_converters.py (9)
CHP(401-527)thermal_efficiency(105-106)thermal_efficiency(109-111)thermal_efficiency(201-202)thermal_efficiency(205-207)thermal_efficiency(512-513)thermal_efficiency(516-518)electrical_efficiency(521-522)electrical_efficiency(525-527)
flixopt/modeling.py (2)
flixopt/structure.py (3)
constraints(1490-1496)add_constraints(1397-1406)Submodel(1362-1541)flixopt/config.py (1)
Modeling(508-519)
🪛 LanguageTool
docs/user-guide/mathematical-notation/features/StatusParameters.md
[style] ~126-~126: ‘prior to’ might be wordy. Consider a shorter alternative.
Context: ...r at least
(EN_WORDINESS_PREMIUM_PRIOR_TO)
🔇 Additional comments (59)
docs/user-guide/mathematical-notation/dimensions.md (1)
100-106: Terminology update is consistentThe new “binary states (active/inactive)” wording matches the status terminology elsewhere; no technical impact.
docs/user-guide/recipes/index.md (1)
25-32: Recipe title rename looks goodRenaming the topic to “Status Constraints” aligns with the new status/active‑inactive vocabulary.
.github/workflows/test.yaml (1)
3-10: No behavioral change in workflowOnly the inline comment on
workflow_callwas tweaked; YAML structure and triggers remain unchanged.flixopt/features.py (1)
26-83: InvestmentModel change is consistent with state-based boundsUsing
BoundingPatterns.bounds_with_statewithstate=self._variables['invested']matches the intent that size is zero when not invested and bounded when invested. No issues seen.flixopt/modeling.py (10)
54-81: Binary-state counting docs now match behaviorThe updated
count_consecutive_statesdocstring correctly describes counting the final consecutive “active” period and treating the final “inactive” state as zero. Implementation remains unchanged and consistent.
118-177: Status-oriented utilities documentation is consistent
compute_consecutive_hours_in_stateandcompute_previous_off_durationnow use “active/inactive” wording, matching how they are consumed by the new status logic (uptime/downtime). The behavior (usingto_binaryand complementing for “off”) is unchanged and still correct.
199-243: expression_tracking_variable type and docs are clearerAllowing
tracked_expression: linopy.expressions.LinearExpression | linopy.Variableand clarifying the “tracker = expression, optional bounds” behavior matches how it’s used (e.g., foractive_hours). No functional change, and usage inStatusModelis valid.
355-395: mutual_exclusivity_constraint documentation now matches the mathThe new docstring cleanly states the at‑most‑one‑active semantics (
Σ binary_vars ≤ tolerance) and keeps the existing binary checks and single-constraint implementation. Looks good.
401-432: basic_bounds docstring matches implementationThe clarified description of lower/upper bounds and the returned
[lower_constraint, upper_constraint]list lines up with the current implementation. No behavior change.
434-477: bounds_with_state behavior remains correct under new namingThe “force to 0 when state=0, enforce [lower, upper] when state=1” semantics are clearly documented and still correctly implemented via the Big‑M style constraints and epsilon floor. The change to the
stateargument name is consistent with the status terminology.
479-515: scaled_bounds documentation aligned with usageThe updated docstring clearly frames
relative_boundsas factors relative to the scaling variable and matches the implementation. No issues spotted.
518-572: scaled_bounds_with_state docs and math are consistentThe new description of
state,M_misc, and the Big‑M upper/lower bounds matches the actual constraints being added. The four returned constraints (lb2,ub2,ub1,lb1) are still in the documented order.
575-626: state_transition_bounds wording matches existing constraintsThe updated “active/inactive, activate/deactivate” terminology matches how these binaries are used in
StatusModel. The three constraints (transition, initial, mutex) and their formulas remain unchanged and correct.
629-695: continuous_transition_bounds docstring now accurately describes behaviorThe clarified behavior (“only change when transitions occur, within ±max_change”) matches the current Big‑M constraints on the continuous variable. No functional changes; math remains sound.
docs/user-guide/core-concepts.md (1)
27-33: Flow constraints wording matches StatusParametersDescribing constraints as covering “min/max, total flow hours, active/inactive status” ties in well with the new status model; no technical concerns.
flixopt/flow_system.py (2)
48-56: Docstring update for hours_of_previous_timesteps is accurateReferencing uptime/downtime as a key consumer of
hours_of_previous_timestepsreflects how it feeds the status tracking logic; no behavioral changes.
73-83: Example updated to use status_parametersSwitching the example to
status_parameters=...is consistent with the new StatusModel/StatusParameters API elsewhere in the PR.mkdocs.yml (1)
21-29: MkDocs nav correctly points to StatusParametersThe feature link under Mathematical Notation now targets
StatusParameters.md, which matches the new feature name and avoids dangling references.docs/user-guide/mathematical-notation/features/InvestParameters.md (1)
18-18: LGTM! Documentation clarity improvements.The addition of "With:" subsections explicitly defining variables used in the equations improves documentation readability and follows best practices for mathematical notation.
Also applies to: 38-38, 85-85, 105-105, 130-130, 154-154, 219-219, 236-236
tests/test_storage.py (1)
410-426: LGTM! Variable naming updated consistently.The test correctly updates binary variable references from
|onto|status, aligning with the broader terminology shift from OnOffParameters to StatusParameters. The test logic remains sound, and assertions properly verify the prevent_simultaneous_charge_and_discharge functionality.examples/02_Complex/complex_example_results.py (1)
32-33: LGTM! Example updated for new variable naming.The plot variable references correctly updated from
|onto|status, ensuring examples remain functional with the renamed API.docs/user-guide/mathematical-notation/modeling-patterns/index.md (1)
20-20: LGTM! Documentation terminology updated consistently.The updates from "on/off" to "active/inactive" and
OnOffParameterstoStatusParametersmaintain consistency with the API changes and improve conceptual clarity.Also applies to: 46-46
docs/user-guide/mathematical-notation/elements/Storage.md (1)
56-71: LGTM! Documentation completeness improved.The addition of previously undocumented parameters (
minimal_final_charge_state,maximal_final_charge_state,eta_charge,eta_discharge) and the reference to the "Bounds with State" pattern improve the documentation's completeness and usability.docs/user-guide/mathematical-notation/modeling-patterns/bounds-and-states.md (1)
14-17: LGTM! Documentation improvements and terminology updates.The addition of "With:" subsections for variable definitions and the consistent update from "on/off" to "active/inactive" terminology enhance documentation clarity and align with the StatusParameters API changes.
Also applies to: 29-29, 36-41, 50-51, 64-68, 84-84, 95-103, 114-115, 134-137, 157-160
docs/user-guide/mathematical-notation/modeling-patterns/duration-tracking.md (1)
18-21: LGTM! Documentation updated for new parameter naming.The code examples correctly update the parameter name from
state_variabletostate, and documentation references are updated from OnOffParameters to StatusParameters with corresponding active/inactive terminology. These changes maintain consistency with the API rename.Also applies to: 42-44, 61-63, 95-96, 123-126, 136-138, 150-153, 161-162
flixopt/__init__.py (1)
34-34: Perfect! I now have enough information to verify this review comment. Let me check one more thing about the documentation reference to ensure completeness:
<function_calls>
#!/bin/bashCheck the stale documentation reference
echo "=== Stale documentation reference ==="
rg -n -B3 -A3 "OnOffParameters" docs/user-guide/mathematical-notation/effects-penalty-objective.md
</function_calls>#!/bin/bash # Verify if this documentation file needs updating echo "=== Check when this documentation was last modified ===" git log --oneline -n 5 -- docs/user-guide/mathematical-notation/effects-penalty-objective.md 2>/dev/null || echo "No git history" echo "" echo "=== Check if there's a corresponding StatusParameters documentation ===" find docs -name "*StatusParameters*" -o -name "*status*parameter*" 2>/dev/null | grep -v ".git" </parameter> </invoke> </function_calls> ```shell #!/bin/bash # Final verification: Check the full picture echo "=== Verify backwards compatibility classes handling ===" rg -n "AggregationParameters|OnOffParameters" flixopt/__init__.py echo "" echo "=== Compare with how deprecated classes are handled ===" sed -n '18,20p' flixopt/__init__.py sed -n '58,70p' flixopt/__init__.pyexamples/04_Scenarios/scenario_example.py (1)
120-127: StatusParameters usage in scenario example is consistentSwitching from
on_off_parameters=fx.OnOffParameters()tostatus_parameters=fx.StatusParameters()on the Boiler thermal flow and CHP electrical flow matches the new API and keeps the intended binary-operation behavior. No issues from this change.Also applies to: 137-139
docs/user-guide/mathematical-notation/elements/Flow.md (1)
26-28: Flow–StatusParameters documentation is coherentThe added references to
StatusParameters(extension text, modeling pattern bullet, key parameter, and See Also) are consistent with the new binary active/inactive feature and match the StatusParameters API. No changes needed here.Also applies to: 36-38, 48-53, 60-60
docs/user-guide/mathematical-notation/modeling-patterns/state-transitions.md (1)
13-15: State transition pattern text aligns with StatusParametersThe refreshed wording (startup/shutdown behavior, mutual exclusivity, and the “Used In → StatusParameters” reference) is consistent with the equations and with the new status-based terminology. I don’t see issues in these updated sections.
Also applies to: 29-33, 51-52, 86-91, 117-118, 139-141, 153-154, 183-185, 200-201, 214-214, 232-233
examples/03_Optimization_modes/example_optimization_modes.py (1)
83-96: StatusParameters usage in optimization-modes example is correctThe Boiler and CHP now use
status_parameters=fx.StatusParameters(...)witheffects_per_startupfields, which matches the new API and preserves the intended startup-cost behavior from the old OnOffParameters examples.Also applies to: 99-107
tests/test_component.py (1)
448-452: Transmission status assertions match the new StatusParameters interfaceThe transmission tests now validate:
transmission.in1.submodel.status.status.solution.valuesinstead of an OnOff-specific attribute.- That the status pattern (always on vs. partially on) matches expectations, with updated messages (“Status does not work properly”).
This correctly exercises the new status submodel without changing the underlying transmission behavior checks.
Also applies to: 513-516, 593-597
examples/05_Two-stage-optimization/two_stage_optimization.py (1)
48-61: Two-stage example correctly migrated to StatusParametersThe Kessel and BHKW2 configurations now use
status_parameters=fx.StatusParameters(...)with:
effects_per_startupreplacingeffects_per_switch_on.min_uptime/min_downtimereplacing consecutive on/off hour minima.This is consistent with the new StatusParameters API and preserves the earlier operational semantics.
Also applies to: 63-79
tests/test_linear_converter.py (3)
137-192: LGTM! Test correctly updated for StatusParameters terminology.The test properly:
- Uses
fx.StatusParameterswith new parameter names (active_hours_min,active_hours_max,effects_per_active_hour)- Asserts correct variable names (
Converter|status,Converter|active_hours)- Verifies constraint naming (
Converter|active_hours,Converter->costs(temporal))- Validates the status-based calculation logic
374-374: Comment updated to reflect status terminology.The comment correctly notes "If there's no status parameter" instead of the previous on/off terminology.
381-497: LGTM! Piecewise conversion test properly updated for StatusParameters.The test correctly:
- Renamed to
test_piecewise_conversion_with_status- Uses
fx.StatusParameterswith appropriate new parameter names- Verifies
Converter|statusvariable is created and used aszero_point- Validates the single_segment constraint uses
model.variables['Converter|status'](Line 481)- Checks
Converter|active_hoursconstraint with correct status-based calculation (Lines 485-489)- Verifies cost effects use status variable (Lines 495-496)
tests/test_scenarios.py (2)
143-173: LGTM! Boiler configuration correctly updated to StatusParameters.The configuration properly uses:
status_parameters=fx.StatusParameters(effects_per_active_hour=...)at component level- Nested
status_parametersin thermal_flow with all renamed fields:
active_hours_min/max(wason_hours_total_min/max)max_uptime/min_uptime(wasconsecutive_on_hours_max/min)max_downtime(wasconsecutive_off_hours_max)effects_per_startup(waseffects_per_switch_on)startup_limit(wasswitch_on_total_max)
234-234: LGTM! LinearConverter correctly uses StatusParameters.The
effects_per_startupparameter is correctly used with the newfx.StatusParametersclass.CHANGELOG.md (1)
54-123: Excellent changelog documentation for the breaking change.The changelog entry is comprehensive and well-structured:
- Clear summary of the terminology change
- Detailed migration tables for all renamed entities
- Explicit note that this is a clean breaking change with no backwards compatibility wrapper
- Find-and-replace guidance for users
examples/02_Complex/complex_example.py (1)
51-116: LGTM! Example correctly demonstrates StatusParameters usage.The example properly showcases:
- Component-level
status_parameterswitheffects_per_active_hour(Lines 54-56)- Flow-level
status_parameterswith comprehensive constraints (Lines 72-80):
active_hours_min/maxfor total operating hoursmax_uptime/min_uptimefor consecutive operationmax_downtimefor consecutive downtimeeffects_per_startupfor startup costsstartup_limitfor maximum starts- CHP units with
effects_per_startup(Lines 91, 115)This serves as good documentation for users migrating to the new API.
tests/test_functional.py (8)
6-17: LGTM! Module docstring properly updated for status terminology.The docstring correctly describes tests for "status operational constraints" and lists the renamed test functions (
test_startup_shutdown,test_consecutive_uptime_downtime).
333-369: LGTM! test_on correctly updated to use StatusParameters.The test properly:
- Uses
fx.StatusParameters()instead offx.OnOffParameters()- Accesses solution via
submodel.status.status.solution.values(Line 357)
372-420: LGTM! test_off correctly updated for StatusParameters.The test properly:
- Uses
fx.StatusParameters(max_downtime=100)with new parameter name- Accesses
status.statusandstatus.inactivesolution values correctly (Lines 401, 408-409)
423-478: LGTM! Test renamed and updated for startup/shutdown terminology.The test correctly:
- Renamed from
test_switch_on_offtotest_startup_shutdown- Uses
force_startup_tracking=True(wasforce_switch_on=True)- Accesses
status.startupandstatus.shutdownsolution values (Lines 459, 466)Minor note: Error messages at Lines 463 and 470 still reference old variable names (
"Boiler__Q_th__switch_on"). Consider updating for consistency, though this doesn't affect test functionality.
481-528: LGTM! test_on_total_max correctly uses active_hours_max.The test properly uses
fx.StatusParameters(active_hours_max=1)and accessesstatus.status.solution.values.
531-602: LGTM! test_on_total_bounds correctly uses active_hours_min/max.The test properly uses:
fx.StatusParameters(active_hours_max=2)for the first boilerfx.StatusParameters(active_hours_min=3)for the backup boiler
605-663: LGTM! Test renamed and updated for uptime/downtime terminology.The test correctly:
- Renamed from
test_consecutive_on_offtotest_consecutive_uptime_downtime- Uses
max_uptime=2, min_uptime=2(wasconsecutive_on_hours_max/min)- Accesses solution via correct paths
666-733: LGTM! test_consecutive_off correctly uses downtime parameters.The test properly uses
fx.StatusParameters(max_downtime=2, min_downtime=2)and accessesstatus.statusandstatus.inactivesolution values.flixopt/components.py (2)
552-688: Transmission absolute_losses correctly wired to flow statusThe updated
Transmission/TransmissionModellogic looks consistent:
status_parametersis now a first-class ctor argument and passed into the baseComponent.- When
absolute_lossesis nonzero,TransmissionModel.__init__ensures each participating flow hasflow.status_parameters = StatusParameters()if none was provided, soin_flow.submodel.status.statusis always available.create_transmission_equationthen gates absolute losses with that binary (out + status * absolute_losses = in * (1 - rel_losses)), which matches the documented “absolute losses create binary active/inactive variables” behavior.This keeps the API flexible (users can still supply explicit
status_parameterson flows or the Transmission) while guaranteeing correctness when absolute losses are used.Also applies to: 736-777
781-826: LinearConverter piecewise zero_point now correctly uses component statusUsing
zero_point=self.status.status if self.status is not None else FalseinLinearConverterModel’s piecewise branch keeps the previous on/off semantics but with the new status model:
- When the converter has component-level
status_parameters, the piecewise conversion is anchored to that status binary.- When only flow-level status is used (and no component-level StatusParameters),
self.statusremainsNone, so the piecewise model sees a constantFalsezero point and relies on per-flow status constraints instead—identical to the prior behavior.No changes needed from a modeling or API perspective.
flixopt/elements.py (3)
89-129: StatusParameters plumbing through Component and Flow is consistentThe way
status_parametersis threaded now looks solid:
Componentaccepts an optionalstatus_parameters, stores it, and propagates its flow_system plus coordinate transformation via_set_flow_systemandtransform_data.Flowstores its own optionalstatus_parameters, propagates the flow_system reference, and callstransform_dataon it after fitting its own numeric fields.- This ensures both component-level and flow-level StatusParameters share the same coordinate system and can be modeled independently or together as needed.
No changes needed here.
Also applies to: 309-346, 448-483, 507-545
547-573: FlowModel status/investment gating and previous_status handling look correctThe updated FlowModel logic for status is coherent:
_constraint_flow_ratecleanly separates four cases (no status/no investment, status only, investment only, both), delegating bounds to the appropriateBoundingPatternshelper and always using the binary status variable when present.absolute_flow_rate_boundsnow forceslb=0wheneverwith_statusis true, which is essential to allow true on/off switching; the actual min-flow behavior is then enforced viabounds_with_state/scaled_bounds_with_stateusing the status binary._create_status_modelpassesprevious_statusderived fromprevious_flow_ratethroughModelingUtilitiesAbstract.to_binary, which is what the uptime/downtime tests rely on for “previously active” behavior.- The
statusproperty andwith_statusflag correctly track whether a StatusModel submodel exists for the flow.This matches the expectations encoded in
TestFlowOnModeland the uptime/downtime tests.Also applies to: 600-633, 669-733, 798-825, 827-833, 847-860
922-983: ComponentModel aggregation of status and previous_status is well-structuredThe component-level status logic is consistent with the flow-level status model:
- If
Component.status_parametersis set, flows without explicit status_parameters are given a defaultStatusParameters(), ensuring every relevant flow has a StatusModel.- After creating all FlowModels, the component builds a binary
statusvariable and constraints that make it 1 iff any connected flow is active, then wraps that in a StatusModel with the component’s own StatusParameters.previous_statusaggregates each flow’sstatus._previous_statusacross inputs/outputs, aligns time indices by padding, and ORs them into a single component-level previous status vector.This matches the intended semantics (“component active if any flow is active”) and provides a sensible previous_status for component-level uptime/downtime constraints.
Also applies to: 992-1010
flixopt/linear_converters.py (7)
15-18: TYPE_CHECKING import updated cleanly to StatusParametersUsing
StatusParametersonly underTYPE_CHECKINGtogether with postponed annotations keeps runtime imports minimal and correctly reflects the new interface type.
124-133: Power2Heat: status_parameters wiring and docs look correctThe new
status_parametersparameter is optional, forwarded correctly toLinearConverter, and the electrode boiler example uses validStatusParametersfields (min_uptime,effects_per_startup), so the change is consistent with the new terminology.Also applies to: 150-158, 171-194
220-229: HeatPump: integration with StatusParameters is coherentConstructor signature, super call, and the geothermal example using
min_uptimeandeffects_per_active_hourall correctly referenceStatusParametersand keep the external API shape intact.Also applies to: 246-254, 266-290
315-324: CoolingTower: status-based constraints hooked up properlyThe
status_parametersargument is threaded through toLinearConverter, and the example’sStatusParametersusage (min_uptime,effects_per_active_hour) matches the provided interface, without altering existing conversion logic.Also applies to: 341-349, 363-384
410-421: CHP: status_parameters addition maintains prior behaviorAdding
status_parametersto the CHP constructor and forwarding it in thesuper().__init__call preserves the previous structure while exposing the new status-based constraints; the industrial CHP example uses validStatusParametersfields (min_uptime,effects_per_startup,active_hours_max), so the docs remain accurate.Also applies to: 440-451, 465-495
540-551: HeatPumpWithSource: StatusParameters usage and forwarding are soundThe new
status_parametersargument is optional, correctly passed toLinearConverter, and the example’sStatusParameterscall (withmin_uptimeandeffects_per_startup) aligns with the centralStatusParametersdefinition.Also applies to: 569-578, 596-622
32-39: Perfect! I have all the information needed to verify the review comment. Let me complete my findings:All verification checks passed - review comment is accurate
The code inspection confirms:
LinearConverter accepts
status_parameters: Defined at line 165 inflixopt/components.pywith signaturedef __init__(self, label: str, inputs: list[Flow], outputs: list[Flow], status_parameters: StatusParameters | None = None, ...)Boiler properly forwards the parameter: At line 109 in
flixopt/linear_converters.py,super().__init__()is called withstatus_parameters=status_parametersExamples are consistent with StatusParameters API:
- Lines 62-65: Natural gas boiler without status_parameters (valid use)
- Lines 76-99: Biomass boiler with
StatusParameters(min_uptime=4, effects_per_startup={'startup_fuel': 50})(correct API usage)No remaining old references in active code: Only CHANGELOG.md and docs contain historical references to
OnOffParameters
1. Return type annotation for consecutive_duration_tracking (flixopt/modeling.py:255):
- Changed from tuple[linopy.Variable, tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint]]
- To tuple[dict[str, linopy.Variable], dict[str, linopy.Constraint]] to match the actual return value
2. Clarified inactive property docstring (flixopt/features.py:284-291):
- Replaced the confusing "deprecated" note with a clear explanation that:
- The variable is only created when downtime tracking is enabled
- Users should prefer 1 - status expression for general use
3. Fixed _get_previous_uptime docstring (flixopt/features.py:318-322):
- Clarified that it returns 0 when no previous status is provided (assumes previously inactive)
4. Fixed _get_previous_downtime docstring (flixopt/features.py:329-333):
- Clarified that it returns one timestep duration when no previous status is provided (assumes previously inactive)
5. No action needed for effects_per_startup without use_startup_tracking:
- Verified that use_startup_tracking already returns True when effects_per_startup has values (line 1258 in interface.py), so this is already
handled correctly
6. Test fixes (tests/test_flow.py):
- Updated three test assertions to use model.hours_per_step.sum('time') as the expected upper bound for active_hours when active_hours_max is
not specified
* Perfect! Here's the **final complete renaming table with Option A**:
## Parameters Class (`OnOffParameters` → `StatusParameters`)
| Current Name | Recommended Name | Rationale |
|--------------|------------------|-----------|
| `OnOffParameters` | **`StatusParameters`** | Aligns with PyPSA, clearer semantics |
| `effects_per_switch_on` | **`effects_per_startup`** | Standard UC terminology |
| `effects_per_running_hour` | **`effects_per_active_hour`** | Clear, concise, matches "active" state |
| `on_hours_total_min` | **`active_hours_min`** | Total (not consecutive) active hours |
| `on_hours_total_max` | **`active_hours_max`** | Total (not consecutive) active hours |
| `consecutive_on_hours_min` | **`min_uptime`** | Standard UC term (consecutive) |
| `consecutive_on_hours_max` | **`max_uptime`** | Standard UC term (consecutive) |
| `consecutive_off_hours_min` | **`min_downtime`** | Standard UC term (consecutive) |
| `consecutive_off_hours_max` | **`max_downtime`** | Standard UC term (consecutive) |
| `switch_on_total_max` | **`startup_limit`** | Clearer intent, matches "startup" |
| `force_switch_on` | **`force_startup_tracking`** | More explicit about what is forced |
## Model Class (`OnOffModel` → `StatusModel`)
### Class Name
| Current Name | Recommended Name |
|--------------|------------------|
| `OnOffModel` | **`StatusModel`** |
### Constructor Parameters
| Current Name | Recommended Name | Rationale |
|--------------|------------------|-----------|
| `on_variable` | **`status`** | Aligns with PyPSA and literature |
| `previous_states` | **`previous_status`** | Consistency with status variable |
### Variables (short_name in add_variables/expression_tracking_variable)
| Current Name | Recommended Name | Type | Notes |
|--------------|------------------|------|-------|
| `self.on` | **`self.status`** | Input variable | Main binary state variable |
| `'off'` | **Remove variable** | Binary variable | Replace with expression `1 - status` |
| `'switch\|on'` | **`'startup'`** | Binary variable | Startup event indicator |
| `'switch\|off'` | **`'shutdown'`** | Binary variable | Shutdown event indicator |
| `'switch\|count'` | **`'startup_count'`** | Integer variable | Number of startups |
| `'on_hours_total'` | **`'active_hours'`** | Continuous variable | Total active duration |
| `'consecutive_on_hours'` | **`'uptime'`** | Continuous variable | Consecutive active hours |
| `'consecutive_off_hours'` | **`'downtime'`** | Continuous variable | Consecutive inactive hours |
### Properties
| Current Name | Recommended Name | Returns | Meaning |
|--------------|------------------|---------|---------|
| `on_hours_total` | **`active_hours`** | `linopy.Variable` | Total active hours |
| `off` | **Remove property** | — | Use `1 - status` expression |
| `switch_on` | **`startup`** | `linopy.Variable \| None` | Startup events |
| `switch_off` | **`shutdown`** | `linopy.Variable \| None` | Shutdown events |
| `switch_on_nr` | **`startup_count`** | `linopy.Variable \| None` | Number of startups |
| `consecutive_on_hours` | **`uptime`** | `linopy.Variable \| None` | Consecutive active hours |
| `consecutive_off_hours` | **`downtime`** | `linopy.Variable \| None` | Consecutive inactive hours |
### Internal Methods
| Current Name | Recommended Name |
|--------------|------------------|
| `_get_previous_on_duration()` | **`_get_previous_uptime()`** |
| `_get_previous_off_duration()` | **`_get_previous_downtime()`** |
### Internal Properties/Flags (in parameters)
| Current Name | Recommended Name |
|--------------|------------------|
| `use_off` | **Remove** (use expression instead) |
| `use_switch_on` | **`use_startup_tracking`** |
| `use_consecutive_on_hours` | **`use_uptime_tracking`** |
| `use_consecutive_off_hours` | **`use_downtime_tracking`** |
## Constraint Names (short_name in add_constraints)
| Current Name | Recommended Name |
|--------------|------------------|
| `'complementary'` | **Remove** (no off variable) |
| `'on_hours_total'` | **`'active_hours'`** |
| `'switch\|on'`, `'switch\|off'` | **`'startup'`, `'shutdown'`** |
| `'switch\|count'` | **`'startup_count'`** |
| `'consecutive_on_hours'` | **`'uptime'`** |
| `'consecutive_off_hours'` | **`'downtime'`** |
## Complete Terminology Summary (Option A)
**State:**
- `status` (binary): 1 = active, 0 = inactive
**Events:**
- `startup` (binary): transition from inactive to active
- `shutdown` (binary): transition from active to inactive
**Durations:**
- `active_hours` (continuous): **total** hours in active state across time horizon
- `uptime` (continuous): **consecutive** hours currently active (UC standard)
- `downtime` (continuous): **consecutive** hours currently inactive (UC standard)
**Parameter Bounds:**
- `active_hours_min/max`: limits on **total** active hours
- `min_uptime/max_uptime`: limits on **consecutive** active hours (UC standard)
- `min_downtime/max_downtime`: limits on **consecutive** inactive hours (UC standard)
- `startup_limit`: maximum number of startup events
**Effects:**
- `effects_per_startup`: costs/impacts per startup event
- `effects_per_active_hour`: costs/impacts per active hour
This aligns perfectly with PyPSA and the unit commitment literature! 🎯
* Refactor tests and examples
* Refactor tests and examples
* Update CHANGELOG.md
* Python Docstrings Updated:
1. interface.py - Module docstring now references "Status decisions"
2. components.py - Updated all docstrings:
- status_parameters parameter descriptions
- Example code updated with new parameter names (effects_per_startup, min_uptime, startup_limit)
- Fixed incorrect "OnOff feature" docstring to "Investment feature"
- Updated TODO comment to reference StatusParameters
3. linear_converters.py - All docstrings updated:
- Import statement updated to StatusParameters
- All parameter descriptions updated
- All example code updated with new terminology
4. flow_system.py - Updated references from "consecutive_on_hours" to "uptime and downtime" and on_off_parameters to status_parameters
5. modeling.py - Updated docstring from "switch-on/off variables" to "state transition constraints for binary switching variables"
Documentation Markdown Files Updated:
1. Flow.md - All references updated:
- Links to StatusParameters
- "on/off state" → "active/inactive state"
- Parameter names updated
2. StatusParameters.md (renamed from OnOffParameters.md) - Comprehensive updates:
- Title changed to "StatusParameters"
- All terminology updated: on/off → active/inactive
- Mathematical notation updated: s^on/s^off → s^startup/s^shutdown
- Duration variables: d^on/d^off → d^uptime/d^downtime
- Parameter names updated in all examples
- All Python code examples updated with new API
3. Other modeling pattern docs - Updated all references to StatusParameters and active/inactive terminology
4. mkdocs.yml - Navigation updated to reference StatusParameters.md
All docstrings and documentation now consistently use the new Status terminology aligned with PyPSA and unit commitment standards!
* Update remaining mentions of old parameters
* ⏺ Perfect! I've addressed all the actionable review comments:
Changes Made:
1. Fixed error message in modeling.py
- Corrected ModelingPrimitives.state_transition_bounds() → BoundingPatterns.state_transition_bounds() in error message (flixopt/modeling.py:591)
2. Fixed Transmission type hint (flixopt/components.py:667)
- Changed status_parameters: StatusParameters = None → status_parameters: StatusParameters | None = None
3. Fixed absolute_losses=0 edge case (flixopt/components.py:768)
- Added np.any(self.element.absolute_losses != 0) check in create_transmission_equation to match the initialization logic
- This prevents AttributeError when absolute_losses is explicitly set to 0
4. Updated test assertion messages (tests/test_component.py)
- Changed "On does not work properly" → "Status does not work properly"
5. Fixed effects_per_startup type (examples/02_Complex/complex_example.py)
- Changed scalar effects_per_startup=0.01 → dict effects_per_startup={Costs.label: 0.01} in all 3 occurrences
- Now consistent with the StatusParameters API which expects a dict mapping effect names to values
6. Updated test_functional.py docstring
- Removed reference to non-existent TestStatus class
- Updated to accurately describe the status-related test functions
7. Consistent unbounded upper bounds (flixopt/features.py:191)
- Changed np.inf → None for unbounded active_hours_max
- Now consistent with FlowModel's total_flow_hours pattern
All changes maintain backward compatibility and align with the codebase's existing patterns. The documentation in index.md was already correct (BoundingPatterns is
the right class for state_transition_bounds).
* Changes Made:
1. CHANGELOG.md - Fixed parameter rename documentation (lines 89-90)
- Changed incorrect status_parameters → status_parameters
- To correct: on_off_parameters → status_parameters
2. CHANGELOG.md - Removed duplicate logger warning (line 803 in v2.1.0)
- Removed duplicate entry that was already documented in v2.0.1
- Fixed v2.0.1 entry to say on_off_parameters (the name at that time)
3. StatusParameters.md - Aligned flow bounds formulation (line 229)
- Updated summary to include max(ε, rel_lower) like the main text
- Now consistent: s(t) · P · max(ε, rel_lower) ≤ p(t) ≤ s(t) · P · rel_upper
4. features.py - Narrowed previous_status type hint (line 155)
- Changed from Numeric_TPS | None to xr.DataArray | None
- Added import xarray as xr (line 12)
- This accurately reflects that _get_previous_uptime() and _get_previous_downtime() use xarray APIs
All changes are verified to compile correctly and maintain consistency with the codebase patterns!
* Fixed Issues
1. Constraint naming in tests (tests/test_component.py:126-127, 158, 168,
338, 348):
- Updated test expectations from 'TestComponent|on|lb' and
'TestComponent|on|ub' to 'TestComponent|status|lb' and
'TestComponent|status|ub' to match the actual constraint names
2. Added 'off' property to StatusModel (flixopt/features.py:284-287):
- Added a new property that returns 1 - self.status for backward
compatibility with tests expecting an off attribute
3. Fixed deprecated parameter name (tests/test_functional.py:435):
- Changed force_switch_on=True to force_startup_tracking=True in
StatusParameters
4. Fixed property name (tests/test_functional.py:466):
- Changed switch_off to shutdown to match the actual property name in
StatusModel
* Delete mistakingly added files
* Delete mistakingly added files
* Final touches
* Final touches
* Replace off with inactive
* Rename low level parameetrs as well:
switch_on -> activate
switch_off -> deactivate
* Rename low level parameetrs as well:
switch_on -> activate
switch_off -> deactivate
state_variable -> state
* Rename low level parameetrs as well:
switch_on -> activate
switch_off -> deactivate
state_variable -> state
* Docstring Improvements Summary
✅ All Parameters Now Documented
Each primitive now has complete parameter documentation with:
- Clear description of what each parameter does
- Type expectations
- Default values where applicable
✅ Focused on Math & Parameters
Removed:
- Excessive examples at low level
- Use case lists that belong at higher levels
Enhanced:
- Mathematical formulations (using proper · symbol for multiplication)
- Clear behavior descriptions
- Precise return value documentation
Updated Functions:
ModelingPrimitives:
1. expression_tracking_variable
- All 6 parameters documented
- Clear math formulation
2. consecutive_duration_tracking
- All 9 parameters documented
- Explained Big-M value
- Clear what constraints are returned
3. mutual_exclusivity_constraint
- All 4 parameters documented
- Simplified, focused on math
BoundingPatterns:
4. basic_bounds
- All 4 parameters documented
- Concise formulation
5. bounds_with_state
- All 5 parameters documented
- Explained epsilon (ε) usage
6. scaled_bounds
- All 5 parameters documented
- Clear scaling relationship
7. scaled_bounds_with_state
- All 7 parameters documented
- Explained Big-M formulation
8. state_transition_bounds
- All 7 parameters documented
- Removed verbose examples, kept math focus
9. continuous_transition_bounds
- All 8 parameters documented
- Clear Big-M constraint explanation
Result
✅ All parameters documented
✅ Math-focused docstrings
✅ Consistent format across all primitives
✅ Tests still passing
The modeling primitives now have professional, complete documentation!
* Update docs
* Add missing type hints
* Fix bullet points
* Fix bullet points
* Re-apply changes from main
* Bugfix: Usage of old on_off_parameters
* Update CHANGELOG.md
* Update CHANGELOG.md
* Update CHANGELOG.md
* Fix typos
* Improve flagging of wether to create inactive varaible
* Improve default upper bound of active_hours
* Bugfix self._model.hours_per_step.sum('time').item() with scenarios/periods
* Fix test
* FIx names
* pdate the test assertions to expect upper=total_hours instead of upper=inf when active_hours_max is not
specified
* Empty
* Trigger CI
* Fix test
* Triggger CI
* Summary of Fixes
1. Return type annotation for consecutive_duration_tracking (flixopt/modeling.py:255):
- Changed from tuple[linopy.Variable, tuple[linopy.Constraint, linopy.Constraint, linopy.Constraint]]
- To tuple[dict[str, linopy.Variable], dict[str, linopy.Constraint]] to match the actual return value
2. Clarified inactive property docstring (flixopt/features.py:284-291):
- Replaced the confusing "deprecated" note with a clear explanation that:
- The variable is only created when downtime tracking is enabled
- Users should prefer 1 - status expression for general use
3. Fixed _get_previous_uptime docstring (flixopt/features.py:318-322):
- Clarified that it returns 0 when no previous status is provided (assumes previously inactive)
4. Fixed _get_previous_downtime docstring (flixopt/features.py:329-333):
- Clarified that it returns one timestep duration when no previous status is provided (assumes previously inactive)
5. No action needed for effects_per_startup without use_startup_tracking:
- Verified that use_startup_tracking already returns True when effects_per_startup has values (line 1258 in interface.py), so this is already
handled correctly
6. Test fixes (tests/test_flow.py):
- Updated three test assertions to use model.hours_per_step.sum('time') as the expected upper bound for active_hours when active_hours_max is
not specified
* Trigger CI
Description
Brief description of the changes in this PR.
Type of Change
Related Issues
Closes #(issue number)
Testing
Checklist
Summary by CodeRabbit
Refactor
OnOffParameterstoStatusParametersacross the public API.on_off_parameters→status_parameters;effects_per_switch_on→effects_per_startup;on_hours_min/max→active_hours_min/max; and related fields.on→status;consecutive_on_hours→uptime;consecutive_off_hours→downtime.Documentation
StatusParametersterminology and active/inactive state nomenclature.✏️ Tip: You can customize this high-level summary in your review settings.