s2-python 0.0.1__py3-none-any.whl → 0.2.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.
Files changed (53) hide show
  1. {s2_python-0.0.1.dist-info → s2_python-0.2.0.dist-info}/METADATA +22 -4
  2. s2_python-0.2.0.dist-info/RECORD +54 -0
  3. {s2_python-0.0.1.dist-info → s2_python-0.2.0.dist-info}/WHEEL +1 -1
  4. s2python/__init__.py +1 -1
  5. s2python/common/__init__.py +1 -1
  6. s2python/common/duration.py +5 -5
  7. s2python/common/handshake.py +5 -5
  8. s2python/common/handshake_response.py +5 -5
  9. s2python/common/instruction_status_update.py +6 -10
  10. s2python/common/number_range.py +17 -21
  11. s2python/common/power_forecast.py +7 -9
  12. s2python/common/power_forecast_element.py +9 -10
  13. s2python/common/power_forecast_value.py +4 -6
  14. s2python/common/power_measurement.py +7 -7
  15. s2python/common/power_range.py +11 -13
  16. s2python/common/power_value.py +4 -4
  17. s2python/common/reception_status.py +5 -7
  18. s2python/common/resource_manager_details.py +11 -12
  19. s2python/common/revoke_object.py +6 -6
  20. s2python/common/role.py +4 -4
  21. s2python/common/select_control_type.py +5 -5
  22. s2python/common/session_request.py +5 -5
  23. s2python/common/support.py +6 -4
  24. s2python/common/timer.py +6 -6
  25. s2python/common/transition.py +12 -14
  26. s2python/frbc/frbc_actuator_description.py +53 -74
  27. s2python/frbc/frbc_actuator_status.py +10 -12
  28. s2python/frbc/frbc_fill_level_target_profile.py +10 -14
  29. s2python/frbc/frbc_fill_level_target_profile_element.py +7 -9
  30. s2python/frbc/frbc_instruction.py +8 -8
  31. s2python/frbc/frbc_leakage_behaviour.py +8 -10
  32. s2python/frbc/frbc_leakage_behaviour_element.py +6 -8
  33. s2python/frbc/frbc_operation_mode.py +19 -29
  34. s2python/frbc/frbc_operation_mode_element.py +11 -13
  35. s2python/frbc/frbc_storage_description.py +6 -8
  36. s2python/frbc/frbc_storage_status.py +5 -5
  37. s2python/frbc/frbc_system_description.py +10 -13
  38. s2python/frbc/frbc_timer_status.py +7 -7
  39. s2python/frbc/frbc_usage_forecast.py +7 -9
  40. s2python/frbc/frbc_usage_forecast_element.py +5 -7
  41. s2python/frbc/rm.py +0 -0
  42. s2python/generated/gen_s2.py +1150 -1130
  43. s2python/reception_status_awaiter.py +60 -0
  44. s2python/s2_connection.py +470 -0
  45. s2python/s2_control_type.py +56 -0
  46. s2python/s2_parser.py +113 -0
  47. s2python/s2_validation_error.py +7 -5
  48. s2python/utils.py +7 -2
  49. s2python/validate_values_mixin.py +32 -89
  50. s2python/version.py +2 -0
  51. s2_python-0.0.1.dist-info/RECORD +0 -49
  52. {s2_python-0.0.1.dist-info → s2_python-0.2.0.dist-info}/entry_points.txt +0 -0
  53. {s2_python-0.0.1.dist-info → s2_python-0.2.0.dist-info}/top_level.txt +0 -0
@@ -1,1591 +1,1611 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: openapi.yml
3
- # timestamp: 2023-07-31T15:51:31+00:00
3
+ # timestamp: 2024-07-29T10:18:52+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- from datetime import datetime
8
7
  from enum import Enum
9
8
  from typing import List, Optional
10
9
 
11
- from pydantic import BaseModel, Extra, Field, conint, constr
10
+ from pydantic import (
11
+ AwareDatetime,
12
+ BaseModel,
13
+ ConfigDict,
14
+ Field,
15
+ RootModel,
16
+ conint,
17
+ constr,
18
+ )
19
+ from typing_extensions import Literal
12
20
 
13
21
 
14
- class Commodity(Enum):
15
- GAS = "GAS"
16
- HEAT = "HEAT"
17
- ELECTRICITY = "ELECTRICITY"
18
- OIL = "OIL"
19
-
20
-
21
- class CommodityQuantity(Enum):
22
- ELECTRIC_POWER_L1 = "ELECTRIC.POWER.L1"
23
- ELECTRIC_POWER_L2 = "ELECTRIC.POWER.L2"
24
- ELECTRIC_POWER_L3 = "ELECTRIC.POWER.L3"
25
- ELECTRIC_POWER_3_PHASE_SYMMETRIC = "ELECTRIC.POWER.3_PHASE_SYMMETRIC"
26
- NATURAL_GAS_FLOW_RATE = "NATURAL_GAS.FLOW_RATE"
27
- HYDROGEN_FLOW_RATE = "HYDROGEN.FLOW_RATE"
28
- HEAT_TEMPERATURE = "HEAT.TEMPERATURE"
29
- HEAT_FLOW_RATE = "HEAT.FLOW_RATE"
30
- HEAT_THERMAL_POWER = "HEAT.THERMAL_POWER"
31
- OIL_FLOW_RATE = "OIL.FLOW_RATE"
22
+ class Duration(RootModel[conint(ge=0)]):
23
+ root: conint(ge=0) = Field(..., description='Duration in milliseconds')
32
24
 
33
25
 
34
- class ControlType(Enum):
35
- POWER_ENVELOPE_BASED_CONTROL = "POWER_ENVELOPE_BASED_CONTROL"
36
- POWER_PROFILE_BASED_CONTROL = "POWER_PROFILE_BASED_CONTROL"
37
- OPERATION_MODE_BASED_CONTROL = "OPERATION_MODE_BASED_CONTROL"
38
- FILL_RATE_BASED_CONTROL = "FILL_RATE_BASED_CONTROL"
39
- DEMAND_DRIVEN_BASED_CONTROL = "DEMAND_DRIVEN_BASED_CONTROL"
40
- NOT_CONTROLABLE = "NOT_CONTROLABLE"
41
- NO_SELECTION = "NO_SELECTION"
26
+ class ID(RootModel[constr(pattern=r'[a-zA-Z0-9\-_:]{2,64}')]):
27
+ root: constr(pattern=r'[a-zA-Z0-9\-_:]{2,64}') = Field(..., description='UUID')
42
28
 
43
29
 
44
30
  class Currency(Enum):
45
- AED = "AED"
46
- ANG = "ANG"
47
- AUD = "AUD"
48
- CHE = "CHE"
49
- CHF = "CHF"
50
- CHW = "CHW"
51
- EUR = "EUR"
52
- GBP = "GBP"
53
- LBP = "LBP"
54
- LKR = "LKR"
55
- LRD = "LRD"
56
- LSL = "LSL"
57
- LYD = "LYD"
58
- MAD = "MAD"
59
- MDL = "MDL"
60
- MGA = "MGA"
61
- MKD = "MKD"
62
- MMK = "MMK"
63
- MNT = "MNT"
64
- MOP = "MOP"
65
- MRO = "MRO"
66
- MUR = "MUR"
67
- MVR = "MVR"
68
- MWK = "MWK"
69
- MXN = "MXN"
70
- MXV = "MXV"
71
- MYR = "MYR"
72
- MZN = "MZN"
73
- NAD = "NAD"
74
- NGN = "NGN"
75
- NIO = "NIO"
76
- NOK = "NOK"
77
- NPR = "NPR"
78
- NZD = "NZD"
79
- OMR = "OMR"
80
- PAB = "PAB"
81
- PEN = "PEN"
82
- PGK = "PGK"
83
- PHP = "PHP"
84
- PKR = "PKR"
85
- PLN = "PLN"
86
- PYG = "PYG"
87
- QAR = "QAR"
88
- RON = "RON"
89
- RSD = "RSD"
90
- RUB = "RUB"
91
- RWF = "RWF"
92
- SAR = "SAR"
93
- SBD = "SBD"
94
- SCR = "SCR"
95
- SDG = "SDG"
96
- SEK = "SEK"
97
- SGD = "SGD"
98
- SHP = "SHP"
99
- SLL = "SLL"
100
- SOS = "SOS"
101
- SRD = "SRD"
102
- SSP = "SSP"
103
- STD = "STD"
104
- SYP = "SYP"
105
- SZL = "SZL"
106
- THB = "THB"
107
- TJS = "TJS"
108
- TMT = "TMT"
109
- TND = "TND"
110
- TOP = "TOP"
111
- TRY = "TRY"
112
- TTD = "TTD"
113
- TWD = "TWD"
114
- TZS = "TZS"
115
- UAH = "UAH"
116
- UGX = "UGX"
117
- USD = "USD"
118
- USN = "USN"
119
- UYI = "UYI"
120
- UYU = "UYU"
121
- UZS = "UZS"
122
- VEF = "VEF"
123
- VND = "VND"
124
- VUV = "VUV"
125
- WST = "WST"
126
- XAG = "XAG"
127
- XAU = "XAU"
128
- XBA = "XBA"
129
- XBB = "XBB"
130
- XBC = "XBC"
131
- XBD = "XBD"
132
- XCD = "XCD"
133
- XOF = "XOF"
134
- XPD = "XPD"
135
- XPF = "XPF"
136
- XPT = "XPT"
137
- XSU = "XSU"
138
- XTS = "XTS"
139
- XUA = "XUA"
140
- XXX = "XXX"
141
- YER = "YER"
142
- ZAR = "ZAR"
143
- ZMW = "ZMW"
144
- ZWL = "ZWL"
145
-
146
-
147
- class Duration(BaseModel):
148
- __root__: conint(ge=0) = Field(..., description="Duration in milliseconds")
149
-
150
-
151
- class EnergyManagementRole(Enum):
152
- CEM = "CEM"
153
- RM = "RM"
154
-
155
-
156
- class FRBCUsageForecastElement(BaseModel):
157
- class Config:
158
- extra = Extra.forbid
31
+ AED = 'AED'
32
+ ANG = 'ANG'
33
+ AUD = 'AUD'
34
+ CHE = 'CHE'
35
+ CHF = 'CHF'
36
+ CHW = 'CHW'
37
+ EUR = 'EUR'
38
+ GBP = 'GBP'
39
+ LBP = 'LBP'
40
+ LKR = 'LKR'
41
+ LRD = 'LRD'
42
+ LSL = 'LSL'
43
+ LYD = 'LYD'
44
+ MAD = 'MAD'
45
+ MDL = 'MDL'
46
+ MGA = 'MGA'
47
+ MKD = 'MKD'
48
+ MMK = 'MMK'
49
+ MNT = 'MNT'
50
+ MOP = 'MOP'
51
+ MRO = 'MRO'
52
+ MUR = 'MUR'
53
+ MVR = 'MVR'
54
+ MWK = 'MWK'
55
+ MXN = 'MXN'
56
+ MXV = 'MXV'
57
+ MYR = 'MYR'
58
+ MZN = 'MZN'
59
+ NAD = 'NAD'
60
+ NGN = 'NGN'
61
+ NIO = 'NIO'
62
+ NOK = 'NOK'
63
+ NPR = 'NPR'
64
+ NZD = 'NZD'
65
+ OMR = 'OMR'
66
+ PAB = 'PAB'
67
+ PEN = 'PEN'
68
+ PGK = 'PGK'
69
+ PHP = 'PHP'
70
+ PKR = 'PKR'
71
+ PLN = 'PLN'
72
+ PYG = 'PYG'
73
+ QAR = 'QAR'
74
+ RON = 'RON'
75
+ RSD = 'RSD'
76
+ RUB = 'RUB'
77
+ RWF = 'RWF'
78
+ SAR = 'SAR'
79
+ SBD = 'SBD'
80
+ SCR = 'SCR'
81
+ SDG = 'SDG'
82
+ SEK = 'SEK'
83
+ SGD = 'SGD'
84
+ SHP = 'SHP'
85
+ SLL = 'SLL'
86
+ SOS = 'SOS'
87
+ SRD = 'SRD'
88
+ SSP = 'SSP'
89
+ STD = 'STD'
90
+ SYP = 'SYP'
91
+ SZL = 'SZL'
92
+ THB = 'THB'
93
+ TJS = 'TJS'
94
+ TMT = 'TMT'
95
+ TND = 'TND'
96
+ TOP = 'TOP'
97
+ TRY = 'TRY'
98
+ TTD = 'TTD'
99
+ TWD = 'TWD'
100
+ TZS = 'TZS'
101
+ UAH = 'UAH'
102
+ UGX = 'UGX'
103
+ USD = 'USD'
104
+ USN = 'USN'
105
+ UYI = 'UYI'
106
+ UYU = 'UYU'
107
+ UZS = 'UZS'
108
+ VEF = 'VEF'
109
+ VND = 'VND'
110
+ VUV = 'VUV'
111
+ WST = 'WST'
112
+ XAG = 'XAG'
113
+ XAU = 'XAU'
114
+ XBA = 'XBA'
115
+ XBB = 'XBB'
116
+ XBC = 'XBC'
117
+ XBD = 'XBD'
118
+ XCD = 'XCD'
119
+ XOF = 'XOF'
120
+ XPD = 'XPD'
121
+ XPF = 'XPF'
122
+ XPT = 'XPT'
123
+ XSU = 'XSU'
124
+ XTS = 'XTS'
125
+ XUA = 'XUA'
126
+ XXX = 'XXX'
127
+ YER = 'YER'
128
+ ZAR = 'ZAR'
129
+ ZMW = 'ZMW'
130
+ ZWL = 'ZWL'
159
131
 
160
- duration: Duration = Field(
161
- ..., description="Indicator for how long the given usage_rate is valid."
162
- )
163
- usage_rate_expected: float = Field(
164
- ...,
165
- description="The most likely value for the usage rate; the expected increase or decrease of the fill_level per second",
166
- )
167
- usage_rate_lower_68PPR: Optional[float] = Field(
168
- None,
169
- description="The lower limit of the range with a 68\xa0% probability that the usage rate is within that range",
170
- )
171
- usage_rate_lower_95PPR: Optional[float] = Field(
172
- None,
173
- description="The lower limit of the range with a 95\xa0% probability that the usage rate is within that range",
174
- )
175
- usage_rate_lower_limit: Optional[float] = Field(
176
- None,
177
- description="The lower limit of the range with a 100\xa0% probability that the usage rate is within that range",
178
- )
179
- usage_rate_upper_68PPR: Optional[float] = Field(
180
- None,
181
- description="The upper limit of the range with a 68\xa0% probability that the usage rate is within that range",
182
- )
183
- usage_rate_upper_95PPR: Optional[float] = Field(
184
- None,
185
- description="The upper limit of the range with a 95\xa0% probability that the usage rate is within that range. ",
186
- )
187
- usage_rate_upper_limit: Optional[float] = Field(
188
- None,
189
- description="The upper limit of the range with a 100\xa0% probability that the usage rate is within that range.",
190
- )
191
132
 
133
+ class SessionRequestType(Enum):
134
+ RECONNECT = 'RECONNECT'
135
+ TERMINATE = 'TERMINATE'
192
136
 
193
- class ID(BaseModel):
194
- __root__: constr(regex=r"[a-zA-Z0-9\-_:]{2,64}") = Field(
195
- ..., description="An identifier expressed as a UUID"
196
- )
197
137
 
138
+ class RevokableObjects(Enum):
139
+ PEBC_PowerConstraints = 'PEBC.PowerConstraints'
140
+ PEBC_EnergyConstraint = 'PEBC.EnergyConstraint'
141
+ PEBC_Instruction = 'PEBC.Instruction'
142
+ PPBC_PowerProfileDefinition = 'PPBC.PowerProfileDefinition'
143
+ PPBC_ScheduleInstruction = 'PPBC.ScheduleInstruction'
144
+ PPBC_StartInterruptionInstruction = 'PPBC.StartInterruptionInstruction'
145
+ PPBC_EndInterruptionInstruction = 'PPBC.EndInterruptionInstruction'
146
+ OMBC_SystemDescription = 'OMBC.SystemDescription'
147
+ OMBC_Instruction = 'OMBC.Instruction'
148
+ FRBC_SystemDescription = 'FRBC.SystemDescription'
149
+ FRBC_Instruction = 'FRBC.Instruction'
150
+ DDBC_SystemDescription = 'DDBC.SystemDescription'
151
+ DDBC_Instruction = 'DDBC.Instruction'
198
152
 
