Skip to main content

redispatch_xml/documents/
activation.rs

1use serde::{Deserialize, Serialize};
2
3use crate::types::{
4    AttrV, AttrVWithScheme, ControlZone, Direction, DocumentId, DocumentVersion,
5    MarketParticipantId, MarketRoleType, MeasureUnit, Period, TimeInterval, UtcDateTime,
6};
7
8// ── Namespace ─────────────────────────────────────────────────────────────────
9
10/// Expected XML namespace for `ActivationDocument`.
11pub const NAMESPACE: &str = "urn:entsoe.eu:wgedi:errp:activationdocument:5:0";
12
13// ── DocumentType ─────────────────────────────────────────────────────────────
14
15/// `DocumentType` codes for `ActivationDocument`.
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
17pub enum ActivationDocType {
18    /// Activation response (ACR).
19    #[serde(rename = "A41")]
20    ActivationResponse,
21    /// Tender reduction (AAR).
22    #[serde(rename = "A42")]
23    TenderReduction,
24    /// Redispatch activation document (ACO).
25    #[serde(rename = "A96")]
26    RedispatchActivation,
27}
28
29/// `ProcessType` codes for `ActivationDocument`.
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
31pub enum ActivationProcessType {
32    /// Redispatch activation process.
33    #[serde(rename = "A41")]
34    Redispatch,
35    /// Test / other.
36    #[serde(rename = "Z01")]
37    Other,
38}
39
40/// `Status` codes used in `ActivationTimeSeries`.
41#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
42pub enum TimeSeriesStatus {
43    /// Volumes available (used for partial-rejection ACR).
44    #[serde(rename = "A06")]
45    Available,
46    /// Quantities activated (Information).
47    #[serde(rename = "A07")]
48    Activated,
49    /// Quantities ordered (Anweisung / ACO).
50    #[serde(rename = "A10")]
51    Ordered,
52}
53
54/// `BusinessType` codes used in `ActivationTimeSeries`.
55#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
56pub enum TimeSeriesBusinessType {
57    /// System Operator redispatching (Deltaanweisung).
58    #[serde(rename = "A46")]
59    SystemOperatorRedispatching,
60    /// Internal redispatch (Sollwertvorgabe).
61    #[serde(rename = "A85")]
62    InternalRedispatch,
63}
64
65// ── Document-level Reason ─────────────────────────────────────────────────────
66
67/// Reason code at the `ActivationDocument` root level (document-level
68/// acceptance/rejection).
69#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
70pub enum DocumentReasonCode {
71    /// Deadline exceeded (Frist abgelaufen).
72    #[serde(rename = "A57")]
73    DeadlineExceeded,
74    /// Complementary information.
75    #[serde(rename = "A95")]
76    ComplementaryInfo,
77    /// Technical constraint.
78    #[serde(rename = "A96")]
79    TechnicalConstraint,
80}
81
82/// Root-level reason attached to an `ActivationDocument`.
83#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
84pub struct DocumentReason {
85    /// Document-level reason code.
86    #[serde(rename = "ReasonCode")]
87    pub code: AttrV<DocumentReasonCode>,
88    /// Optional free-text description.
89    #[serde(
90        rename = "ReasonText",
91        default,
92        skip_serializing_if = "Option::is_none"
93    )]
94    pub text: Option<String>,
95}
96
97// ── ActivationTimeSeries ──────────────────────────────────────────────────────
98
99/// Reference to a `ResourceObject` with its NDE coding scheme.
100pub type ResourceObjectRef = AttrVWithScheme<String, ResourceObjectCodingScheme>;
101
102/// Coding scheme for resource object identifiers.
103#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
104pub enum ResourceObjectCodingScheme {
105    /// Germany National coding scheme (BDEW resource code).
106    #[serde(rename = "NDE")]
107    Nde,
108}
109
110/// Reference to a control zone (EIC) with `codingScheme = "A01"`.
111pub type ControlZoneRef = AttrVWithScheme<ControlZone, EicCodingScheme>;
112
113/// Coding scheme for EIC-coded identifiers (always `A01`).
114#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
115pub enum EicCodingScheme {
116    /// EIC — Energy Identification Coding Scheme.
117    #[serde(rename = "A01")]
118    Eic,
119}
120
121/// A single activated time series within an `ActivationDocument`.
122///
123/// Each `ActivationTimeSeries` covers one direction (up/down) for one
124/// `ResourceObject`. An `ActivationDocument` may contain up to two time
125/// series (one per direction).
126#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
127pub struct ActivationTimeSeries {
128    /// Unique time-series identifier within this document.
129    #[serde(rename = "AllocationIdentification")]
130    pub allocation_identification: AttrV<DocumentId>,
131    /// Resource provider (EIV or NB) — optional when sender is the provider.
132    #[serde(
133        rename = "ResourceProvider",
134        default,
135        skip_serializing_if = "Option::is_none"
136    )]
137    pub resource_provider: Option<AttrVWithScheme<MarketParticipantId>>,
138    /// Business type: delta instruction (`A46`) or setpoint (`A85`).
139    #[serde(rename = "BusinessType")]
140    pub business_type: AttrV<TimeSeriesBusinessType>,
141    /// German TSO control block (always `10YCB-GERMANY--8`, EIC).
142    #[serde(rename = "AcquiringArea")]
143    pub acquiring_area: AttrVWithScheme<String, EicCodingScheme>,
144    /// Connecting control zone where the resource object is connected.
145    #[serde(rename = "ConnectingArea")]
146    pub connecting_area: ControlZoneRef,
147    /// Physical unit of the quantity values (`MAW` or `P1`).
148    #[serde(rename = "MeasureUnit")]
149    pub measure_unit: AttrV<MeasureUnit>,
150    /// Redispatch direction: up (`A01`) or down (`A02`).
151    #[serde(rename = "Direction")]
152    pub direction: AttrV<Direction>,
153    /// Activation / order / availability status.
154    #[serde(rename = "Status")]
155    pub status: AttrV<TimeSeriesStatus>,
156    /// Resource object identifier (BDEW resource code, NDE scheme).
157    #[serde(rename = "ResourceObject")]
158    pub resource_object: ResourceObjectRef,
159    /// `DocumentIdentification` of the originating planning data (optional).
160    #[serde(
161        rename = "SendersDocumentIdentification",
162        default,
163        skip_serializing_if = "Option::is_none"
164    )]
165    pub senders_document_identification: Option<AttrV<DocumentId>>,
166    /// `DocumentVersion` of the originating planning data (optional).
167    #[serde(
168        rename = "SendersDocumentVersion",
169        default,
170        skip_serializing_if = "Option::is_none"
171    )]
172    pub senders_document_version: Option<AttrV<DocumentVersion>>,
173    /// `CreationDateTime` of the originating planning data (optional).
174    #[serde(
175        rename = "SendersDocumentDateTime",
176        default,
177        skip_serializing_if = "Option::is_none"
178    )]
179    pub senders_document_date_time: Option<AttrV<UtcDateTime>>,
180    /// Original `TimeSeriesIdentification` (not used in practice).
181    #[serde(
182        rename = "SendersTimeSeriesIdentification",
183        default,
184        skip_serializing_if = "Option::is_none"
185    )]
186    pub senders_time_series_identification: Option<AttrV<DocumentId>>,
187    /// Original sender's market participant ID when forwarded via data provider.
188    #[serde(
189        rename = "OriginalSenderIdentification",
190        default,
191        skip_serializing_if = "Option::is_none"
192    )]
193    pub original_sender_identification: Option<AttrVWithScheme<MarketParticipantId>>,
194    /// Original `DocumentIdentification` when forwarded.
195    #[serde(
196        rename = "OriginalDocumentIdentification",
197        default,
198        skip_serializing_if = "Option::is_none"
199    )]
200    pub original_document_identification: Option<AttrV<DocumentId>>,
201    /// Original `DocumentVersion` when forwarded.
202    #[serde(
203        rename = "OriginalDocumentVersion",
204        default,
205        skip_serializing_if = "Option::is_none"
206    )]
207    pub original_document_version: Option<AttrV<DocumentVersion>>,
208    /// Original `CreationDateTime` when forwarded.
209    #[serde(
210        rename = "OriginalDocumentDateTime",
211        default,
212        skip_serializing_if = "Option::is_none"
213    )]
214    pub original_document_date_time: Option<AttrV<UtcDateTime>>,
215    /// Original `AllocationIdentification` when forwarded.
216    #[serde(
217        rename = "OriginalAllocationIdentification",
218        default,
219        skip_serializing_if = "Option::is_none"
220    )]
221    pub original_allocation_identification: Option<AttrV<DocumentId>>,
222    /// Quarter-hour activation data for the delivery day.
223    #[serde(rename = "Period")]
224    pub period: Period,
225}
226
227// ── ActivationDocument ────────────────────────────────────────────────────────
228
229/// `ActivationDocument` — Redispatch 2.0 activation instruction, response, or
230/// reduction document.
231///
232/// XSD version: 1.1f (Fehlerkorrektur 2026-02-19)  
233/// Namespace: `urn:entsoe.eu:wgedi:errp:activationdocument:5:0`
234///
235/// Three document types share this format:
236/// - **ACO** (`A96`): Activation order sent by the requesting NB to the
237///   resource provider's NB.
238/// - **ACR** (`A41`): Activation response from the resource provider's NB.
239/// - **AAR** (`A42`): Tender reduction sent by the requesting NB when it
240///   reduces or cancels a previously issued ACO.
241#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
242#[serde(rename = "ActivationDocument")]
243pub struct ActivationDocument {
244    /// Unique document identifier (max 35 chars, case-sensitive).
245    #[serde(rename = "DocumentIdentification")]
246    pub document_identification: AttrV<DocumentId>,
247    /// Document version number (1–999).
248    #[serde(rename = "DocumentVersion")]
249    pub document_version: AttrV<DocumentVersion>,
250    /// Document type: ACR (`A41`), AAR (`A42`), or ACO (`A96`).
251    #[serde(rename = "DocumentType")]
252    pub document_type: AttrV<ActivationDocType>,
253    /// Process type: always `A41` (redispatch process).
254    #[serde(rename = "ProcessType")]
255    pub process_type: AttrV<ActivationProcessType>,
256    /// Sender's market participant identifier.
257    #[serde(rename = "SenderIdentification")]
258    pub sender_identification: AttrVWithScheme<MarketParticipantId>,
259    /// Sender's market role.
260    #[serde(rename = "SenderRole")]
261    pub sender_role: AttrV<MarketRoleType>,
262    /// Receiver's market participant identifier.
263    #[serde(rename = "ReceiverIdentification")]
264    pub receiver_identification: AttrVWithScheme<MarketParticipantId>,
265    /// Receiver's market role.
266    #[serde(rename = "ReceiverRole")]
267    pub receiver_role: AttrV<MarketRoleType>,
268    /// Document creation timestamp (UTC, second precision).
269    #[serde(rename = "CreationDateTime")]
270    pub creation_date_time: AttrV<UtcDateTime>,
271    /// Delivery day covered by this document (UTC interval, minute precision).
272    #[serde(rename = "ActivationTimeInterval")]
273    pub activation_time_interval: AttrV<TimeInterval>,
274    /// `DocumentIdentification` of the ACO this ACR/AAR responds to (optional).
275    #[serde(
276        rename = "OrderIdentification",
277        default,
278        skip_serializing_if = "Option::is_none"
279    )]
280    pub order_identification: Option<AttrV<DocumentId>>,
281    /// `DocumentVersion` of the ACO this ACR/AAR responds to (optional).
282    #[serde(
283        rename = "OrderIdentificationVersion",
284        default,
285        skip_serializing_if = "Option::is_none"
286    )]
287    pub order_identification_version: Option<AttrV<DocumentVersion>>,
288    /// Activated time series (1–2 entries; one per direction).
289    #[serde(rename = "ActivationTimeSeries", default)]
290    pub time_series: Vec<ActivationTimeSeries>,
291    /// Document-level reason (optional; present on full rejections).
292    #[serde(rename = "Reason", default, skip_serializing_if = "Option::is_none")]
293    pub reason: Option<DocumentReason>,
294}