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