199
- class InstructionStatus(Enum):
200
- NEW = "NEW"
201
- ACCEPTED = "ACCEPTED"
202
- REJECTED = "REJECTED"
203
- REVOKED = "REVOKED"
204
- STARTED = "STARTED"
205
- SUCCEEDED = "SUCCEEDED"
206
- ABORTED = "ABORTED"
207
153
 
154
+ class EnergyManagementRole(Enum):
155
+ CEM = 'CEM'
156
+ RM = 'RM'
208
157
 
209
- class InstructionStatusUpdate(BaseModel):
210
- class Config:
211
- extra = Extra.forbid
212
158
 
213
- instruction_id: ID = Field(
214
- ..., description="ID of this instruction (as provided by the CEM) "
215
- )
216
- message_id: ID = Field(..., description="ID of this message")
217
- message_type: str = Field("InstructionStatusUpdate", const=True)
218
- status_type: InstructionStatus = Field(
219
- ..., description="Present status of this instruction."
220
- )
221
- timestamp: datetime = Field(
222
- ..., description="Timestamp when status_type has changed the last time."
223
- )
159
+ class ReceptionStatusValues(Enum):
160
+ INVALID_DATA = 'INVALID_DATA'
161
+ INVALID_MESSAGE = 'INVALID_MESSAGE'
162
+ INVALID_CONTENT = 'INVALID_CONTENT'
163
+ TEMPORARY_ERROR = 'TEMPORARY_ERROR'
164
+ PERMANENT_ERROR = 'PERMANENT_ERROR'
165
+ OK = 'OK'
224
166
 
225
167
 
226
168
  class NumberRange(BaseModel):
