You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This removes the redundant DsmCapacityHeuristicBalancingNegStrategy/DsmCapacityHeuristicBalancingPosStrategy - it is fine to have both names resolving to the same class, but not good to have duplicated codebase without benefit.
It looks similar, and actually was.
Additionally a bug in the base_market for the list of currently open auctions is fixed. This did not have any known use yet. This was also found in #810
Preserve existing functionality and expected model behavior while applying fixes.
Non-compliant requirements:
Reduce memory growth during long-running, concurrent/multi-simulation workloads.
Clean up likely sources of retained objects / long-lived references / cache and lifecycle issues.
Note changes in release notes (if any).
Requires further human verification:
Update documentation related to the changes.
Reduce memory growth during long-running, concurrent/multi-simulation workloads (requires profiling/benchmarking in representative workloads to confirm).
The new DsmCapacityHeuristicBalancingStrategy no longer includes a market_id field in generated bid dicts (the previous POS/NEG classes set market_id to CRM_pos/CRM_neg). If any downstream code relies on bid["market_id"] for routing, serialization, or grouping, this can trigger a KeyError or mis-classify bids specifically for CRM markets.
classDsmCapacityHeuristicBalancingStrategy(MinMaxStrategy):
""" Strategy for Positive/Negative CRM Reserve (Demand Side, i.e., up & down, symmetric). """defcalculate_bids(self, unit, market_config, product_tuples, **kwargs):
bids= []
max_power=unit.max_plant_capacitymin_power=unit.min_plant_capacityforproductinproduct_tuples:
start, end, only_hours=productblock_times= [dtfordtinunit.index.get_date_list() ifstart<=dt<end]
# For all time steps in block, calculate possible symmetric bidup_caps= []
down_caps= []
fortinblock_times:
flex=unit.flex_power_requirement.at[t]
up_caps.append(max_power-flex)
down_caps.append(flex-min_power)
# The symmetric bid is the minimum capacity that is possible in *all* timesteps in the blocksymmetric_capacity=min(min(up_caps), min(down_caps))
ifsymmetric_capacity>0:
bids.append(
{
"start_time": start,
"end_time": end,
"only_hours": only_hours,
"price": 0, # or unit.calculate_marginal_cost(...)"volume": symmetric_capacity,
"unit_id": unit.id,
}
)
returnself.remove_empty_bids(bids)
The check "" in self.additional_fields assumes additional_fields is always an iterable of strings. If additional_fields can be None (or another non-iterable) for some configs, this will raise a TypeError during initialization. Guarding with a truthy/type check (or normalizing to an empty list) would avoid config-time crashes.
def__post_init__(self):
""" Post-initialization checks for checks on failing initializations. """if""inself.additional_fields:
warn(
"Empty string '' found in 'additional_fields' and will be ignored.",
UserWarning,
)
self.additional_fields= [fforfinself.additional_fieldsiff!=""]
Latest suggestions up to ad71102
Explore these optional code suggestions:
Category
Suggestion
Impact
Possible issue
Guard against non-iterable fields
This membership check will raise if additional_fields is None or otherwise non-iterable during initialization. Guard the check by validating it is an iterable collection before using in, then normalize to a list when filtering.
-if "" in self.additional_fields:+if isinstance(self.additional_fields, (list, tuple, set)) and "" in self.additional_fields:
warn(
"Empty string '' found in 'additional_fields' and will be ignored.",
UserWarning,
)
self.additional_fields = [f for f in self.additional_fields if f != ""]
Suggestion importance[1-10]: 5
__
Why: Adding an isinstance guard prevents TypeError if self.additional_fields is None or otherwise non-iterable when "" in self.additional_fields runs, improving robustness of __post_init__. Impact is moderate since it’s defensive and may be unnecessary if additional_fields is guaranteed to be a list elsewhere.
Renaming/removing the two previous strategy classes can break downstream users that still import them. Provide backward-compatible aliases to the new unified strategy so existing imports keep working without changing behavior.
Why: Adding aliases for the removed classes (DsmCapacityHeuristicBalancingPosStrategy/NegStrategy) to point to DsmCapacityHeuristicBalancingStrategy is a practical compatibility improvement that can prevent breakage for external users still importing the old names, without changing runtime behavior of the unified strategy.
❌ Patch coverage is 60.00000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.13%. Comparing base (d8d42d5) to head (ad71102).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
User description
Description
This removes the redundant
DsmCapacityHeuristicBalancingNegStrategy/DsmCapacityHeuristicBalancingPosStrategy- it is fine to have both names resolving to the same class, but not good to have duplicated codebase without benefit.It looks similar, and actually was.
Additionally a bug in the base_market for the list of currently open auctions is fixed. This did not have any known use yet. This was also found in #810
Also
fixes #823
Checklist
docsfolder updates, etc.)Additional Notes (optional)
PR Type
Bug fix, Enhancement, Documentation, Tests
Description
Filter empty
additional_fieldsentries earlyCorrectly remove cleared products from
open_auctionsDeduplicate DSM CRM strategies into one
Update docs, notebook, and tests
Diagram Walkthrough
File Walkthrough
1 files
Warn and drop empty `additional_fields`1 files
Fix `open_auctions` set subtraction bug2 files
Repoint DSM CRM keys to unified strategyMerge DSM pos/neg CRM strategy classes1 files
Update imports and CRM strategy fixtures2 files
Refresh strategy API references after renameUpdate notebook to unified DSM strategy