diff --git a/src/r2x/exporter/sienna.py b/src/r2x/exporter/sienna.py index 24634a42..57be941d 100644 --- a/src/r2x/exporter/sienna.py +++ b/src/r2x/exporter/sienna.py @@ -217,6 +217,7 @@ def process_gen_data(self, fname="gen.csv"): "rating", "unit_type", "active_power", + "active_power_limits_max", "min_rated_capacity", "min_down_time", "min_up_time", diff --git a/src/r2x/models/generators.py b/src/r2x/models/generators.py index 6e0bc52b..c4a17367 100644 --- a/src/r2x/models/generators.py +++ b/src/r2x/models/generators.py @@ -116,6 +116,9 @@ class Generator(Device): shutdown_cost: ( Annotated[NonNegativeFloat, Field(description="Cost in $ of shuting down a unit.")] | None ) = None + active_power_limits_max: Annotated[ + ApparentPower | None, Field(ge=0, description="Maximum output power rating of the unit (MVA).") + ] = None class RenewableGen(Generator): diff --git a/src/r2x/parser/plexos.py b/src/r2x/parser/plexos.py index fb97d6e8..2e2c3ccd 100644 --- a/src/r2x/parser/plexos.py +++ b/src/r2x/parser/plexos.py @@ -685,11 +685,11 @@ def _construct_batteries(self): mapped_records["storage_capacity"] = mapped_records["Capacity"] mapped_records["prime_mover_type"] = PrimeMoversType.BA - valid_fields, ext_data = field_filter(mapped_records, GenericBattery.model_fields) - valid_fields = self._set_unit_availability(valid_fields) - if valid_fields is None: + mapped_records = self._set_unit_availability(mapped_records) + if mapped_records is None: continue + valid_fields, ext_data = field_filter(mapped_records, GenericBattery.model_fields) if not all(key in valid_fields for key in required_fields): missing_fields = [key for key in required_fields if key not in valid_fields] logger.warning( @@ -1014,7 +1014,7 @@ def _set_unit_availability(self, mapped_records): """ # TODO @ktehranchi: #35 Include date_from and date_to in the availability # https://github.com/NREL/R2X/issues/35 - + active_power_limits_max = None availability = mapped_records.get("available", None) if availability is not None and availability > 0: # Set availability, rating, storage_capacity as multiplier of availability/'units' @@ -1051,10 +1051,12 @@ def _set_unit_availability(self, mapped_records): max_ts_rating = np.max( val.data ) # plexos allows dispatch above max rating. Increase rating to max dispatch value - rating = Quantity(max_ts_rating, rating.units) + active_power_limits_max = Quantity(np.maximum(max_ts_rating, rating.magnitude), rating.units) self._apply_action(np.divide, val, rating.magnitude) mapped_records["max_active_power"] = val + mapped_records["active_power"] = rating + mapped_records["active_power_limits_max"] = active_power_limits_max or rating if isinstance(rating_factor, SingleTimeSeries): mapped_records.pop("Rating Factor") # rm for ext exporter