227
- class Config:
228
- extra = Extra.forbid
229
-
230
- end_of_range: float = Field(
231
- ..., description="Number that defines the end of the range"
169
+ model_config = ConfigDict(
170
+ extra='forbid',
232
171
  )
233
172
  start_of_range: float = Field(
234
- ..., description="Number that defines the start of the range"
173
+ ..., description='Number that defines the start of the range'
174
+ )
175
+ end_of_range: float = Field(
176
+ ..., description='Number that defines the end of the range'
235
177
  )
236
178
 
237
179
 
238
- class OMBCInstruction(BaseModel):
239
- class Config:
240
- extra = Extra.forbid
241
-
242
- abnormal_condition: bool = Field(
243
- ...,
244
- description="Indicates if this is an instruction during an abnormal condition",
245
- )
246
- execution_time: datetime = Field(
247
- ..., description="Time when instruction should be executed."
180
+ class Transition(BaseModel):
181
+ model_config = ConfigDict(
182
+ extra='forbid',
248
183
  )
249
184
  id: ID = Field(
250
185
  ...,
251
- description="ID of the instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
186
+ description='ID of the Transition. Must be unique in the scope of the OMBC.SystemDescription, FRBC.ActuatorDescription or DDBC.ActuatorDescription in which it is used.',
252
187
  )
253
- message_id: ID = Field(..., description="ID of this message")
254
- message_type: str = Field("OMBC.Instruction", const=True)
255
- operation_mode_factor: float = Field(
188
+ from_: ID = Field(
256
189
  ...,
257
- description="The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal than 0 and less or equal to 1.",
190
+ alias='from',
191
+ description='ID of the OperationMode (exact type differs per ControlType) that should be switched from.',
258
192
  )
259
- operation_mode_id: ID = Field(
260
- ..., description="ID of the OMBC.OperationMode that should be activated"
193
+ to: ID = Field(
194
+ ...,
195
+ description='ID of the OperationMode (exact type differs per ControlType) that will be switched to.',
261
196
  )
262
-
263
-
264
- class OMBCStatus(BaseModel):
265
- class Config:
266
- extra = Extra.forbid
267
-
268
- active_operation_mode_id: ID = Field(
269
- ..., description="ID of the active OMBC.OperationMode."
197
+ start_timers: List[ID] = Field(
198
+ ...,
199
+ description='List of IDs of Timers that will be (re)started when this transition is initiated',
200
+ max_length=1000,
201
+ min_length=0,
270
202
  )
271
- message_id: ID = Field(..., description="ID of this message")
272
- message_type: str = Field("OMBC.Status", const=True)
273
- operation_mode_factor: float = Field(
203
+ blocking_timers: List[ID] = Field(
274
204
  ...,
275
- description="The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal than 0 and less or equal to 1.",
205
+ description='List of IDs of Timers that block this Transition from initiating while at least one of these Timers is not yet finished',
206
+ max_length=1000,
207
+ min_length=0,
276
208
  )
277
- previous_operation_mode_id: Optional[ID] = Field(
209
+ transition_costs: Optional[float] = Field(
278
210
  None,
279
- description="ID of the OMBC.OperationMode that was previously active. This value shall always be provided, unless the active OMBC.OperationMode is the first OMBC.OperationMode the Resource Manager is aware of.",
211
+ description='Absolute costs for going through this Transition in the currency as described in the ResourceManagerDetails.',
280
212
  )
281
- transition_timestamp: Optional[datetime] = Field(
213
+ transition_duration: Optional[Duration] = Field(
282
214
  None,
283
- description="Time at which the transition from the previous OMBC.OperationMode to the active OMBC.OperationMode was initiated. This value shall always be provided, unless the active OMBC.OperationMode is the first OMBC.OperationMode the Resource Manager is aware of.",
215
+ description='Indicates the time between the initiation of this Transition, and the time at which the device behaves according to the Operation Mode which is defined in the ‘to’ data element. When no value is provided it is assumed the transition duration is negligible.',
284
216
  )
285
-
286
-
287
- class OMBCTimerStatus(BaseModel):
288
- class Config:
289
- extra = Extra.forbid
290
-
291
- finished_at: datetime = Field(
217
+ abnormal_condition_only: bool = Field(
292
218
  ...,
293
- description="Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.",
219
+ description='Indicates if this Transition may only be used during an abnormal condition (see Clause )',
294
220
  )
295
- message_id: ID = Field(..., description="ID of this message")
296
- message_type: str = Field("OMBC.TimerStatus", const=True)
297
- timer_id: ID = Field(..., description="The ID of the timer this message refers to")
298
-
299
221
 
300
- class PEBCEnergyConstraint(BaseModel):
301
- class Config:
302
- extra = Extra.forbid
303
222
 
304
- commodity_quantity: CommodityQuantity = Field(
305
- ...,
306
- description="Type of power quantity which applies to upper_average_power and lower_average_power",
223
+ class Timer(BaseModel):
224
+ model_config = ConfigDict(
225
+ extra='forbid',
307
226
  )
308
227
  id: ID = Field(
309
228
  ...,
310
- description="Identifier of this PEBC.EnergyConstraints. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
229
+ description='ID of the Timer. Must be unique in the scope of the OMBC.SystemDescription, FRBC.ActuatorDescription or DDBC.ActuatorDescription in which it is used.',
311
230
  )
312
- lower_average_power: float = Field(
313
- ...,
314
- description="Lower average power within the time period given by valid_from and valid_until. If the duration is multiplied with this power value, then the associated lower energy content can be derived. This is the lowest amount of energy the resource will consume during that period of time. ",
315
- )
316
- message_id: ID = Field(..., description="ID of this message")
317
- message_type: str = Field("PEBC.EnergyConstraint", const=True)
318
- upper_average_power: float = Field(
319
- ...,
320
- description="Upper average power within the time period given by valid_from and valid_until. If the duration is multiplied with this power value, then the associated upper energy content can be derived. This is the highest amount of energy the resource will consume during that period of time.",
321
- )
322
- valid_from: datetime = Field(
323
- ...,
324
- description="Moment this PEBC.EnergyConstraints information starts to be valid",
231
+ diagnostic_label: Optional[str] = Field(
232
+ None,
233
+ description='Human readable name/description of the Timer. This element is only intended for diagnostic purposes and not for HMI applications.',
325
234
  )
326
- valid_until: datetime = Field(
235
+ duration: Duration = Field(
327
236
  ...,
328
- description="Moment until this PEBC.EnergyConstraints information is valid.",
237
+ description='The time it takes for the Timer to finish after it has been started',
329
238
  )
330
239
 
331
240
 
332
- class PEBCPowerEnvelopeConsequenceType(Enum):
333
- VANISH = "VANISH"
334
- DEFER = "DEFER"
335
-
336
-
337
241
  class PEBCPowerEnvelopeElement(BaseModel):
338
- class Config:
339
- extra = Extra.forbid
340
-
341
- duration: Duration = Field(..., description="The duration of the element")
342
- lower_limit: float = Field(
343
- ...,
344
- description="Lower power limit according to the commodity_quantity of the containing PEBC.PowerEnvelope. The lower_limit must be smaller or equal to the upper_limit. The Resource Manager is requested to keep the power values for the given commodity quantity equal to or above the lower_limit. The lower_limit shall be in accordance with the constraints provided by the Resource Manager through any PEBC.AllowedLimitRange with limit_type LOWER_LIMIT.",
242
+ model_config = ConfigDict(
243
+ extra='forbid',
345
244
  )
245
+ duration: Duration = Field(..., description='The duration of the element')
346
246
  upper_limit: float = Field(
347
247
  ...,
348
- description="Upper power limit according to the commodity_quantity of the containing PEBC.PowerEnvelope. The lower_limit must be smaller or equal to the upper_limit. The Resource Manager is requested to keep the power values for the given commodity quantity equal to or below the upper_limit. The upper_limit shall be in accordance with the constraints provided by the Resource Manager through any PEBC.AllowedLimitRange with limit_type UPPER_LIMIT.",
248
+ description='Upper power limit according to the commodity_quantity of the containing PEBC.PowerEnvelope. The lower_limit must be smaller or equal to the upper_limit. The Resource Manager is requested to keep the power values for the given commodity quantity equal to or below the upper_limit. The upper_limit shall be in accordance with the constraints provided by the Resource Manager through any PEBC.AllowedLimitRange with limit_type UPPER_LIMIT.',
249
+ )
250
+ lower_limit: float = Field(
251
+ ...,
252
+ description='Lower power limit according to the commodity_quantity of the containing PEBC.PowerEnvelope. The lower_limit must be smaller or equal to the upper_limit. The Resource Manager is requested to keep the power values for the given commodity quantity equal to or above the lower_limit. The lower_limit shall be in accordance with the constraints provided by the Resource Manager through any PEBC.AllowedLimitRange with limit_type LOWER_LIMIT.',
349
253
  )
350
254
 
351
255
 
352
- class PEBCPowerEnvelopeLimitType(Enum):
353
- UPPER_LIMIT = "UPPER_LIMIT"
354
- LOWER_LIMIT = "LOWER_LIMIT"
355
-
356
-
357
- class PPBCEndInterruptionInstruction(BaseModel):
358
- class Config:
359
- extra = Extra.forbid
360
-
361
- abnormal_condition: bool = Field(
362
- ...,
363
- description="Indicates if this is an instruction during an abnormal condition",
256
+ class FRBCStorageDescription(BaseModel):
257
+ model_config = ConfigDict(
258
+ extra='forbid',
364
259
  )
365
- execution_time: datetime = Field(
366
- ..., description="End time of Interruption of the PPBC.PowerSequence."
260
+ diagnostic_label: Optional[str] = Field(
261
+ None,
262
+ description='Human readable name/description of the storage (e.g. hot water buffer or battery). This element is only intended for diagnostic purposes and not for HMI applications.',
367
263
  )
368
- id: ID = Field(
264
+ fill_level_label: Optional[str] = Field(
265
+ None,
266
+ description='Human readable description of the (physical) units associated with the fill_level (e.g. degrees Celsius or percentage state of charge). This element is only intended for diagnostic purposes and not for HMI applications.',
267
+ )
268
+ provides_leakage_behaviour: bool = Field(
369
269
  ...,
370
- description="ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
270
+ description='Indicates whether the Storage could provide details of power leakage behaviour through the FRBC.LeakageBehaviour.',
371
271
  )
372
- message_id: ID = Field(..., description="ID of this message")
373
- message_type: str = Field("PPBC.EndInterruptionInstruction", const=True)
374
- power_profile_id: ID = Field(
272
+ provides_fill_level_target_profile: bool = Field(
375
273
  ...,
376
- description="ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence interruption is being ended by the CEM.",
274
+ description='Indicates whether the Storage could provide a target profile for the fill level through the FRBC.FillLevelTargetProfile.',
377
275
  )
378
- power_sequence_id: ID = Field(
276
+ provides_usage_forecast: bool = Field(
379
277
  ...,
380
- description="ID of the PPBC.PowerSequence for which the CEM wants to end the interruption.",
278
+ description='Indicates whether the Storage could provide a UsageForecast through the FRBC.UsageForecast.',
381
279
  )
382
- sequence_container_id: ID = Field(
280
+ fill_level_range: NumberRange = Field(
383
281
  ...,
384
- description="ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence interruption is being ended by the CEM.",
282
+ description='The range in which the fill_level should remain. It is expected of the CEM to keep the fill_level within this range. When the fill_level is not within this range, the Resource Manager can ignore instructions from the CEM (except during abnormal conditions). ',
385
283
  )
386
284
 
387
285
 
388
- class PPBCPowerSequenceStatus(Enum):
389
- NOT_SCHEDULED = "NOT_SCHEDULED"
390
- SCHEDULED = "SCHEDULED"
391
- EXECUTING = "EXECUTING"
392
- INTERRUPTED = "INTERRUPTED"
393
- FINISHED = "FINISHED"
394
- ABORTED = "ABORTED"
395
-
396
-
397
- class PPBCScheduleInstruction(BaseModel):
398
- class Config:
399
- extra = Extra.forbid
400
-
401
- abnormal_condition: bool = Field(
402
- ...,
403
- description="Indicates if this is an instruction during an abnormal condition",
404
- )
405
- execution_time: datetime = Field(
406
- ..., description="Start time of the PPBC.PowerSequence."
407
- )
408
- id: ID = Field(
409
- ...,
410
- description="ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
411
- )
412
- message_id: ID = Field(..., description="ID of this message")
413
- message_type: str = Field("PPBC.ScheduleInstruction", const=True)
414
- power_profile_id: ID = Field(
415
- ...,
416
- description="ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence is being selected and scheduled by the CEM.",
286
+ class FRBCLeakageBehaviourElement(BaseModel):
287
+ model_config = ConfigDict(
288
+ extra='forbid',
417
289
  )
418
- power_sequence_id: ID = Field(
290
+ fill_level_range: NumberRange = Field(
419
291
  ...,
420
- description="ID of the PPBC.PowerSequence that is being selected and scheduled by the CEM.",
292
+ description='The fill level range for which this FRBC.LeakageBehaviourElement applies. The start of the range must be less than the end of the range.',
421
293
  )
422
- sequence_container_id: ID = Field(
294
+ leakage_rate: float = Field(
423
295
  ...,
424
- description="ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence is being selected and scheduled by the CEM.",
296
+ description='Indicates how fast the momentary fill level will decrease per second due to leakage within the given range of the fill level. A positive value indicates that the fill level decreases over time due to leakage.',
425
297
  )
426
298
 
427
299
 
428
- class PPBCStartInterruptionInstruction(BaseModel):
429
- class Config:
430
- extra = Extra.forbid
431
-
432
- abnormal_condition: bool = Field(
433
- ...,
434
- description="Indicates if this is an instruction during an abnormal condition",
300
+ class FRBCUsageForecastElement(BaseModel):
301
+ model_config = ConfigDict(
302
+ extra='forbid',
435
303
  )
436
- execution_time: datetime = Field(
437
- ..., description="Start time of the interruption of the PPBC.PowerSequence."
304
+ duration: Duration = Field(
305
+ ..., description='Indicator for how long the given usage_rate is valid.'
438
306
  )
439
- id: ID = Field(
440
- ...,
441
- description="ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
307
+ usage_rate_upper_limit: Optional[float] = Field(
308
+ None,
309
+ description='The upper limit of the range with a 100 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
442
310
  )
443
- message_id: ID = Field(..., description="ID of this message")
444
- message_type: str = Field("PPBC.StartInterruptionInstruction", const=True)
445
- power_profile_id: ID = Field(
446
- ...,
447
- description="ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence is being interrupted by the CEM.",
311
+ usage_rate_upper_95PPR: Optional[float] = Field(
312
+ None,
313
+ description='The upper limit of the range with a 95 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
448
314
  )
449
- power_sequence_id: ID = Field(
450
- ..., description="ID of the PPBC.PowerSequence that the CEM wants to interrupt."
315
+ usage_rate_upper_68PPR: Optional[float] = Field(
316
+ None,
317
+ description='The upper limit of the range with a 68 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
451
318
  )
452
- sequence_container_id: ID = Field(
319
+ usage_rate_expected: float = Field(
453
320
  ...,
454
- description="ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence is being interrupted by the CEM.",
321
+ description='The most likely value for the usage rate; the expected increase or decrease of the fill_level per second. A positive value indicates that the fill level will decrease due to usage.',
322
+ )
323
+ usage_rate_lower_68PPR: Optional[float] = Field(
324
+ None,
325
+ description='The lower limit of the range with a 68 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
326
+ )
327
+ usage_rate_lower_95PPR: Optional[float] = Field(
328
+ None,
329
+ description='The lower limit of the range with a 95 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
330
+ )
331
+ usage_rate_lower_limit: Optional[float] = Field(
332
+ None,
333
+ description='The lower limit of the range with a 100 % probability that the usage rate is within that range. A positive value indicates that the fill level will decrease due to usage.',
455
334
  )
456
335
 
457
336
 
458
- class PowerForecastValue(BaseModel):
459
- class Config:
460
- extra = Extra.forbid
337
+ class FRBCFillLevelTargetProfileElement(BaseModel):
338
+ model_config = ConfigDict(
339
+ extra='forbid',
340
+ )
341
+ duration: Duration = Field(..., description='The duration of the element.')
342
+ fill_level_range: NumberRange = Field(
343
+ ...,
344
+ description='The target range in which the fill_level must be for the time period during which the element is active. The start of the range must be smaller or equal to the end of the range. The CEM must take best-effort actions to proactively achieve this target.',
345
+ )
461
346
 
462
- commodity_quantity: CommodityQuantity = Field(
463
- ..., description="The power quantity the value refers to"
347
+
348
+ class DDBCAverageDemandRateForecastElement(BaseModel):
349
+ model_config = ConfigDict(
350
+ extra='forbid',
464
351
  )
465
- value_expected: float = Field(..., description="The expected power value.")
466
- value_lower_68PPR: Optional[float] = Field(
352
+ duration: Duration = Field(..., description='Duration of the element')
353
+ demand_rate_upper_limit: Optional[float] = Field(
467
354
  None,
468
- description="The lower boundary of the range with 68\xa0% certainty the power value is in it",
355
+ description='The upper limit of the range with a 100 % probability that the demand rate is within that range',
469
356
  )
470
- value_lower_95PPR: Optional[float] = Field(
357
+ demand_rate_upper_95PPR: Optional[float] = Field(
471
358
  None,
472
- description="The lower boundary of the range with 95\xa0% certainty the power value is in it",
359
+ description='The upper limit of the range with a 95 % probability that the demand rate is within that range',
473
360
  )
474
- value_lower_limit: Optional[float] = Field(
361
+ demand_rate_upper_68PPR: Optional[float] = Field(
475
362
  None,
476
- description="The lower boundary of the range with 100\xa0% certainty the power value is in it",
363
+ description='The upper limit of the range with a 68 % probability that the demand rate is within that range',
477
364
  )
478
- value_upper_68PPR: Optional[float] = Field(
365
+ demand_rate_expected: float = Field(
366
+ ...,
367
+ description='The most likely value for the demand rate; the expected increase or decrease of the fill_level per second',
368
+ )
369
+ demand_rate_lower_68PPR: Optional[float] = Field(
479
370
  None,
480
- description="The upper boundary of the range with 68\xa0% certainty the power value is in it",
371
+ description='The lower limit of the range with a 68 % probability that the demand rate is within that range',
481
372
  )
482
- value_upper_95PPR: Optional[float] = Field(
373
+ demand_rate_lower_95PPR: Optional[float] = Field(
483
374
  None,
484
- description="The upper boundary of the range with 95\xa0% certainty the power value is in it",
375
+ description='The lower limit of the range with a 95 % probability that the demand rate is within that range',
485
376
  )
486
- value_upper_limit: Optional[float] = Field(
377
+ demand_rate_lower_limit: Optional[float] = Field(
487
378
  None,
488
- description="The upper boundary of the range with 100\xa0% certainty the power value is in it",
379
+ description='The lower limit of the range with a 100 % probability that the demand rate is within that range',
489
380
  )
490
381
 
491
382
 
492
- class PowerRange(BaseModel):
493
- class Config:
494
- extra = Extra.forbid
383
+ class RoleType(Enum):
384
+ ENERGY_PRODUCER = 'ENERGY_PRODUCER'
385
+ ENERGY_CONSUMER = 'ENERGY_CONSUMER'
386
+ ENERGY_STORAGE = 'ENERGY_STORAGE'
495
387
 
496
- commodity_quantity: CommodityQuantity = Field(
497
- ..., description="The power quantity the values refer to"
498
- )
499
- end_of_range: float = Field(
500
- ..., description="Power value that defines the end of the range."
388
+
389
+ class Commodity(Enum):
390
+ GAS = 'GAS'
391
+ HEAT = 'HEAT'
392
+ ELECTRICITY = 'ELECTRICITY'
393
+ OIL = 'OIL'
394
+
395
+
396
+ class CommodityQuantity(Enum):
397
+ ELECTRIC_POWER_L1 = 'ELECTRIC.POWER.L1'
398
+ ELECTRIC_POWER_L2 = 'ELECTRIC.POWER.L2'
399
+ ELECTRIC_POWER_L3 = 'ELECTRIC.POWER.L3'
400
+ ELECTRIC_POWER_3_PHASE_SYMMETRIC = 'ELECTRIC.POWER.3_PHASE_SYMMETRIC'
401
+ NATURAL_GAS_FLOW_RATE = 'NATURAL_GAS.FLOW_RATE'
402
+ HYDROGEN_FLOW_RATE = 'HYDROGEN.FLOW_RATE'
403
+ HEAT_TEMPERATURE = 'HEAT.TEMPERATURE'
404
+ HEAT_FLOW_RATE = 'HEAT.FLOW_RATE'
405
+ HEAT_THERMAL_POWER = 'HEAT.THERMAL_POWER'
406
+ OIL_FLOW_RATE = 'OIL.FLOW_RATE'
407
+
408
+
409
+ class InstructionStatus(Enum):
410
+ NEW = 'NEW'
411
+ ACCEPTED = 'ACCEPTED'
412
+ REJECTED = 'REJECTED'
413
+ REVOKED = 'REVOKED'
414
+ STARTED = 'STARTED'
415
+ SUCCEEDED = 'SUCCEEDED'
416
+ ABORTED = 'ABORTED'
417
+
418
+
419
+ class ControlType(Enum):
420
+ POWER_ENVELOPE_BASED_CONTROL = 'POWER_ENVELOPE_BASED_CONTROL'
421
+ POWER_PROFILE_BASED_CONTROL = 'POWER_PROFILE_BASED_CONTROL'
422
+ OPERATION_MODE_BASED_CONTROL = 'OPERATION_MODE_BASED_CONTROL'
423
+ FILL_RATE_BASED_CONTROL = 'FILL_RATE_BASED_CONTROL'
424
+ DEMAND_DRIVEN_BASED_CONTROL = 'DEMAND_DRIVEN_BASED_CONTROL'
425
+ NOT_CONTROLABLE = 'NOT_CONTROLABLE'
426
+ NO_SELECTION = 'NO_SELECTION'
427
+
428
+
429
+ class PEBCPowerEnvelopeLimitType(Enum):
430
+ UPPER_LIMIT = 'UPPER_LIMIT'
431
+ LOWER_LIMIT = 'LOWER_LIMIT'
432
+
433
+
434
+ class PEBCPowerEnvelopeConsequenceType(Enum):
435
+ VANISH = 'VANISH'
436
+ DEFER = 'DEFER'
437
+
438
+
439
+ class PPBCPowerSequenceStatus(Enum):
440
+ NOT_SCHEDULED = 'NOT_SCHEDULED'
441
+ SCHEDULED = 'SCHEDULED'
442
+ EXECUTING = 'EXECUTING'
443
+ INTERRUPTED = 'INTERRUPTED'
444
+ FINISHED = 'FINISHED'
445
+ ABORTED = 'ABORTED'
446
+
447
+
448
+ class OMBCTimerStatus(BaseModel):
449
+ model_config = ConfigDict(
450
+ extra='forbid',
501
451
  )
502
- start_of_range: float = Field(
503
- ..., description="Power value that defines the start of the range."
452
+ message_type: Literal['OMBC.TimerStatus'] = 'OMBC.TimerStatus'
453
+ message_id: ID
454
+ timer_id: ID = Field(..., description='The ID of the timer this message refers to')
455
+ finished_at: AwareDatetime = Field(
456
+ ...,
457
+ description='Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.',
504
458
  )
505
459
 
506
460
 
507
- class PowerValue(BaseModel):
508
- class Config:
509
- extra = Extra.forbid
461
+ class FRBCTimerStatus(BaseModel):
462
+ model_config = ConfigDict(
463
+ extra='forbid',
464
+ )
465
+ message_type: Literal['FRBC.TimerStatus'] = 'FRBC.TimerStatus'
466
+ message_id: ID
467
+ timer_id: ID = Field(..., description='The ID of the timer this message refers to')
468
+ actuator_id: ID = Field(
469
+ ..., description='The ID of the actuator the timer belongs to'
470
+ )
471
+ finished_at: AwareDatetime = Field(
472
+ ...,
473
+ description='Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.',
474
+ )
510
475
 
511
- commodity_quantity: CommodityQuantity = Field(
512
- ..., description="The power quantity the value refers to"
476
+
477
+ class DDBCTimerStatus(BaseModel):
478
+ model_config = ConfigDict(
479
+ extra='forbid',
513
480
  )
514
- value: float = Field(
481
+ message_type: Literal['DDBC.TimerStatus'] = 'DDBC.TimerStatus'
482
+ message_id: ID
483
+ timer_id: ID = Field(..., description='The ID of the timer this message refers to')
484
+ actuator_id: ID = Field(
485
+ ..., description='The ID of the actuator the timer belongs to'
486
+ )
487
+ finished_at: AwareDatetime = Field(
515
488
  ...,
516
- description="Power value expressed in the unit associated with the CommodityQuantity",
489
+ description='Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.',
517
490
  )
518
491
 
519
492
 
520
- class ReceptionStatusValues(Enum):
521
- INVALID_DATA = "INVALID_DATA"
522
- INVALID_MESSAGE = "INVALID_MESSAGE"
523
- INVALID_CONTENT = "INVALID_CONTENT"
524
- TEMPORARY_ERROR = "TEMPORARY_ERROR"
525
- PERMANENT_ERROR = "PERMANENT_ERROR"
526
- OK = "OK"
493
+ class SelectControlType(BaseModel):
494
+ model_config = ConfigDict(
495
+ extra='forbid',
496
+ )
497
+ message_type: Literal['SelectControlType'] = 'SelectControlType'
498
+ message_id: ID
499
+ control_type: ControlType = Field(
500
+ ...,
501
+ description='The ControlType to activate. Must be one of the available ControlTypes as defined in the ResourceManagerDetails',
502
+ )
527
503
 
528
504
 
529
- class RevokableObjects(Enum):
530
- PEBC_PowerConstraints = "PEBC.PowerConstraints"
531
- PEBC_EnergyConstraint = "PEBC.EnergyConstraint"
532
- PEBC_Instruction = "PEBC.Instruction"
533
- PPBC_PowerProfileDefinition = "PPBC.PowerProfileDefinition"
534
- PPBC_ScheduleInstruction = "PPBC.ScheduleInstruction"
535
- PPBC_StartInterruptionInstruction = "PPBC.StartInterruptionInstruction"
536
- PPBC_EndInterruptionInstruction = "PPBC.EndInterruptionInstruction"
537
- OMBC_SystemDescription = "OMBC.SystemDescription"
538
- OMBC_Instruction = "OMBC.Instruction"
539
- FRBC_SystemDescription = "FRBC.SystemDescription"
540
- FRBC_Instruction = "FRBC.Instruction"
541
- DDBC_SystemDescription = "DDBC.SystemDescription"
542
- DDBC_Instruction = "DDBC.Instruction"
505
+ class SessionRequest(BaseModel):
506
+ model_config = ConfigDict(
507
+ extra='forbid',
508
+ )
509
+ message_type: Literal['SessionRequest'] = 'SessionRequest'
510
+ message_id: ID
511
+ request: SessionRequestType = Field(..., description='The type of request')
512
+ diagnostic_label: Optional[str] = Field(
513
+ None,
514
+ description='Optional field for a human readible descirption for debugging purposes',
515
+ )
543
516
 
544
517
 
545
518
  class RevokeObject(BaseModel):
546
- class Config:
547
- extra = Extra.forbid
548
-
549
- message_id: ID = Field(..., description="ID of this message")
550
- message_type: str = Field("RevokeObject", const=True)
551
- object_id: ID = Field(..., description="The ID of object that needs to be revoked")
519
+ model_config = ConfigDict(
520
+ extra='forbid',
521
+ )
522
+ message_type: Literal['RevokeObject'] = 'RevokeObject'
523
+ message_id: ID
552
524
  object_type: RevokableObjects = Field(
553
- ..., description="The type of object that needs to be revoked"
525
+ ..., description='The type of object that needs to be revoked'
554
526
  )
527
+ object_id: ID = Field(..., description='The ID of object that needs to be revoked')
555
528
 
556
529
 
557
- class RoleType(Enum):
558
- ENERGY_PRODUCER = "ENERGY_PRODUCER"
559
- ENERGY_CONSUMER = "ENERGY_CONSUMER"
560
- ENERGY_STORAGE = "ENERGY_STORAGE"
561
-
530
+ class Handshake(BaseModel):
531
+ model_config = ConfigDict(
532
+ extra='forbid',
533
+ )
534
+ message_type: Literal['Handshake'] = 'Handshake'
535
+ message_id: ID
536
+ role: EnergyManagementRole = Field(
537
+ ..., description='The role of the sender of this message'
538
+ )
539
+ supported_protocol_versions: Optional[List[str]] = Field(
540
+ None,
541
+ description='Protocol versions supported by the sender of this message. This field is mandatory for the RM, but optional for the CEM.',
542
+ min_length=1,
543
+ )
562
544
 
563
- class SelectControlType(BaseModel):
564
- class Config:
565
- extra = Extra.forbid
566
545
 
567
- control_type: ControlType = Field(
568
- ...,
569
- description="The ControlType to activate. Must be one of the available ControlTypes as defined in the ResourceManagerDetails",
546
+ class HandshakeResponse(BaseModel):
547
+ model_config = ConfigDict(
548
+ extra='forbid',
549
+ )
550
+ message_type: Literal['HandshakeResponse'] = 'HandshakeResponse'
551
+ message_id: ID
552
+ selected_protocol_version: str = Field(
553
+ ..., description='The protocol version the CEM selected for this session'
570
554
  )
571
- message_id: ID = Field(..., description="ID of this message")
572
- message_type: str = Field("SelectControlType", const=True)
573
555
 
574
556
 
575
- class SessionRequestType(Enum):
576
- RECONNECT = "RECONNECT"
577
- TERMINATE = "TERMINATE"
557
+ class ReceptionStatus(BaseModel):
558
+ model_config = ConfigDict(
559
+ extra='forbid',
560
+ )
561
+ message_type: Literal['ReceptionStatus'] = 'ReceptionStatus'
562
+ subject_message_id: ID = Field(
563
+ ..., description='The message this ReceptionStatus refers to'
564
+ )
565
+ status: ReceptionStatusValues = Field(
566
+ ..., description='Enumeration of status values'
567
+ )
568
+ diagnostic_label: Optional[str] = Field(
569
+ None,
570
+ description='Diagnostic label that can be used to provide additional information for debugging. However, not for HMI purposes.',
571
+ )
578
572
 
579
573
 
580
- class Timer(BaseModel):
581
- class Config:
582
- extra = Extra.forbid
574
+ class InstructionStatusUpdate(BaseModel):
575
+ model_config = ConfigDict(
576
+ extra='forbid',
577
+ )
578
+ message_type: Literal['InstructionStatusUpdate'] = 'InstructionStatusUpdate'
579
+ message_id: ID
580
+ instruction_id: ID = Field(
581
+ ..., description='ID of this instruction (as provided by the CEM) '
582
+ )
583
+ status_type: InstructionStatus = Field(
584
+ ..., description='Present status of this instruction.'
585
+ )
586
+ timestamp: AwareDatetime = Field(
587
+ ..., description='Timestamp when status_type has changed the last time.'
588
+ )
583
589
 
584
- diagnostic_label: Optional[str] = Field(
585
- None,
586
- description="Human readable name/description of the Timer. This element is only intended for diagnostic purposes and not for HMI applications.",
590
+
591
+ class PEBCEnergyConstraint(BaseModel):
592
+ model_config = ConfigDict(
593
+ extra='forbid',
587
594
  )
588
- duration: Duration = Field(
595
+ message_type: Literal['PEBC.EnergyConstraint'] = 'PEBC.EnergyConstraint'
596
+ message_id: ID
597
+ id: ID = Field(
589
598
  ...,
590
- description="The time it takes for the Timer to finish after it has been started",
599
+ description='Identifier of this PEBC.EnergyConstraints. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
591
600
  )
592
- id: ID = Field(
601
+ valid_from: AwareDatetime = Field(
602
+ ...,
603
+ description='Moment this PEBC.EnergyConstraints information starts to be valid',
604
+ )
605
+ valid_until: AwareDatetime = Field(
606
+ ...,
607
+ description='Moment until this PEBC.EnergyConstraints information is valid.',
608
+ )
609
+ upper_average_power: float = Field(
593
610
  ...,
594
- description="ID of the Timer. Must be unique in the scope of the OMBC.SystemDescription, FRBC.ActuatorDescription or DDBC.ActuatorDescription in which it is used.",
611
+ description='Upper average power within the time period given by valid_from and valid_until. If the duration is multiplied with this power value, then the associated upper energy content can be derived. This is the highest amount of energy the resource will consume during that period of time. The Power Envelope created by the CEM must allow at least this much energy consumption (in case the number is positive). Must be greater than or equal to lower_average_power, and can be negative in case of energy production.',
612
+ )
613
+ lower_average_power: float = Field(
614
+ ...,
615
+ description='Lower average power within the time period given by valid_from and valid_until. If the duration is multiplied with this power value, then the associated lower energy content can be derived. This is the lowest amount of energy the resource will consume during that period of time. The Power Envelope created by the CEM must allow at least this much energy production (in case the number is negative). Must be greater than or equal to lower_average_power, and can be negative in case of energy production.',
616
+ )
617
+ commodity_quantity: CommodityQuantity = Field(
618
+ ...,
619
+ description='Type of power quantity which applies to upper_average_power and lower_average_power',
595
620
  )
596
621
 
597
622
 
598
- class Transition(BaseModel):
599
- class Config:
600
- extra = Extra.forbid
623
+ class PPBCScheduleInstruction(BaseModel):
624
+ model_config = ConfigDict(
625
+ extra='forbid',
626
+ )
627
+ message_type: Literal['PPBC.ScheduleInstruction'] = 'PPBC.ScheduleInstruction'
628
+ message_id: ID
629
+ id: ID = Field(
630
+ ...,
631
+ description='ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
632
+ )
633
+ power_profile_id: ID = Field(
634
+ ...,
635
+ description='ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence is being selected and scheduled by the CEM.',
636
+ )
637
+ sequence_container_id: ID = Field(
638
+ ...,
639
+ description='ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence is being selected and scheduled by the CEM.',
640
+ )
641
+ power_sequence_id: ID = Field(
642
+ ...,
643
+ description='ID of the PPBC.PowerSequence that is being selected and scheduled by the CEM.',
644
+ )
645
+ execution_time: AwareDatetime = Field(
646
+ ...,
647
+ description='Indicates the moment the PPBC.PowerSequence shall start. When the specified execution time is in the past, execution must start as soon as possible.',
648
+ )
649
+ abnormal_condition: bool = Field(
650
+ ...,
651
+ description='Indicates if this is an instruction during an abnormal condition',
652
+ )
601
653
 
602
- abnormal_condition_only: bool = Field(
654
+
655
+ class PPBCStartInterruptionInstruction(BaseModel):
656
+ model_config = ConfigDict(
657
+ extra='forbid',
658
+ )
659
+ message_type: Literal['PPBC.StartInterruptionInstruction'] = (
660
+ 'PPBC.StartInterruptionInstruction'
661
+ )
662
+ message_id: ID
663
+ id: ID = Field(
603
664
  ...,
604
- description="Indicates if this Transition may only be used during an abnormal condition (see Clause )",
665
+ description='ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
605
666
  )
606
- blocking_timers: List[ID] = Field(
667
+ power_profile_id: ID = Field(
607
668
  ...,
608
- description="List of IDs of Timers that block this Transition from initiating while at least one of these Timers is not yet finished",
609
- max_items=1000,
610
- min_items=0,
669
+ description='ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence is being interrupted by the CEM.',
611
670
  )
612
- from_: ID = Field(
671
+ sequence_container_id: ID = Field(
672
+ ...,
673
+ description='ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence is being interrupted by the CEM.',
674
+ )
675
+ power_sequence_id: ID = Field(
676
+ ..., description='ID of the PPBC.PowerSequence that the CEM wants to interrupt.'
677
+ )
678
+ execution_time: AwareDatetime = Field(
679
+ ...,
680
+ description='Indicates the moment the PPBC.PowerSequence shall be interrupted. When the specified execution time is in the past, execution must start as soon as possible.',
681
+ )
682
+ abnormal_condition: bool = Field(
683
+ ...,
684
+ description='Indicates if this is an instruction during an abnormal condition',
685
+ )
686
+
687
+
688
+ class PPBCEndInterruptionInstruction(BaseModel):
689
+ model_config = ConfigDict(
690
+ extra='forbid',
691
+ )
692
+ message_type: Literal['PPBC.EndInterruptionInstruction'] = (
693
+ 'PPBC.EndInterruptionInstruction'
694
+ )
695
+ message_id: ID
696
+ id: ID = Field(
697
+ ...,
698
+ description='ID of the Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
699
+ )
700
+ power_profile_id: ID = Field(
613
701
  ...,
614
- alias="from",
615
- description="ID of the OperationMode (exact type differs per ControlType) that should be switched from.",
702
+ description='ID of the PPBC.PowerProfileDefinition of which the PPBC.PowerSequence interruption is being ended by the CEM.',
616
703
  )
617
- id: ID = Field(
704
+ sequence_container_id: ID = Field(
618
705
  ...,
619
- description="ID of the Transition. Must be unique in the scope of the OMBC.SystemDescription, FRBC.ActuatorDescription or DDBC.ActuatorDescription in which it is used.",
706
+ description='ID of the PPBC.PowerSequnceContainer of which the PPBC.PowerSequence interruption is being ended by the CEM.',
620
707
  )
621
- start_timers: List[ID] = Field(
708
+ power_sequence_id: ID = Field(
622
709
  ...,
623
- description="List of IDs of Timers that will be (re)started when this transition is initiated",
624
- max_items=1000,
625
- min_items=0,
710
+ description='ID of the PPBC.PowerSequence for which the CEM wants to end the interruption.',
626
711
  )
627
- to: ID = Field(
712
+ execution_time: AwareDatetime = Field(
628
713
  ...,
629
- description="ID of the OperationMode (exact type differs per ControlType) that will be switched to.",
630
- )
631
- transition_costs: Optional[float] = Field(
632
- None,
633
- description="Absolute costs for going through this Transition in the currency as described in the ResourceManagerDetails.",
714
+ description='Indicates the moment PPBC.PowerSequence interruption shall end. When the specified execution time is in the past, execution must start as soon as possible.',
634
715
  )
635
- transition_duration: Optional[Duration] = Field(
636
- None,
637
- description="Indicates the time between the initiation of this Transition, and the time at which the device behaves according to the Operation Mode which is defined in the ‘to’ data element. When no value is provided it is assumed the transition duration is negligible.",
716
+ abnormal_condition: bool = Field(
717
+ ...,
718
+ description='Indicates if this is an instruction during an abnormal condition',
638
719
  )
639
720
 
640
721
 
641
- class DDBCActuatorStatus(BaseModel):
642
- class Config:
643
- extra = Extra.forbid
644
-
645
- active_operation_mode_id: ID = Field(
646
- ...,
647
- description="The operation mode that is presently active for this actuator.",
722
+ class OMBCStatus(BaseModel):
723
+ model_config = ConfigDict(
724
+ extra='forbid',
648
725
  )
649
- actuator_id: ID = Field(
650
- ..., description="ID of the actuator this messages refers to"
726
+ message_type: Literal['OMBC.Status'] = 'OMBC.Status'
727
+ message_id: ID
728
+ active_operation_mode_id: ID = Field(
729
+ ..., description='ID of the active OMBC.OperationMode.'
651
730
  )
652
- message_id: ID = Field(..., description="ID of this message")
653
- message_type: str = Field("DDBC.ActuatorStatus", const=True)
654
731
  operation_mode_factor: float = Field(
655
732
  ...,
656
- description="The number indicates the factor with which the DDBC.OperationMode is configured. The factor should be greater than or equal to 0 and less or equal to 1.",
733
+ description='The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal than 0 and less or equal to 1.',
657
734
  )
658
735
  previous_operation_mode_id: Optional[ID] = Field(
659
736
  None,
660
- description="ID of the DDBC,OperationMode that was active before the present one. This value shall always be provided, unless the active DDBC.OperationMode is the first DDBC.OperationMode the Resource Manager is aware of.",
737
+ description='ID of the OMBC.OperationMode that was previously active. This value shall always be provided, unless the active OMBC.OperationMode is the first OMBC.OperationMode the Resource Manager is aware of.',
661
738
  )
662
- transition_timestamp: Optional[datetime] = Field(
739
+ transition_timestamp: Optional[AwareDatetime] = Field(
663
740
  None,
664
- description="Time at which the transition from the previous DDBC.OperationMode to the active DDBC.OperationMode was initiated. This value shall always be provided, unless the active DDBC.OperationMode is the first DDBC.OperationMode the Resource Manager is aware of.",
741
+ description='Time at which the transition from the previous OMBC.OperationMode to the active OMBC.OperationMode was initiated. This value shall always be provided, unless the active OMBC.OperationMode is the first OMBC.OperationMode the Resource Manager is aware of.',
665
742
  )
666
743
 
667
744
 
668
- class DDBCAverageDemandRateForecastElement(BaseModel):
669
- class Config:
670
- extra = Extra.forbid
671
-
672
- demand_rate_expected: float = Field(
745
+ class OMBCInstruction(BaseModel):
746
+ model_config = ConfigDict(
747
+ extra='forbid',
748
+ )
749
+ message_type: Literal['OMBC.Instruction'] = 'OMBC.Instruction'
750
+ message_id: ID
751
+ id: ID = Field(
673
752
  ...,
674
- description="The most likely value for the demand rate; the expected increase or decrease of the fill_level per second",
753
+ description='ID of the instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
675
754
  )
676
- demand_rate_lower_68PPR: Optional[float] = Field(
677
- None,
678
- description="The lower limit of the range with a 68\xa0% probability that the demand rate is within that range",
755
+ execution_time: AwareDatetime = Field(
756
+ ...,
757
+ description='Indicates the moment the execution of the instruction shall start. When the specified execution time is in the past, execution must start as soon as possible.',
679
758
  )
680
- demand_rate_lower_95PPR: Optional[float] = Field(
681
- None,
682
- description="The lower limit of the range with a 95\xa0% probability that the demand rate is within that range",
759
+ operation_mode_id: ID = Field(
760
+ ..., description='ID of the OMBC.OperationMode that should be activated'
683
761
  )
684
- demand_rate_lower_limit: Optional[float] = Field(
685
- None,
686
- description="The lower limit of the range with a 100\xa0% probability that the demand rate is within that range",
762
+ operation_mode_factor: float = Field(
763
+ ...,
764
+ description='The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal than 0 and less or equal to 1.',
687
765
  )
688
- demand_rate_upper_68PPR: Optional[float] = Field(
689
- None,
690
- description="The upper limit of the range with a 68\xa0% probability that the demand rate is within that range",
766
+ abnormal_condition: bool = Field(
767
+ ...,
768
+ description='Indicates if this is an instruction during an abnormal condition',
691
769
  )
692
- demand_rate_upper_95PPR: Optional[float] = Field(
770
+
771
+
772
+ class FRBCActuatorStatus(BaseModel):
773
+ model_config = ConfigDict(
774
+ extra='forbid',
775
+ )
776
+ message_type: Literal['FRBC.ActuatorStatus'] = 'FRBC.ActuatorStatus'
777
+ message_id: ID
778
+ actuator_id: ID = Field(
779
+ ..., description='ID of the actuator this messages refers to'
780
+ )
781
+ active_operation_mode_id: ID = Field(
782
+ ..., description='ID of the FRBC.OperationMode that is presently active.'
783
+ )
784
+ operation_mode_factor: float = Field(
785
+ ...,
786
+ description='The number indicates the factor with which the FRBC.OperationMode is configured. The factor should be greater than or equal than 0 and less or equal to 1.',
787
+ )
788
+ previous_operation_mode_id: Optional[ID] = Field(
693
789
  None,
694
- description="The upper limit of the range with a 95\xa0% probability that the demand rate is within that range",
790
+ description='ID of the FRBC.OperationMode that was active before the present one. This value shall always be provided, unless the active FRBC.OperationMode is the first FRBC.OperationMode the Resource Manager is aware of.',
695
791
  )
696
- demand_rate_upper_limit: Optional[float] = Field(
792
+ transition_timestamp: Optional[AwareDatetime] = Field(
697
793
  None,
698
- description="The upper limit of the range with a 100\xa0% probability that the demand rate is within that range",
794
+ description='Time at which the transition from the previous FRBC.OperationMode to the active FRBC.OperationMode was initiated. This value shall always be provided, unless the active FRBC.OperationMode is the first FRBC.OperationMode the Resource Manager is aware of.',
699
795
  )
700
- duration: Duration = Field(..., description="Duration of the element")
701
-
702
796
 
703
- class DDBCInstruction(BaseModel):
704
- class Config:
705
- extra = Extra.forbid
706
797
 
707
- abnormal_condition: bool = Field(
708
- ...,
709
- description="Indicates if this is an instruction during an abnormal condition",
798
+ class FRBCStorageStatus(BaseModel):
799
+ model_config = ConfigDict(
800
+ extra='forbid',
710
801
  )
711
- actuator_id: ID = Field(
712
- ..., description="ID of the actuator this Instruction belongs to."
802
+ message_type: Literal['FRBC.StorageStatus'] = 'FRBC.StorageStatus'
803
+ message_id: ID
804
+ present_fill_level: float = Field(
805
+ ..., description='Present fill level of the Storage'
713
806
  )
714
- execution_time: datetime = Field(
715
- ...,
716
- description="Indicates the moment the execution of the instruction shall start",
807
+
808
+
809
+ class FRBCLeakageBehaviour(BaseModel):
810
+ model_config = ConfigDict(
811
+ extra='forbid',
717
812
  )
718
- id: ID = Field(
813
+ message_type: Literal['FRBC.LeakageBehaviour'] = 'FRBC.LeakageBehaviour'
814
+ message_id: ID
815
+ valid_from: AwareDatetime = Field(
719
816
  ...,
720
- description="Identifier of this DDBC.Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
817
+ description='Moment this FRBC.LeakageBehaviour starts to be valid. If the FRBC.LeakageBehaviour is immediately valid, the DateTimeStamp should be now or in the past.',
721
818
  )
722
- message_id: ID = Field(..., description="ID of this message")
723
- message_type: str = Field("DDBC.Instruction", const=True)
724
- operation_mode_factor: float = Field(
819
+ elements: List[FRBCLeakageBehaviourElement] = Field(
725
820
  ...,
726
- description="The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal to 0 and less or equal to 1.",
821
+ description='List of elements that model the leakage behaviour of the buffer. The fill_level_ranges of the elements must be contiguous.',
822
+ max_length=288,
823
+ min_length=1,
727
824
  )
728
- operation_mode_id: ID = Field(..., description="ID of the DDBC.OperationMode")
729
-
730
825
 
731
- class DDBCOperationMode(BaseModel):
732
- class Config:
733
- extra = Extra.forbid
734
826
 
735
- Id: ID = Field(
736
- ...,
737
- description="ID of this operation mode. Must be unique in the scope of the DDBC.ActuatorDescription in which it is used.",
827
+ class FRBCInstruction(BaseModel):
828
+ model_config = ConfigDict(
829
+ extra='forbid',
738
830
  )
739
- abnormal_condition_only: bool = Field(
831
+ message_type: Literal['FRBC.Instruction'] = 'FRBC.Instruction'
832
+ message_id: ID
833
+ id: ID = Field(
740
834
  ...,
741
- description="Indicates if this DDBC.OperationMode may only be used during an abnormal condition.",
835
+ description='ID of the instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
742
836
  )
743
- diagnostic_label: Optional[str] = Field(
744
- None,
745
- description="Human readable name/description of the DDBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.",
837
+ actuator_id: ID = Field(
838
+ ..., description='ID of the actuator this instruction belongs to.'
746
839
  )
747
- power_ranges: List[PowerRange] = Field(
840
+ operation_mode: ID = Field(
841
+ ..., description='ID of the FRBC.OperationMode that should be activated.'
842
+ )
843
+ operation_mode_factor: float = Field(
748
844
  ...,
749
- description="The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.",
750
- max_items=10,
751
- min_items=1,
845
+ description='The number indicates the factor with which the FRBC.OperationMode should be configured. The factor should be greater than or equal to 0 and less or equal to 1.',
752
846
  )
753
- running_costs: Optional[NumberRange] = Field(
754
- None,
755
- description="Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails, excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.",
847
+ execution_time: AwareDatetime = Field(
848
+ ...,
849
+ description='Indicates the moment the execution of the instruction shall start. When the specified execution time is in the past, execution must start as soon as possible.',
756
850
  )
757
- supply_range: NumberRange = Field(
851
+ abnormal_condition: bool = Field(
758
852
  ...,
759
- description="The supply rate this DDBC.OperationMode can deliver for the CEM to match the demand rate. The start of the NumberRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1.",
853
+ description='Indicates if this is an instruction during an abnormal condition.',
760
854
  )
761
855
 
762
856
 
763
- class DDBCTimerStatus(BaseModel):
764
- class Config:
765
- extra = Extra.forbid
766
-
767
- actuator_id: ID = Field(
768
- ..., description="The ID of the actuator the timer belongs to"
857
+ class FRBCUsageForecast(BaseModel):
858
+ model_config = ConfigDict(
859
+ extra='forbid',
769
860
  )
770
- finished_at: datetime = Field(
861
+ message_type: Literal['FRBC.UsageForecast'] = 'FRBC.UsageForecast'
862
+ message_id: ID
863
+ start_time: AwareDatetime = Field(
864
+ ..., description='Time at which the FRBC.UsageForecast starts.'
865
+ )
866
+ elements: List[FRBCUsageForecastElement] = Field(
771
867
  ...,
772
- description="Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.",
868
+ description='Further elements that model the profile. There shall be at least one element. Elements must be placed in chronological order.',
869
+ max_length=288,
870
+ min_length=1,
773
871
  )
774
- message_id: ID = Field(..., description="ID of this message")
775
- message_type: str = Field("DDBC.TimerStatus", const=True)
776
- timer_id: ID = Field(..., description="The ID of the timer this message refers to")
777
872
 
778
873
 
779
- class FRBCActuatorStatus(BaseModel):
780
- class Config:
781
- extra = Extra.forbid
874
+ class FRBCFillLevelTargetProfile(BaseModel):
875
+ model_config = ConfigDict(
876
+ extra='forbid',
877
+ )
878
+ message_type: Literal['FRBC.FillLevelTargetProfile'] = 'FRBC.FillLevelTargetProfile'
879
+ message_id: ID
880
+ start_time: AwareDatetime = Field(
881
+ ..., description='Time at which the FRBC.FillLevelTargetProfile starts.'
882
+ )
883
+ elements: List[FRBCFillLevelTargetProfileElement] = Field(
884
+ ...,
885
+ description='List of different fill levels that have to be targeted within a given duration. There shall be at least one element. Elements must be placed in chronological order.',
886
+ max_length=288,
887
+ min_length=1,
888
+ )
782
889
 
783
- active_operation_mode_id: ID = Field(
784
- ..., description="ID of the FRBC.OperationMode that is presently active."
890
+
891
+ class DDBCActuatorStatus(BaseModel):
892
+ model_config = ConfigDict(
893
+ extra='forbid',
785
894
  )
895
+ message_type: Literal['DDBC.ActuatorStatus'] = 'DDBC.ActuatorStatus'
896
+ message_id: ID
786
897
  actuator_id: ID = Field(
787
- ..., description="ID of the actuator this messages refers to"
898
+ ..., description='ID of the actuator this messages refers to'
899
+ )
900
+ active_operation_mode_id: ID = Field(
901
+ ...,
902
+ description='The operation mode that is presently active for this actuator.',
788
903
  )
789
- message_id: ID = Field(..., description="ID of this message")
790
- message_type: str = Field("FRBC.ActuatorStatus", const=True)
791
904
  operation_mode_factor: float = Field(
792
905
  ...,
793
- description="The number indicates the factor with which the FRBC.OperationMode is configured. The factor should be greater than or equal than 0 and less or equal to 1.",
906
+ description='The number indicates the factor with which the DDBC.OperationMode is configured. The factor should be greater than or equal to 0 and less or equal to 1.',
794
907
  )
795
908
  previous_operation_mode_id: Optional[ID] = Field(
796
909
  None,
797
- description="ID of the FRBC.OperationMode that was active before the present one. This value shall always be provided, unless the active FRBC.OperationMode is the first FRBC.OperationMode the Resource Manager is aware of.",
910
+ description='ID of the DDBC,OperationMode that was active before the present one. This value shall always be provided, unless the active DDBC.OperationMode is the first DDBC.OperationMode the Resource Manager is aware of.',
798
911
  )
799
- transition_timestamp: Optional[datetime] = Field(
912
+ transition_timestamp: Optional[AwareDatetime] = Field(
800
913
  None,
801
- description="Time at which the transition from the previous FRBC.OperationMode to the active FRBC.OperationMode was initiated. This value shall always be provided, unless the active FRBC.OperationMode is the first FRBC.OperationMode the Resource Manager is aware of.",
914
+ description='Time at which the transition from the previous DDBC.OperationMode to the active DDBC.OperationMode was initiated. This value shall always be provided, unless the active DDBC.OperationMode is the first DDBC.OperationMode the Resource Manager is aware of.',
802
915
  )
803
916
 
804
917
 
805
- class FRBCFillLevelTargetProfileElement(BaseModel):
806
- class Config:
807
- extra = Extra.forbid
808
-
809
- duration: Duration = Field(..., description="The duration of the element.")
810
- fill_level_range: NumberRange = Field(
811
- ...,
812
- description="The target range in which the fill_level must be for the time period during which the element is active. The start of the range must be smaller or equal to the end of the range. The CEM must take best-effort actions to proactively achieve this target.",
918
+ class DDBCInstruction(BaseModel):
919
+ model_config = ConfigDict(
920
+ extra='forbid',
813
921
  )
814
-
815
-
816
- class FRBCInstruction(BaseModel):
817
- class Config:
818
- extra = Extra.forbid
819
-
820
- abnormal_condition: bool = Field(
922
+ message_type: Literal['DDBC.Instruction'] = 'DDBC.Instruction'
923
+ message_id: ID
924
+ id: ID = Field(
821
925
  ...,
822
- description="Indicates if this is an instruction during an abnormal condition.",
926
+ description='Identifier of this DDBC.Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
823
927
  )
824
- actuator_id: ID = Field(
825
- ..., description="ID of the actuator this instruction belongs to."
826
- )
827
- execution_time: datetime = Field(
828
- ..., description="Time when instruction should be executed."
928
+ execution_time: AwareDatetime = Field(
929
+ ...,
930
+ description='Indicates the moment the execution of the instruction shall start. When the specified execution time is in the past, execution must start as soon as possible.',
829
931
  )
830
- id: ID = Field(
932
+ abnormal_condition: bool = Field(
831
933
  ...,
832
- description="ID of the instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
934
+ description='Indicates if this is an instruction during an abnormal condition',
833
935
  )
834
- message_id: ID = Field(..., description="ID of this message")
835
- message_type: str = Field("FRBC.Instruction", const=True)
836
- operation_mode: ID = Field(
837
- ..., description="ID of the FRBC.OperationMode that should be activated."
936
+ actuator_id: ID = Field(
937
+ ..., description='ID of the actuator this Instruction belongs to.'
838
938
  )
939
+ operation_mode_id: ID = Field(..., description='ID of the DDBC.OperationMode')
839
940
  operation_mode_factor: float = Field(
840
941
  ...,
841
- description="The number indicates the factor with which the FRBC.OperationMode should be configured. The factor should be greater than or equal to 0 and less or equal to 1.",
942
+ description='The number indicates the factor with which the OMBC.OperationMode should be configured. The factor should be greater than or equal to 0 and less or equal to 1.',
842
943
  )
843
944
 
844
945
 
845
- class FRBCLeakageBehaviourElement(BaseModel):
846
- class Config:
847
- extra = Extra.forbid
848
-
849
- fill_level_range: NumberRange = Field(
850
- ...,
851
- description="The fill level range for which this FRBC.LeakageBehaviourElement applies. The start of the range must be less than the end of the range.",
946
+ class DDBCAverageDemandRateForecast(BaseModel):
947
+ model_config = ConfigDict(
948
+ extra='forbid',
852
949
  )
853
- leakage_rate: float = Field(
950
+ message_type: Literal['DDBC.AverageDemandRateForecast'] = (
951
+ 'DDBC.AverageDemandRateForecast'
952
+ )
953
+ message_id: ID
954
+ start_time: AwareDatetime = Field(..., description='Start time of the profile.')
955
+ elements: List[DDBCAverageDemandRateForecastElement] = Field(
854
956
  ...,
855
- description="Indicates how fast the momentary fill level will decrease per second due to leakage within the given range of the fill level.",
957
+ description='Elements of the profile. Elements must be placed in chronological order.',
958
+ max_length=288,
959
+ min_length=1,
856
960
  )
857
961
 
858
962
 
859
- class FRBCOperationModeElement(BaseModel):
860
- class Config:
861
- extra = Extra.forbid
862
-
863
- fill_level_range: NumberRange = Field(
864
- ...,
865
- description="The range of the fill level for which this FRBC.OperationModeElement applies. The start of the NumberRange shall be smaller than the end of the NumberRange.",
963
+ class PowerValue(BaseModel):
964
+ model_config = ConfigDict(
965
+ extra='forbid',
866
966
  )
867
- fill_rate: NumberRange = Field(
868
- ...,
869
- description="Indicates the change in fill_level per second. The lower_boundary of the NumberRange is associated with an operation_mode_factor of 0, the upper_boundary is associated with an operation_mode_factor of 1. ",
967
+ commodity_quantity: CommodityQuantity = Field(
968
+ ..., description='The power quantity the value refers to'
870
969
  )
871
- power_ranges: List[PowerRange] = Field(
970
+ value: float = Field(
872
971
  ...,
873
- description="The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.",
874
- max_items=10,
875
- min_items=1,
876
- )
877
- running_costs: Optional[NumberRange] = Field(
878
- None,
879
- description="Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails, excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.",
972
+ description='Power value expressed in the unit associated with the CommodityQuantity',
880
973
  )
881
974
 
882
975
 
883
- class FRBCStorageDescription(BaseModel):
884
- class Config:
885
- extra = Extra.forbid
886
-
887
- diagnostic_label: Optional[str] = Field(
976
+ class PowerForecastValue(BaseModel):
977
+ model_config = ConfigDict(
978
+ extra='forbid',
979
+ )
980
+ value_upper_limit: Optional[float] = Field(
888
981
  None,
889
- description="Human readable name/description of the storage (e.g. hot water buffer or battery). This element is only intended for diagnostic purposes and not for HMI applications.",
982
+ description='The upper boundary of the range with 100 % certainty the power value is in it',
890
983
  )
891
- fill_level_label: Optional[str] = Field(
984
+ value_upper_95PPR: Optional[float] = Field(
892
985
  None,
893
- description="Human readable description of the (physical) units associated with the fill_level (e.g. degrees Celsius or percentage state of charge). This element is only intended for diagnostic purposes and not for HMI applications.",
986
+ description='The upper boundary of the range with 95 % certainty the power value is in it',
894
987
  )
895
- fill_level_range: NumberRange = Field(
896
- ...,
897
- description="The range in which the fill_level should remain. It is expected of the CEM to keep the fill_level within this range. When the fill_level is not within this range, the Resource Manager can ignore instructions from the CEM (except during abnormal conditions). ",
988
+ value_upper_68PPR: Optional[float] = Field(
989
+ None,
990
+ description='The upper boundary of the range with 68 % certainty the power value is in it',
898
991
  )
899
- provides_fill_level_target_profile: bool = Field(
900
- ...,
901
- description="Indicates whether the Storage could provide a target profile for the fill level through the FRBC.FillLevelTargetProfile.",
992
+ value_expected: float = Field(..., description='The expected power value.')
993
+ value_lower_68PPR: Optional[float] = Field(
994
+ None,
995
+ description='The lower boundary of the range with 68 % certainty the power value is in it',
902
996
  )
903
- provides_leakage_behaviour: bool = Field(
904
- ...,
905
- description="Indicates whether the Storage could provide details of power leakage behaviour through the FRBC.LeakageBehaviour.",
997
+ value_lower_95PPR: Optional[float] = Field(
998
+ None,
999
+ description='The lower boundary of the range with 95 % certainty the power value is in it',
906
1000
  )
907
- provides_usage_forecast: bool = Field(
908
- ...,
909
- description="Indicates whether the Storage could provide a UsageForecast through the FRBC.UsageForecast.",
1001
+ value_lower_limit: Optional[float] = Field(
1002
+ None,
1003
+ description='The lower boundary of the range with 100 % certainty the power value is in it',
1004
+ )
1005
+ commodity_quantity: CommodityQuantity = Field(
1006
+ ..., description='The power quantity the value refers to'
910
1007
  )
911
1008
 
912
1009
 
913
- class FRBCStorageStatus(BaseModel):
914
- class Config:
915
- extra = Extra.forbid
916
-
917
- message_id: ID = Field(..., description="ID of this message")
918
- message_type: str = Field("FRBC.StorageStatus", const=True)
919
- present_fill_level: float = Field(
920
- ..., description="Present fill level of the Storage"
1010
+ class PowerRange(BaseModel):
1011
+ model_config = ConfigDict(
1012
+ extra='forbid',
1013
+ )
1014
+ start_of_range: float = Field(
1015
+ ..., description='Power value that defines the start of the range.'
1016
+ )
1017
+ end_of_range: float = Field(
1018
+ ..., description='Power value that defines the end of the range.'
1019
+ )
1020
+ commodity_quantity: CommodityQuantity = Field(
1021
+ ..., description='The power quantity the values refer to'
921
1022
  )
922
1023
 
923
1024
 
924
- class FRBCTimerStatus(BaseModel):
925
- class Config:
926
- extra = Extra.forbid
1025
+ class Role(BaseModel):
1026
+ model_config = ConfigDict(
1027
+ extra='forbid',
1028
+ )
1029
+ role: RoleType = Field(
1030
+ ..., description='Role type of the Resource Manager for the given commodity'
1031
+ )
1032
+ commodity: Commodity = Field(..., description='Commodity the role refers to.')
927
1033
 
928
- actuator_id: ID = Field(
929
- ..., description="The ID of the actuator the timer belongs to"
1034
+
1035
+ class PowerForecastElement(BaseModel):
1036
+ model_config = ConfigDict(
1037
+ extra='forbid',
930
1038
  )
931
- finished_at: datetime = Field(
1039
+ duration: Duration = Field(..., description='Duration of the PowerForecastElement')
1040
+ power_values: List[PowerForecastValue] = Field(
932
1041
  ...,
933
- description="Indicates when the Timer will be finished. If the DateTimeStamp is in the future, the timer is not yet finished. If the DateTimeStamp is in the past, the timer is finished. If the timer was never started, the value can be an arbitrary DateTimeStamp in the past.",
1042
+ description='The values of power that are expected for the given period of time. There shall be at least one PowerForecastValue, and at most one PowerForecastValue per CommodityQuantity.',
1043
+ max_length=10,
1044
+ min_length=1,
934
1045
  )
935
- message_id: ID = Field(..., description="ID of this message")
936
- message_type: str = Field("FRBC.TimerStatus", const=True)
937
- timer_id: ID = Field(..., description="The ID of the timer this message refers to")
938
-
939
1046
 
940
- class FRBCUsageForecast(BaseModel):
941
- class Config:
942
- extra = Extra.forbid
943
1047
 
944
- elements: List[FRBCUsageForecastElement] = Field(
1048
+ class PEBCAllowedLimitRange(BaseModel):
1049
+ model_config = ConfigDict(
1050
+ extra='forbid',
1051
+ )
1052
+ commodity_quantity: CommodityQuantity = Field(
1053
+ ..., description='Type of power quantity this PEBC.AllowedLimitRange applies to'
1054
+ )
1055
+ limit_type: PEBCPowerEnvelopeLimitType = Field(
945
1056
  ...,
946
- description="Further elements that model the profile. There shall be at least one element. Elements must be placed in chronological order.",
947
- max_items=288,
948
- min_items=1,
1057
+ description='Indicates if this ranges applies to the upper limit or the lower limit',
949
1058
  )
950
- message_id: ID = Field(..., description="ID of this message")
951
- message_type: str = Field("FRBC.UsageForecast", const=True)
952
- start_time: datetime = Field(
953
- ..., description="Time at which the FRBC.UsageForecast starts."
1059
+ range_boundary: NumberRange = Field(
1060
+ ...,
1061
+ description='Boundaries of the power range of this PEBC.AllowedLimitRange. The CEM is allowed to choose values within this range for the power envelope for the limit as described in limit_type. The start of the range shall be smaller or equal than the end of the range. ',
1062
+ )
1063
+ abnormal_condition_only: bool = Field(
1064
+ ...,
1065
+ description='Indicates if this PEBC.AllowedLimitRange may only be used during an abnormal condition',
954
1066
  )
955
1067
 
956
1068
 
957
- class Handshake(BaseModel):
958
- class Config:
959
- extra = Extra.forbid
960
-
961
- message_id: ID = Field(..., description="ID of this message")
962
- message_type: str = Field("Handshake", const=True)
963
- role: EnergyManagementRole = Field(
964
- ..., description="The role of the sender of this message"
1069
+ class PEBCPowerEnvelope(BaseModel):
1070
+ model_config = ConfigDict(
1071
+ extra='forbid',
965
1072
  )
966
- supported_protocol_versions: Optional[List[str]] = Field(
967
- None,
968
- description="Protocol versions supported by the sender of this message. This field is mandatory for the RM, but optional for the CEM.",
969
- min_items=1,
1073
+ id: ID = Field(
1074
+ ...,
1075
+ description='Identifier of this PEBC.PowerEnvelope. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
970
1076
  )
971
-
972
-
973
- class HandshakeResponse(BaseModel):
974
- class Config:
975
- extra = Extra.forbid
976
-
977
- message_id: ID = Field(..., description="ID of this message")
978
- message_type: str = Field("HandshakeResponse", const=True)
979
- selected_protocol_version: str = Field(
980
- ..., description="The protocol version the CEM selected for this session"
1077
+ commodity_quantity: CommodityQuantity = Field(
1078
+ ..., description='Type of power quantity this PEBC.PowerEnvelope applies to'
1079
+ )
1080
+ power_envelope_elements: List[PEBCPowerEnvelopeElement] = Field(
1081
+ ...,
1082
+ description='The elements of this PEBC.PowerEnvelope. Shall contain at least one element. Elements must be placed in chronological order.',
1083
+ max_length=288,
1084
+ min_length=1,
981
1085
  )
982
1086
 
983
1087
 
984
- class OMBCOperationMode(BaseModel):
985
- class Config:
986
- extra = Extra.forbid
987
-
988
- abnormal_condition_only: bool = Field(
1088
+ class PPBCPowerSequenceElement(BaseModel):
1089
+ model_config = ConfigDict(
1090
+ extra='forbid',
1091
+ )
1092
+ duration: Duration = Field(
1093
+ ..., description='Duration of the PPBC.PowerSequenceElement.'
1094
+ )
1095
+ power_values: List[PowerForecastValue] = Field(
989
1096
  ...,
990
- description="Indicates if this OMBC.OperationMode may only be used during an abnormal condition.",
1097
+ description='The value of power and deviations for the given duration. The array should contain at least one PowerForecastValue and at most one PowerForecastValue per CommodityQuantity.',
1098
+ max_length=10,
1099
+ min_length=1,
991
1100
  )
992
- diagnostic_label: Optional[str] = Field(
993
- None,
994
- description="Human readable name/description of the OMBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.",
1101
+
1102
+
1103
+ class PPBCPowerSequenceContainerStatus(BaseModel):
1104
+ model_config = ConfigDict(
1105
+ extra='forbid',
995
1106
  )
996
- id: ID = Field(
1107
+ power_profile_id: ID = Field(
997
1108
  ...,
998
- description="ID of the OBMC.OperationMode. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1109
+ description='ID of the PPBC.PowerProfileDefinition of which the data element ‘sequence_container_id’ refers to. ',
999
1110
  )
1000
- power_ranges: List[PowerRange] = Field(
1111
+ sequence_container_id: ID = Field(
1001
1112
  ...,
1002
- description="The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.",
1003
- max_items=10,
1004
- min_items=1,
1113
+ description='ID of the PPBC.PowerSequenceContainer this PPBC.PowerSequenceContainerStatus provides information about.',
1005
1114
  )
1006
- running_costs: Optional[NumberRange] = Field(
1115
+ selected_sequence_id: Optional[ID] = Field(
1007
1116
  None,
1008
- description="Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails , excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.",
1117
+ description='ID of selected PPBC.PowerSequence. When no ID is given, no sequence was selected yet.',
1118
+ )
1119
+ progress: Optional[Duration] = Field(
1120
+ None,
1121
+ description='Time that has passed since the selected sequence has started. A value must be provided, unless no sequence has been selected or the selected sequence hasn’t started yet.',
1122
+ )
1123
+ status: PPBCPowerSequenceStatus = Field(
1124
+ ..., description='Status of the selected PPBC.PowerSequence'
1009
1125
  )
1010
1126
 
1011
1127
 
1012
- class OMBCSystemDescription(BaseModel):
1013
- class Config:
1014
- extra = Extra.forbid
1015
-
1016
- message_id: ID = Field(..., description="ID of this message")
1017
- message_type: str = Field("OMBC.SystemDescription", const=True)
1018
- operation_modes: List[OMBCOperationMode] = Field(
1019
- ...,
1020
- description="OMBC.OperationModes available for the CEM in order to coordinate the device behaviour.",
1021
- max_items=100,
1022
- min_items=1,
1128
+ class OMBCOperationMode(BaseModel):
1129
+ model_config = ConfigDict(
1130
+ extra='forbid',
1023
1131
  )
1024
- timers: List[Timer] = Field(
1132
+ id: ID = Field(
1025
1133
  ...,
1026
- description="Timers that control when certain transitions can be made.",
1027
- max_items=1000,
1028
- min_items=0,
1134
+ description='ID of the OBMC.OperationMode. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1029
1135
  )
1030
- transitions: List[Transition] = Field(
1136
+ diagnostic_label: Optional[str] = Field(
1137
+ None,
1138
+ description='Human readable name/description of the OMBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.',
1139
+ )
1140
+ power_ranges: List[PowerRange] = Field(
1031
1141
  ...,
1032
- description="Possible transitions to switch from one OMBC.OperationMode to another.",
1033
- max_items=1000,
1034
- min_items=0,
1142
+ description='The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.',
1143
+ max_length=10,
1144
+ min_length=1,
1145
+ )
1146
+ running_costs: Optional[NumberRange] = Field(
1147
+ None,
1148
+ description='Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails , excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.',
1035
1149
  )
1036
- valid_from: datetime = Field(
1150
+ abnormal_condition_only: bool = Field(
1037
1151
  ...,
1038
- description="Moment this OMBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.",
1152
+ description='Indicates if this OMBC.OperationMode may only be used during an abnormal condition.',
1039
1153
  )
1040
1154
 
1041
1155
 
1042
- class PEBCAllowedLimitRange(BaseModel):
1043
- class Config:
1044
- extra = Extra.forbid
1045
-
1046
- abnormal_condition_only: bool = Field(
1047
- ...,
1048
- description="Indicates if this PEBC.AllowedLimitRange may only be used during an abnormal condition",
1156
+ class FRBCOperationModeElement(BaseModel):
1157
+ model_config = ConfigDict(
1158
+ extra='forbid',
1049
1159
  )
1050
- commodity_quantity: CommodityQuantity = Field(
1051
- ..., description="Type of power quantity this PEBC.AllowedLimitRange applies to"
1160
+ fill_level_range: NumberRange = Field(
1161
+ ...,
1162
+ description='The range of the fill level for which this FRBC.OperationModeElement applies. The start of the NumberRange shall be smaller than the end of the NumberRange.',
1052
1163
  )
1053
- limit_type: PEBCPowerEnvelopeLimitType = Field(
1164
+ fill_rate: NumberRange = Field(
1054
1165
  ...,
1055
- description="Indicates if this ranges applies to the upper limit or the lower limit",
1166
+ description='Indicates the change in fill_level per second. The lower_boundary of the NumberRange is associated with an operation_mode_factor of 0, the upper_boundary is associated with an operation_mode_factor of 1. ',
1056
1167
  )
1057
- range_boundary: NumberRange = Field(
1168
+ power_ranges: List[PowerRange] = Field(
1058
1169
  ...,
1059
- description="Boundaries of the power range of this PEBC.AllowedLimitRange. The CEM is allowed to choose values within this range for the power envelope for the limit as described in limit_type. The start of the range shall be smaller or equal than the end of the range. ",
1170
+ description='The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.',
1171
+ max_length=10,
1172
+ min_length=1,
1173
+ )
1174
+ running_costs: Optional[NumberRange] = Field(
1175
+ None,
1176
+ description='Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails, excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.',
1060
1177
  )
1061
1178
 
1062
1179
 
1063
- class PEBCPowerConstraints(BaseModel):
1064
- class Config:
1065
- extra = Extra.forbid
1066
-
1067
- allowed_limit_ranges: List[PEBCAllowedLimitRange] = Field(
1180
+ class DDBCOperationMode(BaseModel):
1181
+ model_config = ConfigDict(
1182
+ extra='forbid',
1183
+ )
1184
+ Id: ID = Field(
1068
1185
  ...,
1069
- description="The actual constraints. There shall be at least one PEBC.AllowedLimitRange for the UPPER_LIMIT and at least one AllowedLimitRange for the LOWER_LIMIT. It is allowed to have multiple PEBC.AllowedLimitRange objects with identical CommodityQuantities and LimitTypes.",
1070
- max_items=100,
1071
- min_items=2,
1186
+ description='ID of this operation mode. Must be unique in the scope of the DDBC.ActuatorDescription in which it is used.',
1072
1187
  )
1073
- consequence_type: PEBCPowerEnvelopeConsequenceType = Field(
1074
- ..., description="Type of consequence of limiting power"
1188
+ diagnostic_label: Optional[str] = Field(
1189
+ None,
1190
+ description='Human readable name/description of the DDBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.',
1075
1191
  )
1076
- id: ID = Field(
1192
+ power_ranges: List[PowerRange] = Field(
1077
1193
  ...,
1078
- description="Identifier of this PEBC.PowerConstraints. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1194
+ description='The power produced or consumed by this operation mode. The start of each PowerRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1. In the array there must be at least one PowerRange, and at most one PowerRange per CommodityQuantity.',
1195
+ max_length=10,
1196
+ min_length=1,
1079
1197
  )
1080
- message_id: ID = Field(..., description="ID of this message")
1081
- message_type: str = Field("PEBC.PowerConstraints", const=True)
1082
- valid_from: datetime = Field(
1083
- ..., description="Moment this PEBC.PowerConstraints start to be valid"
1198
+ supply_range: NumberRange = Field(
1199
+ ...,
1200
+ description='The supply rate this DDBC.OperationMode can deliver for the CEM to match the demand rate. The start of the NumberRange is associated with an operation_mode_factor of 0, the end is associated with an operation_mode_factor of 1.',
1084
1201
  )
1085
- valid_until: Optional[datetime] = Field(
1202
+ running_costs: Optional[NumberRange] = Field(
1086
1203
  None,
1087
- description="Moment until this PEBC.PowerConstraints is valid. If valid_until is not present, there is no determined end time of this PEBC.PowerConstraints.",
1204
+ description='Additional costs per second (e.g. wear, services) associated with this operation mode in the currency defined by the ResourceManagerDetails, excluding the commodity cost. The range is expressing uncertainty and is not linked to the operation_mode_factor.',
1205
+ )
1206
+ abnormal_condition_only: bool = Field(
1207
+ ...,
1208
+ description='Indicates if this DDBC.OperationMode may only be used during an abnormal condition.',
1088
1209
  )
1089
1210
 
1090
1211
 
1091
- class PEBCPowerEnvelope(BaseModel):
1092
- class Config:
1093
- extra = Extra.forbid
1094
-
1095
- commodity_quantity: CommodityQuantity = Field(
1096
- ..., description="Type of power quantity this PEBC.PowerEnvelope applies to"
1097
- )
1098
- id: ID = Field(
1099
- ...,
1100
- description="Identifier of this PEBC.PowerEnvelope. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1212
+ class ResourceManagerDetails(BaseModel):
1213
+ model_config = ConfigDict(
1214
+ extra='forbid',
1101
1215
  )
1102
- power_envelope_elements: List[PEBCPowerEnvelopeElement] = Field(
1216
+ message_type: Literal['ResourceManagerDetails'] = 'ResourceManagerDetails'
1217
+ message_id: ID
1218
+ resource_id: ID = Field(
1103
1219
  ...,
1104
- description="The elements of this PEBC.PowerEnvelope. Shall contain at least one element. Elements must be placed in chronological order.",
1105
- max_items=288,
1106
- min_items=1,
1220
+ description='Identifier of the Resource Manager. Must be unique within the scope of the CEM.',
1107
1221
  )
1108
-
1109
-
1110
- class PPBCPowerSequenceContainerStatus(BaseModel):
1111
- class Config:
1112
- extra = Extra.forbid
1113
-
1114
- power_profile_id: ID = Field(
1222
+ name: Optional[str] = Field(None, description='Human readable name given by user')
1223
+ roles: List[Role] = Field(
1115
1224
  ...,
1116
- description="ID of the PPBC.PowerProfileDefinition of which the data element ‘sequence_container_id’ refers to. ",
1225
+ description='Each Resource Manager provides one or more energy Roles',
1226
+ max_length=3,
1227
+ min_length=1,
1117
1228
  )
1118
- progress: Optional[Duration] = Field(
1229
+ manufacturer: Optional[str] = Field(None, description='Name of Manufacturer')
1230
+ model: Optional[str] = Field(
1119
1231
  None,
1120
- description="Time that has passed since the selected sequence has started. A value must be provided, unless no sequence has been selected or the selected sequence hasn’t started yet.",
1232
+ description='Name of the model of the device (provided by the manufacturer)',
1121
1233
  )
1122
- selected_sequence_id: Optional[ID] = Field(
1234
+ serial_number: Optional[str] = Field(
1235
+ None, description='Serial number of the device (provided by the manufacturer)'
1236
+ )
1237
+ firmware_version: Optional[str] = Field(
1123
1238
  None,
1124
- description="ID of selected PPBC.PowerSequence. When no ID is given, no sequence was selected yet.",
1239
+ description='Version identifier of the firmware used in the device (provided by the manufacturer)',
1125
1240
  )
1126
- sequence_container_id: ID = Field(
1241
+ instruction_processing_delay: Duration = Field(
1127
1242
  ...,
1128
- description="ID of the PPBC.PowerSequenceContainer this PPBC.PowerSequenceContainerStatus provides information about.",
1243
+ description='The average time the combination of Resource Manager and HBES/BACS/SASS or (Smart) device needs to process and execute an instruction',
1129
1244
  )
1130
- status: PPBCPowerSequenceStatus = Field(
1131
- ..., description="Status of the selected PPBC.PowerSequence"
1245
+ available_control_types: List[ControlType] = Field(
1246
+ ...,
1247
+ description='The control types supported by this Resource Manager.',
1248
+ max_length=5,
1249
+ min_length=1,
1132
1250
  )
1133
-
1134
-
1135
- class PPBCPowerSequenceElement(BaseModel):
1136
- class Config:
1137
- extra = Extra.forbid
1138
-
1139
- duration: Duration = Field(
1140
- ..., description="Duration of the PPBC.PowerSequenceElement."
1251
+ currency: Optional[Currency] = Field(
1252
+ None,
1253
+ description='Currency to be used for all information regarding costs. Mandatory if cost information is published.',
1141
1254
  )
1142
- power_values: List[PowerForecastValue] = Field(
1255
+ provides_forecast: bool = Field(
1143
1256
  ...,
1144
- description="The value of power and deviations for the given duration. The array should contain at least one PowerForecastValue and at most one PowerForecastValue per CommodityQuantity.",
1145
- max_items=10,
1146
- min_items=1,
1257
+ description='Indicates whether the ResourceManager is able to provide PowerForecasts',
1147
1258
  )
1148
-
1149
-
1150
- class PowerForecastElement(BaseModel):
1151
- class Config:
1152
- extra = Extra.forbid
1153
-
1154
- duration: Duration = Field(..., description="Duration of the PowerForecastElement")
1155
- power_values: List[PowerForecastValue] = Field(
1259
+ provides_power_measurement_types: List[CommodityQuantity] = Field(
1156
1260
  ...,
1157
- description="The values of power that are expected for the given period of time. There shall be at least one PowerForecastValue, and at most one PowerForecastValue per CommodityQuantity.",
1158
- max_items=10,
1159
- min_items=1,
1261
+ description='Array of all CommodityQuantities that this Resource Manager can provide measurements for. ',
1262
+ max_length=10,
1263
+ min_length=1,
1160
1264
  )
1161
1265
 
1162
1266
 
1163
1267
  class PowerMeasurement(BaseModel):
1164
- class Config:
1165
- extra = Extra.forbid
1166
-
1167
- measurement_timestamp: datetime = Field(
1168
- ..., description="Timestamp when PowerValues were measured."
1268
+ model_config = ConfigDict(
1269
+ extra='forbid',
1270
+ )
1271
+ message_type: Literal['PowerMeasurement'] = 'PowerMeasurement'
1272
+ message_id: ID
1273
+ measurement_timestamp: AwareDatetime = Field(
1274
+ ..., description='Timestamp when PowerValues were measured.'
1169
1275
  )
1170
- message_id: ID = Field(..., description="ID of this message")
1171
- message_type: str = Field("PowerMeasurement", const=True)
1172
1276
  values: List[PowerValue] = Field(
1173
1277
  ...,
1174
- description="Array of measured PowerValues. Must contain at least one item and at most one item per ‘commodity_quantity’ (defined inside the PowerValue).",
1175
- max_items=10,
1176
- min_items=1,
1278
+ description='Array of measured PowerValues. Must contain at least one item and at most one item per ‘commodity_quantity’ (defined inside the PowerValue).',
1279
+ max_length=10,
1280
+ min_length=1,
1177
1281
  )
1178
1282
 
1179
1283
 
1180
- class ReceptionStatus(BaseModel):
1181
- class Config:
1182
- extra = Extra.forbid
1183
-
1184
- diagnostic_label: Optional[str] = Field(
1185
- None,
1186
- description="Diagnostic label that can be used to provide additional information for debugging. However, not for HMI purposes.",
1284
+ class PowerForecast(BaseModel):
1285
+ model_config = ConfigDict(
1286
+ extra='forbid',
1187
1287
  )
1188
- message_type: str = Field("ReceptionStatus", const=True)
1189
- status: ReceptionStatusValues = Field(
1190
- ..., description="Enumeration of status values"
1288
+ message_type: Literal['PowerForecast'] = 'PowerForecast'
1289
+ message_id: ID
1290
+ start_time: AwareDatetime = Field(
1291
+ ..., description='Start time of time period that is covered by the profile.'
1191
1292
  )
1192
- subject_message_id: ID = Field(
1193
- ..., description="The message this ReceptionStatus refers to"
1293
+ elements: List[PowerForecastElement] = Field(
1294
+ ...,
1295
+ description='Elements of which this forecast consists. Contains at least one element. Elements must be placed in chronological order.',
1296
+ max_length=288,
1297
+ min_length=1,
1194
1298
  )
1195
1299
 
1196
1300
 
1197
- class Role(BaseModel):
1198
- class Config:
1199
- extra = Extra.forbid
1200
-
1201
- commodity: Commodity = Field(..., description="Commodity the role refers to.")
1202
- role: RoleType = Field(
1203
- ..., description="Role type of the Resource Manager for the given commodity"
1301
+ class PEBCPowerConstraints(BaseModel):
1302
+ model_config = ConfigDict(
1303
+ extra='forbid',
1204
1304
  )
1205
-
1206
-
1207
- class SessionRequest(BaseModel):
1208
- class Config:
1209
- extra = Extra.forbid
1210
-
1211
- diagnostic_label: Optional[str] = Field(
1305
+ message_type: Literal['PEBC.PowerConstraints'] = 'PEBC.PowerConstraints'
1306
+ message_id: ID
1307
+ id: ID = Field(
1308
+ ...,
1309
+ description='Identifier of this PEBC.PowerConstraints. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1310
+ )
1311
+ valid_from: AwareDatetime = Field(
1312
+ ..., description='Moment this PEBC.PowerConstraints start to be valid'
1313
+ )
1314
+ valid_until: Optional[AwareDatetime] = Field(
1212
1315
  None,
1213
- description="Optional field for a human readible descirption for debugging purposes",
1316
+ description='Moment until this PEBC.PowerConstraints is valid. If valid_until is not present, there is no determined end time of this PEBC.PowerConstraints.',
1317
+ )
1318
+ consequence_type: PEBCPowerEnvelopeConsequenceType = Field(
1319
+ ..., description='Type of consequence of limiting power'
1320
+ )
1321
+ allowed_limit_ranges: List[PEBCAllowedLimitRange] = Field(
1322
+ ...,
1323
+ description='The actual constraints. There shall be at least one PEBC.AllowedLimitRange for the UPPER_LIMIT and at least one AllowedLimitRange for the LOWER_LIMIT. It is allowed to have multiple PEBC.AllowedLimitRange objects with identical CommodityQuantities and LimitTypes.',
1324
+ max_length=100,
1325
+ min_length=2,
1214
1326
  )
1215
- message_id: ID = Field(..., description="ID of this message")
1216
- message_type: str = Field("SessionRequest", const=True)
1217
- request: SessionRequestType = Field(..., description="The type of request")
1218
-
1219
1327
 
1220
- class DDBCActuatorDescription(BaseModel):
1221
- class Config:
1222
- extra = Extra.forbid
1223
1328
 
1224
- diagnostic_label: Optional[str] = Field(
1225
- None,
1226
- description="Human readable name/description of the actuator. This element is only intended for diagnostic purposes and not for HMI applications.",
1329
+ class PEBCInstruction(BaseModel):
1330
+ model_config = ConfigDict(
1331
+ extra='forbid',
1227
1332
  )
1333
+ message_type: Literal['PEBC.Instruction'] = 'PEBC.Instruction'
1334
+ message_id: ID
1228
1335
  id: ID = Field(
1229
1336
  ...,
1230
- description="ID of this DDBC.ActuatorDescription. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1337
+ description='Identifier of this PEBC.Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1231
1338
  )
1232
- operation_modes: List[DDBCOperationMode] = Field(
1339
+ execution_time: AwareDatetime = Field(
1233
1340
  ...,
1234
- description="List of all Operation Modes that are available for this actuator. There shall be at least one DDBC.OperationMode.",
1235
- max_items=100,
1236
- min_items=1,
1341
+ description='Indicates the moment the execution of the instruction shall start. When the specified execution time is in the past, execution must start as soon as possible.',
1237
1342
  )
1238
- supported_commodites: List[Commodity] = Field(
1343
+ abnormal_condition: bool = Field(
1239
1344
  ...,
1240
- description="Commodities supported by the operation modes of this actuator. There shall be at least one commodity",
1241
- max_items=4,
1242
- min_items=1,
1345
+ description='Indicates if this is an instruction during an abnormal condition.',
1243
1346
  )
1244
- timers: List[Timer] = Field(
1347
+ power_constraints_id: ID = Field(
1245
1348
  ...,
1246
- description="List of Timers associated with Transitions for this Actuator. Can be empty.",
1247
- max_items=1000,
1248
- min_items=0,
1349
+ description='Identifier of the PEBC.PowerConstraints this PEBC.Instruction was based on.',
1249
1350
  )
1250
- transitions: List[Transition] = Field(
1351
+ power_envelopes: List[PEBCPowerEnvelope] = Field(
1251
1352
  ...,
1252
- description="List of Transitions between Operation Modes. Shall contain at least one Transition.",
1253
- max_items=1000,
1254
- min_items=0,
1353
+ description='The PEBC.PowerEnvelope(s) that should be followed by the Resource Manager. There shall be at least one PEBC.PowerEnvelope, but at most one PEBC.PowerEnvelope for each CommodityQuantity.',
1354
+ max_length=10,
1355
+ min_length=1,
1255
1356
  )
1256
1357
 
1257
1358
 
1258
- class DDBCAverageDemandRateForecast(BaseModel):
1259
- class Config:
1260
- extra = Extra.forbid
1261
-
1262
- elements: List[DDBCAverageDemandRateForecastElement] = Field(
1359
+ class PPBCPowerProfileStatus(BaseModel):
1360
+ model_config = ConfigDict(
1361
+ extra='forbid',
1362
+ )
1363
+ message_type: Literal['PPBC.PowerProfileStatus'] = 'PPBC.PowerProfileStatus'
1364
+ message_id: ID
1365
+ sequence_container_status: List[PPBCPowerSequenceContainerStatus] = Field(
1263
1366
  ...,
1264
- description="Elements of the profile. Elements must be placed in chronological order.",
1265
- max_items=288,
1266
- min_items=1,
1367
+ description='Array with status information for all PPBC.PowerSequenceContainers in the PPBC.PowerProfileDefinition.',
1368
+ max_length=1000,
1369
+ min_length=1,
1267
1370
  )
1268
- message_id: ID = Field(..., description="ID of this message")
1269
- message_type: str = Field("DDBC.AverageDemandRateForecast", const=True)
1270
- start_time: datetime = Field(..., description="Start time of the profile.")
1271
-
1272
1371
 
1273
- class DDBCSystemDescription(BaseModel):
1274
- class Config:
1275
- extra = Extra.forbid
1276
1372
 
1277
- actuators: List[DDBCActuatorDescription] = Field(
1373
+ class OMBCSystemDescription(BaseModel):
1374
+ model_config = ConfigDict(
1375
+ extra='forbid',
1376
+ )
1377
+ message_type: Literal['OMBC.SystemDescription'] = 'OMBC.SystemDescription'
1378
+ message_id: ID
1379
+ valid_from: AwareDatetime = Field(
1278
1380
  ...,
1279
- description="List of all available actuators in the system. Must contain at least one DDBC.ActuatorAggregated.",
1280
- max_items=10,
1281
- min_items=1,
1381
+ description='Moment this OMBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.',
1282
1382
  )
1283
- message_id: ID = Field(..., description="ID of this message")
1284
- message_type: str = Field("DDBC.SystemDescription", const=True)
1285
- present_demand_rate: NumberRange = Field(
1286
- ..., description="Present demand rate that needs to be satisfied by the system"
1383
+ operation_modes: List[OMBCOperationMode] = Field(
1384
+ ...,
1385
+ description='OMBC.OperationModes available for the CEM in order to coordinate the device behaviour.',
1386
+ max_length=100,
1387
+ min_length=1,
1287
1388
  )
1288
- provides_average_demand_rate_forecast: bool = Field(
1389
+ transitions: List[Transition] = Field(
1289
1390
  ...,
1290
- description="Indicates whether the Resource Manager could provide a demand rate forecast through the DDBC.AverageDemandRateForecast.",
1391
+ description='Possible transitions to switch from one OMBC.OperationMode to another.',
1392
+ max_length=1000,
1393
+ min_length=0,
1291
1394
  )
1292
- valid_from: datetime = Field(
1395
+ timers: List[Timer] = Field(
1293
1396
  ...,
1294
- description="Moment this DDBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.",
1397
+ description='Timers that control when certain transitions can be made.',
1398
+ max_length=1000,
1399
+ min_length=0,
1295
1400
  )
1296
1401
 
1297
1402
 
1298
- class FRBCFillLevelTargetProfile(BaseModel):
1299
- class Config:
1300
- extra = Extra.forbid
1301
-
1302
- elements: List[FRBCFillLevelTargetProfileElement] = Field(
1403
+ class PPBCPowerSequence(BaseModel):
1404
+ model_config = ConfigDict(
1405
+ extra='forbid',
1406
+ )
1407
+ id: ID = Field(
1303
1408
  ...,
1304
- description="List of different fill levels that have to be targeted within a given duration. There shall be at least one element. Elements must be placed in chronological order.",
1305
- max_items=288,
1306
- min_items=1,
1409
+ description='ID of the PPBC.PowerSequence. Must be unique in the scope of the PPBC.PowerSequnceContainer in which it is used.',
1307
1410
  )
1308
- message_id: ID = Field(..., description="ID of this message")
1309
- message_type: str = Field("FRBC.FillLevelTargetProfile", const=True)
1310
- start_time: datetime = Field(
1311
- ..., description="Time at which the FRBC.FillLevelTargetProfile starts."
1411
+ elements: List[PPBCPowerSequenceElement] = Field(
1412
+ ...,
1413
+ description='List of PPBC.PowerSequenceElements. Shall contain at least one element. Elements must be placed in chronological order.',
1414
+ max_length=288,
1415
+ min_length=1,
1312
1416
  )
1313
-
1314
-
1315
- class FRBCLeakageBehaviour(BaseModel):
1316
- class Config:
1317
- extra = Extra.forbid
1318
-
1319
- elements: List[FRBCLeakageBehaviourElement] = Field(
1417
+ is_interruptible: bool = Field(
1320
1418
  ...,
1321
- description="List of elements that model the leakage behaviour of the buffer. The fill_level_ranges of the elements must be contiguous.",
1322
- max_items=288,
1323
- min_items=1,
1419
+ description='Indicates whether the option of pausing a sequence is available.',
1324
1420
  )
1325
- message_id: ID = Field(..., description="ID of this message")
1326
- message_type: str = Field("FRBC.LeakageBehaviour", const=True)
1327
- valid_from: datetime = Field(
1421
+ max_pause_before: Optional[Duration] = Field(
1422
+ None,
1423
+ description='The maximum duration for which a device can be paused between the end of the previous running sequence and the start of this one',
1424
+ )
1425
+ abnormal_condition_only: bool = Field(
1328
1426
  ...,
1329
- description="Moment this FRBC.LeakageBehaviour starts to be valid. If the FRBC.LeakageBehaviour is immediately valid, the DateTimeStamp should be now or in the past.",
1427
+ description='Indicates if this PPBC.PowerSequence may only be used during an abnormal condition',
1330
1428
  )
1331
1429
 
1332
1430
 
1333
1431
  class FRBCOperationMode(BaseModel):
1334
- class Config:
1335
- extra = Extra.forbid
1336
-
1337
- abnormal_condition_only: bool = Field(
1432
+ model_config = ConfigDict(
1433
+ extra='forbid',
1434
+ )
1435
+ id: ID = Field(
1338
1436
  ...,
1339
- description="Indicates if this FRBC.OperationMode may only be used during an abnormal condition",
1437
+ description='ID of the FRBC.OperationMode. Must be unique in the scope of the FRBC.ActuatorDescription in which it is used.',
1340
1438
  )
1341
1439
  diagnostic_label: Optional[str] = Field(
1342
1440
  None,
1343
- description="Human readable name/description of the FRBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.",
1441
+ description='Human readable name/description of the FRBC.OperationMode. This element is only intended for diagnostic purposes and not for HMI applications.',
1344
1442
  )
1345
1443
  elements: List[FRBCOperationModeElement] = Field(
1346
1444
  ...,
1347
- description="List of FRBC.OperationModeElements, which describe the properties of this FRBC.OperationMode depending on the fill_level. The fill_level_ranges of the items in the Array must be contiguous.",
1348
- max_items=100,
1349
- min_items=1,
1445
+ description='List of FRBC.OperationModeElements, which describe the properties of this FRBC.OperationMode depending on the fill_level. The fill_level_ranges of the items in the Array must be contiguous.',
1446
+ max_length=100,
1447
+ min_length=1,
1350
1448
  )
1351
- id: ID = Field(
1449
+ abnormal_condition_only: bool = Field(
1352
1450
  ...,
1353
- description="ID of the FRBC.OperationMode. Must be unique in the scope of the FRBC.ActuatorDescription in which it is used.",
1451
+ description='Indicates if this FRBC.OperationMode may only be used during an abnormal condition',
1354
1452
  )
1355
1453
 
1356
1454
 
1357
- class PEBCInstruction(BaseModel):
1358
- class Config:
1359
- extra = Extra.forbid
1360
-
1361
- abnormal_condition: bool = Field(
1362
- ...,
1363
- description="Indicates if this is an instruction during an abnormal condition.",
1455
+ class DDBCActuatorDescription(BaseModel):
1456
+ model_config = ConfigDict(
1457
+ extra='forbid',
1364
1458
  )
1365
- execution_time: datetime = Field(
1459
+ id: ID = Field(
1366
1460
  ...,
1367
- description="Indicates the moment the execution of the instruction shall start.",
1461
+ description='ID of this DDBC.ActuatorDescription. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1368
1462
  )
1369
- id: ID = Field(
1463
+ diagnostic_label: Optional[str] = Field(
1464
+ None,
1465
+ description='Human readable name/description of the actuator. This element is only intended for diagnostic purposes and not for HMI applications.',
1466
+ )
1467
+ supported_commodites: List[Commodity] = Field(
1370
1468
  ...,
1371
- description="Identifier of this PEBC.Instruction. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1469
+ description='Commodities supported by the operation modes of this actuator. There shall be at least one commodity',
1470
+ max_length=4,
1471
+ min_length=1,
1372
1472
  )
1373
- message_id: ID = Field(..., description="ID of this message")
1374
- message_type: str = Field("PEBC.Instruction", const=True)
1375
- power_constraints_id: ID = Field(
1473
+ operation_modes: List[DDBCOperationMode] = Field(
1376
1474
  ...,
1377
- description="Identifier of the PEBC.PowerConstraints this PEBC.Instruction was based on.",
1475
+ description='List of all Operation Modes that are available for this actuator. There shall be at least one DDBC.OperationMode.',
1476
+ max_length=100,
1477
+ min_length=1,
1378
1478
  )
1379
- power_envelopes: List[PEBCPowerEnvelope] = Field(
1479
+ transitions: List[Transition] = Field(
1380
1480
  ...,
1381
- description="The PEBC.PowerEnvelope(s) that should be followed by the Resource Manager. There shall be at least one PEBC.PowerEnvelope, but at most one PEBC.PowerEnvelope for each CommodityQuantity.",
1382
- max_items=10,
1383
- min_items=1,
1481
+ description='List of Transitions between Operation Modes. Shall contain at least one Transition.',
1482
+ max_length=1000,
1483
+ min_length=0,
1384
1484
  )
1385
-
1386
-
1387
- class PPBCPowerProfileStatus(BaseModel):
1388
- class Config:
1389
- extra = Extra.forbid
1390
-
1391
- message_id: ID = Field(..., description="ID of this message")
1392
- message_type: str = Field("PPBC.PowerProfileStatus", const=True)
1393
- sequence_container_status: List[PPBCPowerSequenceContainerStatus] = Field(
1485
+ timers: List[Timer] = Field(
1394
1486
  ...,
1395
- description="Array with status information for all PPBC.PowerSequenceContainers in the PPBC.PowerProfileDefinition.",
1396
- max_items=1000,
1397
- min_items=1,
1487
+ description='List of Timers associated with Transitions for this Actuator. Can be empty.',
1488
+ max_length=1000,
1489
+ min_length=0,
1398
1490
  )
1399
1491
 
1400
1492
 
1401
- class PPBCPowerSequence(BaseModel):
1402
- class Config:
1403
- extra = Extra.forbid
1404
-
1405
- abnormal_condition_only: bool = Field(
1406
- ...,
1407
- description="Indicates if this PPBC.PowerSequence may only be used during an abnormal condition",
1493
+ class DDBCSystemDescription(BaseModel):
1494
+ model_config = ConfigDict(
1495
+ extra='forbid',
1408
1496
  )
1409
- elements: List[PPBCPowerSequenceElement] = Field(
1497
+ message_type: Literal['DDBC.SystemDescription'] = 'DDBC.SystemDescription'
1498
+ message_id: ID
1499
+ valid_from: AwareDatetime = Field(
1410
1500
  ...,
1411
- description="List of PPBC.PowerSequenceElements. Shall contain at least one element. Elements must be placed in chronological order.",
1412
- max_items=288,
1413
- min_items=1,
1501
+ description='Moment this DDBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.',
1414
1502
  )
1415
- id: ID = Field(
1503
+ actuators: List[DDBCActuatorDescription] = Field(
1416
1504
  ...,
1417
- description="ID of the PPBC.PowerSequence. Must be unique in the scope of the PPBC.PowerSequnceContainer in which it is used.",
1505
+ description='List of all available actuators in the system. Must contain at least one DDBC.ActuatorAggregated.',
1506
+ max_length=10,
1507
+ min_length=1,
1418
1508
  )
1419
- is_interruptible: bool = Field(
1420
- ...,
1421
- description="Indicates whether the option of pausing a sequence is available.",
1509
+ present_demand_rate: NumberRange = Field(
1510
+ ..., description='Present demand rate that needs to be satisfied by the system'
1422
1511
  )
1423
- max_pause_before: Optional[Duration] = Field(
1424
- None,
1425
- description="The maximum duration for which a device can be paused between the end of the previous running sequence and the start of this one",
1512
+ provides_average_demand_rate_forecast: bool = Field(
1513
+ ...,
1514
+ description='Indicates whether the Resource Manager could provide a demand rate forecast through the DDBC.AverageDemandRateForecast.',
1426
1515
  )
1427
1516
 
1428
1517
 
1429
1518
  class PPBCPowerSequenceContainer(BaseModel):
1430
- class Config:
1431
- extra = Extra.forbid
1432
-
1519
+ model_config = ConfigDict(
1520
+ extra='forbid',
1521
+ )
1433
1522
  id: ID = Field(
1434
1523
  ...,
1435
- description="ID of the PPBC.PowerSequenceContainer. Must be unique in the scope of the PPBC.PowerProfileDefinition in which it is used.",
1524
+ description='ID of the PPBC.PowerSequenceContainer. Must be unique in the scope of the PPBC.PowerProfileDefinition in which it is used.',
1436
1525
  )
1437
1526
  power_sequences: List[PPBCPowerSequence] = Field(
1438
1527
  ...,
1439
- description="List of alternative Sequences where one could be chosen by the CEM",
1440
- max_items=288,
1441
- min_items=1,
1442
- )
1443
-
1444
-
1445
- class PowerForecast(BaseModel):
1446
- class Config:
1447
- extra = Extra.forbid
1448
-
1449
- elements: List[PowerForecastElement] = Field(
1450
- ...,
1451
- description="Elements of which this forecast consists. Contains at least one element. Elements must be placed in chronological order.",
1452
- max_items=288,
1453
- min_items=1,
1454
- )
1455
- message_id: ID = Field(..., description="ID of this message")
1456
- message_type: str = Field("PowerForecast", const=True)
1457
- start_time: datetime = Field(
1458
- ..., description="Start time of time period that is covered by the profile."
1528
+ description='List of alternative Sequences where one could be chosen by the CEM',
1529
+ max_length=288,
1530
+ min_length=1,
1459
1531
  )
1460
1532
 
1461
1533
 
1462
- class ResourceManagerDetails(BaseModel):
1463
- class Config:
1464
- extra = Extra.forbid
1465
-
1466
- available_control_types: List[ControlType] = Field(
1467
- ...,
1468
- description="The control types supported by this Resource Manager.",
1469
- max_items=5,
1470
- min_items=1,
1471
- )
1472
- currency: Optional[Currency] = Field(
1473
- None,
1474
- description="Currency to be used for all information regarding costs. Mandatory if cost information is published.",
1475
- )
1476
- firmware_version: Optional[str] = Field(
1477
- None,
1478
- description="Version identifier of the firmware used in the device (provided by the manufacturer)",
1534
+ class FRBCActuatorDescription(BaseModel):
1535
+ model_config = ConfigDict(
1536
+ extra='forbid',
1479
1537
  )
1480
- instruction_processing_delay: Duration = Field(
1538
+ id: ID = Field(
1481
1539
  ...,
1482
- description="The average time the combination of Resource Manager and HBES/BACS/SASS or (Smart) device needs to process and execute an instruction",
1540
+ description='ID of the Actuator. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1483
1541
  )
1484
- manufacturer: Optional[str] = Field(None, description="Name of Manufacturer")
1485
- message_id: ID = Field(..., description="ID of this message")
1486
- message_type: str = Field("ResourceManagerDetails", const=True)
1487
- model: Optional[str] = Field(
1542
+ diagnostic_label: Optional[str] = Field(
1488
1543
  None,
1489
- description="Name of the model of the device (provided by the manufacturer)",
1544
+ description='Human readable name/description for the actuator. This element is only intended for diagnostic purposes and not for HMI applications.',
1490
1545
  )
1491
- name: Optional[str] = Field(None, description="Human readable name given by user")
1492
- provides_forecast: bool = Field(
1546
+ supported_commodities: List[Commodity] = Field(
1493
1547
  ...,
1494
- description="Indicates whether the ResourceManager is able to provide PowerForecasts",
1548
+ description='List of all supported Commodities.',
1549
+ max_length=4,
1550
+ min_length=1,
1495
1551
  )
1496
- provides_power_measurement_types: List[CommodityQuantity] = Field(
1552
+ operation_modes: List[FRBCOperationMode] = Field(
1497
1553
  ...,
1498
- description="Array of all CommodityQuantities that this Resource Manager can provide measurements for. ",
1499
- max_items=10,
1500
- min_items=1,
1554
+ description='Provided FRBC.OperationModes associated with this actuator',
1555
+ max_length=100,
1556
+ min_length=1,
1501
1557
  )
1502
- resource_id: ID = Field(
1558
+ transitions: List[Transition] = Field(
1503
1559
  ...,
1504
- description="Identifier of the Resource Manager. Must be unique within the scope of the CEM.",
1560
+ description='Possible transitions between FRBC.OperationModes associated with this actuator.',
1561
+ max_length=1000,
1562
+ min_length=0,
1505
1563
  )
1506
- roles: List[Role] = Field(
1564
+ timers: List[Timer] = Field(
1507
1565
  ...,
1508
- description="Each Resource Manager provides one or more energy Roles",
1509
- max_items=3,
1510
- min_items=1,
1511
- )
1512
- serial_number: Optional[str] = Field(
1513
- None, description="Serial number of the device (provided by the manufacturer)"
1566
+ description='List of Timers associated with this actuator',
1567
+ max_length=1000,
1568
+ min_length=0,
1514
1569
  )
1515
1570
 
1516
1571
 
1517
- class FRBCActuatorDescription(BaseModel):
1518
- class Config:
1519
- extra = Extra.forbid
1520
-
1521
- diagnostic_label: Optional[str] = Field(
1522
- None,
1523
- description="Human readable name/description for the actuator. This element is only intended for diagnostic purposes and not for HMI applications.",
1572
+ class PPBCPowerProfileDefinition(BaseModel):
1573
+ model_config = ConfigDict(
1574
+ extra='forbid',
1524
1575
  )
1576
+ message_type: Literal['PPBC.PowerProfileDefinition'] = 'PPBC.PowerProfileDefinition'
1577
+ message_id: ID
1525
1578
  id: ID = Field(
1526
1579
  ...,
1527
- description="ID of the Actuator. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1580
+ description='ID of the PPBC.PowerProfileDefinition. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.',
1528
1581
  )
1529
- operation_modes: List[FRBCOperationMode] = Field(
1582
+ start_time: AwareDatetime = Field(
1530
1583
  ...,
1531
- description="Provided FRBC.OperationModes associated with this actuator",
1532
- max_items=100,
1533
- min_items=1,
1534
- )
1535
- supported_commodities: List[Commodity] = Field(
1536
- ..., description="List of all supported Commodities.", max_items=4, min_items=1
1584
+ description='Indicates the first possible time the first PPBC.PowerSequence could start',
1537
1585
  )
1538
- timers: List[Timer] = Field(
1586
+ end_time: AwareDatetime = Field(
1539
1587
  ...,
1540
- description="List of Timers associated with this actuator",
1541
- max_items=1000,
1542
- min_items=0,
1588
+ description='Indicates when the last PPBC.PowerSequence shall be finished at the latest',
1543
1589
  )
1544
- transitions: List[Transition] = Field(
1590
+ power_sequences_containers: List[PPBCPowerSequenceContainer] = Field(
1545
1591
  ...,
1546
- description="Possible transitions between FRBC.OperationModes associated with this actuator.",
1547
- max_items=1000,
1548
- min_items=0,
1592
+ description='The PPBC.PowerSequenceContainers that make up this PPBC.PowerProfileDefinition. There shall be at least one PPBC.PowerSequenceContainer that includes at least one PPBC.PowerSequence. PPBC.PowerSequenceContainers must be placed in chronological order.',
1593
+ max_length=1000,
1594
+ min_length=1,
1549
1595
  )
1550
1596
 
1551
1597
 
1552
1598
  class FRBCSystemDescription(BaseModel):
1553
- class Config:
1554
- extra = Extra.forbid
1555
-
1556
- actuators: List[FRBCActuatorDescription] = Field(
1557
- ..., description="Details of all Actuators.", max_items=10, min_items=1
1558
- )
1559
- message_id: ID = Field(..., description="ID of this message")
1560
- message_type: str = Field("FRBC.SystemDescription", const=True)
1561
- storage: FRBCStorageDescription = Field(..., description="Details of the storage.")
1562
- valid_from: datetime = Field(
1563
- ...,
1564
- description="Moment this FRBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.",
1565
- )
1566
-
1567
-
1568
- class PPBCPowerProfileDefinition(BaseModel):
1569
- class Config:
1570
- extra = Extra.forbid
1571
-
1572
- end_time: datetime = Field(
1573
- ...,
1574
- description="Indicates when the last PPBC.PowerSequence shall be finished at the latest",
1575
- )
1576
- id: ID = Field(
1577
- ...,
1578
- description="ID of the PPBC.PowerProfileDefinition. Must be unique in the scope of the Resource Manager, for at least the duration of the session between Resource Manager and CEM.",
1599
+ model_config = ConfigDict(
1600
+ extra='forbid',
1579
1601
  )
1580
- message_id: ID = Field(..., description="ID of this message")
1581
- message_type: str = Field("PPBC.PowerProfileDefinition", const=True)
1582
- power_sequences_containers: List[PPBCPowerSequenceContainer] = Field(
1602
+ message_type: Literal['FRBC.SystemDescription'] = 'FRBC.SystemDescription'
1603
+ message_id: ID
1604
+ valid_from: AwareDatetime = Field(
1583
1605
  ...,
1584
- description="The PPBC.PowerSequenceContainers that make up this PPBC.PowerProfileDefinition. There shall be at least one PPBC.PowerSequenceContainer that includes at least one PPBC.PowerSequence. PPBC.PowerSequenceContainers must be placed in chronological order.",
1585
- max_items=1000,
1586
- min_items=1,
1606
+ description='Moment this FRBC.SystemDescription starts to be valid. If the system description is immediately valid, the DateTimeStamp should be now or in the past.',
1587
1607
  )
1588
- start_time: datetime = Field(
1589
- ...,
1590
- description="Indicates the first possible time the first PPBC.PowerSequence could start",
1608
+ actuators: List[FRBCActuatorDescription] = Field(
1609
+ ..., description='Details of all Actuators.', max_length=10, min_length=1
1591
1610
  )
1611
+ storage: FRBCStorageDescription = Field(..., description='Details of the storage.')