power-openapi-models 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- power_openapi_models/__init__.py +52 -0
- power_openapi_models/_schema_version.txt +1 -0
- power_openapi_models/core/__init__.py +5 -0
- power_openapi_models/core/models.py +818 -0
- power_openapi_models/document.py +290 -0
- power_openapi_models/dynamics/__init__.py +5 -0
- power_openapi_models/dynamics/models.py +257 -0
- power_openapi_models/infrastructure_core/__init__.py +5 -0
- power_openapi_models/infrastructure_core/models.py +175 -0
- power_openapi_models/investments/__init__.py +5 -0
- power_openapi_models/investments/models.py +564 -0
- power_openapi_models/operations/__init__.py +5 -0
- power_openapi_models/operations/models.py +2958 -0
- power_openapi_models/py.typed +0 -0
- power_openapi_models/timeseries/__init__.py +5 -0
- power_openapi_models/timeseries/models.py +626 -0
- power_openapi_models-0.1.0.dist-info/METADATA +237 -0
- power_openapi_models-0.1.0.dist-info/RECORD +21 -0
- power_openapi_models-0.1.0.dist-info/WHEEL +5 -0
- power_openapi_models-0.1.0.dist-info/licenses/LICENSE +29 -0
- power_openapi_models-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,818 @@
|
|
|
1
|
+
# generated by datamodel-codegen:
|
|
2
|
+
# filename: openapi-core.json
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
from enum import Enum, IntEnum
|
|
6
|
+
from pydantic import BaseModel, Field, RootModel
|
|
7
|
+
from typing import Literal
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
from power_openapi_models.infrastructure_core.models import (
|
|
11
|
+
ComplexNumber,
|
|
12
|
+
DataSource,
|
|
13
|
+
FromTo,
|
|
14
|
+
FromToToFrom,
|
|
15
|
+
FunctionData,
|
|
16
|
+
GeographicInfo,
|
|
17
|
+
InOut,
|
|
18
|
+
LinearFunctionData,
|
|
19
|
+
MinMax,
|
|
20
|
+
PiecewiseLinearData,
|
|
21
|
+
PiecewiseStepData,
|
|
22
|
+
QuadraticFunctionData,
|
|
23
|
+
SupplementalAttributeAssociation,
|
|
24
|
+
TimeSeriesLinearFunctionData,
|
|
25
|
+
TimeSeriesPiecewiseLinearData,
|
|
26
|
+
TimeSeriesPiecewiseStepData,
|
|
27
|
+
TimeSeriesQuadraticFunctionData,
|
|
28
|
+
UnitSystem,
|
|
29
|
+
UpDown,
|
|
30
|
+
XYCoords,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
__all__ = [
|
|
34
|
+
"ComplexNumber",
|
|
35
|
+
"DataSource",
|
|
36
|
+
"FromTo",
|
|
37
|
+
"FromToToFrom",
|
|
38
|
+
"FunctionData",
|
|
39
|
+
"GeographicInfo",
|
|
40
|
+
"InOut",
|
|
41
|
+
"LinearFunctionData",
|
|
42
|
+
"MinMax",
|
|
43
|
+
"PiecewiseLinearData",
|
|
44
|
+
"PiecewiseStepData",
|
|
45
|
+
"QuadraticFunctionData",
|
|
46
|
+
"SupplementalAttributeAssociation",
|
|
47
|
+
"TimeSeriesLinearFunctionData",
|
|
48
|
+
"TimeSeriesPiecewiseLinearData",
|
|
49
|
+
"TimeSeriesPiecewiseStepData",
|
|
50
|
+
"TimeSeriesQuadraticFunctionData",
|
|
51
|
+
"UnitSystem",
|
|
52
|
+
"UpDown",
|
|
53
|
+
"XYCoords",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class ACBusType(Enum):
|
|
58
|
+
PQ = "PQ"
|
|
59
|
+
PV = "PV"
|
|
60
|
+
REF = "REF"
|
|
61
|
+
ISOLATED = "ISOLATED"
|
|
62
|
+
SLACK = "SLACK"
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class ChargeDischarge(BaseModel):
|
|
66
|
+
charge: float
|
|
67
|
+
discharge: float
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class MinMaxByKey(RootModel[dict[str, MinMax]]):
|
|
71
|
+
root: dict[str, MinMax]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class OutageFactors(BaseModel):
|
|
75
|
+
planned: float | None = Field(None, title="Planned")
|
|
76
|
+
forced: float | None = Field(None, title="Forced")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class Arc(BaseModel):
|
|
80
|
+
id: int = Field(..., description="Unique integer identifier for this component.")
|
|
81
|
+
from_id: int = Field(..., description="ID of the initial bus.")
|
|
82
|
+
to_id: int = Field(..., description="ID of the terminal bus.")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class CurveMultiStep(IntEnum):
|
|
86
|
+
integer_0 = 0
|
|
87
|
+
integer_1 = 1
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class CurveStyles(IntEnum):
|
|
91
|
+
integer_0 = 0
|
|
92
|
+
integer_1 = 1
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class StartUpStages(BaseModel):
|
|
96
|
+
startup_stages_type: Literal["STAGES"] = "STAGES"
|
|
97
|
+
cold: float
|
|
98
|
+
hot: float
|
|
99
|
+
warm: float
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class DbdPnts(BaseModel):
|
|
103
|
+
dbd1: float | None = None
|
|
104
|
+
dbd2: float | None = None
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class DCBus(BaseModel):
|
|
108
|
+
area: int | None = Field(None, description="ID of the area containing the DC bus.")
|
|
109
|
+
available: bool = Field(
|
|
110
|
+
...,
|
|
111
|
+
description="Indicator of whether the component is connected and online (`true`) or disconnected, offline, or down (`false`). Unavailable components are excluded during simulations.",
|
|
112
|
+
)
|
|
113
|
+
base_voltage: float | None = Field(
|
|
114
|
+
None,
|
|
115
|
+
description="The base voltage. in psy5 a required param with an option to be nothing Units: kV.",
|
|
116
|
+
)
|
|
117
|
+
id: int = Field(..., description="Unique integer identifier for this component.")
|
|
118
|
+
load_zone: int | None = Field(None, description="ID of the load zone containing the DC bus.")
|
|
119
|
+
magnitude: float | None = Field(
|
|
120
|
+
None,
|
|
121
|
+
description="Voltage as a multiple of `base_voltage`. in psy5 a required param with an option to be nothing Units: pu.",
|
|
122
|
+
)
|
|
123
|
+
name: str = Field(
|
|
124
|
+
...,
|
|
125
|
+
description="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.",
|
|
126
|
+
)
|
|
127
|
+
number: float = Field(..., description="A unique bus identification number (positive integer).")
|
|
128
|
+
voltage_limits: MinMax | None = Field(
|
|
129
|
+
None,
|
|
130
|
+
description="Limits on the voltage variation as multiples of `base_voltage`. in psy5 a required param with an option to be nothing Units: pu.",
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class PollutantType(Enum):
|
|
135
|
+
CO2 = "CO2"
|
|
136
|
+
CO2E = "CO2E"
|
|
137
|
+
CH4 = "CH4"
|
|
138
|
+
N2O = "N2O"
|
|
139
|
+
NOX = "NOX"
|
|
140
|
+
SO2 = "SO2"
|
|
141
|
+
CO = "CO"
|
|
142
|
+
VOC = "VOC"
|
|
143
|
+
PM25 = "PM25"
|
|
144
|
+
PM10 = "PM10"
|
|
145
|
+
HG = "HG"
|
|
146
|
+
HAP = "HAP"
|
|
147
|
+
CUSTOM = "CUSTOM"
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class EmissionBasis(Enum):
|
|
151
|
+
FUEL_INPUT = "FUEL_INPUT"
|
|
152
|
+
POWER_OUTPUT = "POWER_OUTPUT"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class MassUnit(Enum):
|
|
156
|
+
KG = "KG"
|
|
157
|
+
LB = "LB"
|
|
158
|
+
SHORT_TON = "SHORT_TON"
|
|
159
|
+
METRIC_TON = "METRIC_TON"
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
class EnergyUnit(Enum):
|
|
163
|
+
MMBTU = "MMBTU"
|
|
164
|
+
GJ = "GJ"
|
|
165
|
+
MWH = "MWH"
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class EnergyUnitBasis(Enum):
|
|
169
|
+
MWH = "MWH"
|
|
170
|
+
MWMIN = "MWMIN"
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
class ImpedanceUnitBasis(Enum):
|
|
174
|
+
NATURAL_UNITS = "NATURAL_UNITS"
|
|
175
|
+
COMPONENT_BASE = "COMPONENT_BASE"
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class AdmittanceUnitBasis(Enum):
|
|
179
|
+
NATURAL_UNITS = "NATURAL_UNITS"
|
|
180
|
+
COMPONENT_MVAR = "COMPONENT_MVAR"
|
|
181
|
+
COMPONENT_BASE = "COMPONENT_BASE"
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class ShuntAdmittanceUnitBasis(Enum):
|
|
185
|
+
NATURAL_UNITS = "NATURAL_UNITS"
|
|
186
|
+
COMPONENT_MVAR = "COMPONENT_MVAR"
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class FdbdPnts(BaseModel):
|
|
190
|
+
fdbd1: float | None = None
|
|
191
|
+
fdbd2: float | None = None
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class HydroReservoirCost(BaseModel):
|
|
195
|
+
cost_type: Literal["HYDRO_RES"] = "HYDRO_RES"
|
|
196
|
+
level_shortage_cost: float | None = 0.0
|
|
197
|
+
level_surplus_cost: float | None = 0.0
|
|
198
|
+
spillage_cost: float | None = 0.0
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class LoadZone(BaseModel):
|
|
202
|
+
id: int = Field(..., description="Unique integer identifier for this component.")
|
|
203
|
+
name: str = Field(
|
|
204
|
+
...,
|
|
205
|
+
description="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.",
|
|
206
|
+
)
|
|
207
|
+
peak_active_power: float = Field(
|
|
208
|
+
...,
|
|
209
|
+
description="Peak active power in the zone. Units: per power_units — NATURAL_UNITS: MW, COMPONENT_BASE: pu .",
|
|
210
|
+
)
|
|
211
|
+
peak_reactive_power: float = Field(
|
|
212
|
+
...,
|
|
213
|
+
description="Peak reactive power in the zone. Units: per power_units — NATURAL_UNITS: MVAr, COMPONENT_BASE: pu .",
|
|
214
|
+
)
|
|
215
|
+
base_power: float = Field(
|
|
216
|
+
...,
|
|
217
|
+
description="System base power for per-unitization of this component's per-unit fields, recorded per component in lieu of a system-level table. Units: MVA.",
|
|
218
|
+
)
|
|
219
|
+
power_units: UnitSystem = Field(
|
|
220
|
+
...,
|
|
221
|
+
description="Unit basis for this component's power-family fields (active/reactive/apparent power, ratings, limits, ramp rates). COMPONENT_BASE: per unit on this component's own base_power. NATURAL_UNITS: the field's physical unit.",
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
class PrimeMovers(Enum):
|
|
226
|
+
BA = "BA"
|
|
227
|
+
BT = "BT"
|
|
228
|
+
CA = "CA"
|
|
229
|
+
CC = "CC"
|
|
230
|
+
CE = "CE"
|
|
231
|
+
CP = "CP"
|
|
232
|
+
CS = "CS"
|
|
233
|
+
CT = "CT"
|
|
234
|
+
ES = "ES"
|
|
235
|
+
FC = "FC"
|
|
236
|
+
FW = "FW"
|
|
237
|
+
GT = "GT"
|
|
238
|
+
HA = "HA"
|
|
239
|
+
HB = "HB"
|
|
240
|
+
HK = "HK"
|
|
241
|
+
HY = "HY"
|
|
242
|
+
IC = "IC"
|
|
243
|
+
PS = "PS"
|
|
244
|
+
OT = "OT"
|
|
245
|
+
ST = "ST"
|
|
246
|
+
PVe = "PVe"
|
|
247
|
+
WT = "WT"
|
|
248
|
+
WS = "WS"
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
class ReservoirLocation(Enum):
|
|
252
|
+
HEAD = "HEAD"
|
|
253
|
+
TAIL = "TAIL"
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class StartUpShutDown(BaseModel):
|
|
257
|
+
startup: float | None = Field(None, title="StartUp")
|
|
258
|
+
shutdown: float | None = Field(None, title="ShutDown")
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
class StorageTech(Enum):
|
|
262
|
+
PTES = "PTES"
|
|
263
|
+
LIB = "LIB"
|
|
264
|
+
LAB = "LAB"
|
|
265
|
+
FLWB = "FLWB"
|
|
266
|
+
SIB = "SIB"
|
|
267
|
+
ZIB = "ZIB"
|
|
268
|
+
HGS = "HGS"
|
|
269
|
+
LAES = "LAES"
|
|
270
|
+
OTHER_CHEM = "OTHER_CHEM"
|
|
271
|
+
OTHER_MECH = "OTHER_MECH"
|
|
272
|
+
OTHER_THERM = "OTHER_THERM"
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
class ThermalFuels(Enum):
|
|
276
|
+
ANTHRACITE_COAL = "ANTHRACITE_COAL"
|
|
277
|
+
BITUMINOUS_COAL = "BITUMINOUS_COAL"
|
|
278
|
+
LIGNITE_COAL = "LIGNITE_COAL"
|
|
279
|
+
SUBBITUMINOUS_COAL = "SUBBITUMINOUS_COAL"
|
|
280
|
+
WASTE_COAL = "WASTE_COAL"
|
|
281
|
+
REFINED_COAL = "REFINED_COAL"
|
|
282
|
+
SYNTHESIS_GAS_COAL = "SYNTHESIS_GAS_COAL"
|
|
283
|
+
DISTILLATE_FUEL_OIL = "DISTILLATE_FUEL_OIL"
|
|
284
|
+
JET_FUEL = "JET_FUEL"
|
|
285
|
+
KEROSENE = "KEROSENE"
|
|
286
|
+
PETROLEUM_COKE = "PETROLEUM_COKE"
|
|
287
|
+
RESIDUAL_FUEL_OIL = "RESIDUAL_FUEL_OIL"
|
|
288
|
+
PROPANE = "PROPANE"
|
|
289
|
+
SYNTHESIS_GAS_PETROLEUM_COKE = "SYNTHESIS_GAS_PETROLEUM_COKE"
|
|
290
|
+
WASTE_OIL = "WASTE_OIL"
|
|
291
|
+
BLAST_FURNACE_GAS = "BLAST_FURNACE_GAS"
|
|
292
|
+
NATURAL_GAS = "NATURAL_GAS"
|
|
293
|
+
OTHER_GAS = "OTHER_GAS"
|
|
294
|
+
AG_BYPRODUCT = "AG_BYPRODUCT"
|
|
295
|
+
MUNICIPAL_WASTE = "MUNICIPAL_WASTE"
|
|
296
|
+
OTHER_BIOMASS_SOLIDS = "OTHER_BIOMASS_SOLIDS"
|
|
297
|
+
WOOD_WASTE_SOLIDS = "WOOD_WASTE_SOLIDS"
|
|
298
|
+
OTHER_BIOMASS_LIQUIDS = "OTHER_BIOMASS_LIQUIDS"
|
|
299
|
+
SLUDGE_WASTE = "SLUDGE_WASTE"
|
|
300
|
+
BLACK_LIQUOR = "BLACK_LIQUOR"
|
|
301
|
+
WOOD_WASTE_LIQUIDS = "WOOD_WASTE_LIQUIDS"
|
|
302
|
+
LANDFILL_GAS = "LANDFILL_GAS"
|
|
303
|
+
OTHER_BIOMASS_GAS = "OTHER_BIOMASS_GAS"
|
|
304
|
+
NUCLEAR = "NUCLEAR"
|
|
305
|
+
WASTE_HEAT = "WASTE_HEAT"
|
|
306
|
+
TIRE_DERIVED_FUEL = "TIRE_DERIVED_FUEL"
|
|
307
|
+
COAL = "COAL"
|
|
308
|
+
GEOTHERMAL = "GEOTHERMAL"
|
|
309
|
+
OTHER = "OTHER"
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
class TurbinePump(BaseModel):
|
|
313
|
+
turbine: float
|
|
314
|
+
pump: float
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
class ACBus(BaseModel):
|
|
318
|
+
id: int = Field(..., description="Unique integer identifier for this component.")
|
|
319
|
+
number: int = Field(..., description="A unique bus identification number (positive integer).")
|
|
320
|
+
name: str = Field(
|
|
321
|
+
...,
|
|
322
|
+
description="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.",
|
|
323
|
+
)
|
|
324
|
+
available: bool = Field(
|
|
325
|
+
...,
|
|
326
|
+
description="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.",
|
|
327
|
+
)
|
|
328
|
+
bustype: ACBusType | None = Field(
|
|
329
|
+
None,
|
|
330
|
+
description="Used to describe the connectivity and behavior of this bus. in psy5 a required param with an option to be nothing",
|
|
331
|
+
)
|
|
332
|
+
angle: float | None = Field(None, description="Angle of the bus. Units: rad.")
|
|
333
|
+
magnitude: float | None = Field(
|
|
334
|
+
None, description="Voltage as a multiple of `base_voltage`. Units: pu."
|
|
335
|
+
)
|
|
336
|
+
voltage_limits: MinMax | None = Field(
|
|
337
|
+
None,
|
|
338
|
+
description="Limits on the voltage variation as multiples of `base_voltage`. Units: pu.",
|
|
339
|
+
)
|
|
340
|
+
base_voltage: float | None = Field(None, description="The base voltage. Units: kV.")
|
|
341
|
+
area: int | None = Field(None, description="ID of the area containing the bus.")
|
|
342
|
+
load_zone: int | None = Field(None, description="ID of the load zone containing the bus.")
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class AverageRateCurve(BaseModel):
|
|
346
|
+
curve_type: Literal["AVERAGE_RATE"] = "AVERAGE_RATE"
|
|
347
|
+
function_data: LinearFunctionData | PiecewiseStepData = Field(
|
|
348
|
+
..., discriminator="function_type"
|
|
349
|
+
)
|
|
350
|
+
initial_input: float | None = None
|
|
351
|
+
input_at_zero: float | None = None
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
class IncrementalCurve(BaseModel):
|
|
355
|
+
curve_type: Literal["INCREMENTAL"] = "INCREMENTAL"
|
|
356
|
+
function_data: LinearFunctionData | PiecewiseStepData = Field(
|
|
357
|
+
..., discriminator="function_type"
|
|
358
|
+
)
|
|
359
|
+
initial_input: float | None = None
|
|
360
|
+
input_at_zero: float | None = None
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
class Area(BaseModel):
|
|
364
|
+
id: int = Field(..., description="Unique integer identifier for this component.")
|
|
365
|
+
name: str = Field(
|
|
366
|
+
...,
|
|
367
|
+
description="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.",
|
|
368
|
+
)
|
|
369
|
+
peak_active_power: float | None = Field(
|
|
370
|
+
0.0,
|
|
371
|
+
description="Peak active power in the area. Units: per power_units — NATURAL_UNITS: MW, COMPONENT_BASE: pu .",
|
|
372
|
+
)
|
|
373
|
+
peak_reactive_power: float | None = Field(
|
|
374
|
+
0.0,
|
|
375
|
+
description="Peak reactive power in the area. Units: per power_units — NATURAL_UNITS: MVAr, COMPONENT_BASE: pu .",
|
|
376
|
+
)
|
|
377
|
+
load_response: float | None = Field(
|
|
378
|
+
0.0,
|
|
379
|
+
description="Load-frequency damping parameter modeling how much the load in the area changes due to changes in frequency. Units: MW/Hz.",
|
|
380
|
+
)
|
|
381
|
+
base_power: float = Field(
|
|
382
|
+
...,
|
|
383
|
+
description="System base power for per-unitization of this component's per-unit fields, recorded per component in lieu of a system-level table. Units: MVA.",
|
|
384
|
+
)
|
|
385
|
+
power_units: UnitSystem = Field(
|
|
386
|
+
...,
|
|
387
|
+
description="Unit basis for this component's power-family fields (active/reactive/apparent power, ratings, limits, ramp rates). COMPONENT_BASE: per unit on this component's own base_power. NATURAL_UNITS: the field's physical unit.",
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
class InputOutputCurve(BaseModel):
|
|
392
|
+
curve_type: Literal["INPUT_OUTPUT"] = "INPUT_OUTPUT"
|
|
393
|
+
function_data: QuadraticFunctionData | LinearFunctionData | PiecewiseLinearData = Field(
|
|
394
|
+
..., discriminator="function_type"
|
|
395
|
+
)
|
|
396
|
+
input_at_zero: float | None = None
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class LossValueCurve(RootModel[InputOutputCurve | IncrementalCurve]):
|
|
400
|
+
root: InputOutputCurve | IncrementalCurve = Field(
|
|
401
|
+
default_factory=lambda: InputOutputCurve.model_validate(
|
|
402
|
+
{
|
|
403
|
+
"curve_type": "INPUT_OUTPUT",
|
|
404
|
+
"function_data": {
|
|
405
|
+
"function_type": "LINEAR",
|
|
406
|
+
"constant_term": 0,
|
|
407
|
+
"proportional_term": 0,
|
|
408
|
+
},
|
|
409
|
+
}
|
|
410
|
+
),
|
|
411
|
+
description="The shape of a loss curve, selected by `curve_type`. `INPUT_OUTPUT` gives the total loss at each flow level -- a constant loss plus a proportional loss rate, in MW of loss per MW of flow. `INCREMENTAL` gives the marginal loss rate instead, the form a piecewise model uses to give different proportional losses on different flow segments. Individual loss fields accept narrower sets of shapes than this union admits; the consuming data layer enforces that, not this schema.",
|
|
412
|
+
discriminator="curve_type",
|
|
413
|
+
title="LossValueCurve",
|
|
414
|
+
)
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
class TimeSeriesAverageRateCurve(BaseModel):
|
|
418
|
+
curve_type: Literal["TIME_SERIES_AVERAGE_RATE"] = "TIME_SERIES_AVERAGE_RATE"
|
|
419
|
+
function_data: FunctionData = Field(
|
|
420
|
+
...,
|
|
421
|
+
description="Only TIME_SERIES_LINEAR or TIME_SERIES_PIECEWISE_STEP is admissible here; all other FunctionData variants, static or time-series-backed, are rejected by the consuming constructor.",
|
|
422
|
+
)
|
|
423
|
+
initial_input_association_id: int | None = Field(
|
|
424
|
+
None,
|
|
425
|
+
description="Store-minted id of the time series supplying the initial input value, or null.",
|
|
426
|
+
)
|
|
427
|
+
input_at_zero_association_id: int | None = Field(
|
|
428
|
+
None,
|
|
429
|
+
description="Store-minted id of the time series supplying the input at zero output, or null.",
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
class TimeSeriesIncrementalCurve(BaseModel):
|
|
434
|
+
curve_type: Literal["TIME_SERIES_INCREMENTAL"] = "TIME_SERIES_INCREMENTAL"
|
|
435
|
+
function_data: FunctionData = Field(
|
|
436
|
+
...,
|
|
437
|
+
description="Only TIME_SERIES_LINEAR or TIME_SERIES_PIECEWISE_STEP is admissible here; all other FunctionData variants, static or time-series-backed, are rejected by the consuming constructor.",
|
|
438
|
+
)
|
|
439
|
+
initial_input_association_id: int | None = Field(
|
|
440
|
+
None,
|
|
441
|
+
description="Store-minted id of the time series supplying the initial input value, or null.",
|
|
442
|
+
)
|
|
443
|
+
input_at_zero_association_id: int | None = Field(
|
|
444
|
+
None,
|
|
445
|
+
description="Store-minted id of the time series supplying the input at zero output, or null.",
|
|
446
|
+
)
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
class TimeSeriesInputOutputCurve(BaseModel):
|
|
450
|
+
curve_type: Literal["TIME_SERIES_INPUT_OUTPUT"] = "TIME_SERIES_INPUT_OUTPUT"
|
|
451
|
+
function_data: FunctionData = Field(
|
|
452
|
+
...,
|
|
453
|
+
description="Only TIME_SERIES_LINEAR, TIME_SERIES_QUADRATIC, or TIME_SERIES_PIECEWISE_LINEAR is admissible here; the static variants and TIME_SERIES_PIECEWISE_STEP are invalid and rejected by the consuming constructor.",
|
|
454
|
+
)
|
|
455
|
+
input_at_zero: float | None = Field(
|
|
456
|
+
None,
|
|
457
|
+
description="Optional explicit input value at zero output. A number here, unlike the incremental and average-rate variants, where it is a time series reference.",
|
|
458
|
+
)
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
class LossCurve(BaseModel):
|
|
462
|
+
power_units: UnitSystem = UnitSystem.NATURAL_UNITS
|
|
463
|
+
value_curve: LossValueCurve = Field(
|
|
464
|
+
{
|
|
465
|
+
"curve_type": "INPUT_OUTPUT",
|
|
466
|
+
"function_data": {
|
|
467
|
+
"function_type": "LINEAR",
|
|
468
|
+
"constant_term": 0,
|
|
469
|
+
"proportional_term": 0,
|
|
470
|
+
},
|
|
471
|
+
},
|
|
472
|
+
validate_default=True,
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
class ValueCurve(
|
|
477
|
+
RootModel[
|
|
478
|
+
InputOutputCurve
|
|
479
|
+
| IncrementalCurve
|
|
480
|
+
| AverageRateCurve
|
|
481
|
+
| TimeSeriesInputOutputCurve
|
|
482
|
+
| TimeSeriesIncrementalCurve
|
|
483
|
+
| TimeSeriesAverageRateCurve
|
|
484
|
+
]
|
|
485
|
+
):
|
|
486
|
+
root: (
|
|
487
|
+
InputOutputCurve
|
|
488
|
+
| IncrementalCurve
|
|
489
|
+
| AverageRateCurve
|
|
490
|
+
| TimeSeriesInputOutputCurve
|
|
491
|
+
| TimeSeriesIncrementalCurve
|
|
492
|
+
| TimeSeriesAverageRateCurve
|
|
493
|
+
) = Field(
|
|
494
|
+
...,
|
|
495
|
+
description="A cost or fuel curve: function data plus a declaration of how to read its y axis. `INPUT_OUTPUT` reads y as the total `f(x)`, `INCREMENTAL` as the marginal rate `f'(x)`, and `AVERAGE_RATE` as the average `f(x)/x`; the three can express the same underlying function and are inter-convertible given `initial_input`. The `TIME_SERIES_*` variants are the time-varying equivalents. Which form to use follows the data source: bid stacks are incremental, total cost tables input-output, efficiency tables average rate.",
|
|
496
|
+
discriminator="curve_type",
|
|
497
|
+
title="ValueCurve",
|
|
498
|
+
)
|
|
499
|
+
|
|
500
|
+
|
|
501
|
+
class StorageCapitalCost(BaseModel):
|
|
502
|
+
charge_capital_cost: ValueCurve
|
|
503
|
+
discharge_capital_cost: ValueCurve
|
|
504
|
+
energy_capital_cost: ValueCurve
|
|
505
|
+
interconnection_cost: float = 0.0
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
class CostCurve(BaseModel):
|
|
509
|
+
power_units: UnitSystem = UnitSystem.NATURAL_UNITS
|
|
510
|
+
value_curve: ValueCurve
|
|
511
|
+
variable_cost_type: Literal["COST"] = "COST"
|
|
512
|
+
vom_cost: InputOutputCurve = Field(
|
|
513
|
+
default_factory=lambda: InputOutputCurve.model_validate(
|
|
514
|
+
{
|
|
515
|
+
"curve_type": "INPUT_OUTPUT",
|
|
516
|
+
"function_data": {
|
|
517
|
+
"function_type": "LINEAR",
|
|
518
|
+
"constant_term": 0,
|
|
519
|
+
"proportional_term": 0,
|
|
520
|
+
},
|
|
521
|
+
}
|
|
522
|
+
)
|
|
523
|
+
)
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
class EmissionsData(BaseModel):
|
|
527
|
+
id: int
|
|
528
|
+
name: str = Field(..., description="Identifier for this emissions attribute")
|
|
529
|
+
pollutant: PollutantType = Field(
|
|
530
|
+
...,
|
|
531
|
+
description="Pollutant identity (CO2, CO2E, CH4, N2O, NOX, SO2, PM25, PM10, HG, HAP, CUSTOM)",
|
|
532
|
+
)
|
|
533
|
+
emission_rate: ValueCurve = Field(
|
|
534
|
+
...,
|
|
535
|
+
description="Emission rate as a ValueCurve, typically an IncrementalCurve with LinearFunctionData (constant or linearly varying rate) or PiecewiseStepData (piecewise step rates). Rates must be non-negative and finite.",
|
|
536
|
+
)
|
|
537
|
+
basis: EmissionBasis = Field(
|
|
538
|
+
...,
|
|
539
|
+
description="FUEL_INPUT (mass per unit of heat input) or POWER_OUTPUT (mass per unit of electrical output)",
|
|
540
|
+
)
|
|
541
|
+
start_up_adder: float | None = Field(
|
|
542
|
+
0.0,
|
|
543
|
+
description="Per-start emission pulse, in mass_unit. Must be finite and non-negative. Units: per mass_unit — KG: kg, LB: lb, SHORT_TON: ston, METRIC_TON: t .",
|
|
544
|
+
)
|
|
545
|
+
mass_unit: MassUnit | None = Field("KG", description="Mass unit of the emission rate numerator")
|
|
546
|
+
energy_unit: EnergyUnit = Field(
|
|
547
|
+
...,
|
|
548
|
+
description="Energy unit for the rate denominator. Must be MMBTU or GJ when basis is FUEL_INPUT, and MWH when basis is POWER_OUTPUT.",
|
|
549
|
+
)
|
|
550
|
+
gwp: float | None = Field(
|
|
551
|
+
1.0,
|
|
552
|
+
description="GWP100 multiplier for CO2-equivalent reporting. Must be finite and non-negative. Units: 1.",
|
|
553
|
+
)
|
|
554
|
+
available: bool | None = Field(True, description="Whether this attribute is active")
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
class FuelCurve(BaseModel):
|
|
558
|
+
fuel_cost: float | None = Field(
|
|
559
|
+
None,
|
|
560
|
+
description="Fixed fuel cost per unit of fuel, or null when fuel_cost_time_series names a time-varying one. Exactly one of the two is set; producers and consumers enforce it.",
|
|
561
|
+
)
|
|
562
|
+
fuel_cost_time_series: int | None = Field(
|
|
563
|
+
None,
|
|
564
|
+
description="Store-minted id of the fuel-cost time series association, or null when fuel_cost carries a fixed value. Exactly one of the two is set.",
|
|
565
|
+
)
|
|
566
|
+
power_units: UnitSystem
|
|
567
|
+
startup_fuel_offtake: InputOutputCurve | None = Field(
|
|
568
|
+
None, description="Fuel consumed during startup, as a curve in the unit's fuel units."
|
|
569
|
+
)
|
|
570
|
+
value_curve: ValueCurve
|
|
571
|
+
variable_cost_type: Literal["FUEL"] = "FUEL"
|
|
572
|
+
vom_cost: InputOutputCurve = Field(
|
|
573
|
+
{
|
|
574
|
+
"curve_type": "INPUT_OUTPUT",
|
|
575
|
+
"function_data": {
|
|
576
|
+
"function_type": "LINEAR",
|
|
577
|
+
"constant_term": 0,
|
|
578
|
+
"proportional_term": 0,
|
|
579
|
+
},
|
|
580
|
+
},
|
|
581
|
+
validate_default=True,
|
|
582
|
+
)
|
|
583
|
+
|
|
584
|
+
|
|
585
|
+
class RenewableGenerationCost(BaseModel):
|
|
586
|
+
cost_type: Literal["RENEWABLE"] = "RENEWABLE"
|
|
587
|
+
curtailment_cost: CostCurve | None = Field(
|
|
588
|
+
default_factory=lambda: CostCurve.model_validate(
|
|
589
|
+
{
|
|
590
|
+
"variable_cost_type": "COST",
|
|
591
|
+
"value_curve": {
|
|
592
|
+
"curve_type": "INPUT_OUTPUT",
|
|
593
|
+
"function_data": {
|
|
594
|
+
"function_type": "LINEAR",
|
|
595
|
+
"constant_term": 0,
|
|
596
|
+
"proportional_term": 0,
|
|
597
|
+
},
|
|
598
|
+
},
|
|
599
|
+
"vom_cost": {
|
|
600
|
+
"curve_type": "INPUT_OUTPUT",
|
|
601
|
+
"function_data": {
|
|
602
|
+
"function_type": "LINEAR",
|
|
603
|
+
"constant_term": 0,
|
|
604
|
+
"proportional_term": 0,
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
}
|
|
608
|
+
)
|
|
609
|
+
)
|
|
610
|
+
variable_operation_cost: CostCurve
|
|
611
|
+
fixed: float | None = 0.0
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
class ProductionVariableCostCurve(RootModel[CostCurve | FuelCurve]):
|
|
615
|
+
root: CostCurve | FuelCurve = Field(
|
|
616
|
+
...,
|
|
617
|
+
description="Variable production cost of a device, selected by `variable_cost_type` between a curve denominated directly in currency (`COST`) and one denominated in fuel with a separate fuel price (`FUEL`).",
|
|
618
|
+
discriminator="variable_cost_type",
|
|
619
|
+
title="ProductionVariableCostCurve",
|
|
620
|
+
)
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
class StorageCost(BaseModel):
|
|
624
|
+
cost_type: Literal["STORAGE"] = "STORAGE"
|
|
625
|
+
charge_variable_cost: CostCurve | None = None
|
|
626
|
+
discharge_variable_cost: CostCurve | None = None
|
|
627
|
+
fixed: float = 0.0
|
|
628
|
+
shut_down: float = 0.0
|
|
629
|
+
start_up: float | ChargeDischarge = 0.0
|
|
630
|
+
energy_shortage_cost: float | None = 0.0
|
|
631
|
+
energy_surplus_cost: float | None = 0.0
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
class ImportExportCost(BaseModel):
|
|
635
|
+
cost_type: Literal["IMPORTEXPORT"] = "IMPORTEXPORT"
|
|
636
|
+
import_offer_curves: CostCurve | None = None
|
|
637
|
+
export_offer_curves: CostCurve | None = None
|
|
638
|
+
energy_import_weekly_limit: float = Field(
|
|
639
|
+
...,
|
|
640
|
+
description="Weekly limit on imported energy, in MWh. MWh is the only representation: neither producers nor consumers rescale it by a system base. Units: MWh.",
|
|
641
|
+
)
|
|
642
|
+
energy_export_weekly_limit: float = Field(
|
|
643
|
+
...,
|
|
644
|
+
description="Weekly limit on exported energy, in MWh. MWh is the only representation: neither producers nor consumers rescale it by a system base. Units: MWh.",
|
|
645
|
+
)
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
class ImportExportTimeSeriesCost(BaseModel):
|
|
649
|
+
cost_type: Literal["IMPORT_EXPORT_TIME_SERIES"] = "IMPORT_EXPORT_TIME_SERIES"
|
|
650
|
+
import_offer_curves: CostCurve = Field(
|
|
651
|
+
...,
|
|
652
|
+
description="Import price curves whose value curve admits only the TIME_SERIES_INCREMENTAL variant; any other variant is rejected by the consuming constructor.",
|
|
653
|
+
)
|
|
654
|
+
export_offer_curves: CostCurve = Field(
|
|
655
|
+
...,
|
|
656
|
+
description="Export price curves whose value curve admits only the TIME_SERIES_INCREMENTAL variant; any other variant is rejected by the consuming constructor.",
|
|
657
|
+
)
|
|
658
|
+
energy_import_weekly_limit: float = Field(
|
|
659
|
+
...,
|
|
660
|
+
description="Weekly limit on imported energy, in MWh. MWh is the only representation: neither producers nor consumers rescale it by a system base. Units: MWh.",
|
|
661
|
+
)
|
|
662
|
+
energy_export_weekly_limit: float = Field(
|
|
663
|
+
...,
|
|
664
|
+
description="Weekly limit on exported energy, in MWh. MWh is the only representation: neither producers nor consumers rescale it by a system base. Units: MWh.",
|
|
665
|
+
)
|
|
666
|
+
ancillary_service_offers: list[int]
|
|
667
|
+
|
|
668
|
+
|
|
669
|
+
class LoadCost(BaseModel):
|
|
670
|
+
cost_type: Literal["LOAD"] = "LOAD"
|
|
671
|
+
fixed: float | None = 0.0
|
|
672
|
+
variable_operation_cost: CostCurve
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
class MarketBidTimeSeriesCost(BaseModel):
|
|
676
|
+
cost_type: Literal["MARKET_BID_TIME_SERIES"] = "MARKET_BID_TIME_SERIES"
|
|
677
|
+
minimum_energy_offer: TimeSeriesInputOutputCurve = Field(
|
|
678
|
+
...,
|
|
679
|
+
description="Minimum-energy offer: cost to operate at minimum stable level, in $/MWh at the curve's minimum power, stored as submitted. $/h sources convert at parse (MEO = no-load cost / P_min). Time-series-backed linear curve; only the TIME_SERIES_LINEAR function-data variant is admissible here — the consuming constructor rejects any other.",
|
|
680
|
+
)
|
|
681
|
+
start_up_association_id: int = Field(
|
|
682
|
+
...,
|
|
683
|
+
description="Store-minted id of a time series of three-stage (hot, warm, cold) start-up costs.",
|
|
684
|
+
)
|
|
685
|
+
shut_down: TimeSeriesInputOutputCurve = Field(
|
|
686
|
+
...,
|
|
687
|
+
description="Shut-down cost as a time-series-backed linear curve. Only the TIME_SERIES_LINEAR function-data variant is admissible here; the consuming constructor rejects any other.",
|
|
688
|
+
)
|
|
689
|
+
incremental_offer_curves: CostCurve = Field(
|
|
690
|
+
...,
|
|
691
|
+
description="Sell offer curves whose value curve is a time-series-backed piecewise incremental curve. Only the TIME_SERIES_INCREMENTAL variant is admissible here; any other variant is rejected by the consuming constructor.",
|
|
692
|
+
)
|
|
693
|
+
decremental_offer_curves: CostCurve = Field(
|
|
694
|
+
...,
|
|
695
|
+
description="Buy offer curves whose value curve is a time-series-backed piecewise incremental curve. Only the TIME_SERIES_INCREMENTAL variant is admissible here; any other variant is rejected by the consuming constructor.",
|
|
696
|
+
)
|
|
697
|
+
ancillary_service_offers: list[int] = Field(
|
|
698
|
+
..., description="IDs of the ancillary service components that this bid offers into."
|
|
699
|
+
)
|
|
700
|
+
incremental_slope: bool | None = Field(
|
|
701
|
+
False,
|
|
702
|
+
description="Linear-interpolation flag for the incremental offer curves; false (default) is the step interpretation. Mutually exclusive with block groups on the same curve.",
|
|
703
|
+
)
|
|
704
|
+
decremental_slope: bool | None = Field(
|
|
705
|
+
False,
|
|
706
|
+
description="Linear-interpolation flag for the decremental offer curves; false (default) is the step interpretation. Mutually exclusive with block groups on the same curve.",
|
|
707
|
+
)
|
|
708
|
+
curve_style: CurveStyles | None = Field(
|
|
709
|
+
0,
|
|
710
|
+
description="Curve-clearing style for the bid: 0 = VARIABLE (default; continuous quantity with one or more segments); 1 = FIXED (all-or-nothing block with a single segment). FIXED is mutually exclusive with incremental_slope/decremental_slope and requires a single-segment offer curve.",
|
|
711
|
+
)
|
|
712
|
+
curve_multistep: CurveMultiStep | None = Field(
|
|
713
|
+
0,
|
|
714
|
+
description="Multi-step block indicator for the bid: 0 = SINGLE_STEP (default; each step of the bid clears independently); 1 = MULTI_STEP (the bid must be awarded as one block across every step it covers). Counted in model steps so it applies at any resolution. Independent of curve_style: curve_style is the quantity structure, curve_multistep is the time structure, and they compose.",
|
|
715
|
+
)
|
|
716
|
+
|
|
717
|
+
|
|
718
|
+
class CapitalCost(BaseModel):
|
|
719
|
+
capital_cost: ValueCurve
|
|
720
|
+
interconnection_cost: float | None = 0.0
|
|
721
|
+
|
|
722
|
+
|
|
723
|
+
class MarketBidCost(BaseModel):
|
|
724
|
+
cost_type: Literal["MARKET_BID"] = "MARKET_BID"
|
|
725
|
+
minimum_energy_offer: InputOutputCurve = Field(
|
|
726
|
+
default_factory=lambda: InputOutputCurve.model_validate(
|
|
727
|
+
{
|
|
728
|
+
"curve_type": "INPUT_OUTPUT",
|
|
729
|
+
"function_data": {
|
|
730
|
+
"function_type": "LINEAR",
|
|
731
|
+
"constant_term": 0,
|
|
732
|
+
"proportional_term": 0,
|
|
733
|
+
},
|
|
734
|
+
}
|
|
735
|
+
),
|
|
736
|
+
description="Minimum-energy offer: cost to operate at minimum stable level, in $/MWh at the curve's minimum power, stored as submitted. $/h sources convert at parse (MEO = no-load cost / P_min). Legacy scalar promotion: a bare scalar value `s` from a legacy source converts to an `InputOutputCurve` of `LinearFunctionData` with `constant_term = s` and `proportional_term = 0`.",
|
|
737
|
+
)
|
|
738
|
+
start_up: StartUpStages = Field(
|
|
739
|
+
..., description="Start-up cost at different stages of the thermal cycle (hot, warm, cold)."
|
|
740
|
+
)
|
|
741
|
+
shut_down: InputOutputCurve = Field(
|
|
742
|
+
default_factory=lambda: InputOutputCurve.model_validate(
|
|
743
|
+
{
|
|
744
|
+
"curve_type": "INPUT_OUTPUT",
|
|
745
|
+
"function_data": {
|
|
746
|
+
"function_type": "LINEAR",
|
|
747
|
+
"constant_term": 0,
|
|
748
|
+
"proportional_term": 0,
|
|
749
|
+
},
|
|
750
|
+
}
|
|
751
|
+
),
|
|
752
|
+
description="Shut-down cost. Legacy scalar promotion: a bare scalar value `s` from a legacy source converts to an `InputOutputCurve` of `LinearFunctionData` with `constant_term = s` and `proportional_term = 0`.",
|
|
753
|
+
)
|
|
754
|
+
incremental_offer_curves: CostCurve = Field(
|
|
755
|
+
..., description="Sell offer curves data as a `CostCurve` of `PiecewiseIncrementalCurve`."
|
|
756
|
+
)
|
|
757
|
+
decremental_offer_curves: CostCurve = Field(
|
|
758
|
+
..., description="Buy offer curves data as a `CostCurve` of `PiecewiseIncrementalCurve`."
|
|
759
|
+
)
|
|
760
|
+
ancillary_service_offers: list[int] = Field(
|
|
761
|
+
..., description="IDs of the ancillary service components that this market bid offers into."
|
|
762
|
+
)
|
|
763
|
+
incremental_slope: bool | None = Field(
|
|
764
|
+
False,
|
|
765
|
+
description="Linear-interpolation flag for the incremental offer curves; false (default) is the step interpretation. Mutually exclusive with block groups on the same curve.",
|
|
766
|
+
)
|
|
767
|
+
decremental_slope: bool | None = Field(
|
|
768
|
+
False,
|
|
769
|
+
description="Linear-interpolation flag for the decremental offer curves; false (default) is the step interpretation. Mutually exclusive with block groups on the same curve.",
|
|
770
|
+
)
|
|
771
|
+
curve_style: CurveStyles | None = Field(
|
|
772
|
+
0,
|
|
773
|
+
description="Curve-clearing style for the bid: 0 = VARIABLE (default; continuous quantity with one or more segments); 1 = FIXED (all-or-nothing block with a single segment). FIXED is mutually exclusive with incremental_slope/decremental_slope and requires a single-segment offer curve.",
|
|
774
|
+
)
|
|
775
|
+
curve_multistep: CurveMultiStep | None = Field(
|
|
776
|
+
0,
|
|
777
|
+
description="Multi-step block indicator for the bid: 0 = SINGLE_STEP (default; each step of the bid clears independently); 1 = MULTI_STEP (the bid must be awarded as one block across every step it covers). Counted in model steps so it applies at any resolution. Independent of curve_style: curve_style is the quantity structure, curve_multistep is the time structure, and they compose.",
|
|
778
|
+
)
|
|
779
|
+
|
|
780
|
+
|
|
781
|
+
class HydroGenerationCost(BaseModel):
|
|
782
|
+
cost_type: Literal["HYDRO_GEN"] = "HYDRO_GEN"
|
|
783
|
+
fixed: float | None = 0.0
|
|
784
|
+
variable_operation_cost: ProductionVariableCostCurve
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
class ThermalGenerationCost(BaseModel):
|
|
788
|
+
cost_type: Literal["THERMAL"] = "THERMAL"
|
|
789
|
+
fixed: float = Field(
|
|
790
|
+
...,
|
|
791
|
+
description="Fixed cost of keeping the unit online. For some cost represenations this field can be duplicative",
|
|
792
|
+
)
|
|
793
|
+
shut_down: float = Field(..., description="Cost to turn the unit off")
|
|
794
|
+
start_up: float | StartUpStages = Field(
|
|
795
|
+
...,
|
|
796
|
+
description="Start-up cost can take linear or multi-stage cost",
|
|
797
|
+
)
|
|
798
|
+
variable_operation_cost: ProductionVariableCostCurve
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
class HydroStorageGenerationCost(RootModel[HydroGenerationCost | StorageCost]):
|
|
802
|
+
root: HydroGenerationCost | StorageCost = Field(
|
|
803
|
+
...,
|
|
804
|
+
description="Operating cost of hydro generation with storage, selected by `cost_type` between the hydro generation (`HYDRO_GEN`) and storage (`STORAGE`) cost representations.",
|
|
805
|
+
discriminator="cost_type",
|
|
806
|
+
title="HydroStorageGenerationCost",
|
|
807
|
+
)
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
class GenericOperationCost(
|
|
811
|
+
RootModel[ThermalGenerationCost | RenewableGenerationCost | HydroGenerationCost]
|
|
812
|
+
):
|
|
813
|
+
root: ThermalGenerationCost | RenewableGenerationCost | HydroGenerationCost = Field(
|
|
814
|
+
...,
|
|
815
|
+
description="Operating cost of a generation technology, selected by `cost_type` among the thermal (`THERMAL`), renewable (`RENEWABLE`), and hydro (`HYDRO_GEN`) generation cost representations.",
|
|
816
|
+
discriminator="cost_type",
|
|
817
|
+
title="GenericOperationCost",
|
|
818
|
+
)
|