mms-client 1.6.0__py3-none-any.whl → 1.8.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.
- mms_client/security/certs.py +34 -1
- mms_client/security/crypto.py +30 -22
- mms_client/services/base.py +133 -66
- mms_client/services/market.py +31 -12
- mms_client/services/registration.py +12 -9
- mms_client/services/report.py +144 -1
- mms_client/types/base.py +53 -13
- mms_client/types/enums.py +34 -0
- mms_client/types/report.py +474 -0
- mms_client/types/resource.py +4 -34
- mms_client/types/transport.py +2 -2
- mms_client/utils/multipart_transport.py +259 -0
- mms_client/utils/serialization.py +137 -44
- mms_client/utils/web.py +16 -2
- {mms_client-1.6.0.dist-info → mms_client-1.8.0.dist-info}/METADATA +14 -5
- {mms_client-1.6.0.dist-info → mms_client-1.8.0.dist-info}/RECORD +18 -16
- {mms_client-1.6.0.dist-info → mms_client-1.8.0.dist-info}/LICENSE +0 -0
- {mms_client-1.6.0.dist-info → mms_client-1.8.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
"""Contains objects for report data."""
|
|
2
|
+
|
|
3
|
+
from datetime import date as Date
|
|
4
|
+
from decimal import Decimal
|
|
5
|
+
from enum import StrEnum
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
from typing import List
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from pydantic_core import PydanticUndefined
|
|
11
|
+
from pydantic_extra_types.pendulum_dt import DateTime
|
|
12
|
+
from pydantic_xml import BaseXmlModel
|
|
13
|
+
from pydantic_xml import attr
|
|
14
|
+
from pydantic_xml import element
|
|
15
|
+
from pydantic_xml import wrapped
|
|
16
|
+
|
|
17
|
+
from mms_client.types.base import Envelope
|
|
18
|
+
from mms_client.types.base import Payload
|
|
19
|
+
from mms_client.types.enums import AreaCode
|
|
20
|
+
from mms_client.types.enums import BaseLineSettingMethod
|
|
21
|
+
from mms_client.types.enums import CommandMonitorMethod
|
|
22
|
+
from mms_client.types.enums import ContractType
|
|
23
|
+
from mms_client.types.enums import RemainingReserveAvailability
|
|
24
|
+
from mms_client.types.enums import SignalType
|
|
25
|
+
from mms_client.types.fields import company_short_name
|
|
26
|
+
from mms_client.types.fields import participant
|
|
27
|
+
from mms_client.types.fields import percentage
|
|
28
|
+
from mms_client.types.fields import resource_name
|
|
29
|
+
from mms_client.types.fields import resource_short_name
|
|
30
|
+
from mms_client.types.fields import system_code
|
|
31
|
+
from mms_client.types.fields import transaction_id
|
|
32
|
+
from mms_client.types.registration import QueryType
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def file_name(alias: str, optional: bool = False):
|
|
36
|
+
"""Create a field for a file name.
|
|
37
|
+
|
|
38
|
+
Arguments:
|
|
39
|
+
alias (str): The name of the alias to assign to the Pydanitc field. This value will be used to map the field
|
|
40
|
+
to the JSON/XML key.
|
|
41
|
+
optional (bool): If True, the field will be optional with a default of None. If False, the field will be
|
|
42
|
+
required, with no default.
|
|
43
|
+
|
|
44
|
+
Returns: A Pydantic Field object for the file name.
|
|
45
|
+
"""
|
|
46
|
+
return attr(default=None if optional else PydanticUndefined, name=alias, min_length=0, max_length=60)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def row_number(alias: str, optional: bool = False):
|
|
50
|
+
"""Create a field for a row number.
|
|
51
|
+
|
|
52
|
+
Arguments:
|
|
53
|
+
alias (str): The name of the alias to assign to the Pydanitc field. This value will be used to map the field
|
|
54
|
+
to the JSON/XML key.
|
|
55
|
+
optional (bool): If True, the field will be optional with a default of None. If False, the field will be
|
|
56
|
+
required, with no default.
|
|
57
|
+
|
|
58
|
+
Returns: A Pydantic Field object for the row number.
|
|
59
|
+
"""
|
|
60
|
+
return attr(default=None if optional else PydanticUndefined, name=alias, ge=1, lt=100000000)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class ApplicationType(StrEnum):
|
|
64
|
+
"""Represents the type of report to be submitted."""
|
|
65
|
+
|
|
66
|
+
MARKET_REPORT = "MARKET_REPORT"
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class ReportType(StrEnum):
|
|
70
|
+
"""Represents the type of data to be submitted."""
|
|
71
|
+
|
|
72
|
+
REGISTRATION = "REGISTRATION"
|
|
73
|
+
MARKET = "MA"
|
|
74
|
+
INTERFACE = "INTERFACE"
|
|
75
|
+
SWITCH = "SWITCH"
|
|
76
|
+
SYSTEM = "SYSTEM"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class ReportSubType(StrEnum):
|
|
80
|
+
"""Represents the sub-category of data to be submitted."""
|
|
81
|
+
|
|
82
|
+
AWARDS = "AWARDS"
|
|
83
|
+
MERIT_ORDER_LIST = "MOL"
|
|
84
|
+
OFFERS = "OFFERS"
|
|
85
|
+
ADJUSTMENT_PRICES = "BUP"
|
|
86
|
+
RESERVE_REQUIREMENTS = "RESREQ"
|
|
87
|
+
ACCESS = "ACCESS"
|
|
88
|
+
RESOURCES = "RESOURCE"
|
|
89
|
+
REQUESTS = "REQUEST"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
class ReportName(StrEnum):
|
|
93
|
+
"""Represents the name of a report."""
|
|
94
|
+
|
|
95
|
+
TSO_RESOURCE_LIST = "ResourceList"
|
|
96
|
+
BSP_RESOURCE_LIST = "BSP_ResourceList"
|
|
97
|
+
RESOURCE_SETTLEMENT = "ResourceSttl"
|
|
98
|
+
RESOURCE_SETTLEMENT_OTM = "ResourceSttlOTM"
|
|
99
|
+
TSO_OFFERS = "Offers"
|
|
100
|
+
BSP_OFFERS = "BSP_Offers"
|
|
101
|
+
RESERVE_REQUIREMENTS = "ReserveReqs"
|
|
102
|
+
TSO_BUP = "BUP"
|
|
103
|
+
BSP_BUP = "BSP_BUP"
|
|
104
|
+
MERIT_ORDER_LIST = "MOL"
|
|
105
|
+
TSO_AWARDS = "ContractResult"
|
|
106
|
+
BSP_AWARDS = "BSP_ContractResult"
|
|
107
|
+
TSO_BASELINE_AWARDS = "MeasureBaseContractResult"
|
|
108
|
+
BSP_BASELINE_AWARDS = "BSP_MeasureBaseContractResult"
|
|
109
|
+
TSO_AWARDS_AFTER_GC = "ContractResultAfterGC"
|
|
110
|
+
BSP_AWARDS_AFTER_GC = "BSP_ContractResultAfterGC"
|
|
111
|
+
TSO_SWITCH_REQUEST = "SwitchRequest"
|
|
112
|
+
TSO_ACCESS_LOG = "AccessLog"
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class Periodicity(StrEnum):
|
|
116
|
+
"""Represents the periodicity of the report data to be generated."""
|
|
117
|
+
|
|
118
|
+
YEARLY = "YEARLY"
|
|
119
|
+
MONTHLY = "MONTHLY"
|
|
120
|
+
DAILY = "DAILY"
|
|
121
|
+
HOURLY = "HOURLY"
|
|
122
|
+
HALF_HOURLY = "HALF_HOURLY"
|
|
123
|
+
SUB_HOURLY = "SUB_HOURLY"
|
|
124
|
+
ON_DEMAND = "ON_DEMAND"
|
|
125
|
+
NOT_APPLICABLE = "NOT_APPLICABLE"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class ParameterName(StrEnum):
|
|
129
|
+
"""Represents the name of a parameter."""
|
|
130
|
+
|
|
131
|
+
START_TIME = "START_TIME"
|
|
132
|
+
END_TIME = "END_TIME"
|
|
133
|
+
RESOURCE_NAME = "RESOURCE_NAME"
|
|
134
|
+
MARKET_TYPE = "MARKET_TYPE"
|
|
135
|
+
AREA = "AREA"
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class AccessClass(StrEnum):
|
|
139
|
+
"""Represents the access class of the report data to be generated."""
|
|
140
|
+
|
|
141
|
+
BSP = "BSP"
|
|
142
|
+
TSO = "TSO"
|
|
143
|
+
MO = "MO"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
class FileType(StrEnum):
|
|
147
|
+
"""Represents the type of file to be returned."""
|
|
148
|
+
|
|
149
|
+
CSV = "CSV"
|
|
150
|
+
XML = "XML"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class Timezone(StrEnum):
|
|
154
|
+
"""Represents the timezone of the report data to be generated."""
|
|
155
|
+
|
|
156
|
+
JST = "JST"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class ReportBase(Envelope, tag="MarketReport"):
|
|
160
|
+
"""Represents the base fields for a report request."""
|
|
161
|
+
|
|
162
|
+
# The type of application for which the report is being requested
|
|
163
|
+
application_type: ApplicationType = attr(name="ApplicationType")
|
|
164
|
+
|
|
165
|
+
# The MMS code of the business entity to which the requesting user belongs, and will be used to track the user who
|
|
166
|
+
# made the request. This value will be checked against the certificate used to make the request.
|
|
167
|
+
participant: str = participant("ParticipantName")
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class ReportMetadata(Payload):
|
|
171
|
+
"""Represents the base fields for report metadata."""
|
|
172
|
+
|
|
173
|
+
# The type of report being requested
|
|
174
|
+
report_type: ReportType = attr(name="ReportType")
|
|
175
|
+
|
|
176
|
+
# The sub-type of report being requested
|
|
177
|
+
report_sub_type: ReportSubType = attr(name="ReportSubType")
|
|
178
|
+
|
|
179
|
+
# The periodicity of the report data to be returned (this should always be "ON_DEMAND")
|
|
180
|
+
periodicity: Periodicity = attr(name="Periodicity")
|
|
181
|
+
|
|
182
|
+
# The name of the report being requested
|
|
183
|
+
name: ReportName = attr(name="ReportName")
|
|
184
|
+
|
|
185
|
+
# The target date for the data to be returned
|
|
186
|
+
date: Date = attr(name="Date")
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
class ReportData(ReportMetadata):
|
|
190
|
+
"""Represents the base fields for report data."""
|
|
191
|
+
|
|
192
|
+
# The access class of the report data to be returned
|
|
193
|
+
access_class: AccessClass = attr(name="AccessClass")
|
|
194
|
+
|
|
195
|
+
# The name of the file to which the report data will be downloaded
|
|
196
|
+
filename: str = file_name("FileName")
|
|
197
|
+
|
|
198
|
+
# The type of file to which the report data will be downloaded
|
|
199
|
+
file_type: FileType = attr(name="FileType")
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class ReportItem(ReportData):
|
|
203
|
+
"""Represents the base fields for report items."""
|
|
204
|
+
|
|
205
|
+
# The ID of the report that this item represents
|
|
206
|
+
transaction_id: str = transaction_id("TransactionId")
|
|
207
|
+
|
|
208
|
+
# The size of the file to which the report data will be downloaded, in bytes
|
|
209
|
+
file_size: int = attr(name="FileSize", ge=0)
|
|
210
|
+
|
|
211
|
+
# Whether the file is binary or not
|
|
212
|
+
is_binary: bool = attr(name="BinaryFile")
|
|
213
|
+
|
|
214
|
+
# The date when the report will be deleted
|
|
215
|
+
expiry_date: Date = attr(name="ExpiryDate")
|
|
216
|
+
|
|
217
|
+
# The description/title of the report
|
|
218
|
+
description: str = attr(name="Description", max_length=100)
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class Parameter(BaseXmlModel):
|
|
222
|
+
"""Represents a parameter for a report."""
|
|
223
|
+
|
|
224
|
+
# The name of the parameter
|
|
225
|
+
# If the search item is the start date and time, use "START_TIME".
|
|
226
|
+
# If the search item is the end date and time, use "END_TIME".
|
|
227
|
+
# If the search item is related to power supply, use "RESOURCE_NAME".
|
|
228
|
+
# ※ When the ReportSubType is "ADJUSTMENT_PRICES", specifying the power supply is mandatory.
|
|
229
|
+
# If the search item is the target market, use "MARKET_TYPE" (refer to Appendix 3).
|
|
230
|
+
# If the search item is the local area, use "AREA" (refer to Appendix 3).
|
|
231
|
+
# Specifying "START_TIME" and "END_TIME" is mandatory.
|
|
232
|
+
name: ParameterName = attr(name="Name")
|
|
233
|
+
|
|
234
|
+
# The value of the parameter
|
|
235
|
+
# If the search item is the start or end date and time, the format is YYYY-MM-DDTHH:MI:SS.
|
|
236
|
+
# If the search item is related to power supply, specify the power supply code.
|
|
237
|
+
# ※ If the Name is "MARKET_TYPE", specify the target market. (Refer to Appendix 1).
|
|
238
|
+
# ※ If the Name is "AREA", specify the local area. (Refer to Appendix 1).
|
|
239
|
+
value: str = attr(name="Value", max_length=200)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class NewReportRequest(ReportMetadata, tag="ReportCreateRequest"):
|
|
243
|
+
"""Represents the base fields for a new report request.
|
|
244
|
+
|
|
245
|
+
For report generation requests, the search criteria related to start date and time and end date and time are as
|
|
246
|
+
follows:
|
|
247
|
+
If the target of creation is a daily report, then the time part of the specified start date and time and end
|
|
248
|
+
date and time is not used for the search.
|
|
249
|
+
If the target of creation is an hourly report, then reports are created for the records spanning from the
|
|
250
|
+
specified start date and time to the end date and time. For example, if start date and time is
|
|
251
|
+
2021-05-01T05:10:00 and end date and time is 2021-05-01T06:10:00, and a report with 30-minute intervals is
|
|
252
|
+
requested, reports for "05:00:00-05:30:00", "05:30:00-06:00:00", and "06:00:00-06:30:00" of May 1, 2021, will
|
|
253
|
+
be created. If start date and time is 2021-05-01T05:00:00 and end date and time is 2021-05-01T06:00:00, and a
|
|
254
|
+
report with 30-minute intervals is requested, reports for "05:00:00-05:30:00" and "05:30:00-06:00:00" of May 1,
|
|
255
|
+
2021, will be created.
|
|
256
|
+
|
|
257
|
+
The created reports are saved for 2 days and then deleted. The period during which the created reports are saved
|
|
258
|
+
prevents the re-creation of reports under the same conditions. Even a slight difference in the specified conditions
|
|
259
|
+
allows for the re-creation of reports.
|
|
260
|
+
|
|
261
|
+
Report generation requests should be executed one by one, ensuring that the Transaction ID is returned before
|
|
262
|
+
proceeding to the next request.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
# The name of the BSP for which the report is being created
|
|
266
|
+
bsp_name: Optional[str] = participant("BSPName", True)
|
|
267
|
+
|
|
268
|
+
# Parameters to be use when configuring the report
|
|
269
|
+
parameters: List[Parameter] = element(tag="Param", max_length=5)
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class NewReportResponse(NewReportRequest, tag="ReportCreateRequest"):
|
|
273
|
+
"""Represents the base fields for a new report response."""
|
|
274
|
+
|
|
275
|
+
# The transaction ID of the request
|
|
276
|
+
transaction_id: str = attr(default="")
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
class ListReportRequest(ReportMetadata, tag="ReportListRequest"):
|
|
280
|
+
"""Represents the base fields for a list report request."""
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
class ListReportResponse(ListReportRequest, tag="ReportListRequest"):
|
|
284
|
+
"""Represents the base fields for a list report response."""
|
|
285
|
+
|
|
286
|
+
# The list of reports that match the query
|
|
287
|
+
reports: List[ReportItem] = wrapped(path="ReportListResponse", entity=element(tag="ReportItem"))
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
class ReportDownloadRequest(ReportData):
|
|
291
|
+
"""Represents the base fields for a report download request.
|
|
292
|
+
|
|
293
|
+
This is used when the Transaction ID obtained as a response to the report generation request is unknown while
|
|
294
|
+
downloading the report. If the requested report exists, the content of the report will be provided as a response. If
|
|
295
|
+
the requested report does not exist, the response described on this page will be provided. Report download requests
|
|
296
|
+
should be made one file at a time, ensuring that each download is completed before making the next request.
|
|
297
|
+
"""
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
class ReportDownloadRequestTrnID(Payload):
|
|
301
|
+
"""Represents the base fields for a report download request.
|
|
302
|
+
|
|
303
|
+
This is used when the Transaction ID obtained as a response to the report generation request is known when
|
|
304
|
+
downloading the report. If the requested report exists, the content of the report will be provided as a response. If
|
|
305
|
+
the requested report does not exist, the response described on this page will be provided. Report download requests
|
|
306
|
+
should be made one file at a time, ensuring that each download is completed before making the next request.
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
# The transaction ID of the request
|
|
310
|
+
transaction_id: str = transaction_id("TransactionId")
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
class OutboundData(Envelope):
|
|
314
|
+
"""Represents the base fields for actual report data."""
|
|
315
|
+
|
|
316
|
+
# The name of the dataset to be returned
|
|
317
|
+
dataset_name: Optional[ReportName] = attr(default=None, name="DatasetName")
|
|
318
|
+
|
|
319
|
+
# The type of dataset to be returned
|
|
320
|
+
dataset_type: Optional[Periodicity] = attr(default=None, name="DatasetType")
|
|
321
|
+
|
|
322
|
+
# The date for which the dataset is being returned
|
|
323
|
+
date: Optional[Date] = attr(default=None, name="Date")
|
|
324
|
+
|
|
325
|
+
# The type of date for which the dataset is being returned
|
|
326
|
+
date_type: Optional[QueryType] = attr(default=None, name="DateType")
|
|
327
|
+
|
|
328
|
+
# The timezone for which the dataset is being returned
|
|
329
|
+
timezone: Optional[Timezone] = attr(default=None, name="DateTimeIndicator")
|
|
330
|
+
|
|
331
|
+
# The time the report was published
|
|
332
|
+
publish_time: Optional[DateTime] = attr(default=None, name="PublishTime")
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class ReportLineBase(Payload):
|
|
336
|
+
"""Represents the base fields for a report line item."""
|
|
337
|
+
|
|
338
|
+
# The row number of the report line item
|
|
339
|
+
row_number: Optional[int] = row_number("ROW", True)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class BSPResourceListItem(ReportLineBase, tag="BSP_ResourceList"):
|
|
343
|
+
"""Represents the base fields for a BSP resource report line item."""
|
|
344
|
+
|
|
345
|
+
# The MMS code of the business entity to which the registration applies
|
|
346
|
+
participant: str = participant("ParticipantName")
|
|
347
|
+
|
|
348
|
+
# Abbrevated name of the business entity to which the registration applies
|
|
349
|
+
company_short_name: str = company_short_name("CompanyShortName")
|
|
350
|
+
|
|
351
|
+
# The date from which the power generation unit is available to trade
|
|
352
|
+
start: Date = attr(name="StartDate")
|
|
353
|
+
|
|
354
|
+
# The date until which the power generation unit is available to trade
|
|
355
|
+
end: Optional[Date] = attr(default=None, name="EndDate")
|
|
356
|
+
|
|
357
|
+
# An abbreviated name for the power generation unit
|
|
358
|
+
short_name: str = resource_short_name("ResourceShortName")
|
|
359
|
+
|
|
360
|
+
# The full name for the power generation unit
|
|
361
|
+
full_name: str = resource_name("ResourceName")
|
|
362
|
+
|
|
363
|
+
# The grid code of the power generation unit
|
|
364
|
+
system_code: str = system_code("SystemCode")
|
|
365
|
+
|
|
366
|
+
# The region in which the power generation unit is located and in which its energy will be traded
|
|
367
|
+
area: AreaCode = attr(name="Area")
|
|
368
|
+
|
|
369
|
+
# Whether or not the resource is primary control power. Refers to the ability of a power generation unit or system
|
|
370
|
+
# to rapidly adjust its output in response to fluctuations in demand or supply within the electrical grid. This
|
|
371
|
+
# primary control power is essential for maintaining the stability and frequency of the grid, especially during
|
|
372
|
+
# sudden changes in load or generation. Typically, primary control power is provided by resources such as
|
|
373
|
+
# hydroelectric plants, natural gas turbines, or other fast-responding power generation assets. If you want to
|
|
374
|
+
# allow market participation for the specified product category, you should set this to True.
|
|
375
|
+
has_primary: Optional[bool] = attr(default=None, name="Pri")
|
|
376
|
+
|
|
377
|
+
# Whether or not the resource is secondary 1 control power. Secondary control power, also known as secondary reserve
|
|
378
|
+
# or frequency containment reserve, refers to a type of reserve power that is used to stabilize the grid frequency
|
|
379
|
+
# in the event of sudden changes in supply or demand. It is one of the mechanisms used in the regulation of grid
|
|
380
|
+
# frequency and is typically provided by power plants or other sources that can quickly adjust their output in
|
|
381
|
+
# response to frequency deviations. The secondary control power is activated automatically and rapidly in response
|
|
382
|
+
# to frequency deviations detected by the grid's control system. If you want to allow market participation for the
|
|
383
|
+
# specified product category, you should set this to True.
|
|
384
|
+
has_secondary_1: Optional[bool] = attr(default=None, name="Sec1")
|
|
385
|
+
|
|
386
|
+
# Whether or not the resource is secondary 2 control power. Secondary control power, also known as secondary reserve
|
|
387
|
+
# or frequency containment reserve, refers to a type of reserve power that is used to stabilize the grid frequency
|
|
388
|
+
# in the event of sudden changes in supply or demand. It is one of the mechanisms used in the regulation of grid
|
|
389
|
+
# frequency and is typically provided by power plants or other sources that can quickly adjust their output in
|
|
390
|
+
# response to frequency deviations. The secondary control power is activated automatically and rapidly in response
|
|
391
|
+
# to frequency deviations detected by the grid's control system. If you want to allow market participation for the
|
|
392
|
+
# specified product category, you should set this to True.
|
|
393
|
+
has_secondary_2: Optional[bool] = attr(default=None, name="Sec2")
|
|
394
|
+
|
|
395
|
+
# Whether or not the resource is tertairy 1 control power. Tertiary control power refers to the capacity of a
|
|
396
|
+
# power generation unit or system to provide regulation services at the tertiary level of frequency control in
|
|
397
|
+
# an electrical grid. In an electrical grid, frequency regulation is typically categorized into primary, secondary,
|
|
398
|
+
# and tertiary control levels, each serving a specific role in maintaining grid stability. Tertiary control,
|
|
399
|
+
# also known as frequency containment reserve (FCR), operates on a slower timescale compared to primary and
|
|
400
|
+
# secondary control. It helps to fine-tune grid frequency over longer periods, usually several minutes to hours,
|
|
401
|
+
# by adjusting the output of power generation units. The tertiary control power is often provided by power plants
|
|
402
|
+
# that can adjust their output relatively quickly but are not as fast as those providing primary and secondary
|
|
403
|
+
# control. This control level helps to ensure that the grid frequency remains within acceptable limits, thus
|
|
404
|
+
# maintaining grid stability and reliability.If you want to allow market participation for the specified product
|
|
405
|
+
# category, you should set this to True.
|
|
406
|
+
has_tertiary_1: Optional[bool] = attr(default=None, name="Ter1")
|
|
407
|
+
|
|
408
|
+
# Whether or not the resource is tertairy 2 control power. Tertiary control power refers to the capacity of a
|
|
409
|
+
# power generation unit or system to provide regulation services at the tertiary level of frequency control in
|
|
410
|
+
# an electrical grid. In an electrical grid, frequency regulation is typically categorized into primary, secondary,
|
|
411
|
+
# and tertiary control levels, each serving a specific role in maintaining grid stability. Tertiary control,
|
|
412
|
+
# also known as frequency containment reserve (FCR), operates on a slower timescale compared to primary and
|
|
413
|
+
# secondary control. It helps to fine-tune grid frequency over longer periods, usually several minutes to hours,
|
|
414
|
+
# by adjusting the output of power generation units. The tertiary control power is often provided by power plants
|
|
415
|
+
# that can adjust their output relatively quickly but are not as fast as those providing primary and secondary
|
|
416
|
+
# control. This control level helps to ensure that the grid frequency remains within acceptable limits, thus
|
|
417
|
+
# maintaining grid stability and reliability.If you want to allow market participation for the specified product
|
|
418
|
+
# category, you should set this to True.
|
|
419
|
+
has_tertiary_2: Optional[bool] = attr(default=None, name="Ter2")
|
|
420
|
+
|
|
421
|
+
# How the power generation unit is used in the market
|
|
422
|
+
contract_type: Optional[ContractType] = attr(default=None, name="ContractType")
|
|
423
|
+
|
|
424
|
+
# Primary-Secondary 1 command-and-control and monitoring method. Refers to the methodology or system utilized for
|
|
425
|
+
# regulating and overseeing power generation units' operations in response to external commands or signals. This
|
|
426
|
+
# method encompasses the process by which instructions are transmitted to power generation units, and their
|
|
427
|
+
# performance is monitored to ensure compliance with these instructions. If has_secondary_1 is set to True, then
|
|
428
|
+
# it must be set to DEDICATED_LINE. At least one of the following combinations must be set:
|
|
429
|
+
# primary_secondary_1_control_method
|
|
430
|
+
# secondary_2_tertiary_control_method
|
|
431
|
+
primary_secondary_1_control_method: Optional[CommandMonitorMethod] = attr(
|
|
432
|
+
default=None, name="PriSec1CommandOperationMethod"
|
|
433
|
+
)
|
|
434
|
+
|
|
435
|
+
# Secondary 2-Tertiary command-and-control and monitoring method. Refers to the methodology or system utilized for
|
|
436
|
+
# regulating and overseeing power generation units' operations in response to external commands or signals. This
|
|
437
|
+
# method encompasses the process by which instructions are transmitted to power generation units, and their
|
|
438
|
+
# performance is monitored to ensure compliance with these instructions.
|
|
439
|
+
secondary_2_tertiary_control_method: Optional[CommandMonitorMethod] = attr(
|
|
440
|
+
default=None, name="Sec2Ter1Ter2CommandOperationMethod"
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
# Adjustment Coefficient (α) (Tertiary Adjustment Power ②). If this is not set for a power supply, it is treated as
|
|
444
|
+
# "1" during the execution process but will not be output when retrieving this report.
|
|
445
|
+
tertiary_2_adjustment_coefficient: Annotated[Decimal, percentage("CoefficientTR2", True)]
|
|
446
|
+
|
|
447
|
+
# Method determinining how the baseline is set for a power generation unit. The setting method is available when
|
|
448
|
+
# the contract type is not ONLY_POWER_SUPPLY_1 and at least one of the following is True: has_primary,
|
|
449
|
+
# has_secondary_1, has_secondary_2 or has_tertiary_1. Additionally, it can only be set when resource_type is
|
|
450
|
+
# VPP_GEN, VPP_GEN_AND_DEM or VPP_DEM. It's mandatory in these cases and cannot be set for other power sources.
|
|
451
|
+
baseline_setting_method: Optional[BaseLineSettingMethod] = attr(default=None, name="BaselineSettingsMethod")
|
|
452
|
+
|
|
453
|
+
# The signal type for the power generation unit
|
|
454
|
+
signal_type: SignalType = attr("SignalType")
|
|
455
|
+
|
|
456
|
+
# How the surplus capacity of a power generation unit can be utilized. For contract_type MARKET, POWER_SUPPLY_2,
|
|
457
|
+
# and ONLY_POWER_SUPPLY_1, this field must be set to NOT_AVAILABLE.
|
|
458
|
+
primary_remaining_reserve_utilization: RemainingReserveAvailability = attr(name="PriRemResvUtilization")
|
|
459
|
+
|
|
460
|
+
# How the surplus capacity of a power generation unit can be utilized. For contract_type of MARKET, POWER_SUPPLY_2,
|
|
461
|
+
# and ONLY_POWER_SUPPLY_1, this field must be set to NOT_AVAILABLE.
|
|
462
|
+
secondary_1_remaining_reserve_utilization: RemainingReserveAvailability = attr(name="Sec1RemResvUtilization")
|
|
463
|
+
|
|
464
|
+
# How the surplus capacity of a power generation unit can be utilized. For contract_type of MARKET, POWER_SUPPLY_2,
|
|
465
|
+
# and ONLY_POWER_SUPPLY_1, this field must be set to NOT_AVAILABLE.
|
|
466
|
+
secondary_2_remaining_reserve_utilization: RemainingReserveAvailability = attr(name="Sec2RemResvUtilization")
|
|
467
|
+
|
|
468
|
+
# How the surplus capacity of a power generation unit can be utilized. For contract_type of MARKET, POWER_SUPPLY_2,
|
|
469
|
+
# and ONLY_POWER_SUPPLY_1, this field must be set to NOT_AVAILABLE.
|
|
470
|
+
tertiary_1_remaining_reserve_utilization: RemainingReserveAvailability = attr(name="Ter1RemResvUtilization")
|
|
471
|
+
|
|
472
|
+
# How the surplus capacity of a power generation unit can be utilized. For contract_type of MARKET, POWER_SUPPLY_2,
|
|
473
|
+
# and ONLY_POWER_SUPPLY_1, this field must be set to NOT_AVAILABLE.
|
|
474
|
+
tertiary_2_remaining_reserve_utilization: RemainingReserveAvailability = attr(name="Ter2RemResvUtilization")
|
mms_client/types/resource.py
CHANGED
|
@@ -16,10 +16,14 @@ from pydantic_xml import wrapped
|
|
|
16
16
|
|
|
17
17
|
from mms_client.types.base import Payload
|
|
18
18
|
from mms_client.types.enums import AreaCode
|
|
19
|
+
from mms_client.types.enums import BaseLineSettingMethod
|
|
19
20
|
from mms_client.types.enums import BooleanFlag
|
|
20
21
|
from mms_client.types.enums import CommandMonitorMethod
|
|
22
|
+
from mms_client.types.enums import ContractType
|
|
21
23
|
from mms_client.types.enums import Frequency
|
|
24
|
+
from mms_client.types.enums import RemainingReserveAvailability
|
|
22
25
|
from mms_client.types.enums import ResourceType
|
|
26
|
+
from mms_client.types.enums import SignalType
|
|
23
27
|
from mms_client.types.fields import ASCII_TEXT
|
|
24
28
|
from mms_client.types.fields import JAPANESE_ASCII_TEXT
|
|
25
29
|
from mms_client.types.fields import JAPANESE_TEXT
|
|
@@ -172,40 +176,6 @@ class StopEventType(Enum):
|
|
|
172
176
|
DISCONNECTION = "21"
|
|
173
177
|
|
|
174
178
|
|
|
175
|
-
class ContractType(Enum):
|
|
176
|
-
"""Describes the type of contract for a power generation unit."""
|
|
177
|
-
|
|
178
|
-
MARKET = "1"
|
|
179
|
-
MARKET_AND_POWER_SUPPLY_2 = "2"
|
|
180
|
-
POWER_SUPPLY_2 = "3"
|
|
181
|
-
ONLY_POWER_SUPPLY_1 = "4"
|
|
182
|
-
MARKET_AND_REMAINING_RESERVE_UTILIZATION = "5"
|
|
183
|
-
REMAINING_RESERVE_UTILIZATION = "6"
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
class RemainingReserveAvailability(Enum):
|
|
187
|
-
"""Describes the availability of remaining reserves for a power generation unit."""
|
|
188
|
-
|
|
189
|
-
NOT_AVAILABLE = "0"
|
|
190
|
-
AVAILABLE_FOR_UP_ONLY = "1"
|
|
191
|
-
AVAILABLE_FOR_DOWN_ONLY = "2"
|
|
192
|
-
AVAILABLE_FOR_UP_AND_DOWN = "3"
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
class SignalType(Enum):
|
|
196
|
-
"""Describes the type of signal used to monitor and command a power generation unit."""
|
|
197
|
-
|
|
198
|
-
ACTUAL_OUTPUT_ORDER = "1"
|
|
199
|
-
DIFFERENTIAL_OUTPUT_ORDER = "2"
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
class BaseLineSettingMethod(Enum):
|
|
203
|
-
"""Describe how the baseline is set for a power generation unit."""
|
|
204
|
-
|
|
205
|
-
PREDICTION_BASE = "1"
|
|
206
|
-
MEASUREMENT_BASE = "2"
|
|
207
|
-
|
|
208
|
-
|
|
209
179
|
class ThermalType(Enum):
|
|
210
180
|
"""Describes the type of thermal power generation unit."""
|
|
211
181
|
|
mms_client/types/transport.py
CHANGED
|
@@ -55,7 +55,7 @@ class Attachment(BaseModel):
|
|
|
55
55
|
name: str = Field(alias="name")
|
|
56
56
|
|
|
57
57
|
# The attachment file data
|
|
58
|
-
data:
|
|
58
|
+
data: str = Field(alias="binaryData")
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
class MmsRequest(BaseModel):
|
|
@@ -83,7 +83,7 @@ class MmsRequest(BaseModel):
|
|
|
83
83
|
signature: str = Field(alias="requestSignature")
|
|
84
84
|
|
|
85
85
|
# The base-64 encoded payload of the request
|
|
86
|
-
payload:
|
|
86
|
+
payload: str = Field(alias="requestData")
|
|
87
87
|
|
|
88
88
|
# Any attached files to be sent with the request. Only 20 of these are allowed for OMI requests. For MI requests,
|
|
89
89
|
# the limit is 40.
|