Skip to main content

ocpp_types/v21/
common.rs

1// @generated by ocpp-codegen from schemas/. Do not edit by hand -- run
2// `scripts/generate.sh` to regenerate; manual changes will be overwritten.
3
4/// This class does not get 'AdditionalProperties = false' in the schema generation, so it can be extended with arbitrary JSON properties to allow adding custom data.
5#[derive(Debug, Clone, PartialEq, Eq)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7pub struct CustomData {
8    #[cfg_attr(feature = "serde", serde(rename = "vendorId"))]
9    pub vendor_id: heapless::String<255usize>,
10}
11#[cfg(feature = "validate")]
12impl crate::validate::Validate for CustomData {
13    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
14        Ok(())
15    }
16}
17#[derive(Debug, Clone, PartialEq, Eq)]
18#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
19pub enum GenericStatusEnum {
20    Accepted,
21    Rejected,
22}
23#[cfg(feature = "validate")]
24impl crate::validate::Validate for GenericStatusEnum {
25    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
26        Ok(())
27    }
28}
29#[cfg(feature = "alloc")]
30/// Element providing more information about the status.
31#[derive(Debug, Clone, PartialEq, Eq)]
32#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
33pub struct StatusInfo<CustomDataType = crate::NoCustomData> {
34    /// Additional text to provide detailed information.
35    #[cfg_attr(feature = "serde", serde(rename = "additionalInfo"))]
36    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
37    pub additional_info: Option<alloc::string::String>,
38    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
39    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
40    pub custom_data: Option<CustomDataType>,
41    /// A predefined code for the reason why the status is returned in this response. The string is case-insensitive.
42    #[cfg_attr(feature = "serde", serde(rename = "reasonCode"))]
43    pub reason_code: heapless::String<20usize>,
44}
45#[cfg(all(feature = "validate", feature = "alloc"))]
46impl<CustomDataType> crate::validate::Validate for StatusInfo<CustomDataType> {
47    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
48        if let Some(value) = &self.additional_info {
49            crate::validate::check_max_length(value, 1024usize)
50                .map_err(|error| error.in_field("additionalInfo"))?;
51        }
52        Ok(())
53    }
54}
55#[cfg(not(feature = "alloc"))]
56/// Element providing more information about the status.
57#[derive(Debug, Clone, PartialEq, Eq)]
58#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
59pub struct StatusInfo<
60    CustomDataType = crate::NoCustomData,
61    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
62> {
63    /// Additional text to provide detailed information.
64    #[cfg_attr(feature = "serde", serde(rename = "additionalInfo"))]
65    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
66    pub additional_info: Option<heapless::String<STATUS_INFO_ADDITIONAL_INFO_CAP>>,
67    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
68    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
69    pub custom_data: Option<CustomDataType>,
70    /// A predefined code for the reason why the status is returned in this response. The string is case-insensitive.
71    #[cfg_attr(feature = "serde", serde(rename = "reasonCode"))]
72    pub reason_code: heapless::String<20usize>,
73}
74#[cfg(all(feature = "validate", not(feature = "alloc")))]
75impl<
76    CustomDataType,
77    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
78> crate::validate::Validate
79for StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP> {
80    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
81        if let Some(value) = &self.additional_info {
82            crate::validate::check_max_length(value, 1024usize)
83                .map_err(|error| error.in_field("additionalInfo"))?;
84        }
85        Ok(())
86    }
87}
88#[derive(Debug, Clone, PartialEq, Eq)]
89#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
90pub struct PeriodicEventStreamParams<CustomDataType = crate::NoCustomData> {
91    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
92    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
93    pub custom_data: Option<CustomDataType>,
94    /// Time in seconds after which stream data is sent.
95    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
96    pub interval: Option<i64>,
97    /// Number of items to be sent together in stream.
98    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
99    pub values: Option<i64>,
100}
101#[cfg(feature = "validate")]
102impl<CustomDataType> crate::validate::Validate
103for PeriodicEventStreamParams<CustomDataType> {
104    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
105        if let Some(value) = self.interval {
106            crate::validate::check_min_i64(value, 0i64)
107                .map_err(|error| error.in_field("interval"))?;
108        }
109        if let Some(value) = self.values {
110            crate::validate::check_min_i64(value, 0i64)
111                .map_err(|error| error.in_field("values"))?;
112        }
113        Ok(())
114    }
115}
116/// Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
117#[derive(Debug, Clone, PartialEq, Eq)]
118#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
119pub struct AdditionalInfo<CustomDataType = crate::NoCustomData> {
120    /// *(2.1)* This field specifies the additional IdToken.
121    #[cfg_attr(feature = "serde", serde(rename = "additionalIdToken"))]
122    pub additional_id_token: heapless::String<255usize>,
123    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
124    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
125    pub custom_data: Option<CustomDataType>,
126    /// _additionalInfo_ can be used to send extra information to CSMS in addition to the regular authorization with _IdToken_. _AdditionalInfo_ contains one or more custom _types_, which need to be agreed upon by all parties involved. When the _type_ is not supported, the CSMS/Charging Station MAY ignore the _additionalInfo_.
127    pub r#type: heapless::String<50usize>,
128}
129#[cfg(feature = "validate")]
130impl<CustomDataType> crate::validate::Validate for AdditionalInfo<CustomDataType> {
131    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
132        Ok(())
133    }
134}
135#[cfg(feature = "alloc")]
136/// Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
137#[derive(Debug, Clone, PartialEq, Eq)]
138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
139pub struct IdToken<CustomDataType = crate::NoCustomData> {
140    #[cfg_attr(feature = "serde", serde(rename = "additionalInfo"))]
141    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
142    pub additional_info: Option<alloc::vec::Vec<AdditionalInfo<CustomDataType>>>,
143    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
144    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
145    pub custom_data: Option<CustomDataType>,
146    /// *(2.1)* IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can for example also contain a UUID.
147    #[cfg_attr(feature = "serde", serde(rename = "idToken"))]
148    pub id_token: heapless::String<255usize>,
149    /// *(2.1)* Enumeration of possible idToken types. Values defined in Appendix as IdTokenEnumStringType.
150    pub r#type: heapless::String<20usize>,
151}
152#[cfg(all(feature = "validate", feature = "alloc"))]
153impl<CustomDataType> crate::validate::Validate for IdToken<CustomDataType> {
154    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
155        if let Some(value) = &self.additional_info {
156            crate::validate::check_min_items(value.len(), 1usize)
157                .map_err(|error| error.in_field("additionalInfo"))?;
158            for (index, item) in value.iter().enumerate() {
159                crate::validate::Validate::validate(item)
160                    .map_err(|error| error.in_index(index).in_field("additionalInfo"))?;
161            }
162        }
163        Ok(())
164    }
165}
166#[cfg(not(feature = "alloc"))]
167/// Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
168#[derive(Debug, Clone, PartialEq, Eq)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
170pub struct IdToken<
171    CustomDataType = crate::NoCustomData,
172    const ID_TOKEN_ADDITIONAL_INFO_CAP: usize = 8usize,
173> {
174    #[cfg_attr(feature = "serde", serde(rename = "additionalInfo"))]
175    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
176    pub additional_info: Option<
177        heapless::Vec<AdditionalInfo<CustomDataType>, ID_TOKEN_ADDITIONAL_INFO_CAP>,
178    >,
179    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
180    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
181    pub custom_data: Option<CustomDataType>,
182    /// *(2.1)* IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can for example also contain a UUID.
183    #[cfg_attr(feature = "serde", serde(rename = "idToken"))]
184    pub id_token: heapless::String<255usize>,
185    /// *(2.1)* Enumeration of possible idToken types. Values defined in Appendix as IdTokenEnumStringType.
186    pub r#type: heapless::String<20usize>,
187}
188#[cfg(all(feature = "validate", not(feature = "alloc")))]
189impl<CustomDataType, const ID_TOKEN_ADDITIONAL_INFO_CAP: usize> crate::validate::Validate
190for IdToken<CustomDataType, ID_TOKEN_ADDITIONAL_INFO_CAP> {
191    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
192        if let Some(value) = &self.additional_info {
193            crate::validate::check_min_items(value.len(), 1usize)
194                .map_err(|error| error.in_field("additionalInfo"))?;
195            for (index, item) in value.iter().enumerate() {
196                crate::validate::Validate::validate(item)
197                    .map_err(|error| error.in_index(index).in_field("additionalInfo"))?;
198            }
199        }
200        Ok(())
201    }
202}
203/// Used algorithms for the hashes provided.
204#[derive(Debug, Clone, PartialEq, Eq)]
205#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
206pub enum HashAlgorithmEnum {
207    SHA256,
208    SHA384,
209    SHA512,
210}
211#[cfg(feature = "validate")]
212impl crate::validate::Validate for HashAlgorithmEnum {
213    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
214        Ok(())
215    }
216}
217#[cfg(feature = "alloc")]
218/// Information about a certificate for an OCSP check.
219#[derive(Debug, Clone, PartialEq, Eq)]
220#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
221pub struct OCSPRequestData<CustomDataType = crate::NoCustomData> {
222    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
223    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
224    pub custom_data: Option<CustomDataType>,
225    #[cfg_attr(feature = "serde", serde(rename = "hashAlgorithm"))]
226    pub hash_algorithm: HashAlgorithmEnum,
227    /// The hash of the DER encoded public key:
228    /// the value (excluding tag and length) of the subject
229    /// public key field in the issuer’s certificate.
230    #[cfg_attr(feature = "serde", serde(rename = "issuerKeyHash"))]
231    pub issuer_key_hash: heapless::String<128usize>,
232    /// The hash of the issuer’s distinguished
233    /// name (DN), that must be calculated over the DER
234    /// encoding of the issuer’s name field in the certificate
235    /// being checked.
236    #[cfg_attr(feature = "serde", serde(rename = "issuerNameHash"))]
237    pub issuer_name_hash: heapless::String<128usize>,
238    /// This contains the responder URL (Case insensitive).
239    #[cfg_attr(feature = "serde", serde(rename = "responderURL"))]
240    pub responder_u_r_l: alloc::string::String,
241    /// The string representation of the
242    /// hexadecimal value of the serial number without the
243    /// prefix "0x" and without leading zeroes.
244    #[cfg_attr(feature = "serde", serde(rename = "serialNumber"))]
245    pub serial_number: heapless::String<40usize>,
246}
247#[cfg(all(feature = "validate", feature = "alloc"))]
248impl<CustomDataType> crate::validate::Validate for OCSPRequestData<CustomDataType> {
249    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
250        crate::validate::Validate::validate(&self.hash_algorithm)
251            .map_err(|error| error.in_field("hashAlgorithm"))?;
252        crate::validate::check_max_length(&self.responder_u_r_l, 2000usize)
253            .map_err(|error| error.in_field("responderURL"))?;
254        Ok(())
255    }
256}
257#[cfg(not(feature = "alloc"))]
258/// Information about a certificate for an OCSP check.
259#[derive(Debug, Clone, PartialEq, Eq)]
260#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
261pub struct OCSPRequestData<
262    CustomDataType = crate::NoCustomData,
263    const O_C_S_P_REQUEST_DATA_RESPONDER_U_R_L_CAP: usize = 1024usize,
264> {
265    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
266    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
267    pub custom_data: Option<CustomDataType>,
268    #[cfg_attr(feature = "serde", serde(rename = "hashAlgorithm"))]
269    pub hash_algorithm: HashAlgorithmEnum,
270    /// The hash of the DER encoded public key:
271    /// the value (excluding tag and length) of the subject
272    /// public key field in the issuer’s certificate.
273    #[cfg_attr(feature = "serde", serde(rename = "issuerKeyHash"))]
274    pub issuer_key_hash: heapless::String<128usize>,
275    /// The hash of the issuer’s distinguished
276    /// name (DN), that must be calculated over the DER
277    /// encoding of the issuer’s name field in the certificate
278    /// being checked.
279    #[cfg_attr(feature = "serde", serde(rename = "issuerNameHash"))]
280    pub issuer_name_hash: heapless::String<128usize>,
281    /// This contains the responder URL (Case insensitive).
282    #[cfg_attr(feature = "serde", serde(rename = "responderURL"))]
283    pub responder_u_r_l: heapless::String<O_C_S_P_REQUEST_DATA_RESPONDER_U_R_L_CAP>,
284    /// The string representation of the
285    /// hexadecimal value of the serial number without the
286    /// prefix "0x" and without leading zeroes.
287    #[cfg_attr(feature = "serde", serde(rename = "serialNumber"))]
288    pub serial_number: heapless::String<40usize>,
289}
290#[cfg(all(feature = "validate", not(feature = "alloc")))]
291impl<
292    CustomDataType,
293    const O_C_S_P_REQUEST_DATA_RESPONDER_U_R_L_CAP: usize,
294> crate::validate::Validate
295for OCSPRequestData<CustomDataType, O_C_S_P_REQUEST_DATA_RESPONDER_U_R_L_CAP> {
296    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
297        crate::validate::Validate::validate(&self.hash_algorithm)
298            .map_err(|error| error.in_field("hashAlgorithm"))?;
299        crate::validate::check_max_length(&self.responder_u_r_l, 2000usize)
300            .map_err(|error| error.in_field("responderURL"))?;
301        Ok(())
302    }
303}
304#[derive(Debug, Clone, PartialEq, Eq)]
305#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
306pub enum EnergyTransferModeEnum {
307    #[cfg_attr(feature = "serde", serde(rename = "AC_single_phase"))]
308    ACsinglephase,
309    #[cfg_attr(feature = "serde", serde(rename = "AC_two_phase"))]
310    ACtwophase,
311    #[cfg_attr(feature = "serde", serde(rename = "AC_three_phase"))]
312    ACthreephase,
313    DC,
314    #[cfg_attr(feature = "serde", serde(rename = "AC_BPT"))]
315    ACBPT,
316    #[cfg_attr(feature = "serde", serde(rename = "AC_BPT_DER"))]
317    ACBPTDER,
318    #[cfg_attr(feature = "serde", serde(rename = "AC_DER"))]
319    ACDER,
320    #[cfg_attr(feature = "serde", serde(rename = "DC_BPT"))]
321    DCBPT,
322    #[cfg_attr(feature = "serde", serde(rename = "DC_ACDP"))]
323    DCACDP,
324    #[cfg_attr(feature = "serde", serde(rename = "DC_ACDP_BPT"))]
325    DCACDPBPT,
326    WPT,
327}
328#[cfg(feature = "validate")]
329impl crate::validate::Validate for EnergyTransferModeEnum {
330    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
331        Ok(())
332    }
333}
334/// Certificate status information.
335/// - if all certificates are valid: return 'Accepted'.
336/// - if one of the certificates was revoked, return 'CertificateRevoked'.
337#[derive(Debug, Clone, PartialEq, Eq)]
338#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
339pub enum AuthorizeCertificateStatusEnum {
340    Accepted,
341    SignatureError,
342    CertificateExpired,
343    CertificateRevoked,
344    NoCertificateAvailable,
345    CertChainError,
346    ContractCancelled,
347}
348#[cfg(feature = "validate")]
349impl crate::validate::Validate for AuthorizeCertificateStatusEnum {
350    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
351        Ok(())
352    }
353}
354/// Format of the message.
355#[derive(Debug, Clone, PartialEq, Eq)]
356#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
357pub enum MessageFormatEnum {
358    ASCII,
359    HTML,
360    URI,
361    UTF8,
362    QRCODE,
363}
364#[cfg(feature = "validate")]
365impl crate::validate::Validate for MessageFormatEnum {
366    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
367        Ok(())
368    }
369}
370#[cfg(feature = "alloc")]
371/// Contains message details, for a message to be displayed on a Charging Station.
372#[derive(Debug, Clone, PartialEq, Eq)]
373#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
374pub struct MessageContent<CustomDataType = crate::NoCustomData> {
375    /// *(2.1)* Required. Message contents. +
376    /// Maximum length supported by Charging Station is given in OCPPCommCtrlr.FieldLength\["MessageContentType.content"\].
377    ///     Maximum length defaults to 1024.
378    pub content: alloc::string::String,
379    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
380    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
381    pub custom_data: Option<CustomDataType>,
382    pub format: MessageFormatEnum,
383    /// Message language identifier. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
384    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
385    pub language: Option<heapless::String<8usize>>,
386}
387#[cfg(all(feature = "validate", feature = "alloc"))]
388impl<CustomDataType> crate::validate::Validate for MessageContent<CustomDataType> {
389    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
390        crate::validate::check_max_length(&self.content, 1024usize)
391            .map_err(|error| error.in_field("content"))?;
392        crate::validate::Validate::validate(&self.format)
393            .map_err(|error| error.in_field("format"))?;
394        Ok(())
395    }
396}
397#[cfg(not(feature = "alloc"))]
398/// Contains message details, for a message to be displayed on a Charging Station.
399#[derive(Debug, Clone, PartialEq, Eq)]
400#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
401pub struct MessageContent<
402    CustomDataType = crate::NoCustomData,
403    const MESSAGE_CONTENT_CONTENT_CAP: usize = 1024usize,
404> {
405    /// *(2.1)* Required. Message contents. +
406    /// Maximum length supported by Charging Station is given in OCPPCommCtrlr.FieldLength\["MessageContentType.content"\].
407    ///     Maximum length defaults to 1024.
408    pub content: heapless::String<MESSAGE_CONTENT_CONTENT_CAP>,
409    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
410    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
411    pub custom_data: Option<CustomDataType>,
412    pub format: MessageFormatEnum,
413    /// Message language identifier. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
414    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
415    pub language: Option<heapless::String<8usize>>,
416}
417#[cfg(all(feature = "validate", not(feature = "alloc")))]
418impl<CustomDataType, const MESSAGE_CONTENT_CONTENT_CAP: usize> crate::validate::Validate
419for MessageContent<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP> {
420    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
421        crate::validate::check_max_length(&self.content, 1024usize)
422            .map_err(|error| error.in_field("content"))?;
423        crate::validate::Validate::validate(&self.format)
424            .map_err(|error| error.in_field("format"))?;
425        Ok(())
426    }
427}
428/// Current status of the ID Token.
429#[derive(Debug, Clone, PartialEq, Eq)]
430#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
431pub enum AuthorizationStatusEnum {
432    Accepted,
433    Blocked,
434    ConcurrentTx,
435    Expired,
436    Invalid,
437    NoCredit,
438    NotAllowedTypeEVSE,
439    NotAtThisLocation,
440    NotAtThisTime,
441    Unknown,
442}
443#[cfg(feature = "validate")]
444impl crate::validate::Validate for AuthorizationStatusEnum {
445    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
446        Ok(())
447    }
448}
449#[cfg(feature = "alloc")]
450/// Contains status information about an identifier.
451/// It is advised to not stop charging for a token that expires during charging, as ExpiryDate is only used for caching purposes. If ExpiryDate is not given, the status has no end date.
452#[derive(Debug, Clone, PartialEq, Eq)]
453#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
454pub struct IdTokenInfo<CustomDataType = crate::NoCustomData> {
455    /// Date and Time after which the token must be considered invalid.
456    #[cfg_attr(feature = "serde", serde(rename = "cacheExpiryDateTime"))]
457    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
458    pub cache_expiry_date_time: Option<crate::OcppTimestamp>,
459    /// Priority from a business point of view. Default priority is 0, The range is from -9 to 9. Higher values indicate a higher priority. The chargingPriority in &lt;&lt;transactioneventresponse,TransactionEventResponse&gt;&gt; overrules this one.
460    #[cfg_attr(feature = "serde", serde(rename = "chargingPriority"))]
461    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
462    pub charging_priority: Option<i64>,
463    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
464    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
465    pub custom_data: Option<CustomDataType>,
466    /// Only used when the IdToken is only valid for one or more specific EVSEs, not for the entire Charging Station.
467    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
468    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
469    pub evse_id: Option<alloc::vec::Vec<i64>>,
470    #[cfg_attr(feature = "serde", serde(rename = "groupIdToken"))]
471    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
472    pub group_id_token: Option<IdToken<CustomDataType>>,
473    /// Preferred user interface language of identifier user. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
474    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
475    pub language1: Option<heapless::String<8usize>>,
476    /// Second preferred user interface language of identifier user. Don’t use when language1 is omitted, has to be different from language1. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
477    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
478    pub language2: Option<heapless::String<8usize>>,
479    #[cfg_attr(feature = "serde", serde(rename = "personalMessage"))]
480    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
481    pub personal_message: Option<MessageContent<CustomDataType>>,
482    pub status: AuthorizationStatusEnum,
483}
484#[cfg(all(feature = "validate", feature = "alloc"))]
485impl<CustomDataType> crate::validate::Validate for IdTokenInfo<CustomDataType> {
486    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
487        if let Some(value) = &self.evse_id {
488            crate::validate::check_min_items(value.len(), 1usize)
489                .map_err(|error| error.in_field("evseId"))?;
490            for (index, item) in value.iter().enumerate() {
491                crate::validate::check_min_i64(*item, 0i64)
492                    .map_err(|error| error.in_index(index).in_field("evseId"))?;
493            }
494        }
495        if let Some(value) = &self.group_id_token {
496            crate::validate::Validate::validate(value)
497                .map_err(|error| error.in_field("groupIdToken"))?;
498        }
499        if let Some(value) = &self.personal_message {
500            crate::validate::Validate::validate(value)
501                .map_err(|error| error.in_field("personalMessage"))?;
502        }
503        crate::validate::Validate::validate(&self.status)
504            .map_err(|error| error.in_field("status"))?;
505        Ok(())
506    }
507}
508#[cfg(not(feature = "alloc"))]
509/// Contains status information about an identifier.
510/// It is advised to not stop charging for a token that expires during charging, as ExpiryDate is only used for caching purposes. If ExpiryDate is not given, the status has no end date.
511#[derive(Debug, Clone, PartialEq, Eq)]
512#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
513pub struct IdTokenInfo<
514    CustomDataType = crate::NoCustomData,
515    const ID_TOKEN_INFO_EVSE_ID_CAP: usize = 8usize,
516    const ID_TOKEN_ADDITIONAL_INFO_CAP: usize = 8usize,
517    const MESSAGE_CONTENT_CONTENT_CAP: usize = 1024usize,
518> {
519    /// Date and Time after which the token must be considered invalid.
520    #[cfg_attr(feature = "serde", serde(rename = "cacheExpiryDateTime"))]
521    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
522    pub cache_expiry_date_time: Option<crate::OcppTimestamp>,
523    /// Priority from a business point of view. Default priority is 0, The range is from -9 to 9. Higher values indicate a higher priority. The chargingPriority in &lt;&lt;transactioneventresponse,TransactionEventResponse&gt;&gt; overrules this one.
524    #[cfg_attr(feature = "serde", serde(rename = "chargingPriority"))]
525    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
526    pub charging_priority: Option<i64>,
527    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
528    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
529    pub custom_data: Option<CustomDataType>,
530    /// Only used when the IdToken is only valid for one or more specific EVSEs, not for the entire Charging Station.
531    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
532    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
533    pub evse_id: Option<heapless::Vec<i64, ID_TOKEN_INFO_EVSE_ID_CAP>>,
534    #[cfg_attr(feature = "serde", serde(rename = "groupIdToken"))]
535    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
536    pub group_id_token: Option<IdToken<CustomDataType, ID_TOKEN_ADDITIONAL_INFO_CAP>>,
537    /// Preferred user interface language of identifier user. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
538    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
539    pub language1: Option<heapless::String<8usize>>,
540    /// Second preferred user interface language of identifier user. Don’t use when language1 is omitted, has to be different from language1. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
541    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
542    pub language2: Option<heapless::String<8usize>>,
543    #[cfg_attr(feature = "serde", serde(rename = "personalMessage"))]
544    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
545    pub personal_message: Option<
546        MessageContent<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP>,
547    >,
548    pub status: AuthorizationStatusEnum,
549}
550#[cfg(all(feature = "validate", not(feature = "alloc")))]
551impl<
552    CustomDataType,
553    const ID_TOKEN_INFO_EVSE_ID_CAP: usize,
554    const ID_TOKEN_ADDITIONAL_INFO_CAP: usize,
555    const MESSAGE_CONTENT_CONTENT_CAP: usize,
556> crate::validate::Validate
557for IdTokenInfo<
558    CustomDataType,
559    ID_TOKEN_INFO_EVSE_ID_CAP,
560    ID_TOKEN_ADDITIONAL_INFO_CAP,
561    MESSAGE_CONTENT_CONTENT_CAP,
562> {
563    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
564        if let Some(value) = &self.evse_id {
565            crate::validate::check_min_items(value.len(), 1usize)
566                .map_err(|error| error.in_field("evseId"))?;
567            for (index, item) in value.iter().enumerate() {
568                crate::validate::check_min_i64(*item, 0i64)
569                    .map_err(|error| error.in_index(index).in_field("evseId"))?;
570            }
571        }
572        if let Some(value) = &self.group_id_token {
573            crate::validate::Validate::validate(value)
574                .map_err(|error| error.in_field("groupIdToken"))?;
575        }
576        if let Some(value) = &self.personal_message {
577            crate::validate::Validate::validate(value)
578                .map_err(|error| error.in_field("personalMessage"))?;
579        }
580        crate::validate::Validate::validate(&self.status)
581            .map_err(|error| error.in_field("status"))?;
582        Ok(())
583    }
584}
585#[derive(Debug, Clone, PartialEq, Eq)]
586#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
587pub enum DayOfWeekEnum {
588    Monday,
589    Tuesday,
590    Wednesday,
591    Thursday,
592    Friday,
593    Saturday,
594    Sunday,
595}
596#[cfg(feature = "validate")]
597impl crate::validate::Validate for DayOfWeekEnum {
598    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
599        Ok(())
600    }
601}
602/// Type of EVSE (AC, DC) this tariff applies to.
603#[derive(Debug, Clone, PartialEq, Eq)]
604#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
605pub enum EvseKindEnum {
606    AC,
607    DC,
608}
609#[cfg(feature = "validate")]
610impl crate::validate::Validate for EvseKindEnum {
611    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
612        Ok(())
613    }
614}
615/// These conditions describe if and when a TariffEnergyType or TariffTimeType applies during a transaction.
616///
617/// When more than one restriction is set, they are to be treated as a logical AND. All need to be valid before this price is active.
618///
619/// For reverse energy flow (discharging) negative values of energy, power and current are used.
620///
621/// NOTE: _minXXX_ (where XXX = Kwh/A/Kw) must be read as "closest to zero", and _maxXXX_ as "furthest from zero". For example, a *charging* power range from 10 kW to 50 kWh is given by _minPower_ = 10000 and _maxPower_ = 50000, and a *discharging* power range from -10 kW to -50 kW is given by _minPower_ = -10 and _maxPower_ = -50.
622///
623/// NOTE: _startTimeOfDay_ and _endTimeOfDay_ are in local time, because it is the time in the tariff as it is shown to the EV driver at the Charging Station.
624/// A Charging Station will convert this to the internal time zone that it uses (which is recommended to be UTC, see section Generic chapter 3.1) when performing cost calculation.
625#[derive(Debug, Clone, PartialEq)]
626#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
627pub struct TariffConditions<CustomDataType = crate::NoCustomData> {
628    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
629    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
630    pub custom_data: Option<CustomDataType>,
631    /// Day(s) of the week this is tariff applies.
632    #[cfg_attr(feature = "serde", serde(rename = "dayOfWeek"))]
633    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
634    pub day_of_week: Option<heapless::Vec<DayOfWeekEnum, 7usize>>,
635    /// End time of day in local time. Same syntax as _startTimeOfDay_. +
636    ///     If end time &lt; start time then the period wraps around to the next day. +
637    ///     To stop at end of the day use: 00:00.
638    #[cfg_attr(feature = "serde", serde(rename = "endTimeOfDay"))]
639    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
640    pub end_time_of_day: Option<crate::OcppTimeOfDay>,
641    #[cfg_attr(feature = "serde", serde(rename = "evseKind"))]
642    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
643    pub evse_kind: Option<EvseKindEnum>,
644    /// Maximum duration in seconds the charging MUST last (exclusive).
645    ///       When the duration of a charging is shorter than the defined value, this price is or becomes active.
646    ///       After that moment, this price is no longer active.
647    #[cfg_attr(feature = "serde", serde(rename = "maxChargingTime"))]
648    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
649    pub max_charging_time: Option<i64>,
650    /// Sum of the maximum current (in Amperes) over all phases, for example 20 A.
651    ///       When the EV is charging with less than the defined amount of current, this price becomes/is active. If the charging current is or becomes higher, this price is not or no longer valid and becomes inactive.
652    ///       This is NOT about the maximum current over the entire transaction.
653    #[cfg_attr(feature = "serde", serde(rename = "maxCurrent"))]
654    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
655    pub max_current: Option<f64>,
656    /// Maximum consumed energy in Wh, for example 50000 Wh.
657    ///     Valid until this amount of energy (exclusive) being used.
658    #[cfg_attr(feature = "serde", serde(rename = "maxEnergy"))]
659    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
660    pub max_energy: Option<f64>,
661    /// Maximum duration in seconds the idle period (i.e. not charging) MUST last (exclusive).
662    ///       When the duration of idle time is shorter than the defined value, this price is or becomes active.
663    ///       After that moment, this price is no longer active.
664    #[cfg_attr(feature = "serde", serde(rename = "maxIdleTime"))]
665    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
666    pub max_idle_time: Option<i64>,
667    /// Maximum power in W, for example 20000 W.
668    ///       When the EV is charging with less than the defined amount of power, this price becomes/is active.
669    ///       If the charging power is or becomes higher, this price is not or no longer valid and becomes inactive.
670    ///       This is NOT about the maximum power over the entire transaction.
671    #[cfg_attr(feature = "serde", serde(rename = "maxPower"))]
672    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
673    pub max_power: Option<f64>,
674    /// Maximum duration in seconds the transaction (charging &amp; idle) MUST last (exclusive).
675    ///       When the duration of a transaction is shorter than the defined value, this price is or becomes active.
676    ///       After that moment, this price is no longer active.
677    #[cfg_attr(feature = "serde", serde(rename = "maxTime"))]
678    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
679    pub max_time: Option<i64>,
680    /// Minimum duration in seconds the charging MUST last (inclusive).
681    ///       When the duration of a charging is longer than the defined value, this price is or becomes active.
682    ///       Before that moment, this price is not yet active.
683    #[cfg_attr(feature = "serde", serde(rename = "minChargingTime"))]
684    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
685    pub min_charging_time: Option<i64>,
686    /// Sum of the minimum current (in Amperes) over all phases, for example 5 A.
687    ///     When the EV is charging with more than, or equal to, the defined amount of current, this price is/becomes active. If the charging current is or becomes lower, this price is not or no longer valid and becomes inactive. +
688    ///     This is NOT about the minimum current over the entire transaction.
689    #[cfg_attr(feature = "serde", serde(rename = "minCurrent"))]
690    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
691    pub min_current: Option<f64>,
692    /// Minimum consumed energy in Wh, for example 20000 Wh.
693    ///     Valid from this amount of energy (inclusive) being used.
694    #[cfg_attr(feature = "serde", serde(rename = "minEnergy"))]
695    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
696    pub min_energy: Option<f64>,
697    /// Minimum duration in seconds the idle period (i.e. not charging) MUST last (inclusive).
698    ///       When the duration of the idle time is longer than the defined value, this price is or becomes active.
699    ///       Before that moment, this price is not yet active.
700    #[cfg_attr(feature = "serde", serde(rename = "minIdleTime"))]
701    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
702    pub min_idle_time: Option<i64>,
703    /// Minimum power in W, for example 5000 W.
704    ///       When the EV is charging with more than, or equal to, the defined amount of power, this price is/becomes active.
705    ///       If the charging power is or becomes lower, this price is not or no longer valid and becomes inactive.
706    ///       This is NOT about the minimum power over the entire transaction.
707    #[cfg_attr(feature = "serde", serde(rename = "minPower"))]
708    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
709    pub min_power: Option<f64>,
710    /// Minimum duration in seconds the transaction (charging &amp; idle) MUST last (inclusive).
711    ///       When the duration of a transaction is longer than the defined value, this price is or becomes active.
712    ///       Before that moment, this price is not yet active.
713    #[cfg_attr(feature = "serde", serde(rename = "minTime"))]
714    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
715    pub min_time: Option<i64>,
716    /// Start time of day in local time. +
717    /// Format as per RFC 3339: time-hour ":" time-minute  +
718    /// Must be in 24h format with leading zeros. Hour/Minute separator: ":"
719    /// Regex: (\[0-1\]\[0-9\]\|2\[0-3\]):\[0-5\]\[0-9\]
720    #[cfg_attr(feature = "serde", serde(rename = "startTimeOfDay"))]
721    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
722    pub start_time_of_day: Option<crate::OcppTimeOfDay>,
723    /// Start date in local time, for example: 2015-12-24.
724    /// Valid from this day (inclusive). +
725    /// Format as per RFC 3339: full-date  +
726    ///
727    /// Regex: (\[12\]\[0-9\]{3})-(0\[1-9\]\|1\[0-2\])-(0\[1-9\]\|\[12\]\[0-9\]\|3\[01\])
728    #[cfg_attr(feature = "serde", serde(rename = "validFromDate"))]
729    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
730    pub valid_from_date: Option<crate::OcppDate>,
731    /// End date in local time, for example: 2015-12-27.
732    ///     Valid until this day (exclusive). Same syntax as _validFromDate_.
733    #[cfg_attr(feature = "serde", serde(rename = "validToDate"))]
734    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
735    pub valid_to_date: Option<crate::OcppDate>,
736}
737#[cfg(feature = "validate")]
738impl<CustomDataType> crate::validate::Validate for TariffConditions<CustomDataType> {
739    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
740        if let Some(value) = &self.day_of_week {
741            crate::validate::check_min_items(value.len(), 1usize)
742                .map_err(|error| error.in_field("dayOfWeek"))?;
743            for (index, item) in value.iter().enumerate() {
744                crate::validate::Validate::validate(item)
745                    .map_err(|error| error.in_index(index).in_field("dayOfWeek"))?;
746            }
747        }
748        if let Some(value) = &self.evse_kind {
749            crate::validate::Validate::validate(value)
750                .map_err(|error| error.in_field("evseKind"))?;
751        }
752        Ok(())
753    }
754}
755/// Tariff with optional conditions for a time duration price.
756#[derive(Debug, Clone, PartialEq)]
757#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
758pub struct TariffTimePrice<CustomDataType = crate::NoCustomData> {
759    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
760    pub conditions: Option<TariffConditions<CustomDataType>>,
761    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
762    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
763    pub custom_data: Option<CustomDataType>,
764    /// Price per minute (excl. tax) for this element.
765    #[cfg_attr(feature = "serde", serde(rename = "priceMinute"))]
766    pub price_minute: f64,
767}
768#[cfg(feature = "validate")]
769impl<CustomDataType> crate::validate::Validate for TariffTimePrice<CustomDataType> {
770    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
771        if let Some(value) = &self.conditions {
772            crate::validate::Validate::validate(value)
773                .map_err(|error| error.in_field("conditions"))?;
774        }
775        Ok(())
776    }
777}
778/// Tax percentage
779#[derive(Debug, Clone, PartialEq)]
780#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
781pub struct TaxRate<CustomDataType = crate::NoCustomData> {
782    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
783    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
784    pub custom_data: Option<CustomDataType>,
785    /// Stack level for this type of tax. Default value, when absent, is 0. +
786    /// _stack_ = 0: tax on net price; +
787    /// _stack_ = 1: tax added on top of _stack_ 0; +
788    /// _stack_ = 2: tax added on top of _stack_ 1, etc.
789    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
790    pub stack: Option<i64>,
791    /// Tax percentage
792    pub tax: f64,
793    /// Type of this tax, e.g.  "Federal ",  "State", for information on receipt.
794    pub r#type: heapless::String<20usize>,
795}
796#[cfg(feature = "validate")]
797impl<CustomDataType> crate::validate::Validate for TaxRate<CustomDataType> {
798    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
799        if let Some(value) = self.stack {
800            crate::validate::check_min_i64(value, 0i64)
801                .map_err(|error| error.in_field("stack"))?;
802        }
803        Ok(())
804    }
805}
806#[cfg(feature = "alloc")]
807/// Price elements and tax for time
808#[derive(Debug, Clone, PartialEq)]
809#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
810pub struct TariffTime<CustomDataType = crate::NoCustomData> {
811    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
812    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
813    pub custom_data: Option<CustomDataType>,
814    pub prices: alloc::vec::Vec<TariffTimePrice<CustomDataType>>,
815    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
816    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
817    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
818}
819#[cfg(all(feature = "validate", feature = "alloc"))]
820impl<CustomDataType> crate::validate::Validate for TariffTime<CustomDataType> {
821    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
822        crate::validate::check_min_items(self.prices.len(), 1usize)
823            .map_err(|error| error.in_field("prices"))?;
824        for (index, item) in self.prices.iter().enumerate() {
825            crate::validate::Validate::validate(item)
826                .map_err(|error| error.in_index(index).in_field("prices"))?;
827        }
828        if let Some(value) = &self.tax_rates {
829            crate::validate::check_min_items(value.len(), 1usize)
830                .map_err(|error| error.in_field("taxRates"))?;
831            for (index, item) in value.iter().enumerate() {
832                crate::validate::Validate::validate(item)
833                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
834            }
835        }
836        Ok(())
837    }
838}
839#[cfg(not(feature = "alloc"))]
840/// Price elements and tax for time
841#[derive(Debug, Clone, PartialEq)]
842#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
843pub struct TariffTime<
844    CustomDataType = crate::NoCustomData,
845    const TARIFF_TIME_PRICES_CAP: usize = 8usize,
846> {
847    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
848    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
849    pub custom_data: Option<CustomDataType>,
850    pub prices: heapless::Vec<TariffTimePrice<CustomDataType>, TARIFF_TIME_PRICES_CAP>,
851    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
852    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
853    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
854}
855#[cfg(all(feature = "validate", not(feature = "alloc")))]
856impl<CustomDataType, const TARIFF_TIME_PRICES_CAP: usize> crate::validate::Validate
857for TariffTime<CustomDataType, TARIFF_TIME_PRICES_CAP> {
858    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
859        crate::validate::check_min_items(self.prices.len(), 1usize)
860            .map_err(|error| error.in_field("prices"))?;
861        for (index, item) in self.prices.iter().enumerate() {
862            crate::validate::Validate::validate(item)
863                .map_err(|error| error.in_index(index).in_field("prices"))?;
864        }
865        if let Some(value) = &self.tax_rates {
866            crate::validate::check_min_items(value.len(), 1usize)
867                .map_err(|error| error.in_field("taxRates"))?;
868            for (index, item) in value.iter().enumerate() {
869                crate::validate::Validate::validate(item)
870                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
871            }
872        }
873        Ok(())
874    }
875}
876/// Tariff with optional conditions for an energy price.
877#[derive(Debug, Clone, PartialEq)]
878#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
879pub struct TariffEnergyPrice<CustomDataType = crate::NoCustomData> {
880    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
881    pub conditions: Option<TariffConditions<CustomDataType>>,
882    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
883    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
884    pub custom_data: Option<CustomDataType>,
885    /// Price per kWh (excl. tax) for this element.
886    #[cfg_attr(feature = "serde", serde(rename = "priceKwh"))]
887    pub price_kwh: f64,
888}
889#[cfg(feature = "validate")]
890impl<CustomDataType> crate::validate::Validate for TariffEnergyPrice<CustomDataType> {
891    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
892        if let Some(value) = &self.conditions {
893            crate::validate::Validate::validate(value)
894                .map_err(|error| error.in_field("conditions"))?;
895        }
896        Ok(())
897    }
898}
899#[cfg(feature = "alloc")]
900/// Price elements and tax for energy
901#[derive(Debug, Clone, PartialEq)]
902#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
903pub struct TariffEnergy<CustomDataType = crate::NoCustomData> {
904    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
905    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
906    pub custom_data: Option<CustomDataType>,
907    pub prices: alloc::vec::Vec<TariffEnergyPrice<CustomDataType>>,
908    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
909    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
910    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
911}
912#[cfg(all(feature = "validate", feature = "alloc"))]
913impl<CustomDataType> crate::validate::Validate for TariffEnergy<CustomDataType> {
914    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
915        crate::validate::check_min_items(self.prices.len(), 1usize)
916            .map_err(|error| error.in_field("prices"))?;
917        for (index, item) in self.prices.iter().enumerate() {
918            crate::validate::Validate::validate(item)
919                .map_err(|error| error.in_index(index).in_field("prices"))?;
920        }
921        if let Some(value) = &self.tax_rates {
922            crate::validate::check_min_items(value.len(), 1usize)
923                .map_err(|error| error.in_field("taxRates"))?;
924            for (index, item) in value.iter().enumerate() {
925                crate::validate::Validate::validate(item)
926                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
927            }
928        }
929        Ok(())
930    }
931}
932#[cfg(not(feature = "alloc"))]
933/// Price elements and tax for energy
934#[derive(Debug, Clone, PartialEq)]
935#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
936pub struct TariffEnergy<
937    CustomDataType = crate::NoCustomData,
938    const TARIFF_ENERGY_PRICES_CAP: usize = 8usize,
939> {
940    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
941    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
942    pub custom_data: Option<CustomDataType>,
943    pub prices: heapless::Vec<
944        TariffEnergyPrice<CustomDataType>,
945        TARIFF_ENERGY_PRICES_CAP,
946    >,
947    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
948    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
949    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
950}
951#[cfg(all(feature = "validate", not(feature = "alloc")))]
952impl<CustomDataType, const TARIFF_ENERGY_PRICES_CAP: usize> crate::validate::Validate
953for TariffEnergy<CustomDataType, TARIFF_ENERGY_PRICES_CAP> {
954    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
955        crate::validate::check_min_items(self.prices.len(), 1usize)
956            .map_err(|error| error.in_field("prices"))?;
957        for (index, item) in self.prices.iter().enumerate() {
958            crate::validate::Validate::validate(item)
959                .map_err(|error| error.in_index(index).in_field("prices"))?;
960        }
961        if let Some(value) = &self.tax_rates {
962            crate::validate::check_min_items(value.len(), 1usize)
963                .map_err(|error| error.in_field("taxRates"))?;
964            for (index, item) in value.iter().enumerate() {
965                crate::validate::Validate::validate(item)
966                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
967            }
968        }
969        Ok(())
970    }
971}
972/// These conditions describe if a FixedPrice applies at start of the transaction.
973///
974/// When more than one restriction is set, they are to be treated as a logical AND. All need to be valid before this price is active.
975///
976/// NOTE: _startTimeOfDay_ and _endTimeOfDay_ are in local time, because it is the time in the tariff as it is shown to the EV driver at the Charging Station.
977/// A Charging Station will convert this to the internal time zone that it uses (which is recommended to be UTC, see section Generic chapter 3.1) when performing cost calculation.
978#[derive(Debug, Clone, PartialEq, Eq)]
979#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
980pub struct TariffConditionsFixed<CustomDataType = crate::NoCustomData> {
981    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
982    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
983    pub custom_data: Option<CustomDataType>,
984    /// Day(s) of the week this is tariff applies.
985    #[cfg_attr(feature = "serde", serde(rename = "dayOfWeek"))]
986    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
987    pub day_of_week: Option<heapless::Vec<DayOfWeekEnum, 7usize>>,
988    /// End time of day in local time. Same syntax as _startTimeOfDay_. +
989    ///     If end time &lt; start time then the period wraps around to the next day. +
990    ///     To stop at end of the day use: 00:00.
991    #[cfg_attr(feature = "serde", serde(rename = "endTimeOfDay"))]
992    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
993    pub end_time_of_day: Option<crate::OcppTimeOfDay>,
994    #[cfg_attr(feature = "serde", serde(rename = "evseKind"))]
995    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
996    pub evse_kind: Option<EvseKindEnum>,
997    /// For which payment brand this (adhoc) tariff applies. Can be used to add a surcharge for certain payment brands.
998    ///     Based on value of _additionalIdToken_ from _idToken.additionalInfo.type_ = "PaymentBrand".
999    #[cfg_attr(feature = "serde", serde(rename = "paymentBrand"))]
1000    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1001    pub payment_brand: Option<heapless::String<20usize>>,
1002    /// Type of adhoc payment, e.g. CC, Debit.
1003    ///     Based on value of _additionalIdToken_ from _idToken.additionalInfo.type_ = "PaymentRecognition".
1004    #[cfg_attr(feature = "serde", serde(rename = "paymentRecognition"))]
1005    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1006    pub payment_recognition: Option<heapless::String<20usize>>,
1007    /// Start time of day in local time. +
1008    /// Format as per RFC 3339: time-hour ":" time-minute  +
1009    /// Must be in 24h format with leading zeros. Hour/Minute separator: ":"
1010    /// Regex: (\[0-1\]\[0-9\]\|2\[0-3\]):\[0-5\]\[0-9\]
1011    #[cfg_attr(feature = "serde", serde(rename = "startTimeOfDay"))]
1012    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1013    pub start_time_of_day: Option<crate::OcppTimeOfDay>,
1014    /// Start date in local time, for example: 2015-12-24.
1015    /// Valid from this day (inclusive). +
1016    /// Format as per RFC 3339: full-date  +
1017    ///
1018    /// Regex: (\[12\]\[0-9\]{3})-(0\[1-9\]\|1\[0-2\])-(0\[1-9\]\|\[12\]\[0-9\]\|3\[01\])
1019    #[cfg_attr(feature = "serde", serde(rename = "validFromDate"))]
1020    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1021    pub valid_from_date: Option<crate::OcppDate>,
1022    /// End date in local time, for example: 2015-12-27.
1023    ///     Valid until this day (exclusive). Same syntax as _validFromDate_.
1024    #[cfg_attr(feature = "serde", serde(rename = "validToDate"))]
1025    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1026    pub valid_to_date: Option<crate::OcppDate>,
1027}
1028#[cfg(feature = "validate")]
1029impl<CustomDataType> crate::validate::Validate
1030for TariffConditionsFixed<CustomDataType> {
1031    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1032        if let Some(value) = &self.day_of_week {
1033            crate::validate::check_min_items(value.len(), 1usize)
1034                .map_err(|error| error.in_field("dayOfWeek"))?;
1035            for (index, item) in value.iter().enumerate() {
1036                crate::validate::Validate::validate(item)
1037                    .map_err(|error| error.in_index(index).in_field("dayOfWeek"))?;
1038            }
1039        }
1040        if let Some(value) = &self.evse_kind {
1041            crate::validate::Validate::validate(value)
1042                .map_err(|error| error.in_field("evseKind"))?;
1043        }
1044        Ok(())
1045    }
1046}
1047/// Tariff with optional conditions for a fixed price.
1048#[derive(Debug, Clone, PartialEq)]
1049#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1050pub struct TariffFixedPrice<CustomDataType = crate::NoCustomData> {
1051    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1052    pub conditions: Option<TariffConditionsFixed<CustomDataType>>,
1053    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1054    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1055    pub custom_data: Option<CustomDataType>,
1056    /// Fixed price  for this element e.g. a start fee.
1057    #[cfg_attr(feature = "serde", serde(rename = "priceFixed"))]
1058    pub price_fixed: f64,
1059}
1060#[cfg(feature = "validate")]
1061impl<CustomDataType> crate::validate::Validate for TariffFixedPrice<CustomDataType> {
1062    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1063        if let Some(value) = &self.conditions {
1064            crate::validate::Validate::validate(value)
1065                .map_err(|error| error.in_field("conditions"))?;
1066        }
1067        Ok(())
1068    }
1069}
1070#[cfg(feature = "alloc")]
1071#[derive(Debug, Clone, PartialEq)]
1072#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1073pub struct TariffFixed<CustomDataType = crate::NoCustomData> {
1074    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1075    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1076    pub custom_data: Option<CustomDataType>,
1077    pub prices: alloc::vec::Vec<TariffFixedPrice<CustomDataType>>,
1078    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
1079    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1080    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
1081}
1082#[cfg(all(feature = "validate", feature = "alloc"))]
1083impl<CustomDataType> crate::validate::Validate for TariffFixed<CustomDataType> {
1084    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1085        crate::validate::check_min_items(self.prices.len(), 1usize)
1086            .map_err(|error| error.in_field("prices"))?;
1087        for (index, item) in self.prices.iter().enumerate() {
1088            crate::validate::Validate::validate(item)
1089                .map_err(|error| error.in_index(index).in_field("prices"))?;
1090        }
1091        if let Some(value) = &self.tax_rates {
1092            crate::validate::check_min_items(value.len(), 1usize)
1093                .map_err(|error| error.in_field("taxRates"))?;
1094            for (index, item) in value.iter().enumerate() {
1095                crate::validate::Validate::validate(item)
1096                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
1097            }
1098        }
1099        Ok(())
1100    }
1101}
1102#[cfg(not(feature = "alloc"))]
1103#[derive(Debug, Clone, PartialEq)]
1104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1105pub struct TariffFixed<
1106    CustomDataType = crate::NoCustomData,
1107    const TARIFF_FIXED_PRICES_CAP: usize = 8usize,
1108> {
1109    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1110    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1111    pub custom_data: Option<CustomDataType>,
1112    pub prices: heapless::Vec<TariffFixedPrice<CustomDataType>, TARIFF_FIXED_PRICES_CAP>,
1113    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
1114    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1115    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
1116}
1117#[cfg(all(feature = "validate", not(feature = "alloc")))]
1118impl<CustomDataType, const TARIFF_FIXED_PRICES_CAP: usize> crate::validate::Validate
1119for TariffFixed<CustomDataType, TARIFF_FIXED_PRICES_CAP> {
1120    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1121        crate::validate::check_min_items(self.prices.len(), 1usize)
1122            .map_err(|error| error.in_field("prices"))?;
1123        for (index, item) in self.prices.iter().enumerate() {
1124            crate::validate::Validate::validate(item)
1125                .map_err(|error| error.in_index(index).in_field("prices"))?;
1126        }
1127        if let Some(value) = &self.tax_rates {
1128            crate::validate::check_min_items(value.len(), 1usize)
1129                .map_err(|error| error.in_field("taxRates"))?;
1130            for (index, item) in value.iter().enumerate() {
1131                crate::validate::Validate::validate(item)
1132                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
1133            }
1134        }
1135        Ok(())
1136    }
1137}
1138/// Price with and without tax. At least one of _exclTax_, _inclTax_ must be present.
1139#[derive(Debug, Clone, PartialEq)]
1140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1141pub struct Price<CustomDataType = crate::NoCustomData> {
1142    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1143    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1144    pub custom_data: Option<CustomDataType>,
1145    /// Price/cost excluding tax. Can be absent if _inclTax_ is present.
1146    #[cfg_attr(feature = "serde", serde(rename = "exclTax"))]
1147    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1148    pub excl_tax: Option<f64>,
1149    /// Price/cost including tax. Can be absent if _exclTax_ is present.
1150    #[cfg_attr(feature = "serde", serde(rename = "inclTax"))]
1151    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1152    pub incl_tax: Option<f64>,
1153    #[cfg_attr(feature = "serde", serde(rename = "taxRates"))]
1154    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1155    pub tax_rates: Option<heapless::Vec<TaxRate<CustomDataType>, 5usize>>,
1156}
1157#[cfg(feature = "validate")]
1158impl<CustomDataType> crate::validate::Validate for Price<CustomDataType> {
1159    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1160        if let Some(value) = &self.tax_rates {
1161            crate::validate::check_min_items(value.len(), 1usize)
1162                .map_err(|error| error.in_field("taxRates"))?;
1163            for (index, item) in value.iter().enumerate() {
1164                crate::validate::Validate::validate(item)
1165                    .map_err(|error| error.in_index(index).in_field("taxRates"))?;
1166            }
1167        }
1168        Ok(())
1169    }
1170}
1171#[cfg(feature = "alloc")]
1172/// A tariff is described by fields with prices for:
1173/// energy,
1174/// charging time,
1175/// idle time,
1176/// fixed fee,
1177/// reservation time,
1178/// reservation fixed fee. +
1179/// Each of these fields may have (optional) conditions that specify when a price is applicable. +
1180/// The _description_ contains a human-readable explanation of the tariff to be shown to the user. +
1181/// The other fields are parameters that define the tariff. These are used by the charging station to calculate the price.
1182#[derive(Debug, Clone, PartialEq)]
1183#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1184pub struct Tariff<CustomDataType = crate::NoCustomData> {
1185    #[cfg_attr(feature = "serde", serde(rename = "chargingTime"))]
1186    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1187    pub charging_time: Option<TariffTime<CustomDataType>>,
1188    /// Currency code according to ISO 4217
1189    pub currency: heapless::String<3usize>,
1190    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1191    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1192    pub custom_data: Option<CustomDataType>,
1193    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1194    pub description: Option<heapless::Vec<MessageContent<CustomDataType>, 10usize>>,
1195    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1196    pub energy: Option<TariffEnergy<CustomDataType>>,
1197    #[cfg_attr(feature = "serde", serde(rename = "fixedFee"))]
1198    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1199    pub fixed_fee: Option<TariffFixed<CustomDataType>>,
1200    #[cfg_attr(feature = "serde", serde(rename = "idleTime"))]
1201    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1202    pub idle_time: Option<TariffTime<CustomDataType>>,
1203    #[cfg_attr(feature = "serde", serde(rename = "maxCost"))]
1204    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1205    pub max_cost: Option<Price<CustomDataType>>,
1206    #[cfg_attr(feature = "serde", serde(rename = "minCost"))]
1207    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1208    pub min_cost: Option<Price<CustomDataType>>,
1209    #[cfg_attr(feature = "serde", serde(rename = "reservationFixed"))]
1210    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1211    pub reservation_fixed: Option<TariffFixed<CustomDataType>>,
1212    #[cfg_attr(feature = "serde", serde(rename = "reservationTime"))]
1213    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1214    pub reservation_time: Option<TariffTime<CustomDataType>>,
1215    /// Unique id of tariff
1216    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
1217    pub tariff_id: heapless::String<60usize>,
1218    /// Time when this tariff becomes active. When absent, it is immediately active.
1219    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
1220    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1221    pub valid_from: Option<crate::OcppTimestamp>,
1222}
1223#[cfg(all(feature = "validate", feature = "alloc"))]
1224impl<CustomDataType> crate::validate::Validate for Tariff<CustomDataType> {
1225    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1226        if let Some(value) = &self.charging_time {
1227            crate::validate::Validate::validate(value)
1228                .map_err(|error| error.in_field("chargingTime"))?;
1229        }
1230        if let Some(value) = &self.description {
1231            crate::validate::check_min_items(value.len(), 1usize)
1232                .map_err(|error| error.in_field("description"))?;
1233            for (index, item) in value.iter().enumerate() {
1234                crate::validate::Validate::validate(item)
1235                    .map_err(|error| error.in_index(index).in_field("description"))?;
1236            }
1237        }
1238        if let Some(value) = &self.energy {
1239            crate::validate::Validate::validate(value)
1240                .map_err(|error| error.in_field("energy"))?;
1241        }
1242        if let Some(value) = &self.fixed_fee {
1243            crate::validate::Validate::validate(value)
1244                .map_err(|error| error.in_field("fixedFee"))?;
1245        }
1246        if let Some(value) = &self.idle_time {
1247            crate::validate::Validate::validate(value)
1248                .map_err(|error| error.in_field("idleTime"))?;
1249        }
1250        if let Some(value) = &self.max_cost {
1251            crate::validate::Validate::validate(value)
1252                .map_err(|error| error.in_field("maxCost"))?;
1253        }
1254        if let Some(value) = &self.min_cost {
1255            crate::validate::Validate::validate(value)
1256                .map_err(|error| error.in_field("minCost"))?;
1257        }
1258        if let Some(value) = &self.reservation_fixed {
1259            crate::validate::Validate::validate(value)
1260                .map_err(|error| error.in_field("reservationFixed"))?;
1261        }
1262        if let Some(value) = &self.reservation_time {
1263            crate::validate::Validate::validate(value)
1264                .map_err(|error| error.in_field("reservationTime"))?;
1265        }
1266        Ok(())
1267    }
1268}
1269#[cfg(not(feature = "alloc"))]
1270/// A tariff is described by fields with prices for:
1271/// energy,
1272/// charging time,
1273/// idle time,
1274/// fixed fee,
1275/// reservation time,
1276/// reservation fixed fee. +
1277/// Each of these fields may have (optional) conditions that specify when a price is applicable. +
1278/// The _description_ contains a human-readable explanation of the tariff to be shown to the user. +
1279/// The other fields are parameters that define the tariff. These are used by the charging station to calculate the price.
1280#[derive(Debug, Clone, PartialEq)]
1281#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1282pub struct Tariff<
1283    CustomDataType = crate::NoCustomData,
1284    const TARIFF_TIME_PRICES_CAP: usize = 8usize,
1285    const MESSAGE_CONTENT_CONTENT_CAP: usize = 1024usize,
1286    const TARIFF_ENERGY_PRICES_CAP: usize = 8usize,
1287    const TARIFF_FIXED_PRICES_CAP: usize = 8usize,
1288> {
1289    #[cfg_attr(feature = "serde", serde(rename = "chargingTime"))]
1290    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1291    pub charging_time: Option<TariffTime<CustomDataType, TARIFF_TIME_PRICES_CAP>>,
1292    /// Currency code according to ISO 4217
1293    pub currency: heapless::String<3usize>,
1294    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1295    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1296    pub custom_data: Option<CustomDataType>,
1297    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1298    pub description: Option<
1299        heapless::Vec<
1300            MessageContent<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP>,
1301            10usize,
1302        >,
1303    >,
1304    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1305    pub energy: Option<TariffEnergy<CustomDataType, TARIFF_ENERGY_PRICES_CAP>>,
1306    #[cfg_attr(feature = "serde", serde(rename = "fixedFee"))]
1307    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1308    pub fixed_fee: Option<TariffFixed<CustomDataType, TARIFF_FIXED_PRICES_CAP>>,
1309    #[cfg_attr(feature = "serde", serde(rename = "idleTime"))]
1310    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1311    pub idle_time: Option<TariffTime<CustomDataType, TARIFF_TIME_PRICES_CAP>>,
1312    #[cfg_attr(feature = "serde", serde(rename = "maxCost"))]
1313    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1314    pub max_cost: Option<Price<CustomDataType>>,
1315    #[cfg_attr(feature = "serde", serde(rename = "minCost"))]
1316    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1317    pub min_cost: Option<Price<CustomDataType>>,
1318    #[cfg_attr(feature = "serde", serde(rename = "reservationFixed"))]
1319    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1320    pub reservation_fixed: Option<TariffFixed<CustomDataType, TARIFF_FIXED_PRICES_CAP>>,
1321    #[cfg_attr(feature = "serde", serde(rename = "reservationTime"))]
1322    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1323    pub reservation_time: Option<TariffTime<CustomDataType, TARIFF_TIME_PRICES_CAP>>,
1324    /// Unique id of tariff
1325    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
1326    pub tariff_id: heapless::String<60usize>,
1327    /// Time when this tariff becomes active. When absent, it is immediately active.
1328    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
1329    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1330    pub valid_from: Option<crate::OcppTimestamp>,
1331}
1332#[cfg(all(feature = "validate", not(feature = "alloc")))]
1333impl<
1334    CustomDataType,
1335    const TARIFF_TIME_PRICES_CAP: usize,
1336    const MESSAGE_CONTENT_CONTENT_CAP: usize,
1337    const TARIFF_ENERGY_PRICES_CAP: usize,
1338    const TARIFF_FIXED_PRICES_CAP: usize,
1339> crate::validate::Validate
1340for Tariff<
1341    CustomDataType,
1342    TARIFF_TIME_PRICES_CAP,
1343    MESSAGE_CONTENT_CONTENT_CAP,
1344    TARIFF_ENERGY_PRICES_CAP,
1345    TARIFF_FIXED_PRICES_CAP,
1346> {
1347    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1348        if let Some(value) = &self.charging_time {
1349            crate::validate::Validate::validate(value)
1350                .map_err(|error| error.in_field("chargingTime"))?;
1351        }
1352        if let Some(value) = &self.description {
1353            crate::validate::check_min_items(value.len(), 1usize)
1354                .map_err(|error| error.in_field("description"))?;
1355            for (index, item) in value.iter().enumerate() {
1356                crate::validate::Validate::validate(item)
1357                    .map_err(|error| error.in_index(index).in_field("description"))?;
1358            }
1359        }
1360        if let Some(value) = &self.energy {
1361            crate::validate::Validate::validate(value)
1362                .map_err(|error| error.in_field("energy"))?;
1363        }
1364        if let Some(value) = &self.fixed_fee {
1365            crate::validate::Validate::validate(value)
1366                .map_err(|error| error.in_field("fixedFee"))?;
1367        }
1368        if let Some(value) = &self.idle_time {
1369            crate::validate::Validate::validate(value)
1370                .map_err(|error| error.in_field("idleTime"))?;
1371        }
1372        if let Some(value) = &self.max_cost {
1373            crate::validate::Validate::validate(value)
1374                .map_err(|error| error.in_field("maxCost"))?;
1375        }
1376        if let Some(value) = &self.min_cost {
1377            crate::validate::Validate::validate(value)
1378                .map_err(|error| error.in_field("minCost"))?;
1379        }
1380        if let Some(value) = &self.reservation_fixed {
1381            crate::validate::Validate::validate(value)
1382                .map_err(|error| error.in_field("reservationFixed"))?;
1383        }
1384        if let Some(value) = &self.reservation_time {
1385            crate::validate::Validate::validate(value)
1386                .map_err(|error| error.in_field("reservationTime"))?;
1387        }
1388        Ok(())
1389    }
1390}
1391#[derive(Debug, Clone, PartialEq)]
1392#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1393pub struct BatteryData<CustomDataType = crate::NoCustomData> {
1394    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1395    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1396    pub custom_data: Option<CustomDataType>,
1397    /// Slot number where battery is inserted or removed.
1398    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
1399    pub evse_id: i64,
1400    /// Production date of battery.
1401    #[cfg_attr(feature = "serde", serde(rename = "productionDate"))]
1402    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1403    pub production_date: Option<crate::OcppTimestamp>,
1404    /// Serial number of battery.
1405    #[cfg_attr(feature = "serde", serde(rename = "serialNumber"))]
1406    pub serial_number: heapless::String<50usize>,
1407    /// State of charge
1408    #[cfg_attr(feature = "serde", serde(rename = "soC"))]
1409    pub so_c: f64,
1410    /// State of health
1411    #[cfg_attr(feature = "serde", serde(rename = "soH"))]
1412    pub so_h: f64,
1413    /// Vendor-specific info from battery in undefined format.
1414    #[cfg_attr(feature = "serde", serde(rename = "vendorInfo"))]
1415    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1416    pub vendor_info: Option<heapless::String<500usize>>,
1417}
1418#[cfg(feature = "validate")]
1419impl<CustomDataType> crate::validate::Validate for BatteryData<CustomDataType> {
1420    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1421        crate::validate::check_min_i64(self.evse_id, 0i64)
1422            .map_err(|error| error.in_field("evseId"))?;
1423        crate::validate::check_min_f64(self.so_c, 0f64)
1424            .map_err(|error| error.in_field("soC"))?;
1425        crate::validate::check_max_f64(self.so_c, 100f64)
1426            .map_err(|error| error.in_field("soC"))?;
1427        crate::validate::check_min_f64(self.so_h, 0f64)
1428            .map_err(|error| error.in_field("soH"))?;
1429        crate::validate::check_max_f64(self.so_h, 100f64)
1430            .map_err(|error| error.in_field("soH"))?;
1431        Ok(())
1432    }
1433}
1434/// Battery in/out
1435#[derive(Debug, Clone, PartialEq, Eq)]
1436#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1437pub enum BatterySwapEventEnum {
1438    BatteryIn,
1439    BatteryOut,
1440    BatteryOutTimeout,
1441}
1442#[cfg(feature = "validate")]
1443impl crate::validate::Validate for BatterySwapEventEnum {
1444    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1445        Ok(())
1446    }
1447}
1448/// Defines parameters required for initiating and maintaining wireless communication with other devices.
1449#[derive(Debug, Clone, PartialEq, Eq)]
1450#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1451pub struct Modem<CustomDataType = crate::NoCustomData> {
1452    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1453    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1454    pub custom_data: Option<CustomDataType>,
1455    /// This contains the ICCID of the modem’s SIM card.
1456    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1457    pub iccid: Option<heapless::String<20usize>>,
1458    /// This contains the IMSI of the modem’s SIM card.
1459    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1460    pub imsi: Option<heapless::String<20usize>>,
1461}
1462#[cfg(feature = "validate")]
1463impl<CustomDataType> crate::validate::Validate for Modem<CustomDataType> {
1464    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1465        Ok(())
1466    }
1467}
1468/// The physical system where an Electrical Vehicle (EV) can be charged.
1469#[derive(Debug, Clone, PartialEq, Eq)]
1470#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1471pub struct ChargingStation<CustomDataType = crate::NoCustomData> {
1472    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1473    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1474    pub custom_data: Option<CustomDataType>,
1475    /// This contains the firmware version of the Charging Station.
1476    #[cfg_attr(feature = "serde", serde(rename = "firmwareVersion"))]
1477    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1478    pub firmware_version: Option<heapless::String<50usize>>,
1479    /// Defines the model of the device.
1480    pub model: heapless::String<20usize>,
1481    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1482    pub modem: Option<Modem<CustomDataType>>,
1483    /// Vendor-specific device identifier.
1484    #[cfg_attr(feature = "serde", serde(rename = "serialNumber"))]
1485    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1486    pub serial_number: Option<heapless::String<25usize>>,
1487    /// Identifies the vendor (not necessarily in a unique manner).
1488    #[cfg_attr(feature = "serde", serde(rename = "vendorName"))]
1489    pub vendor_name: heapless::String<50usize>,
1490}
1491#[cfg(feature = "validate")]
1492impl<CustomDataType> crate::validate::Validate for ChargingStation<CustomDataType> {
1493    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1494        if let Some(value) = &self.modem {
1495            crate::validate::Validate::validate(value)
1496                .map_err(|error| error.in_field("modem"))?;
1497        }
1498        Ok(())
1499    }
1500}
1501/// This contains the reason for sending this message to the CSMS.
1502#[derive(Debug, Clone, PartialEq, Eq)]
1503#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1504pub enum BootReasonEnum {
1505    ApplicationReset,
1506    FirmwareUpdate,
1507    LocalReset,
1508    PowerUp,
1509    RemoteReset,
1510    ScheduledReset,
1511    Triggered,
1512    Unknown,
1513    Watchdog,
1514}
1515#[cfg(feature = "validate")]
1516impl crate::validate::Validate for BootReasonEnum {
1517    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1518        Ok(())
1519    }
1520}
1521/// This contains whether the Charging Station has been registered
1522/// within the CSMS.
1523#[derive(Debug, Clone, PartialEq, Eq)]
1524#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1525pub enum RegistrationStatusEnum {
1526    Accepted,
1527    Pending,
1528    Rejected,
1529}
1530#[cfg(feature = "validate")]
1531impl crate::validate::Validate for RegistrationStatusEnum {
1532    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1533        Ok(())
1534    }
1535}
1536/// This indicates the success or failure of the canceling of a reservation by CSMS.
1537#[derive(Debug, Clone, PartialEq, Eq)]
1538#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1539pub enum CancelReservationStatusEnum {
1540    Accepted,
1541    Rejected,
1542}
1543#[cfg(feature = "validate")]
1544impl crate::validate::Validate for CancelReservationStatusEnum {
1545    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1546        Ok(())
1547    }
1548}
1549/// Indicates the type of the signed certificate that is returned. When omitted the certificate is used for both the 15118 connection (if implemented) and the Charging Station to CSMS connection. This field is required when a typeOfCertificate was included in the &lt;&lt;signcertificaterequest,SignCertificateRequest&gt;&gt; that requested this certificate to be signed AND both the 15118 connection and the Charging Station connection are implemented.
1550#[derive(Debug, Clone, PartialEq, Eq)]
1551#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1552pub enum CertificateSigningUseEnum {
1553    ChargingStationCertificate,
1554    V2GCertificate,
1555    V2G20Certificate,
1556}
1557#[cfg(feature = "validate")]
1558impl crate::validate::Validate for CertificateSigningUseEnum {
1559    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1560        Ok(())
1561    }
1562}
1563/// Returns whether certificate signing has been accepted, otherwise rejected.
1564#[derive(Debug, Clone, PartialEq, Eq)]
1565#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1566pub enum CertificateSignedStatusEnum {
1567    Accepted,
1568    Rejected,
1569}
1570#[cfg(feature = "validate")]
1571impl crate::validate::Validate for CertificateSignedStatusEnum {
1572    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1573        Ok(())
1574    }
1575}
1576/// Electric Vehicle Supply Equipment
1577#[derive(Debug, Clone, PartialEq, Eq)]
1578#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1579pub struct EVSE<CustomDataType = crate::NoCustomData> {
1580    /// An id to designate a specific connector (on an EVSE) by connector index number.
1581    #[cfg_attr(feature = "serde", serde(rename = "connectorId"))]
1582    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1583    pub connector_id: Option<i64>,
1584    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1585    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1586    pub custom_data: Option<CustomDataType>,
1587    /// EVSE Identifier. This contains a number (&gt; 0) designating an EVSE of the Charging Station.
1588    pub id: i64,
1589}
1590#[cfg(feature = "validate")]
1591impl<CustomDataType> crate::validate::Validate for EVSE<CustomDataType> {
1592    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1593        if let Some(value) = self.connector_id {
1594            crate::validate::check_min_i64(value, 0i64)
1595                .map_err(|error| error.in_field("connectorId"))?;
1596        }
1597        crate::validate::check_min_i64(self.id, 0i64)
1598            .map_err(|error| error.in_field("id"))?;
1599        Ok(())
1600    }
1601}
1602/// This contains the type of availability change that the Charging Station should perform.
1603#[derive(Debug, Clone, PartialEq, Eq)]
1604#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1605pub enum OperationalStatusEnum {
1606    Inoperative,
1607    Operative,
1608}
1609#[cfg(feature = "validate")]
1610impl crate::validate::Validate for OperationalStatusEnum {
1611    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1612        Ok(())
1613    }
1614}
1615/// This indicates whether the Charging Station is able to perform the availability change.
1616#[derive(Debug, Clone, PartialEq, Eq)]
1617#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1618pub enum ChangeAvailabilityStatusEnum {
1619    Accepted,
1620    Rejected,
1621    Scheduled,
1622}
1623#[cfg(feature = "validate")]
1624impl crate::validate::Validate for ChangeAvailabilityStatusEnum {
1625    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1626        Ok(())
1627    }
1628}
1629/// Status of the operation
1630#[derive(Debug, Clone, PartialEq, Eq)]
1631#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1632pub enum TariffChangeStatusEnum {
1633    Accepted,
1634    Rejected,
1635    TooManyElements,
1636    ConditionNotSupported,
1637    TxNotFound,
1638    NoCurrencyChange,
1639}
1640#[cfg(feature = "validate")]
1641impl crate::validate::Validate for TariffChangeStatusEnum {
1642    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1643        Ok(())
1644    }
1645}
1646/// Accepted if the Charging Station has executed the request, otherwise rejected.
1647#[derive(Debug, Clone, PartialEq, Eq)]
1648#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1649pub enum ClearCacheStatusEnum {
1650    Accepted,
1651    Rejected,
1652}
1653#[cfg(feature = "validate")]
1654impl crate::validate::Validate for ClearCacheStatusEnum {
1655    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1656        Ok(())
1657    }
1658}
1659/// Specifies to purpose of the charging profiles that will be cleared, if they meet the other criteria in the request.
1660#[derive(Debug, Clone, PartialEq, Eq)]
1661#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1662pub enum ChargingProfilePurposeEnum {
1663    ChargingStationExternalConstraints,
1664    ChargingStationMaxProfile,
1665    TxDefaultProfile,
1666    TxProfile,
1667    PriorityCharging,
1668    LocalGeneration,
1669}
1670#[cfg(feature = "validate")]
1671impl crate::validate::Validate for ChargingProfilePurposeEnum {
1672    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1673        Ok(())
1674    }
1675}
1676/// A ClearChargingProfileType is a filter for charging profiles to be cleared by ClearChargingProfileRequest.
1677#[derive(Debug, Clone, PartialEq, Eq)]
1678#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1679pub struct ClearChargingProfile<CustomDataType = crate::NoCustomData> {
1680    #[cfg_attr(feature = "serde", serde(rename = "chargingProfilePurpose"))]
1681    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1682    pub charging_profile_purpose: Option<ChargingProfilePurposeEnum>,
1683    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1684    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1685    pub custom_data: Option<CustomDataType>,
1686    /// Specifies the id of the EVSE for which to clear charging profiles. An evseId of zero (0) specifies the charging profile for the overall Charging Station. Absence of this parameter means the clearing applies to all charging profiles that match the other criteria in the request.
1687    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
1688    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1689    pub evse_id: Option<i64>,
1690    /// Specifies the stackLevel for which charging profiles will be cleared, if they meet the other criteria in the request.
1691    #[cfg_attr(feature = "serde", serde(rename = "stackLevel"))]
1692    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1693    pub stack_level: Option<i64>,
1694}
1695#[cfg(feature = "validate")]
1696impl<CustomDataType> crate::validate::Validate for ClearChargingProfile<CustomDataType> {
1697    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1698        if let Some(value) = &self.charging_profile_purpose {
1699            crate::validate::Validate::validate(value)
1700                .map_err(|error| error.in_field("chargingProfilePurpose"))?;
1701        }
1702        if let Some(value) = self.evse_id {
1703            crate::validate::check_min_i64(value, 0i64)
1704                .map_err(|error| error.in_field("evseId"))?;
1705        }
1706        if let Some(value) = self.stack_level {
1707            crate::validate::check_min_i64(value, 0i64)
1708                .map_err(|error| error.in_field("stackLevel"))?;
1709        }
1710        Ok(())
1711    }
1712}
1713/// Indicates if the Charging Station was able to execute the request.
1714#[derive(Debug, Clone, PartialEq, Eq)]
1715#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1716pub enum ClearChargingProfileStatusEnum {
1717    Accepted,
1718    Unknown,
1719}
1720#[cfg(feature = "validate")]
1721impl crate::validate::Validate for ClearChargingProfileStatusEnum {
1722    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1723        Ok(())
1724    }
1725}
1726/// Name of control settings to clear. Not used when _controlId_ is provided.
1727#[derive(Debug, Clone, PartialEq, Eq)]
1728#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1729pub enum DERControlEnum {
1730    EnterService,
1731    FreqDroop,
1732    FreqWatt,
1733    FixedPFAbsorb,
1734    FixedPFInject,
1735    FixedVar,
1736    Gradients,
1737    HFMustTrip,
1738    HFMayTrip,
1739    HVMustTrip,
1740    HVMomCess,
1741    HVMayTrip,
1742    LimitMaxDischarge,
1743    LFMustTrip,
1744    LVMustTrip,
1745    LVMomCess,
1746    LVMayTrip,
1747    PowerMonitoringMustTrip,
1748    VoltVar,
1749    VoltWatt,
1750    WattPF,
1751    WattVar,
1752}
1753#[cfg(feature = "validate")]
1754impl crate::validate::Validate for DERControlEnum {
1755    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1756        Ok(())
1757    }
1758}
1759/// Result of operation.
1760#[derive(Debug, Clone, PartialEq, Eq)]
1761#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1762pub enum DERControlStatusEnum {
1763    Accepted,
1764    Rejected,
1765    NotSupported,
1766    NotFound,
1767}
1768#[cfg(feature = "validate")]
1769impl crate::validate::Validate for DERControlStatusEnum {
1770    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1771        Ok(())
1772    }
1773}
1774/// Returns whether the Charging Station has been able to remove the message.
1775#[derive(Debug, Clone, PartialEq, Eq)]
1776#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1777pub enum ClearMessageStatusEnum {
1778    Accepted,
1779    Unknown,
1780    Rejected,
1781}
1782#[cfg(feature = "validate")]
1783impl crate::validate::Validate for ClearMessageStatusEnum {
1784    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1785        Ok(())
1786    }
1787}
1788#[derive(Debug, Clone, PartialEq, Eq)]
1789#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1790pub enum TariffClearStatusEnum {
1791    Accepted,
1792    Rejected,
1793    NoTariff,
1794}
1795#[cfg(feature = "validate")]
1796impl crate::validate::Validate for TariffClearStatusEnum {
1797    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1798        Ok(())
1799    }
1800}
1801#[cfg(feature = "alloc")]
1802#[derive(Debug, Clone, PartialEq, Eq)]
1803#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1804pub struct ClearTariffsResult<CustomDataType = crate::NoCustomData> {
1805    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1806    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1807    pub custom_data: Option<CustomDataType>,
1808    pub status: TariffClearStatusEnum,
1809    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
1810    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1811    pub status_info: Option<StatusInfo<CustomDataType>>,
1812    /// Id of tariff for which _status_ is reported. If no tariffs were found, then this field is absent, and _status_ will be `NoTariff`.
1813    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
1814    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1815    pub tariff_id: Option<heapless::String<60usize>>,
1816}
1817#[cfg(all(feature = "validate", feature = "alloc"))]
1818impl<CustomDataType> crate::validate::Validate for ClearTariffsResult<CustomDataType> {
1819    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1820        crate::validate::Validate::validate(&self.status)
1821            .map_err(|error| error.in_field("status"))?;
1822        if let Some(value) = &self.status_info {
1823            crate::validate::Validate::validate(value)
1824                .map_err(|error| error.in_field("statusInfo"))?;
1825        }
1826        Ok(())
1827    }
1828}
1829#[cfg(not(feature = "alloc"))]
1830#[derive(Debug, Clone, PartialEq, Eq)]
1831#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1832pub struct ClearTariffsResult<
1833    CustomDataType = crate::NoCustomData,
1834    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
1835> {
1836    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1837    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1838    pub custom_data: Option<CustomDataType>,
1839    pub status: TariffClearStatusEnum,
1840    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
1841    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1842    pub status_info: Option<StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP>>,
1843    /// Id of tariff for which _status_ is reported. If no tariffs were found, then this field is absent, and _status_ will be `NoTariff`.
1844    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
1845    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1846    pub tariff_id: Option<heapless::String<60usize>>,
1847}
1848#[cfg(all(feature = "validate", not(feature = "alloc")))]
1849impl<
1850    CustomDataType,
1851    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
1852> crate::validate::Validate
1853for ClearTariffsResult<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP> {
1854    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1855        crate::validate::Validate::validate(&self.status)
1856            .map_err(|error| error.in_field("status"))?;
1857        if let Some(value) = &self.status_info {
1858            crate::validate::Validate::validate(value)
1859                .map_err(|error| error.in_field("statusInfo"))?;
1860        }
1861        Ok(())
1862    }
1863}
1864/// Result of the clear request for this monitor, identified by its Id.
1865#[derive(Debug, Clone, PartialEq, Eq)]
1866#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1867pub enum ClearMonitoringStatusEnum {
1868    Accepted,
1869    Rejected,
1870    NotFound,
1871}
1872#[cfg(feature = "validate")]
1873impl crate::validate::Validate for ClearMonitoringStatusEnum {
1874    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1875        Ok(())
1876    }
1877}
1878#[cfg(feature = "alloc")]
1879#[derive(Debug, Clone, PartialEq, Eq)]
1880#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1881pub struct ClearMonitoringResult<CustomDataType = crate::NoCustomData> {
1882    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1883    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1884    pub custom_data: Option<CustomDataType>,
1885    /// Id of the monitor of which a clear was requested.
1886    pub id: i64,
1887    pub status: ClearMonitoringStatusEnum,
1888    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
1889    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1890    pub status_info: Option<StatusInfo<CustomDataType>>,
1891}
1892#[cfg(all(feature = "validate", feature = "alloc"))]
1893impl<CustomDataType> crate::validate::Validate
1894for ClearMonitoringResult<CustomDataType> {
1895    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1896        crate::validate::check_min_i64(self.id, 0i64)
1897            .map_err(|error| error.in_field("id"))?;
1898        crate::validate::Validate::validate(&self.status)
1899            .map_err(|error| error.in_field("status"))?;
1900        if let Some(value) = &self.status_info {
1901            crate::validate::Validate::validate(value)
1902                .map_err(|error| error.in_field("statusInfo"))?;
1903        }
1904        Ok(())
1905    }
1906}
1907#[cfg(not(feature = "alloc"))]
1908#[derive(Debug, Clone, PartialEq, Eq)]
1909#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1910pub struct ClearMonitoringResult<
1911    CustomDataType = crate::NoCustomData,
1912    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
1913> {
1914    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1915    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1916    pub custom_data: Option<CustomDataType>,
1917    /// Id of the monitor of which a clear was requested.
1918    pub id: i64,
1919    pub status: ClearMonitoringStatusEnum,
1920    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
1921    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1922    pub status_info: Option<StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP>>,
1923}
1924#[cfg(all(feature = "validate", not(feature = "alloc")))]
1925impl<
1926    CustomDataType,
1927    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
1928> crate::validate::Validate
1929for ClearMonitoringResult<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP> {
1930    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1931        crate::validate::check_min_i64(self.id, 0i64)
1932            .map_err(|error| error.in_field("id"))?;
1933        crate::validate::Validate::validate(&self.status)
1934            .map_err(|error| error.in_field("status"))?;
1935        if let Some(value) = &self.status_info {
1936            crate::validate::Validate::validate(value)
1937                .map_err(|error| error.in_field("statusInfo"))?;
1938        }
1939        Ok(())
1940    }
1941}
1942#[derive(Debug, Clone, PartialEq, Eq)]
1943#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1944pub struct CertificateHashData<CustomDataType = crate::NoCustomData> {
1945    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
1946    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
1947    pub custom_data: Option<CustomDataType>,
1948    #[cfg_attr(feature = "serde", serde(rename = "hashAlgorithm"))]
1949    pub hash_algorithm: HashAlgorithmEnum,
1950    /// The hash of the DER encoded public key:
1951    /// the value (excluding tag and length) of the subject
1952    /// public key field in the issuer’s certificate.
1953    #[cfg_attr(feature = "serde", serde(rename = "issuerKeyHash"))]
1954    pub issuer_key_hash: heapless::String<128usize>,
1955    /// The hash of the issuer’s distinguished
1956    /// name (DN), that must be calculated over the DER
1957    /// encoding of the issuer’s name field in the certificate
1958    /// being checked.
1959    #[cfg_attr(feature = "serde", serde(rename = "issuerNameHash"))]
1960    pub issuer_name_hash: heapless::String<128usize>,
1961    /// The string representation of the
1962    /// hexadecimal value of the serial number without the
1963    /// prefix "0x" and without leading zeroes.
1964    #[cfg_attr(feature = "serde", serde(rename = "serialNumber"))]
1965    pub serial_number: heapless::String<40usize>,
1966}
1967#[cfg(feature = "validate")]
1968impl<CustomDataType> crate::validate::Validate for CertificateHashData<CustomDataType> {
1969    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1970        crate::validate::Validate::validate(&self.hash_algorithm)
1971            .map_err(|error| error.in_field("hashAlgorithm"))?;
1972        Ok(())
1973    }
1974}
1975/// Indicates whether the request was accepted.
1976#[derive(Debug, Clone, PartialEq, Eq)]
1977#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1978pub enum CustomerInformationStatusEnum {
1979    Accepted,
1980    Rejected,
1981    Invalid,
1982}
1983#[cfg(feature = "validate")]
1984impl crate::validate::Validate for CustomerInformationStatusEnum {
1985    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
1986        Ok(())
1987    }
1988}
1989/// This indicates the success or failure of the data transfer.
1990#[derive(Debug, Clone, PartialEq, Eq)]
1991#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
1992pub enum DataTransferStatusEnum {
1993    Accepted,
1994    Rejected,
1995    UnknownMessageId,
1996    UnknownVendorId,
1997}
1998#[cfg(feature = "validate")]
1999impl crate::validate::Validate for DataTransferStatusEnum {
2000    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2001        Ok(())
2002    }
2003}
2004/// Charging Station indicates if it can process the request.
2005#[derive(Debug, Clone, PartialEq, Eq)]
2006#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2007pub enum DeleteCertificateStatusEnum {
2008    Accepted,
2009    Failed,
2010    NotFound,
2011}
2012#[cfg(feature = "validate")]
2013impl crate::validate::Validate for DeleteCertificateStatusEnum {
2014    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2015        Ok(())
2016    }
2017}
2018/// This contains the progress status of the firmware installation.
2019#[derive(Debug, Clone, PartialEq, Eq)]
2020#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2021pub enum FirmwareStatusEnum {
2022    Downloaded,
2023    DownloadFailed,
2024    Downloading,
2025    DownloadScheduled,
2026    DownloadPaused,
2027    Idle,
2028    InstallationFailed,
2029    Installing,
2030    Installed,
2031    InstallRebooting,
2032    InstallScheduled,
2033    InstallVerificationFailed,
2034    InvalidSignature,
2035    SignatureVerified,
2036}
2037#[cfg(feature = "validate")]
2038impl crate::validate::Validate for FirmwareStatusEnum {
2039    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2040        Ok(())
2041    }
2042}
2043/// Defines whether certificate needs to be installed or updated.
2044#[derive(Debug, Clone, PartialEq, Eq)]
2045#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2046pub enum CertificateActionEnum {
2047    Install,
2048    Update,
2049}
2050#[cfg(feature = "validate")]
2051impl crate::validate::Validate for CertificateActionEnum {
2052    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2053        Ok(())
2054    }
2055}
2056/// Indicates whether the message was processed properly.
2057#[derive(Debug, Clone, PartialEq, Eq)]
2058#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2059pub enum Iso15118EVCertificateStatusEnum {
2060    Accepted,
2061    Failed,
2062}
2063#[cfg(feature = "validate")]
2064impl crate::validate::Validate for Iso15118EVCertificateStatusEnum {
2065    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2066        Ok(())
2067    }
2068}
2069/// This field specifies the report base.
2070#[derive(Debug, Clone, PartialEq, Eq)]
2071#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2072pub enum ReportBaseEnum {
2073    ConfigurationInventory,
2074    FullInventory,
2075    SummaryInventory,
2076}
2077#[cfg(feature = "validate")]
2078impl crate::validate::Validate for ReportBaseEnum {
2079    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2080        Ok(())
2081    }
2082}
2083/// This indicates whether the Charging Station is able to accept this request.
2084#[derive(Debug, Clone, PartialEq, Eq)]
2085#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2086pub enum GenericDeviceModelStatusEnum {
2087    Accepted,
2088    Rejected,
2089    NotSupported,
2090    EmptyResultSet,
2091}
2092#[cfg(feature = "validate")]
2093impl crate::validate::Validate for GenericDeviceModelStatusEnum {
2094    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2095        Ok(())
2096    }
2097}
2098/// Source of status: OCSP, CRL
2099#[derive(Debug, Clone, PartialEq, Eq)]
2100#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2101pub enum CertificateStatusSourceEnum {
2102    CRL,
2103    OCSP,
2104}
2105#[cfg(feature = "validate")]
2106impl crate::validate::Validate for CertificateStatusSourceEnum {
2107    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2108        Ok(())
2109    }
2110}
2111#[cfg(feature = "alloc")]
2112/// Data necessary to request the revocation status of a certificate.
2113#[derive(Debug, Clone, PartialEq, Eq)]
2114#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2115pub struct CertificateStatusRequestInfo<CustomDataType = crate::NoCustomData> {
2116    #[cfg_attr(feature = "serde", serde(rename = "certificateHashData"))]
2117    pub certificate_hash_data: CertificateHashData<CustomDataType>,
2118    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2119    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2120    pub custom_data: Option<CustomDataType>,
2121    pub source: CertificateStatusSourceEnum,
2122    /// URL(s) of _source_.
2123    pub urls: heapless::Vec<alloc::string::String, 5usize>,
2124}
2125#[cfg(all(feature = "validate", feature = "alloc"))]
2126impl<CustomDataType> crate::validate::Validate
2127for CertificateStatusRequestInfo<CustomDataType> {
2128    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2129        crate::validate::Validate::validate(&self.certificate_hash_data)
2130            .map_err(|error| error.in_field("certificateHashData"))?;
2131        crate::validate::Validate::validate(&self.source)
2132            .map_err(|error| error.in_field("source"))?;
2133        crate::validate::check_min_items(self.urls.len(), 1usize)
2134            .map_err(|error| error.in_field("urls"))?;
2135        for (index, item) in self.urls.iter().enumerate() {
2136            crate::validate::check_max_length(item, 2000usize)
2137                .map_err(|error| error.in_index(index).in_field("urls"))?;
2138        }
2139        Ok(())
2140    }
2141}
2142#[cfg(not(feature = "alloc"))]
2143/// Data necessary to request the revocation status of a certificate.
2144#[derive(Debug, Clone, PartialEq, Eq)]
2145#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2146pub struct CertificateStatusRequestInfo<
2147    CustomDataType = crate::NoCustomData,
2148    const CERTIFICATE_STATUS_REQUEST_INFO_URLS_ITEM_CAP: usize = 1024usize,
2149> {
2150    #[cfg_attr(feature = "serde", serde(rename = "certificateHashData"))]
2151    pub certificate_hash_data: CertificateHashData<CustomDataType>,
2152    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2153    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2154    pub custom_data: Option<CustomDataType>,
2155    pub source: CertificateStatusSourceEnum,
2156    /// URL(s) of _source_.
2157    pub urls: heapless::Vec<
2158        heapless::String<CERTIFICATE_STATUS_REQUEST_INFO_URLS_ITEM_CAP>,
2159        5usize,
2160    >,
2161}
2162#[cfg(all(feature = "validate", not(feature = "alloc")))]
2163impl<
2164    CustomDataType,
2165    const CERTIFICATE_STATUS_REQUEST_INFO_URLS_ITEM_CAP: usize,
2166> crate::validate::Validate
2167for CertificateStatusRequestInfo<
2168    CustomDataType,
2169    CERTIFICATE_STATUS_REQUEST_INFO_URLS_ITEM_CAP,
2170> {
2171    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2172        crate::validate::Validate::validate(&self.certificate_hash_data)
2173            .map_err(|error| error.in_field("certificateHashData"))?;
2174        crate::validate::Validate::validate(&self.source)
2175            .map_err(|error| error.in_field("source"))?;
2176        crate::validate::check_min_items(self.urls.len(), 1usize)
2177            .map_err(|error| error.in_field("urls"))?;
2178        for (index, item) in self.urls.iter().enumerate() {
2179            crate::validate::check_max_length(item, 2000usize)
2180                .map_err(|error| error.in_index(index).in_field("urls"))?;
2181        }
2182        Ok(())
2183    }
2184}
2185/// Status of certificate: good, revoked or unknown.
2186#[derive(Debug, Clone, PartialEq, Eq)]
2187#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2188pub enum CertificateStatusEnum {
2189    Good,
2190    Revoked,
2191    Unknown,
2192    Failed,
2193}
2194#[cfg(feature = "validate")]
2195impl crate::validate::Validate for CertificateStatusEnum {
2196    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2197        Ok(())
2198    }
2199}
2200/// Revocation status of certificate
2201#[derive(Debug, Clone, PartialEq, Eq)]
2202#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2203pub struct CertificateStatus<CustomDataType = crate::NoCustomData> {
2204    #[cfg_attr(feature = "serde", serde(rename = "certificateHashData"))]
2205    pub certificate_hash_data: CertificateHashData<CustomDataType>,
2206    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2207    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2208    pub custom_data: Option<CustomDataType>,
2209    #[cfg_attr(feature = "serde", serde(rename = "nextUpdate"))]
2210    pub next_update: crate::OcppTimestamp,
2211    pub source: CertificateStatusSourceEnum,
2212    pub status: CertificateStatusEnum,
2213}
2214#[cfg(feature = "validate")]
2215impl<CustomDataType> crate::validate::Validate for CertificateStatus<CustomDataType> {
2216    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2217        crate::validate::Validate::validate(&self.certificate_hash_data)
2218            .map_err(|error| error.in_field("certificateHashData"))?;
2219        crate::validate::Validate::validate(&self.source)
2220            .map_err(|error| error.in_field("source"))?;
2221        crate::validate::Validate::validate(&self.status)
2222            .map_err(|error| error.in_field("status"))?;
2223        Ok(())
2224    }
2225}
2226/// This indicates whether the charging station was able to retrieve the OCSP certificate status.
2227#[derive(Debug, Clone, PartialEq, Eq)]
2228#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2229pub enum GetCertificateStatusEnum {
2230    Accepted,
2231    Failed,
2232}
2233#[cfg(feature = "validate")]
2234impl crate::validate::Validate for GetCertificateStatusEnum {
2235    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2236        Ok(())
2237    }
2238}
2239#[cfg(feature = "alloc")]
2240/// A ChargingProfileCriterionType is a filter for charging profiles to be selected by a GetChargingProfilesRequest.
2241#[derive(Debug, Clone, PartialEq, Eq)]
2242#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2243pub struct ChargingProfileCriterion<CustomDataType = crate::NoCustomData> {
2244    /// For which charging limit sources, charging profiles SHALL be reported. If omitted, the Charging Station SHALL not filter on chargingLimitSource. Values defined in Appendix as ChargingLimitSourceEnumStringType.
2245    #[cfg_attr(feature = "serde", serde(rename = "chargingLimitSource"))]
2246    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2247    pub charging_limit_source: Option<heapless::Vec<heapless::String<20usize>, 4usize>>,
2248    /// List of all the chargingProfileIds requested. Any ChargingProfile that matches one of these profiles will be reported. If omitted, the Charging Station SHALL not filter on chargingProfileId. This field SHALL NOT contain more ids than set in &lt;&lt;configkey-charging-profile-entries,ChargingProfileEntries.maxLimit&gt;&gt;
2249    #[cfg_attr(feature = "serde", serde(rename = "chargingProfileId"))]
2250    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2251    pub charging_profile_id: Option<alloc::vec::Vec<i64>>,
2252    #[cfg_attr(feature = "serde", serde(rename = "chargingProfilePurpose"))]
2253    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2254    pub charging_profile_purpose: Option<ChargingProfilePurposeEnum>,
2255    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2256    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2257    pub custom_data: Option<CustomDataType>,
2258    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
2259    #[cfg_attr(feature = "serde", serde(rename = "stackLevel"))]
2260    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2261    pub stack_level: Option<i64>,
2262}
2263#[cfg(all(feature = "validate", feature = "alloc"))]
2264impl<CustomDataType> crate::validate::Validate
2265for ChargingProfileCriterion<CustomDataType> {
2266    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2267        if let Some(value) = &self.charging_limit_source {
2268            crate::validate::check_min_items(value.len(), 1usize)
2269                .map_err(|error| error.in_field("chargingLimitSource"))?;
2270        }
2271        if let Some(value) = &self.charging_profile_id {
2272            crate::validate::check_min_items(value.len(), 1usize)
2273                .map_err(|error| error.in_field("chargingProfileId"))?;
2274        }
2275        if let Some(value) = &self.charging_profile_purpose {
2276            crate::validate::Validate::validate(value)
2277                .map_err(|error| error.in_field("chargingProfilePurpose"))?;
2278        }
2279        if let Some(value) = self.stack_level {
2280            crate::validate::check_min_i64(value, 0i64)
2281                .map_err(|error| error.in_field("stackLevel"))?;
2282        }
2283        Ok(())
2284    }
2285}
2286#[cfg(not(feature = "alloc"))]
2287/// A ChargingProfileCriterionType is a filter for charging profiles to be selected by a GetChargingProfilesRequest.
2288#[derive(Debug, Clone, PartialEq, Eq)]
2289#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2290pub struct ChargingProfileCriterion<
2291    CustomDataType = crate::NoCustomData,
2292    const CHARGING_PROFILE_CRITERION_CHARGING_PROFILE_ID_CAP: usize = 8usize,
2293> {
2294    /// For which charging limit sources, charging profiles SHALL be reported. If omitted, the Charging Station SHALL not filter on chargingLimitSource. Values defined in Appendix as ChargingLimitSourceEnumStringType.
2295    #[cfg_attr(feature = "serde", serde(rename = "chargingLimitSource"))]
2296    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2297    pub charging_limit_source: Option<heapless::Vec<heapless::String<20usize>, 4usize>>,
2298    /// List of all the chargingProfileIds requested. Any ChargingProfile that matches one of these profiles will be reported. If omitted, the Charging Station SHALL not filter on chargingProfileId. This field SHALL NOT contain more ids than set in &lt;&lt;configkey-charging-profile-entries,ChargingProfileEntries.maxLimit&gt;&gt;
2299    #[cfg_attr(feature = "serde", serde(rename = "chargingProfileId"))]
2300    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2301    pub charging_profile_id: Option<
2302        heapless::Vec<i64, CHARGING_PROFILE_CRITERION_CHARGING_PROFILE_ID_CAP>,
2303    >,
2304    #[cfg_attr(feature = "serde", serde(rename = "chargingProfilePurpose"))]
2305    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2306    pub charging_profile_purpose: Option<ChargingProfilePurposeEnum>,
2307    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2308    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2309    pub custom_data: Option<CustomDataType>,
2310    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
2311    #[cfg_attr(feature = "serde", serde(rename = "stackLevel"))]
2312    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2313    pub stack_level: Option<i64>,
2314}
2315#[cfg(all(feature = "validate", not(feature = "alloc")))]
2316impl<
2317    CustomDataType,
2318    const CHARGING_PROFILE_CRITERION_CHARGING_PROFILE_ID_CAP: usize,
2319> crate::validate::Validate
2320for ChargingProfileCriterion<
2321    CustomDataType,
2322    CHARGING_PROFILE_CRITERION_CHARGING_PROFILE_ID_CAP,
2323> {
2324    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2325        if let Some(value) = &self.charging_limit_source {
2326            crate::validate::check_min_items(value.len(), 1usize)
2327                .map_err(|error| error.in_field("chargingLimitSource"))?;
2328        }
2329        if let Some(value) = &self.charging_profile_id {
2330            crate::validate::check_min_items(value.len(), 1usize)
2331                .map_err(|error| error.in_field("chargingProfileId"))?;
2332        }
2333        if let Some(value) = &self.charging_profile_purpose {
2334            crate::validate::Validate::validate(value)
2335                .map_err(|error| error.in_field("chargingProfilePurpose"))?;
2336        }
2337        if let Some(value) = self.stack_level {
2338            crate::validate::check_min_i64(value, 0i64)
2339                .map_err(|error| error.in_field("stackLevel"))?;
2340        }
2341        Ok(())
2342    }
2343}
2344/// This indicates whether the Charging Station is able to process this request and will send &lt;&lt;reportchargingprofilesrequest, ReportChargingProfilesRequest&gt;&gt; messages.
2345#[derive(Debug, Clone, PartialEq, Eq)]
2346#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2347pub enum GetChargingProfileStatusEnum {
2348    Accepted,
2349    NoProfiles,
2350}
2351#[cfg(feature = "validate")]
2352impl crate::validate::Validate for GetChargingProfileStatusEnum {
2353    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2354        Ok(())
2355    }
2356}
2357/// Can be used to force a power or current profile.
2358#[derive(Debug, Clone, PartialEq, Eq)]
2359#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2360pub enum ChargingRateUnitEnum {
2361    W,
2362    A,
2363}
2364#[cfg(feature = "validate")]
2365impl crate::validate::Validate for ChargingRateUnitEnum {
2366    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2367        Ok(())
2368    }
2369}
2370/// *(2.1)* Charging operation mode to use during this time interval. When absent defaults to `ChargingOnly`.
2371#[derive(Debug, Clone, PartialEq, Eq)]
2372#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2373pub enum OperationModeEnum {
2374    Idle,
2375    ChargingOnly,
2376    CentralSetpoint,
2377    ExternalSetpoint,
2378    ExternalLimits,
2379    CentralFrequency,
2380    LocalFrequency,
2381    LocalLoadBalancing,
2382}
2383#[cfg(feature = "validate")]
2384impl crate::validate::Validate for OperationModeEnum {
2385    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2386        Ok(())
2387    }
2388}
2389/// *(2.1)* A point of a frequency-watt curve.
2390#[derive(Debug, Clone, PartialEq)]
2391#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2392pub struct V2XFreqWattPoint<CustomDataType = crate::NoCustomData> {
2393    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2394    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2395    pub custom_data: Option<CustomDataType>,
2396    /// Net frequency in Hz.
2397    pub frequency: f64,
2398    /// Power in W to charge (positive) or discharge (negative) at specified frequency.
2399    pub power: f64,
2400}
2401#[cfg(feature = "validate")]
2402impl<CustomDataType> crate::validate::Validate for V2XFreqWattPoint<CustomDataType> {
2403    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2404        Ok(())
2405    }
2406}
2407/// *(2.1)* A point of a signal-watt curve.
2408#[derive(Debug, Clone, PartialEq)]
2409#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2410pub struct V2XSignalWattPoint<CustomDataType = crate::NoCustomData> {
2411    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2412    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2413    pub custom_data: Option<CustomDataType>,
2414    /// Power in W to charge (positive) or discharge (negative) at specified frequency.
2415    pub power: f64,
2416    /// Signal value from an AFRRSignalRequest.
2417    pub signal: i64,
2418}
2419#[cfg(feature = "validate")]
2420impl<CustomDataType> crate::validate::Validate for V2XSignalWattPoint<CustomDataType> {
2421    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2422        Ok(())
2423    }
2424}
2425#[cfg(feature = "alloc")]
2426/// Charging schedule period structure defines a time period in a charging schedule. It is used in: CompositeScheduleType and in ChargingScheduleType. When used in a NotifyEVChargingScheduleRequest only _startPeriod_, _limit_, _limit_L2_, _limit_L3_ are relevant.
2427#[derive(Debug, Clone, PartialEq)]
2428#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2429pub struct ChargingSchedulePeriod<CustomDataType = crate::NoCustomData> {
2430    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2431    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2432    pub custom_data: Option<CustomDataType>,
2433    /// *(2.1)* Limit in _chargingRateUnit_ that the EV is allowed to discharge with. Note, these are negative values in order to be consistent with _setpoint_, which can be positive and negative.  +
2434    /// For AC this field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2435    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit"))]
2436    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2437    pub discharge_limit: Option<f64>,
2438    /// *(2.1)* Limit in _chargingRateUnit_ on phase L2 that the EV is allowed to discharge with.
2439    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L2"))]
2440    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2441    pub discharge_limit_l2: Option<f64>,
2442    /// *(2.1)* Limit in _chargingRateUnit_ on phase L3 that the EV is allowed to discharge with.
2443    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L3"))]
2444    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2445    pub discharge_limit_l3: Option<f64>,
2446    /// *(2.1)* If true, the EVSE must turn off power electronics/modules associated with this transaction. Default value when absent is false.
2447    #[cfg_attr(feature = "serde", serde(rename = "evseSleep"))]
2448    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2449    pub evse_sleep: Option<bool>,
2450    /// Optional only when not required by the _operationMode_, as in CentralSetpoint, ExternalSetpoint, ExternalLimits, LocalFrequency,  LocalLoadBalancing. +
2451    /// Charging rate limit during the schedule period, in the applicable _chargingRateUnit_.
2452    /// This SHOULD be a non-negative value; a negative value is only supported for backwards compatibility with older systems that use a negative value to specify a discharging limit.
2453    /// When using _chargingRateUnit_ = `W`, this field represents the sum of the power of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2454    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2455    pub limit: Option<f64>,
2456    /// *(2.1)* Charging rate limit on phase L2  in the applicable _chargingRateUnit_.
2457    #[cfg_attr(feature = "serde", serde(rename = "limit_L2"))]
2458    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2459    pub limit_l2: Option<f64>,
2460    /// *(2.1)* Charging rate limit on phase L3  in the applicable _chargingRateUnit_.
2461    #[cfg_attr(feature = "serde", serde(rename = "limit_L3"))]
2462    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2463    pub limit_l3: Option<f64>,
2464    /// The number of phases that can be used for charging. +
2465    /// For a DC EVSE this field should be omitted. +
2466    /// For an AC EVSE a default value of _numberPhases_ = 3 will be assumed if the field is absent.
2467    #[cfg_attr(feature = "serde", serde(rename = "numberPhases"))]
2468    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2469    pub number_phases: Option<i64>,
2470    #[cfg_attr(feature = "serde", serde(rename = "operationMode"))]
2471    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2472    pub operation_mode: Option<OperationModeEnum>,
2473    /// Values: 1..3, Used if numberPhases=1 and if the EVSE is capable of switching the phase connected to the EV, i.e. ACPhaseSwitchingSupported is defined and true. It’s not allowed unless both conditions above are true. If both conditions are true, and phaseToUse is omitted, the Charging Station / EVSE will make the selection on its own.
2474    #[cfg_attr(feature = "serde", serde(rename = "phaseToUse"))]
2475    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2476    pub phase_to_use: Option<i64>,
2477    /// *(2.1)* If  true, the EV should attempt to keep the BMS preconditioned for this time interval.
2478    #[cfg_attr(feature = "serde", serde(rename = "preconditioningRequest"))]
2479    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2480    pub preconditioning_request: Option<bool>,
2481    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow as close as possible. Use negative values for discharging. +
2482    /// When a limit and/or _dischargeLimit_ are given the overshoot when following _setpoint_ must remain within these values.
2483    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2484    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2485    pub setpoint: Option<f64>,
2486    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow as closely as possible. Positive values for inductive, negative for capacitive reactive power or current.  +
2487    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2488    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive"))]
2489    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2490    pub setpoint_reactive: Option<f64>,
2491    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L2 as closely as possible.
2492    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L2"))]
2493    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2494    pub setpoint_reactive_l2: Option<f64>,
2495    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L3 as closely as possible.
2496    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L3"))]
2497    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2498    pub setpoint_reactive_l3: Option<f64>,
2499    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L2 as close as possible.
2500    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L2"))]
2501    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2502    pub setpoint_l2: Option<f64>,
2503    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L3 as close as possible.
2504    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L3"))]
2505    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2506    pub setpoint_l3: Option<f64>,
2507    /// Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
2508    #[cfg_attr(feature = "serde", serde(rename = "startPeriod"))]
2509    pub start_period: i64,
2510    /// *(2.1)* Power value that, when present, is used as a baseline on top of which values from _v2xFreqWattCurve_ and _v2xSignalWattCurve_ are added.
2511    #[cfg_attr(feature = "serde", serde(rename = "v2xBaseline"))]
2512    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2513    pub v2x_baseline: Option<f64>,
2514    #[cfg_attr(feature = "serde", serde(rename = "v2xFreqWattCurve"))]
2515    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2516    pub v2x_freq_watt_curve: Option<alloc::vec::Vec<V2XFreqWattPoint<CustomDataType>>>,
2517    #[cfg_attr(feature = "serde", serde(rename = "v2xSignalWattCurve"))]
2518    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2519    pub v2x_signal_watt_curve: Option<
2520        alloc::vec::Vec<V2XSignalWattPoint<CustomDataType>>,
2521    >,
2522}
2523#[cfg(all(feature = "validate", feature = "alloc"))]
2524impl<CustomDataType> crate::validate::Validate
2525for ChargingSchedulePeriod<CustomDataType> {
2526    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2527        if let Some(value) = self.discharge_limit {
2528            crate::validate::check_max_f64(value, 0f64)
2529                .map_err(|error| error.in_field("dischargeLimit"))?;
2530        }
2531        if let Some(value) = self.discharge_limit_l2 {
2532            crate::validate::check_max_f64(value, 0f64)
2533                .map_err(|error| error.in_field("dischargeLimit_L2"))?;
2534        }
2535        if let Some(value) = self.discharge_limit_l3 {
2536            crate::validate::check_max_f64(value, 0f64)
2537                .map_err(|error| error.in_field("dischargeLimit_L3"))?;
2538        }
2539        if let Some(value) = self.number_phases {
2540            crate::validate::check_min_i64(value, 0i64)
2541                .map_err(|error| error.in_field("numberPhases"))?;
2542            crate::validate::check_max_i64(value, 3i64)
2543                .map_err(|error| error.in_field("numberPhases"))?;
2544        }
2545        if let Some(value) = &self.operation_mode {
2546            crate::validate::Validate::validate(value)
2547                .map_err(|error| error.in_field("operationMode"))?;
2548        }
2549        if let Some(value) = self.phase_to_use {
2550            crate::validate::check_min_i64(value, 0i64)
2551                .map_err(|error| error.in_field("phaseToUse"))?;
2552            crate::validate::check_max_i64(value, 3i64)
2553                .map_err(|error| error.in_field("phaseToUse"))?;
2554        }
2555        if let Some(value) = &self.v2x_freq_watt_curve {
2556            crate::validate::check_min_items(value.len(), 1usize)
2557                .map_err(|error| error.in_field("v2xFreqWattCurve"))?;
2558            crate::validate::check_max_items(value.len(), 20usize)
2559                .map_err(|error| error.in_field("v2xFreqWattCurve"))?;
2560            for (index, item) in value.iter().enumerate() {
2561                crate::validate::Validate::validate(item)
2562                    .map_err(|error| {
2563                        error.in_index(index).in_field("v2xFreqWattCurve")
2564                    })?;
2565            }
2566        }
2567        if let Some(value) = &self.v2x_signal_watt_curve {
2568            crate::validate::check_min_items(value.len(), 1usize)
2569                .map_err(|error| error.in_field("v2xSignalWattCurve"))?;
2570            crate::validate::check_max_items(value.len(), 20usize)
2571                .map_err(|error| error.in_field("v2xSignalWattCurve"))?;
2572            for (index, item) in value.iter().enumerate() {
2573                crate::validate::Validate::validate(item)
2574                    .map_err(|error| {
2575                        error.in_index(index).in_field("v2xSignalWattCurve")
2576                    })?;
2577            }
2578        }
2579        Ok(())
2580    }
2581}
2582#[cfg(not(feature = "alloc"))]
2583/// Charging schedule period structure defines a time period in a charging schedule. It is used in: CompositeScheduleType and in ChargingScheduleType. When used in a NotifyEVChargingScheduleRequest only _startPeriod_, _limit_, _limit_L2_, _limit_L3_ are relevant.
2584#[derive(Debug, Clone, PartialEq)]
2585#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2586pub struct ChargingSchedulePeriod<
2587    CustomDataType = crate::NoCustomData,
2588    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize = 8usize,
2589    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize = 8usize,
2590> {
2591    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2592    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2593    pub custom_data: Option<CustomDataType>,
2594    /// *(2.1)* Limit in _chargingRateUnit_ that the EV is allowed to discharge with. Note, these are negative values in order to be consistent with _setpoint_, which can be positive and negative.  +
2595    /// For AC this field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2596    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit"))]
2597    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2598    pub discharge_limit: Option<f64>,
2599    /// *(2.1)* Limit in _chargingRateUnit_ on phase L2 that the EV is allowed to discharge with.
2600    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L2"))]
2601    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2602    pub discharge_limit_l2: Option<f64>,
2603    /// *(2.1)* Limit in _chargingRateUnit_ on phase L3 that the EV is allowed to discharge with.
2604    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L3"))]
2605    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2606    pub discharge_limit_l3: Option<f64>,
2607    /// *(2.1)* If true, the EVSE must turn off power electronics/modules associated with this transaction. Default value when absent is false.
2608    #[cfg_attr(feature = "serde", serde(rename = "evseSleep"))]
2609    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2610    pub evse_sleep: Option<bool>,
2611    /// Optional only when not required by the _operationMode_, as in CentralSetpoint, ExternalSetpoint, ExternalLimits, LocalFrequency,  LocalLoadBalancing. +
2612    /// Charging rate limit during the schedule period, in the applicable _chargingRateUnit_.
2613    /// This SHOULD be a non-negative value; a negative value is only supported for backwards compatibility with older systems that use a negative value to specify a discharging limit.
2614    /// When using _chargingRateUnit_ = `W`, this field represents the sum of the power of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2615    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2616    pub limit: Option<f64>,
2617    /// *(2.1)* Charging rate limit on phase L2  in the applicable _chargingRateUnit_.
2618    #[cfg_attr(feature = "serde", serde(rename = "limit_L2"))]
2619    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2620    pub limit_l2: Option<f64>,
2621    /// *(2.1)* Charging rate limit on phase L3  in the applicable _chargingRateUnit_.
2622    #[cfg_attr(feature = "serde", serde(rename = "limit_L3"))]
2623    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2624    pub limit_l3: Option<f64>,
2625    /// The number of phases that can be used for charging. +
2626    /// For a DC EVSE this field should be omitted. +
2627    /// For an AC EVSE a default value of _numberPhases_ = 3 will be assumed if the field is absent.
2628    #[cfg_attr(feature = "serde", serde(rename = "numberPhases"))]
2629    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2630    pub number_phases: Option<i64>,
2631    #[cfg_attr(feature = "serde", serde(rename = "operationMode"))]
2632    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2633    pub operation_mode: Option<OperationModeEnum>,
2634    /// Values: 1..3, Used if numberPhases=1 and if the EVSE is capable of switching the phase connected to the EV, i.e. ACPhaseSwitchingSupported is defined and true. It’s not allowed unless both conditions above are true. If both conditions are true, and phaseToUse is omitted, the Charging Station / EVSE will make the selection on its own.
2635    #[cfg_attr(feature = "serde", serde(rename = "phaseToUse"))]
2636    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2637    pub phase_to_use: Option<i64>,
2638    /// *(2.1)* If  true, the EV should attempt to keep the BMS preconditioned for this time interval.
2639    #[cfg_attr(feature = "serde", serde(rename = "preconditioningRequest"))]
2640    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2641    pub preconditioning_request: Option<bool>,
2642    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow as close as possible. Use negative values for discharging. +
2643    /// When a limit and/or _dischargeLimit_ are given the overshoot when following _setpoint_ must remain within these values.
2644    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2645    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2646    pub setpoint: Option<f64>,
2647    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow as closely as possible. Positive values for inductive, negative for capacitive reactive power or current.  +
2648    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
2649    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive"))]
2650    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2651    pub setpoint_reactive: Option<f64>,
2652    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L2 as closely as possible.
2653    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L2"))]
2654    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2655    pub setpoint_reactive_l2: Option<f64>,
2656    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L3 as closely as possible.
2657    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L3"))]
2658    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2659    pub setpoint_reactive_l3: Option<f64>,
2660    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L2 as close as possible.
2661    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L2"))]
2662    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2663    pub setpoint_l2: Option<f64>,
2664    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L3 as close as possible.
2665    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L3"))]
2666    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2667    pub setpoint_l3: Option<f64>,
2668    /// Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
2669    #[cfg_attr(feature = "serde", serde(rename = "startPeriod"))]
2670    pub start_period: i64,
2671    /// *(2.1)* Power value that, when present, is used as a baseline on top of which values from _v2xFreqWattCurve_ and _v2xSignalWattCurve_ are added.
2672    #[cfg_attr(feature = "serde", serde(rename = "v2xBaseline"))]
2673    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2674    pub v2x_baseline: Option<f64>,
2675    #[cfg_attr(feature = "serde", serde(rename = "v2xFreqWattCurve"))]
2676    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2677    pub v2x_freq_watt_curve: Option<
2678        heapless::Vec<
2679            V2XFreqWattPoint<CustomDataType>,
2680            CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
2681        >,
2682    >,
2683    #[cfg_attr(feature = "serde", serde(rename = "v2xSignalWattCurve"))]
2684    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2685    pub v2x_signal_watt_curve: Option<
2686        heapless::Vec<
2687            V2XSignalWattPoint<CustomDataType>,
2688            CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
2689        >,
2690    >,
2691}
2692#[cfg(all(feature = "validate", not(feature = "alloc")))]
2693impl<
2694    CustomDataType,
2695    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize,
2696    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize,
2697> crate::validate::Validate
2698for ChargingSchedulePeriod<
2699    CustomDataType,
2700    CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
2701    CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
2702> {
2703    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2704        if let Some(value) = self.discharge_limit {
2705            crate::validate::check_max_f64(value, 0f64)
2706                .map_err(|error| error.in_field("dischargeLimit"))?;
2707        }
2708        if let Some(value) = self.discharge_limit_l2 {
2709            crate::validate::check_max_f64(value, 0f64)
2710                .map_err(|error| error.in_field("dischargeLimit_L2"))?;
2711        }
2712        if let Some(value) = self.discharge_limit_l3 {
2713            crate::validate::check_max_f64(value, 0f64)
2714                .map_err(|error| error.in_field("dischargeLimit_L3"))?;
2715        }
2716        if let Some(value) = self.number_phases {
2717            crate::validate::check_min_i64(value, 0i64)
2718                .map_err(|error| error.in_field("numberPhases"))?;
2719            crate::validate::check_max_i64(value, 3i64)
2720                .map_err(|error| error.in_field("numberPhases"))?;
2721        }
2722        if let Some(value) = &self.operation_mode {
2723            crate::validate::Validate::validate(value)
2724                .map_err(|error| error.in_field("operationMode"))?;
2725        }
2726        if let Some(value) = self.phase_to_use {
2727            crate::validate::check_min_i64(value, 0i64)
2728                .map_err(|error| error.in_field("phaseToUse"))?;
2729            crate::validate::check_max_i64(value, 3i64)
2730                .map_err(|error| error.in_field("phaseToUse"))?;
2731        }
2732        if let Some(value) = &self.v2x_freq_watt_curve {
2733            crate::validate::check_min_items(value.len(), 1usize)
2734                .map_err(|error| error.in_field("v2xFreqWattCurve"))?;
2735            crate::validate::check_max_items(value.len(), 20usize)
2736                .map_err(|error| error.in_field("v2xFreqWattCurve"))?;
2737            for (index, item) in value.iter().enumerate() {
2738                crate::validate::Validate::validate(item)
2739                    .map_err(|error| {
2740                        error.in_index(index).in_field("v2xFreqWattCurve")
2741                    })?;
2742            }
2743        }
2744        if let Some(value) = &self.v2x_signal_watt_curve {
2745            crate::validate::check_min_items(value.len(), 1usize)
2746                .map_err(|error| error.in_field("v2xSignalWattCurve"))?;
2747            crate::validate::check_max_items(value.len(), 20usize)
2748                .map_err(|error| error.in_field("v2xSignalWattCurve"))?;
2749            for (index, item) in value.iter().enumerate() {
2750                crate::validate::Validate::validate(item)
2751                    .map_err(|error| {
2752                        error.in_index(index).in_field("v2xSignalWattCurve")
2753                    })?;
2754            }
2755        }
2756        Ok(())
2757    }
2758}
2759#[cfg(feature = "alloc")]
2760#[derive(Debug, Clone, PartialEq)]
2761#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2762pub struct CompositeSchedule<CustomDataType = crate::NoCustomData> {
2763    #[cfg_attr(feature = "serde", serde(rename = "chargingRateUnit"))]
2764    pub charging_rate_unit: ChargingRateUnitEnum,
2765    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedulePeriod"))]
2766    pub charging_schedule_period: alloc::vec::Vec<
2767        ChargingSchedulePeriod<CustomDataType>,
2768    >,
2769    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2770    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2771    pub custom_data: Option<CustomDataType>,
2772    pub duration: i64,
2773    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
2774    pub evse_id: i64,
2775    #[cfg_attr(feature = "serde", serde(rename = "scheduleStart"))]
2776    pub schedule_start: crate::OcppTimestamp,
2777}
2778#[cfg(all(feature = "validate", feature = "alloc"))]
2779impl<CustomDataType> crate::validate::Validate for CompositeSchedule<CustomDataType> {
2780    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2781        crate::validate::Validate::validate(&self.charging_rate_unit)
2782            .map_err(|error| error.in_field("chargingRateUnit"))?;
2783        crate::validate::check_min_items(self.charging_schedule_period.len(), 1usize)
2784            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
2785        for (index, item) in self.charging_schedule_period.iter().enumerate() {
2786            crate::validate::Validate::validate(item)
2787                .map_err(|error| {
2788                    error.in_index(index).in_field("chargingSchedulePeriod")
2789                })?;
2790        }
2791        crate::validate::check_min_i64(self.evse_id, 0i64)
2792            .map_err(|error| error.in_field("evseId"))?;
2793        Ok(())
2794    }
2795}
2796#[cfg(not(feature = "alloc"))]
2797#[derive(Debug, Clone, PartialEq)]
2798#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2799pub struct CompositeSchedule<
2800    CustomDataType = crate::NoCustomData,
2801    const COMPOSITE_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize = 8usize,
2802    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize = 8usize,
2803    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize = 8usize,
2804> {
2805    #[cfg_attr(feature = "serde", serde(rename = "chargingRateUnit"))]
2806    pub charging_rate_unit: ChargingRateUnitEnum,
2807    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedulePeriod"))]
2808    pub charging_schedule_period: heapless::Vec<
2809        ChargingSchedulePeriod<
2810            CustomDataType,
2811            CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
2812            CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
2813        >,
2814        COMPOSITE_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
2815    >,
2816    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2817    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2818    pub custom_data: Option<CustomDataType>,
2819    pub duration: i64,
2820    #[cfg_attr(feature = "serde", serde(rename = "evseId"))]
2821    pub evse_id: i64,
2822    #[cfg_attr(feature = "serde", serde(rename = "scheduleStart"))]
2823    pub schedule_start: crate::OcppTimestamp,
2824}
2825#[cfg(all(feature = "validate", not(feature = "alloc")))]
2826impl<
2827    CustomDataType,
2828    const COMPOSITE_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize,
2829    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize,
2830    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize,
2831> crate::validate::Validate
2832for CompositeSchedule<
2833    CustomDataType,
2834    COMPOSITE_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
2835    CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
2836    CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
2837> {
2838    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2839        crate::validate::Validate::validate(&self.charging_rate_unit)
2840            .map_err(|error| error.in_field("chargingRateUnit"))?;
2841        crate::validate::check_min_items(self.charging_schedule_period.len(), 1usize)
2842            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
2843        for (index, item) in self.charging_schedule_period.iter().enumerate() {
2844            crate::validate::Validate::validate(item)
2845                .map_err(|error| {
2846                    error.in_index(index).in_field("chargingSchedulePeriod")
2847                })?;
2848        }
2849        crate::validate::check_min_i64(self.evse_id, 0i64)
2850            .map_err(|error| error.in_field("evseId"))?;
2851        Ok(())
2852    }
2853}
2854/// If provided the Charging Station shall return Display Messages with the given priority only.
2855#[derive(Debug, Clone, PartialEq, Eq)]
2856#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2857pub enum MessagePriorityEnum {
2858    AlwaysFront,
2859    InFront,
2860    NormalCycle,
2861}
2862#[cfg(feature = "validate")]
2863impl crate::validate::Validate for MessagePriorityEnum {
2864    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2865        Ok(())
2866    }
2867}
2868/// If provided the Charging Station shall return Display Messages with the given state only.
2869#[derive(Debug, Clone, PartialEq, Eq)]
2870#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2871pub enum MessageStateEnum {
2872    Charging,
2873    Faulted,
2874    Idle,
2875    Unavailable,
2876    Suspended,
2877    Discharging,
2878}
2879#[cfg(feature = "validate")]
2880impl crate::validate::Validate for MessageStateEnum {
2881    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2882        Ok(())
2883    }
2884}
2885/// Indicates if the Charging Station has Display Messages that match the request criteria in the &lt;&lt;getdisplaymessagesrequest,GetDisplayMessagesRequest&gt;&gt;
2886#[derive(Debug, Clone, PartialEq, Eq)]
2887#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2888pub enum GetDisplayMessagesStatusEnum {
2889    Accepted,
2890    Unknown,
2891}
2892#[cfg(feature = "validate")]
2893impl crate::validate::Validate for GetDisplayMessagesStatusEnum {
2894    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2895        Ok(())
2896    }
2897}
2898#[derive(Debug, Clone, PartialEq, Eq)]
2899#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2900pub enum GetCertificateIdUseEnum {
2901    V2GRootCertificate,
2902    MORootCertificate,
2903    CSMSRootCertificate,
2904    V2GCertificateChain,
2905    ManufacturerRootCertificate,
2906    OEMRootCertificate,
2907}
2908#[cfg(feature = "validate")]
2909impl crate::validate::Validate for GetCertificateIdUseEnum {
2910    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2911        Ok(())
2912    }
2913}
2914#[derive(Debug, Clone, PartialEq, Eq)]
2915#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2916pub struct CertificateHashDataChain<CustomDataType = crate::NoCustomData> {
2917    #[cfg_attr(feature = "serde", serde(rename = "certificateHashData"))]
2918    pub certificate_hash_data: CertificateHashData<CustomDataType>,
2919    #[cfg_attr(feature = "serde", serde(rename = "certificateType"))]
2920    pub certificate_type: GetCertificateIdUseEnum,
2921    #[cfg_attr(feature = "serde", serde(rename = "childCertificateHashData"))]
2922    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2923    pub child_certificate_hash_data: Option<
2924        heapless::Vec<CertificateHashData<CustomDataType>, 4usize>,
2925    >,
2926    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2927    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2928    pub custom_data: Option<CustomDataType>,
2929}
2930#[cfg(feature = "validate")]
2931impl<CustomDataType> crate::validate::Validate
2932for CertificateHashDataChain<CustomDataType> {
2933    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2934        crate::validate::Validate::validate(&self.certificate_hash_data)
2935            .map_err(|error| error.in_field("certificateHashData"))?;
2936        crate::validate::Validate::validate(&self.certificate_type)
2937            .map_err(|error| error.in_field("certificateType"))?;
2938        if let Some(value) = &self.child_certificate_hash_data {
2939            crate::validate::check_min_items(value.len(), 1usize)
2940                .map_err(|error| error.in_field("childCertificateHashData"))?;
2941            for (index, item) in value.iter().enumerate() {
2942                crate::validate::Validate::validate(item)
2943                    .map_err(|error| {
2944                        error.in_index(index).in_field("childCertificateHashData")
2945                    })?;
2946            }
2947        }
2948        Ok(())
2949    }
2950}
2951/// Charging Station indicates if it can process the request.
2952#[derive(Debug, Clone, PartialEq, Eq)]
2953#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2954pub enum GetInstalledCertificateStatusEnum {
2955    Accepted,
2956    NotFound,
2957}
2958#[cfg(feature = "validate")]
2959impl crate::validate::Validate for GetInstalledCertificateStatusEnum {
2960    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2961        Ok(())
2962    }
2963}
2964#[cfg(feature = "alloc")]
2965/// Generic class for the configuration of logging entries.
2966#[derive(Debug, Clone, PartialEq, Eq)]
2967#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2968pub struct LogParameters<CustomDataType = crate::NoCustomData> {
2969    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
2970    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2971    pub custom_data: Option<CustomDataType>,
2972    /// This contains the date and time of the latest logging information to include in the diagnostics.
2973    #[cfg_attr(feature = "serde", serde(rename = "latestTimestamp"))]
2974    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2975    pub latest_timestamp: Option<crate::OcppTimestamp>,
2976    /// This contains the date and time of the oldest logging information to include in the diagnostics.
2977    #[cfg_attr(feature = "serde", serde(rename = "oldestTimestamp"))]
2978    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
2979    pub oldest_timestamp: Option<crate::OcppTimestamp>,
2980    /// The URL of the location at the remote system where the log should be stored.
2981    #[cfg_attr(feature = "serde", serde(rename = "remoteLocation"))]
2982    pub remote_location: alloc::string::String,
2983}
2984#[cfg(all(feature = "validate", feature = "alloc"))]
2985impl<CustomDataType> crate::validate::Validate for LogParameters<CustomDataType> {
2986    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
2987        crate::validate::check_max_length(&self.remote_location, 2000usize)
2988            .map_err(|error| error.in_field("remoteLocation"))?;
2989        Ok(())
2990    }
2991}
2992#[cfg(not(feature = "alloc"))]
2993/// Generic class for the configuration of logging entries.
2994#[derive(Debug, Clone, PartialEq, Eq)]
2995#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
2996pub struct LogParameters<
2997    CustomDataType = crate::NoCustomData,
2998    const LOG_PARAMETERS_REMOTE_LOCATION_CAP: usize = 1024usize,
2999> {
3000    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3001    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3002    pub custom_data: Option<CustomDataType>,
3003    /// This contains the date and time of the latest logging information to include in the diagnostics.
3004    #[cfg_attr(feature = "serde", serde(rename = "latestTimestamp"))]
3005    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3006    pub latest_timestamp: Option<crate::OcppTimestamp>,
3007    /// This contains the date and time of the oldest logging information to include in the diagnostics.
3008    #[cfg_attr(feature = "serde", serde(rename = "oldestTimestamp"))]
3009    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3010    pub oldest_timestamp: Option<crate::OcppTimestamp>,
3011    /// The URL of the location at the remote system where the log should be stored.
3012    #[cfg_attr(feature = "serde", serde(rename = "remoteLocation"))]
3013    pub remote_location: heapless::String<LOG_PARAMETERS_REMOTE_LOCATION_CAP>,
3014}
3015#[cfg(all(feature = "validate", not(feature = "alloc")))]
3016impl<
3017    CustomDataType,
3018    const LOG_PARAMETERS_REMOTE_LOCATION_CAP: usize,
3019> crate::validate::Validate
3020for LogParameters<CustomDataType, LOG_PARAMETERS_REMOTE_LOCATION_CAP> {
3021    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3022        crate::validate::check_max_length(&self.remote_location, 2000usize)
3023            .map_err(|error| error.in_field("remoteLocation"))?;
3024        Ok(())
3025    }
3026}
3027/// This contains the type of log file that the Charging Station
3028/// should send.
3029#[derive(Debug, Clone, PartialEq, Eq)]
3030#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3031pub enum LogEnum {
3032    DiagnosticsLog,
3033    SecurityLog,
3034    DataCollectorLog,
3035}
3036#[cfg(feature = "validate")]
3037impl crate::validate::Validate for LogEnum {
3038    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3039        Ok(())
3040    }
3041}
3042/// This field indicates whether the Charging Station was able to accept the request.
3043#[derive(Debug, Clone, PartialEq, Eq)]
3044#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3045pub enum LogStatusEnum {
3046    Accepted,
3047    Rejected,
3048    AcceptedCanceled,
3049}
3050#[cfg(feature = "validate")]
3051impl crate::validate::Validate for LogStatusEnum {
3052    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3053        Ok(())
3054    }
3055}
3056/// A physical or logical component
3057#[derive(Debug, Clone, PartialEq, Eq)]
3058#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3059pub struct Component<CustomDataType = crate::NoCustomData> {
3060    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3061    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3062    pub custom_data: Option<CustomDataType>,
3063    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3064    pub evse: Option<EVSE<CustomDataType>>,
3065    /// Name of instance in case the component exists as multiple instances. Case Insensitive. strongly advised to use Camel Case.
3066    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3067    pub instance: Option<heapless::String<50usize>>,
3068    /// Name of the component. Name should be taken from the list of standardized component names whenever possible. Case Insensitive. strongly advised to use Camel Case.
3069    pub name: heapless::String<50usize>,
3070}
3071#[cfg(feature = "validate")]
3072impl<CustomDataType> crate::validate::Validate for Component<CustomDataType> {
3073    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3074        if let Some(value) = &self.evse {
3075            crate::validate::Validate::validate(value)
3076                .map_err(|error| error.in_field("evse"))?;
3077        }
3078        Ok(())
3079    }
3080}
3081/// Reference key to a component-variable.
3082#[derive(Debug, Clone, PartialEq, Eq)]
3083#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3084pub struct Variable<CustomDataType = crate::NoCustomData> {
3085    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3086    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3087    pub custom_data: Option<CustomDataType>,
3088    /// Name of instance in case the variable exists as multiple instances. Case Insensitive. strongly advised to use Camel Case.
3089    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3090    pub instance: Option<heapless::String<50usize>>,
3091    /// Name of the variable. Name should be taken from the list of standardized variable names whenever possible. Case Insensitive. strongly advised to use Camel Case.
3092    pub name: heapless::String<50usize>,
3093}
3094#[cfg(feature = "validate")]
3095impl<CustomDataType> crate::validate::Validate for Variable<CustomDataType> {
3096    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3097        Ok(())
3098    }
3099}
3100/// Class to report components, variables and variable attributes and characteristics.
3101#[derive(Debug, Clone, PartialEq, Eq)]
3102#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3103pub struct ComponentVariable<CustomDataType = crate::NoCustomData> {
3104    pub component: Component<CustomDataType>,
3105    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3106    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3107    pub custom_data: Option<CustomDataType>,
3108    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3109    pub variable: Option<Variable<CustomDataType>>,
3110}
3111#[cfg(feature = "validate")]
3112impl<CustomDataType> crate::validate::Validate for ComponentVariable<CustomDataType> {
3113    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3114        crate::validate::Validate::validate(&self.component)
3115            .map_err(|error| error.in_field("component"))?;
3116        if let Some(value) = &self.variable {
3117            crate::validate::Validate::validate(value)
3118                .map_err(|error| error.in_field("variable"))?;
3119        }
3120        Ok(())
3121    }
3122}
3123#[derive(Debug, Clone, PartialEq, Eq)]
3124#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3125pub enum MonitoringCriterionEnum {
3126    ThresholdMonitoring,
3127    DeltaMonitoring,
3128    PeriodicMonitoring,
3129}
3130#[cfg(feature = "validate")]
3131impl crate::validate::Validate for MonitoringCriterionEnum {
3132    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3133        Ok(())
3134    }
3135}
3136#[derive(Debug, Clone, PartialEq, Eq)]
3137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3138pub struct ConstantStreamData<CustomDataType = crate::NoCustomData> {
3139    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3140    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3141    pub custom_data: Option<CustomDataType>,
3142    /// Uniquely identifies the stream
3143    pub id: i64,
3144    pub params: PeriodicEventStreamParams<CustomDataType>,
3145    /// Id of monitor used to report his event. It can be a preconfigured or hardwired monitor.
3146    #[cfg_attr(feature = "serde", serde(rename = "variableMonitoringId"))]
3147    pub variable_monitoring_id: i64,
3148}
3149#[cfg(feature = "validate")]
3150impl<CustomDataType> crate::validate::Validate for ConstantStreamData<CustomDataType> {
3151    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3152        crate::validate::check_min_i64(self.id, 0i64)
3153            .map_err(|error| error.in_field("id"))?;
3154        crate::validate::Validate::validate(&self.params)
3155            .map_err(|error| error.in_field("params"))?;
3156        crate::validate::check_min_i64(self.variable_monitoring_id, 0i64)
3157            .map_err(|error| error.in_field("variableMonitoringId"))?;
3158        Ok(())
3159    }
3160}
3161#[derive(Debug, Clone, PartialEq, Eq)]
3162#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3163pub enum ComponentCriterionEnum {
3164    Active,
3165    Available,
3166    Enabled,
3167    Problem,
3168}
3169#[cfg(feature = "validate")]
3170impl crate::validate::Validate for ComponentCriterionEnum {
3171    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3172        Ok(())
3173    }
3174}
3175/// Status of operation
3176#[derive(Debug, Clone, PartialEq, Eq)]
3177#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3178pub enum TariffGetStatusEnum {
3179    Accepted,
3180    Rejected,
3181    NoTariff,
3182}
3183#[cfg(feature = "validate")]
3184impl crate::validate::Validate for TariffGetStatusEnum {
3185    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3186        Ok(())
3187    }
3188}
3189/// Kind of tariff (driver/default)
3190#[derive(Debug, Clone, PartialEq, Eq)]
3191#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3192pub enum TariffKindEnum {
3193    DefaultTariff,
3194    DriverTariff,
3195}
3196#[cfg(feature = "validate")]
3197impl crate::validate::Validate for TariffKindEnum {
3198    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3199        Ok(())
3200    }
3201}
3202#[cfg(feature = "alloc")]
3203/// Shows assignment of tariffs to EVSE or IdToken.
3204#[derive(Debug, Clone, PartialEq, Eq)]
3205#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3206pub struct TariffAssignment<CustomDataType = crate::NoCustomData> {
3207    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3208    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3209    pub custom_data: Option<CustomDataType>,
3210    #[cfg_attr(feature = "serde", serde(rename = "evseIds"))]
3211    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3212    pub evse_ids: Option<alloc::vec::Vec<i64>>,
3213    /// IdTokens related to tariff
3214    #[cfg_attr(feature = "serde", serde(rename = "idTokens"))]
3215    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3216    pub id_tokens: Option<alloc::vec::Vec<heapless::String<255usize>>>,
3217    /// Tariff id.
3218    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
3219    pub tariff_id: heapless::String<60usize>,
3220    #[cfg_attr(feature = "serde", serde(rename = "tariffKind"))]
3221    pub tariff_kind: TariffKindEnum,
3222    /// Date/time when this tariff become active.
3223    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
3224    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3225    pub valid_from: Option<crate::OcppTimestamp>,
3226}
3227#[cfg(all(feature = "validate", feature = "alloc"))]
3228impl<CustomDataType> crate::validate::Validate for TariffAssignment<CustomDataType> {
3229    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3230        if let Some(value) = &self.evse_ids {
3231            crate::validate::check_min_items(value.len(), 1usize)
3232                .map_err(|error| error.in_field("evseIds"))?;
3233            for (index, item) in value.iter().enumerate() {
3234                crate::validate::check_min_i64(*item, 0i64)
3235                    .map_err(|error| error.in_index(index).in_field("evseIds"))?;
3236            }
3237        }
3238        if let Some(value) = &self.id_tokens {
3239            crate::validate::check_min_items(value.len(), 1usize)
3240                .map_err(|error| error.in_field("idTokens"))?;
3241        }
3242        crate::validate::Validate::validate(&self.tariff_kind)
3243            .map_err(|error| error.in_field("tariffKind"))?;
3244        Ok(())
3245    }
3246}
3247#[cfg(not(feature = "alloc"))]
3248/// Shows assignment of tariffs to EVSE or IdToken.
3249#[derive(Debug, Clone, PartialEq, Eq)]
3250#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3251pub struct TariffAssignment<
3252    CustomDataType = crate::NoCustomData,
3253    const TARIFF_ASSIGNMENT_EVSE_IDS_CAP: usize = 8usize,
3254    const TARIFF_ASSIGNMENT_ID_TOKENS_CAP: usize = 8usize,
3255> {
3256    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3257    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3258    pub custom_data: Option<CustomDataType>,
3259    #[cfg_attr(feature = "serde", serde(rename = "evseIds"))]
3260    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3261    pub evse_ids: Option<heapless::Vec<i64, TARIFF_ASSIGNMENT_EVSE_IDS_CAP>>,
3262    /// IdTokens related to tariff
3263    #[cfg_attr(feature = "serde", serde(rename = "idTokens"))]
3264    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3265    pub id_tokens: Option<
3266        heapless::Vec<heapless::String<255usize>, TARIFF_ASSIGNMENT_ID_TOKENS_CAP>,
3267    >,
3268    /// Tariff id.
3269    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
3270    pub tariff_id: heapless::String<60usize>,
3271    #[cfg_attr(feature = "serde", serde(rename = "tariffKind"))]
3272    pub tariff_kind: TariffKindEnum,
3273    /// Date/time when this tariff become active.
3274    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
3275    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3276    pub valid_from: Option<crate::OcppTimestamp>,
3277}
3278#[cfg(all(feature = "validate", not(feature = "alloc")))]
3279impl<
3280    CustomDataType,
3281    const TARIFF_ASSIGNMENT_EVSE_IDS_CAP: usize,
3282    const TARIFF_ASSIGNMENT_ID_TOKENS_CAP: usize,
3283> crate::validate::Validate
3284for TariffAssignment<
3285    CustomDataType,
3286    TARIFF_ASSIGNMENT_EVSE_IDS_CAP,
3287    TARIFF_ASSIGNMENT_ID_TOKENS_CAP,
3288> {
3289    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3290        if let Some(value) = &self.evse_ids {
3291            crate::validate::check_min_items(value.len(), 1usize)
3292                .map_err(|error| error.in_field("evseIds"))?;
3293            for (index, item) in value.iter().enumerate() {
3294                crate::validate::check_min_i64(*item, 0i64)
3295                    .map_err(|error| error.in_index(index).in_field("evseIds"))?;
3296            }
3297        }
3298        if let Some(value) = &self.id_tokens {
3299            crate::validate::check_min_items(value.len(), 1usize)
3300                .map_err(|error| error.in_field("idTokens"))?;
3301        }
3302        crate::validate::Validate::validate(&self.tariff_kind)
3303            .map_err(|error| error.in_field("tariffKind"))?;
3304        Ok(())
3305    }
3306}
3307/// Attribute type for which value is requested. When absent, default Actual is assumed.
3308#[derive(Debug, Clone, PartialEq, Eq)]
3309#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3310pub enum AttributeEnum {
3311    Actual,
3312    Target,
3313    MinSet,
3314    MaxSet,
3315}
3316#[cfg(feature = "validate")]
3317impl crate::validate::Validate for AttributeEnum {
3318    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3319        Ok(())
3320    }
3321}
3322/// Class to hold parameters for GetVariables request.
3323#[derive(Debug, Clone, PartialEq, Eq)]
3324#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3325pub struct GetVariableData<CustomDataType = crate::NoCustomData> {
3326    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
3327    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3328    pub attribute_type: Option<AttributeEnum>,
3329    pub component: Component<CustomDataType>,
3330    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3331    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3332    pub custom_data: Option<CustomDataType>,
3333    pub variable: Variable<CustomDataType>,
3334}
3335#[cfg(feature = "validate")]
3336impl<CustomDataType> crate::validate::Validate for GetVariableData<CustomDataType> {
3337    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3338        if let Some(value) = &self.attribute_type {
3339            crate::validate::Validate::validate(value)
3340                .map_err(|error| error.in_field("attributeType"))?;
3341        }
3342        crate::validate::Validate::validate(&self.component)
3343            .map_err(|error| error.in_field("component"))?;
3344        crate::validate::Validate::validate(&self.variable)
3345            .map_err(|error| error.in_field("variable"))?;
3346        Ok(())
3347    }
3348}
3349#[derive(Debug, Clone, PartialEq, Eq)]
3350#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3351pub enum GetVariableStatusEnum {
3352    Accepted,
3353    Rejected,
3354    UnknownComponent,
3355    UnknownVariable,
3356    NotSupportedAttributeType,
3357}
3358#[cfg(feature = "validate")]
3359impl crate::validate::Validate for GetVariableStatusEnum {
3360    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3361        Ok(())
3362    }
3363}
3364#[cfg(feature = "alloc")]
3365/// Class to hold results of GetVariables request.
3366#[derive(Debug, Clone, PartialEq, Eq)]
3367#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3368pub struct GetVariableResult<CustomDataType = crate::NoCustomData> {
3369    #[cfg_attr(feature = "serde", serde(rename = "attributeStatus"))]
3370    pub attribute_status: GetVariableStatusEnum,
3371    #[cfg_attr(feature = "serde", serde(rename = "attributeStatusInfo"))]
3372    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3373    pub attribute_status_info: Option<StatusInfo<CustomDataType>>,
3374    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
3375    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3376    pub attribute_type: Option<AttributeEnum>,
3377    /// Value of requested attribute type of component-variable. This field can only be empty when the given status is NOT accepted.
3378    ///
3379    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
3380    #[cfg_attr(feature = "serde", serde(rename = "attributeValue"))]
3381    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3382    pub attribute_value: Option<alloc::string::String>,
3383    pub component: Component<CustomDataType>,
3384    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3385    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3386    pub custom_data: Option<CustomDataType>,
3387    pub variable: Variable<CustomDataType>,
3388}
3389#[cfg(all(feature = "validate", feature = "alloc"))]
3390impl<CustomDataType> crate::validate::Validate for GetVariableResult<CustomDataType> {
3391    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3392        crate::validate::Validate::validate(&self.attribute_status)
3393            .map_err(|error| error.in_field("attributeStatus"))?;
3394        if let Some(value) = &self.attribute_status_info {
3395            crate::validate::Validate::validate(value)
3396                .map_err(|error| error.in_field("attributeStatusInfo"))?;
3397        }
3398        if let Some(value) = &self.attribute_type {
3399            crate::validate::Validate::validate(value)
3400                .map_err(|error| error.in_field("attributeType"))?;
3401        }
3402        if let Some(value) = &self.attribute_value {
3403            crate::validate::check_max_length(value, 2500usize)
3404                .map_err(|error| error.in_field("attributeValue"))?;
3405        }
3406        crate::validate::Validate::validate(&self.component)
3407            .map_err(|error| error.in_field("component"))?;
3408        crate::validate::Validate::validate(&self.variable)
3409            .map_err(|error| error.in_field("variable"))?;
3410        Ok(())
3411    }
3412}
3413#[cfg(not(feature = "alloc"))]
3414/// Class to hold results of GetVariables request.
3415#[derive(Debug, Clone, PartialEq, Eq)]
3416#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3417pub struct GetVariableResult<
3418    CustomDataType = crate::NoCustomData,
3419    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
3420    const GET_VARIABLE_RESULT_ATTRIBUTE_VALUE_CAP: usize = 1024usize,
3421> {
3422    #[cfg_attr(feature = "serde", serde(rename = "attributeStatus"))]
3423    pub attribute_status: GetVariableStatusEnum,
3424    #[cfg_attr(feature = "serde", serde(rename = "attributeStatusInfo"))]
3425    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3426    pub attribute_status_info: Option<
3427        StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP>,
3428    >,
3429    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
3430    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3431    pub attribute_type: Option<AttributeEnum>,
3432    /// Value of requested attribute type of component-variable. This field can only be empty when the given status is NOT accepted.
3433    ///
3434    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
3435    #[cfg_attr(feature = "serde", serde(rename = "attributeValue"))]
3436    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3437    pub attribute_value: Option<
3438        heapless::String<GET_VARIABLE_RESULT_ATTRIBUTE_VALUE_CAP>,
3439    >,
3440    pub component: Component<CustomDataType>,
3441    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3442    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3443    pub custom_data: Option<CustomDataType>,
3444    pub variable: Variable<CustomDataType>,
3445}
3446#[cfg(all(feature = "validate", not(feature = "alloc")))]
3447impl<
3448    CustomDataType,
3449    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
3450    const GET_VARIABLE_RESULT_ATTRIBUTE_VALUE_CAP: usize,
3451> crate::validate::Validate
3452for GetVariableResult<
3453    CustomDataType,
3454    STATUS_INFO_ADDITIONAL_INFO_CAP,
3455    GET_VARIABLE_RESULT_ATTRIBUTE_VALUE_CAP,
3456> {
3457    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3458        crate::validate::Validate::validate(&self.attribute_status)
3459            .map_err(|error| error.in_field("attributeStatus"))?;
3460        if let Some(value) = &self.attribute_status_info {
3461            crate::validate::Validate::validate(value)
3462                .map_err(|error| error.in_field("attributeStatusInfo"))?;
3463        }
3464        if let Some(value) = &self.attribute_type {
3465            crate::validate::Validate::validate(value)
3466                .map_err(|error| error.in_field("attributeType"))?;
3467        }
3468        if let Some(value) = &self.attribute_value {
3469            crate::validate::check_max_length(value, 2500usize)
3470                .map_err(|error| error.in_field("attributeValue"))?;
3471        }
3472        crate::validate::Validate::validate(&self.component)
3473            .map_err(|error| error.in_field("component"))?;
3474        crate::validate::Validate::validate(&self.variable)
3475            .map_err(|error| error.in_field("variable"))?;
3476        Ok(())
3477    }
3478}
3479/// Indicates the certificate type that is sent.
3480#[derive(Debug, Clone, PartialEq, Eq)]
3481#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3482pub enum InstallCertificateUseEnum {
3483    V2GRootCertificate,
3484    MORootCertificate,
3485    ManufacturerRootCertificate,
3486    CSMSRootCertificate,
3487    OEMRootCertificate,
3488}
3489#[cfg(feature = "validate")]
3490impl crate::validate::Validate for InstallCertificateUseEnum {
3491    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3492        Ok(())
3493    }
3494}
3495/// Charging Station indicates if installation was successful.
3496#[derive(Debug, Clone, PartialEq, Eq)]
3497#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3498pub enum InstallCertificateStatusEnum {
3499    Accepted,
3500    Rejected,
3501    Failed,
3502}
3503#[cfg(feature = "validate")]
3504impl crate::validate::Validate for InstallCertificateStatusEnum {
3505    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3506        Ok(())
3507    }
3508}
3509/// This contains the status of the log upload.
3510#[derive(Debug, Clone, PartialEq, Eq)]
3511#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3512pub enum UploadLogStatusEnum {
3513    BadMessage,
3514    Idle,
3515    NotSupportedOperation,
3516    PermissionDenied,
3517    Uploaded,
3518    UploadFailure,
3519    Uploading,
3520    AcceptedCanceled,
3521}
3522#[cfg(feature = "validate")]
3523impl crate::validate::Validate for UploadLogStatusEnum {
3524    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3525        Ok(())
3526    }
3527}
3528/// Type of detail value: start, end or sample. Default = "Sample.Periodic"
3529#[derive(Debug, Clone, PartialEq, Eq)]
3530#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3531pub enum ReadingContextEnum {
3532    #[cfg_attr(feature = "serde", serde(rename = "Interruption.Begin"))]
3533    InterruptionBegin,
3534    #[cfg_attr(feature = "serde", serde(rename = "Interruption.End"))]
3535    InterruptionEnd,
3536    Other,
3537    #[cfg_attr(feature = "serde", serde(rename = "Sample.Clock"))]
3538    SampleClock,
3539    #[cfg_attr(feature = "serde", serde(rename = "Sample.Periodic"))]
3540    SamplePeriodic,
3541    #[cfg_attr(feature = "serde", serde(rename = "Transaction.Begin"))]
3542    TransactionBegin,
3543    #[cfg_attr(feature = "serde", serde(rename = "Transaction.End"))]
3544    TransactionEnd,
3545    Trigger,
3546}
3547#[cfg(feature = "validate")]
3548impl crate::validate::Validate for ReadingContextEnum {
3549    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3550        Ok(())
3551    }
3552}
3553/// Indicates where the measured value has been sampled. Default =  "Outlet"
3554#[derive(Debug, Clone, PartialEq, Eq)]
3555#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3556pub enum LocationEnum {
3557    Body,
3558    Cable,
3559    EV,
3560    Inlet,
3561    Outlet,
3562    Upstream,
3563}
3564#[cfg(feature = "validate")]
3565impl crate::validate::Validate for LocationEnum {
3566    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3567        Ok(())
3568    }
3569}
3570/// Type of measurement. Default = "Energy.Active.Import.Register"
3571#[derive(Debug, Clone, PartialEq, Eq)]
3572#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3573pub enum MeasurandEnum {
3574    #[cfg_attr(feature = "serde", serde(rename = "Current.Export"))]
3575    CurrentExport,
3576    #[cfg_attr(feature = "serde", serde(rename = "Current.Export.Offered"))]
3577    CurrentExportOffered,
3578    #[cfg_attr(feature = "serde", serde(rename = "Current.Export.Minimum"))]
3579    CurrentExportMinimum,
3580    #[cfg_attr(feature = "serde", serde(rename = "Current.Import"))]
3581    CurrentImport,
3582    #[cfg_attr(feature = "serde", serde(rename = "Current.Import.Offered"))]
3583    CurrentImportOffered,
3584    #[cfg_attr(feature = "serde", serde(rename = "Current.Import.Minimum"))]
3585    CurrentImportMinimum,
3586    #[cfg_attr(feature = "serde", serde(rename = "Current.Offered"))]
3587    CurrentOffered,
3588    #[cfg_attr(feature = "serde", serde(rename = "Display.PresentSOC"))]
3589    DisplayPresentSOC,
3590    #[cfg_attr(feature = "serde", serde(rename = "Display.MinimumSOC"))]
3591    DisplayMinimumSOC,
3592    #[cfg_attr(feature = "serde", serde(rename = "Display.TargetSOC"))]
3593    DisplayTargetSOC,
3594    #[cfg_attr(feature = "serde", serde(rename = "Display.MaximumSOC"))]
3595    DisplayMaximumSOC,
3596    #[cfg_attr(feature = "serde", serde(rename = "Display.RemainingTimeToMinimumSOC"))]
3597    DisplayRemainingTimeToMinimumSOC,
3598    #[cfg_attr(feature = "serde", serde(rename = "Display.RemainingTimeToTargetSOC"))]
3599    DisplayRemainingTimeToTargetSOC,
3600    #[cfg_attr(feature = "serde", serde(rename = "Display.RemainingTimeToMaximumSOC"))]
3601    DisplayRemainingTimeToMaximumSOC,
3602    #[cfg_attr(feature = "serde", serde(rename = "Display.ChargingComplete"))]
3603    DisplayChargingComplete,
3604    #[cfg_attr(feature = "serde", serde(rename = "Display.BatteryEnergyCapacity"))]
3605    DisplayBatteryEnergyCapacity,
3606    #[cfg_attr(feature = "serde", serde(rename = "Display.InletHot"))]
3607    DisplayInletHot,
3608    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Export.Interval"))]
3609    EnergyActiveExportInterval,
3610    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Export.Register"))]
3611    EnergyActiveExportRegister,
3612    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Import.Interval"))]
3613    EnergyActiveImportInterval,
3614    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Import.Register"))]
3615    EnergyActiveImportRegister,
3616    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Import.CableLoss"))]
3617    EnergyActiveImportCableLoss,
3618    #[cfg_attr(
3619        feature = "serde",
3620        serde(rename = "Energy.Active.Import.LocalGeneration.Register")
3621    )]
3622    EnergyActiveImportLocalGenerationRegister,
3623    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Net"))]
3624    EnergyActiveNet,
3625    #[cfg_attr(feature = "serde", serde(rename = "Energy.Active.Setpoint.Interval"))]
3626    EnergyActiveSetpointInterval,
3627    #[cfg_attr(feature = "serde", serde(rename = "Energy.Apparent.Export"))]
3628    EnergyApparentExport,
3629    #[cfg_attr(feature = "serde", serde(rename = "Energy.Apparent.Import"))]
3630    EnergyApparentImport,
3631    #[cfg_attr(feature = "serde", serde(rename = "Energy.Apparent.Net"))]
3632    EnergyApparentNet,
3633    #[cfg_attr(feature = "serde", serde(rename = "Energy.Reactive.Export.Interval"))]
3634    EnergyReactiveExportInterval,
3635    #[cfg_attr(feature = "serde", serde(rename = "Energy.Reactive.Export.Register"))]
3636    EnergyReactiveExportRegister,
3637    #[cfg_attr(feature = "serde", serde(rename = "Energy.Reactive.Import.Interval"))]
3638    EnergyReactiveImportInterval,
3639    #[cfg_attr(feature = "serde", serde(rename = "Energy.Reactive.Import.Register"))]
3640    EnergyReactiveImportRegister,
3641    #[cfg_attr(feature = "serde", serde(rename = "Energy.Reactive.Net"))]
3642    EnergyReactiveNet,
3643    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Target"))]
3644    EnergyRequestTarget,
3645    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Minimum"))]
3646    EnergyRequestMinimum,
3647    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Maximum"))]
3648    EnergyRequestMaximum,
3649    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Minimum.V2X"))]
3650    EnergyRequestMinimumV2X,
3651    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Maximum.V2X"))]
3652    EnergyRequestMaximumV2X,
3653    #[cfg_attr(feature = "serde", serde(rename = "EnergyRequest.Bulk"))]
3654    EnergyRequestBulk,
3655    Frequency,
3656    #[cfg_attr(feature = "serde", serde(rename = "Power.Active.Export"))]
3657    PowerActiveExport,
3658    #[cfg_attr(feature = "serde", serde(rename = "Power.Active.Import"))]
3659    PowerActiveImport,
3660    #[cfg_attr(feature = "serde", serde(rename = "Power.Active.Setpoint"))]
3661    PowerActiveSetpoint,
3662    #[cfg_attr(feature = "serde", serde(rename = "Power.Active.Residual"))]
3663    PowerActiveResidual,
3664    #[cfg_attr(feature = "serde", serde(rename = "Power.Export.Minimum"))]
3665    PowerExportMinimum,
3666    #[cfg_attr(feature = "serde", serde(rename = "Power.Export.Offered"))]
3667    PowerExportOffered,
3668    #[cfg_attr(feature = "serde", serde(rename = "Power.Factor"))]
3669    PowerFactor,
3670    #[cfg_attr(feature = "serde", serde(rename = "Power.Import.Offered"))]
3671    PowerImportOffered,
3672    #[cfg_attr(feature = "serde", serde(rename = "Power.Import.Minimum"))]
3673    PowerImportMinimum,
3674    #[cfg_attr(feature = "serde", serde(rename = "Power.Offered"))]
3675    PowerOffered,
3676    #[cfg_attr(feature = "serde", serde(rename = "Power.Reactive.Export"))]
3677    PowerReactiveExport,
3678    #[cfg_attr(feature = "serde", serde(rename = "Power.Reactive.Import"))]
3679    PowerReactiveImport,
3680    SoC,
3681    Voltage,
3682    #[cfg_attr(feature = "serde", serde(rename = "Voltage.Minimum"))]
3683    VoltageMinimum,
3684    #[cfg_attr(feature = "serde", serde(rename = "Voltage.Maximum"))]
3685    VoltageMaximum,
3686}
3687#[cfg(feature = "validate")]
3688impl crate::validate::Validate for MeasurandEnum {
3689    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3690        Ok(())
3691    }
3692}
3693/// Indicates how the measured value is to be interpreted. For instance between L1 and neutral (L1-N) Please note that not all values of phase are applicable to all Measurands. When phase is absent, the measured value is interpreted as an overall value.
3694#[derive(Debug, Clone, PartialEq, Eq)]
3695#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3696pub enum PhaseEnum {
3697    L1,
3698    L2,
3699    L3,
3700    N,
3701    #[cfg_attr(feature = "serde", serde(rename = "L1-N"))]
3702    L1N,
3703    #[cfg_attr(feature = "serde", serde(rename = "L2-N"))]
3704    L2N,
3705    #[cfg_attr(feature = "serde", serde(rename = "L3-N"))]
3706    L3N,
3707    #[cfg_attr(feature = "serde", serde(rename = "L1-L2"))]
3708    L1L2,
3709    #[cfg_attr(feature = "serde", serde(rename = "L2-L3"))]
3710    L2L3,
3711    #[cfg_attr(feature = "serde", serde(rename = "L3-L1"))]
3712    L3L1,
3713}
3714#[cfg(feature = "validate")]
3715impl crate::validate::Validate for PhaseEnum {
3716    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3717        Ok(())
3718    }
3719}
3720#[cfg(feature = "alloc")]
3721/// Represent a signed version of the meter value.
3722#[derive(Debug, Clone, PartialEq, Eq)]
3723#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3724pub struct SignedMeterValue<CustomDataType = crate::NoCustomData> {
3725    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3726    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3727    pub custom_data: Option<CustomDataType>,
3728    /// Format used by the energy meter to encode the meter data. For example: OCMF or EDL.
3729    #[cfg_attr(feature = "serde", serde(rename = "encodingMethod"))]
3730    pub encoding_method: heapless::String<50usize>,
3731    /// *(2.1)* Base64 encoded, sending depends on configuration variable _PublicKeyWithSignedMeterValue_.
3732    #[cfg_attr(feature = "serde", serde(rename = "publicKey"))]
3733    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3734    pub public_key: Option<alloc::string::String>,
3735    /// Base64 encoded, contains the signed data from the meter in the format specified in _encodingMethod_, which might contain more then just the meter value. It can contain information like timestamps, reference to a customer etc.
3736    #[cfg_attr(feature = "serde", serde(rename = "signedMeterData"))]
3737    pub signed_meter_data: alloc::string::String,
3738    /// *(2.1)* Method used to create the digital signature. Optional, if already included in _signedMeterData_. Standard values for this are defined in Appendix as SigningMethodEnumStringType.
3739    #[cfg_attr(feature = "serde", serde(rename = "signingMethod"))]
3740    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3741    pub signing_method: Option<heapless::String<50usize>>,
3742}
3743#[cfg(all(feature = "validate", feature = "alloc"))]
3744impl<CustomDataType> crate::validate::Validate for SignedMeterValue<CustomDataType> {
3745    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3746        if let Some(value) = &self.public_key {
3747            crate::validate::check_max_length(value, 2500usize)
3748                .map_err(|error| error.in_field("publicKey"))?;
3749        }
3750        crate::validate::check_max_length(&self.signed_meter_data, 32768usize)
3751            .map_err(|error| error.in_field("signedMeterData"))?;
3752        Ok(())
3753    }
3754}
3755#[cfg(not(feature = "alloc"))]
3756/// Represent a signed version of the meter value.
3757#[derive(Debug, Clone, PartialEq, Eq)]
3758#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3759pub struct SignedMeterValue<
3760    CustomDataType = crate::NoCustomData,
3761    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize = 1024usize,
3762    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize = 1024usize,
3763> {
3764    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3765    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3766    pub custom_data: Option<CustomDataType>,
3767    /// Format used by the energy meter to encode the meter data. For example: OCMF or EDL.
3768    #[cfg_attr(feature = "serde", serde(rename = "encodingMethod"))]
3769    pub encoding_method: heapless::String<50usize>,
3770    /// *(2.1)* Base64 encoded, sending depends on configuration variable _PublicKeyWithSignedMeterValue_.
3771    #[cfg_attr(feature = "serde", serde(rename = "publicKey"))]
3772    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3773    pub public_key: Option<heapless::String<SIGNED_METER_VALUE_PUBLIC_KEY_CAP>>,
3774    /// Base64 encoded, contains the signed data from the meter in the format specified in _encodingMethod_, which might contain more then just the meter value. It can contain information like timestamps, reference to a customer etc.
3775    #[cfg_attr(feature = "serde", serde(rename = "signedMeterData"))]
3776    pub signed_meter_data: heapless::String<SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP>,
3777    /// *(2.1)* Method used to create the digital signature. Optional, if already included in _signedMeterData_. Standard values for this are defined in Appendix as SigningMethodEnumStringType.
3778    #[cfg_attr(feature = "serde", serde(rename = "signingMethod"))]
3779    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3780    pub signing_method: Option<heapless::String<50usize>>,
3781}
3782#[cfg(all(feature = "validate", not(feature = "alloc")))]
3783impl<
3784    CustomDataType,
3785    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize,
3786    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize,
3787> crate::validate::Validate
3788for SignedMeterValue<
3789    CustomDataType,
3790    SIGNED_METER_VALUE_PUBLIC_KEY_CAP,
3791    SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP,
3792> {
3793    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3794        if let Some(value) = &self.public_key {
3795            crate::validate::check_max_length(value, 2500usize)
3796                .map_err(|error| error.in_field("publicKey"))?;
3797        }
3798        crate::validate::check_max_length(&self.signed_meter_data, 32768usize)
3799            .map_err(|error| error.in_field("signedMeterData"))?;
3800        Ok(())
3801    }
3802}
3803/// Represents a UnitOfMeasure with a multiplier
3804#[derive(Debug, Clone, PartialEq, Eq)]
3805#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3806pub struct UnitOfMeasure<CustomDataType = crate::NoCustomData> {
3807    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3808    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3809    pub custom_data: Option<CustomDataType>,
3810    /// Multiplier, this value represents the exponent to base 10. I.e. multiplier 3 means 10 raised to the 3rd power. Default is 0. +
3811    /// The _multiplier_ only multiplies the value of the measurand. It does not specify a conversion between units, for example, kW and W.
3812    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3813    pub multiplier: Option<i64>,
3814    /// Unit of the value. Default = "Wh" if the (default) measurand is an "Energy" type.
3815    /// This field SHALL use a value from the list Standardized Units of Measurements in Part 2 Appendices.
3816    /// If an applicable unit is available in that list, otherwise a "custom" unit might be used.
3817    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3818    pub unit: Option<heapless::String<20usize>>,
3819}
3820#[cfg(feature = "validate")]
3821impl<CustomDataType> crate::validate::Validate for UnitOfMeasure<CustomDataType> {
3822    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3823        Ok(())
3824    }
3825}
3826#[cfg(feature = "alloc")]
3827/// Single sampled value in MeterValues. Each value can be accompanied by optional fields.
3828///
3829/// To save on mobile data usage, default values of all of the optional fields are such that. The value without any additional fields will be interpreted, as a register reading of active import energy in Wh (Watt-hour) units.
3830#[derive(Debug, Clone, PartialEq)]
3831#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3832pub struct SampledValue<CustomDataType = crate::NoCustomData> {
3833    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3834    pub context: Option<ReadingContextEnum>,
3835    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3836    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3837    pub custom_data: Option<CustomDataType>,
3838    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3839    pub location: Option<LocationEnum>,
3840    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3841    pub measurand: Option<MeasurandEnum>,
3842    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3843    pub phase: Option<PhaseEnum>,
3844    #[cfg_attr(feature = "serde", serde(rename = "signedMeterValue"))]
3845    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3846    pub signed_meter_value: Option<SignedMeterValue<CustomDataType>>,
3847    #[cfg_attr(feature = "serde", serde(rename = "unitOfMeasure"))]
3848    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3849    pub unit_of_measure: Option<UnitOfMeasure<CustomDataType>>,
3850    /// Indicates the measured value.
3851    pub value: f64,
3852}
3853#[cfg(all(feature = "validate", feature = "alloc"))]
3854impl<CustomDataType> crate::validate::Validate for SampledValue<CustomDataType> {
3855    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3856        if let Some(value) = &self.context {
3857            crate::validate::Validate::validate(value)
3858                .map_err(|error| error.in_field("context"))?;
3859        }
3860        if let Some(value) = &self.location {
3861            crate::validate::Validate::validate(value)
3862                .map_err(|error| error.in_field("location"))?;
3863        }
3864        if let Some(value) = &self.measurand {
3865            crate::validate::Validate::validate(value)
3866                .map_err(|error| error.in_field("measurand"))?;
3867        }
3868        if let Some(value) = &self.phase {
3869            crate::validate::Validate::validate(value)
3870                .map_err(|error| error.in_field("phase"))?;
3871        }
3872        if let Some(value) = &self.signed_meter_value {
3873            crate::validate::Validate::validate(value)
3874                .map_err(|error| error.in_field("signedMeterValue"))?;
3875        }
3876        if let Some(value) = &self.unit_of_measure {
3877            crate::validate::Validate::validate(value)
3878                .map_err(|error| error.in_field("unitOfMeasure"))?;
3879        }
3880        Ok(())
3881    }
3882}
3883#[cfg(not(feature = "alloc"))]
3884/// Single sampled value in MeterValues. Each value can be accompanied by optional fields.
3885///
3886/// To save on mobile data usage, default values of all of the optional fields are such that. The value without any additional fields will be interpreted, as a register reading of active import energy in Wh (Watt-hour) units.
3887#[derive(Debug, Clone, PartialEq)]
3888#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3889pub struct SampledValue<
3890    CustomDataType = crate::NoCustomData,
3891    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize = 1024usize,
3892    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize = 1024usize,
3893> {
3894    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3895    pub context: Option<ReadingContextEnum>,
3896    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3897    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3898    pub custom_data: Option<CustomDataType>,
3899    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3900    pub location: Option<LocationEnum>,
3901    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3902    pub measurand: Option<MeasurandEnum>,
3903    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3904    pub phase: Option<PhaseEnum>,
3905    #[cfg_attr(feature = "serde", serde(rename = "signedMeterValue"))]
3906    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3907    pub signed_meter_value: Option<
3908        SignedMeterValue<
3909            CustomDataType,
3910            SIGNED_METER_VALUE_PUBLIC_KEY_CAP,
3911            SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP,
3912        >,
3913    >,
3914    #[cfg_attr(feature = "serde", serde(rename = "unitOfMeasure"))]
3915    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3916    pub unit_of_measure: Option<UnitOfMeasure<CustomDataType>>,
3917    /// Indicates the measured value.
3918    pub value: f64,
3919}
3920#[cfg(all(feature = "validate", not(feature = "alloc")))]
3921impl<
3922    CustomDataType,
3923    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize,
3924    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize,
3925> crate::validate::Validate
3926for SampledValue<
3927    CustomDataType,
3928    SIGNED_METER_VALUE_PUBLIC_KEY_CAP,
3929    SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP,
3930> {
3931    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3932        if let Some(value) = &self.context {
3933            crate::validate::Validate::validate(value)
3934                .map_err(|error| error.in_field("context"))?;
3935        }
3936        if let Some(value) = &self.location {
3937            crate::validate::Validate::validate(value)
3938                .map_err(|error| error.in_field("location"))?;
3939        }
3940        if let Some(value) = &self.measurand {
3941            crate::validate::Validate::validate(value)
3942                .map_err(|error| error.in_field("measurand"))?;
3943        }
3944        if let Some(value) = &self.phase {
3945            crate::validate::Validate::validate(value)
3946                .map_err(|error| error.in_field("phase"))?;
3947        }
3948        if let Some(value) = &self.signed_meter_value {
3949            crate::validate::Validate::validate(value)
3950                .map_err(|error| error.in_field("signedMeterValue"))?;
3951        }
3952        if let Some(value) = &self.unit_of_measure {
3953            crate::validate::Validate::validate(value)
3954                .map_err(|error| error.in_field("unitOfMeasure"))?;
3955        }
3956        Ok(())
3957    }
3958}
3959#[cfg(feature = "alloc")]
3960/// Collection of one or more sampled values in MeterValuesRequest and TransactionEvent. All sampled values in a MeterValue are sampled at the same point in time.
3961#[derive(Debug, Clone, PartialEq)]
3962#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3963pub struct MeterValue<CustomDataType = crate::NoCustomData> {
3964    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3965    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3966    pub custom_data: Option<CustomDataType>,
3967    #[cfg_attr(feature = "serde", serde(rename = "sampledValue"))]
3968    pub sampled_value: alloc::vec::Vec<SampledValue<CustomDataType>>,
3969    /// Timestamp for measured value(s).
3970    pub timestamp: crate::OcppTimestamp,
3971}
3972#[cfg(all(feature = "validate", feature = "alloc"))]
3973impl<CustomDataType> crate::validate::Validate for MeterValue<CustomDataType> {
3974    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
3975        crate::validate::check_min_items(self.sampled_value.len(), 1usize)
3976            .map_err(|error| error.in_field("sampledValue"))?;
3977        for (index, item) in self.sampled_value.iter().enumerate() {
3978            crate::validate::Validate::validate(item)
3979                .map_err(|error| error.in_index(index).in_field("sampledValue"))?;
3980        }
3981        Ok(())
3982    }
3983}
3984#[cfg(not(feature = "alloc"))]
3985/// Collection of one or more sampled values in MeterValuesRequest and TransactionEvent. All sampled values in a MeterValue are sampled at the same point in time.
3986#[derive(Debug, Clone, PartialEq)]
3987#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
3988pub struct MeterValue<
3989    CustomDataType = crate::NoCustomData,
3990    const METER_VALUE_SAMPLED_VALUE_CAP: usize = 8usize,
3991    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize = 1024usize,
3992    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize = 1024usize,
3993> {
3994    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
3995    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
3996    pub custom_data: Option<CustomDataType>,
3997    #[cfg_attr(feature = "serde", serde(rename = "sampledValue"))]
3998    pub sampled_value: heapless::Vec<
3999        SampledValue<
4000            CustomDataType,
4001            SIGNED_METER_VALUE_PUBLIC_KEY_CAP,
4002            SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP,
4003        >,
4004        METER_VALUE_SAMPLED_VALUE_CAP,
4005    >,
4006    /// Timestamp for measured value(s).
4007    pub timestamp: crate::OcppTimestamp,
4008}
4009#[cfg(all(feature = "validate", not(feature = "alloc")))]
4010impl<
4011    CustomDataType,
4012    const METER_VALUE_SAMPLED_VALUE_CAP: usize,
4013    const SIGNED_METER_VALUE_PUBLIC_KEY_CAP: usize,
4014    const SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP: usize,
4015> crate::validate::Validate
4016for MeterValue<
4017    CustomDataType,
4018    METER_VALUE_SAMPLED_VALUE_CAP,
4019    SIGNED_METER_VALUE_PUBLIC_KEY_CAP,
4020    SIGNED_METER_VALUE_SIGNED_METER_DATA_CAP,
4021> {
4022    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4023        crate::validate::check_min_items(self.sampled_value.len(), 1usize)
4024            .map_err(|error| error.in_field("sampledValue"))?;
4025        for (index, item) in self.sampled_value.iter().enumerate() {
4026            crate::validate::Validate::validate(item)
4027                .map_err(|error| error.in_index(index).in_field("sampledValue"))?;
4028        }
4029        Ok(())
4030    }
4031}
4032#[derive(Debug, Clone, PartialEq, Eq)]
4033#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4034pub enum NotifyAllowedEnergyTransferStatusEnum {
4035    Accepted,
4036    Rejected,
4037}
4038#[cfg(feature = "validate")]
4039impl crate::validate::Validate for NotifyAllowedEnergyTransferStatusEnum {
4040    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4041        Ok(())
4042    }
4043}
4044#[derive(Debug, Clone, PartialEq, Eq)]
4045#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4046pub struct ChargingLimit<CustomDataType = crate::NoCustomData> {
4047    /// Represents the source of the charging limit. Values defined in appendix as ChargingLimitSourceEnumStringType.
4048    #[cfg_attr(feature = "serde", serde(rename = "chargingLimitSource"))]
4049    pub charging_limit_source: heapless::String<20usize>,
4050    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4051    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4052    pub custom_data: Option<CustomDataType>,
4053    /// Indicates whether the charging limit is critical for the grid.
4054    #[cfg_attr(feature = "serde", serde(rename = "isGridCritical"))]
4055    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4056    pub is_grid_critical: Option<bool>,
4057    /// *(2.1)* True when the reported limit concerns local generation that is providing extra capacity, instead of a limitation.
4058    #[cfg_attr(feature = "serde", serde(rename = "isLocalGeneration"))]
4059    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4060    pub is_local_generation: Option<bool>,
4061}
4062#[cfg(feature = "validate")]
4063impl<CustomDataType> crate::validate::Validate for ChargingLimit<CustomDataType> {
4064    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4065        Ok(())
4066    }
4067}
4068/// Part of ISO 15118-20 price schedule.
4069#[derive(Debug, Clone, PartialEq, Eq)]
4070#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4071pub struct RationalNumber<CustomDataType = crate::NoCustomData> {
4072    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4073    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4074    pub custom_data: Option<CustomDataType>,
4075    /// The exponent to base 10 (dec)
4076    pub exponent: i64,
4077    /// Value which shall be multiplied.
4078    pub value: i64,
4079}
4080#[cfg(feature = "validate")]
4081impl<CustomDataType> crate::validate::Validate for RationalNumber<CustomDataType> {
4082    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4083        Ok(())
4084    }
4085}
4086/// Part of ISO 15118-20 price schedule.
4087#[derive(Debug, Clone, PartialEq, Eq)]
4088#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4089pub struct AdditionalSelectedServices<CustomDataType = crate::NoCustomData> {
4090    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4091    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4092    pub custom_data: Option<CustomDataType>,
4093    #[cfg_attr(feature = "serde", serde(rename = "serviceFee"))]
4094    pub service_fee: RationalNumber<CustomDataType>,
4095    /// Human readable string to identify this service.
4096    #[cfg_attr(feature = "serde", serde(rename = "serviceName"))]
4097    pub service_name: heapless::String<80usize>,
4098}
4099#[cfg(feature = "validate")]
4100impl<CustomDataType> crate::validate::Validate
4101for AdditionalSelectedServices<CustomDataType> {
4102    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4103        crate::validate::Validate::validate(&self.service_fee)
4104            .map_err(|error| error.in_field("serviceFee"))?;
4105        Ok(())
4106    }
4107}
4108/// Part of ISO 15118-20 price schedule.
4109#[derive(Debug, Clone, PartialEq, Eq)]
4110#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4111pub struct OverstayRule<CustomDataType = crate::NoCustomData> {
4112    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4113    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4114    pub custom_data: Option<CustomDataType>,
4115    #[cfg_attr(feature = "serde", serde(rename = "overstayFee"))]
4116    pub overstay_fee: RationalNumber<CustomDataType>,
4117    /// Time till overstay will be reapplied
4118    #[cfg_attr(feature = "serde", serde(rename = "overstayFeePeriod"))]
4119    pub overstay_fee_period: i64,
4120    /// Human readable string to identify the overstay rule.
4121    #[cfg_attr(feature = "serde", serde(rename = "overstayRuleDescription"))]
4122    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4123    pub overstay_rule_description: Option<heapless::String<32usize>>,
4124    /// Time in seconds after trigger of the parent Overstay Rules for this particular fee to apply.
4125    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
4126    pub start_time: i64,
4127}
4128#[cfg(feature = "validate")]
4129impl<CustomDataType> crate::validate::Validate for OverstayRule<CustomDataType> {
4130    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4131        crate::validate::Validate::validate(&self.overstay_fee)
4132            .map_err(|error| error.in_field("overstayFee"))?;
4133        Ok(())
4134    }
4135}
4136/// Part of ISO 15118-20 price schedule.
4137#[derive(Debug, Clone, PartialEq, Eq)]
4138#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4139pub struct OverstayRuleList<CustomDataType = crate::NoCustomData> {
4140    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4141    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4142    pub custom_data: Option<CustomDataType>,
4143    #[cfg_attr(feature = "serde", serde(rename = "overstayPowerThreshold"))]
4144    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4145    pub overstay_power_threshold: Option<RationalNumber<CustomDataType>>,
4146    #[cfg_attr(feature = "serde", serde(rename = "overstayRule"))]
4147    pub overstay_rule: heapless::Vec<OverstayRule<CustomDataType>, 5usize>,
4148    /// Time till overstay is applied in seconds.
4149    #[cfg_attr(feature = "serde", serde(rename = "overstayTimeThreshold"))]
4150    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4151    pub overstay_time_threshold: Option<i64>,
4152}
4153#[cfg(feature = "validate")]
4154impl<CustomDataType> crate::validate::Validate for OverstayRuleList<CustomDataType> {
4155    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4156        if let Some(value) = &self.overstay_power_threshold {
4157            crate::validate::Validate::validate(value)
4158                .map_err(|error| error.in_field("overstayPowerThreshold"))?;
4159        }
4160        crate::validate::check_min_items(self.overstay_rule.len(), 1usize)
4161            .map_err(|error| error.in_field("overstayRule"))?;
4162        for (index, item) in self.overstay_rule.iter().enumerate() {
4163            crate::validate::Validate::validate(item)
4164                .map_err(|error| error.in_index(index).in_field("overstayRule"))?;
4165        }
4166        Ok(())
4167    }
4168}
4169/// Part of ISO 15118-20 price schedule.
4170#[derive(Debug, Clone, PartialEq, Eq)]
4171#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4172pub struct PriceRule<CustomDataType = crate::NoCustomData> {
4173    /// Number of grams of CO2 per kWh.
4174    #[cfg_attr(feature = "serde", serde(rename = "carbonDioxideEmission"))]
4175    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4176    pub carbon_dioxide_emission: Option<i64>,
4177    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4178    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4179    pub custom_data: Option<CustomDataType>,
4180    #[cfg_attr(feature = "serde", serde(rename = "energyFee"))]
4181    pub energy_fee: RationalNumber<CustomDataType>,
4182    #[cfg_attr(feature = "serde", serde(rename = "parkingFee"))]
4183    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4184    pub parking_fee: Option<RationalNumber<CustomDataType>>,
4185    /// The duration of the parking fee period (in seconds).
4186    /// When the time enters into a ParkingFeePeriod, the ParkingFee will apply to the session. .
4187    #[cfg_attr(feature = "serde", serde(rename = "parkingFeePeriod"))]
4188    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4189    pub parking_fee_period: Option<i64>,
4190    #[cfg_attr(feature = "serde", serde(rename = "powerRangeStart"))]
4191    pub power_range_start: RationalNumber<CustomDataType>,
4192    /// Percentage of the power that is created by renewable resources.
4193    #[cfg_attr(feature = "serde", serde(rename = "renewableGenerationPercentage"))]
4194    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4195    pub renewable_generation_percentage: Option<i64>,
4196}
4197#[cfg(feature = "validate")]
4198impl<CustomDataType> crate::validate::Validate for PriceRule<CustomDataType> {
4199    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4200        if let Some(value) = self.carbon_dioxide_emission {
4201            crate::validate::check_min_i64(value, 0i64)
4202                .map_err(|error| error.in_field("carbonDioxideEmission"))?;
4203        }
4204        crate::validate::Validate::validate(&self.energy_fee)
4205            .map_err(|error| error.in_field("energyFee"))?;
4206        if let Some(value) = &self.parking_fee {
4207            crate::validate::Validate::validate(value)
4208                .map_err(|error| error.in_field("parkingFee"))?;
4209        }
4210        crate::validate::Validate::validate(&self.power_range_start)
4211            .map_err(|error| error.in_field("powerRangeStart"))?;
4212        if let Some(value) = self.renewable_generation_percentage {
4213            crate::validate::check_min_i64(value, 0i64)
4214                .map_err(|error| error.in_field("renewableGenerationPercentage"))?;
4215            crate::validate::check_max_i64(value, 100i64)
4216                .map_err(|error| error.in_field("renewableGenerationPercentage"))?;
4217        }
4218        Ok(())
4219    }
4220}
4221/// Part of ISO 15118-20 price schedule.
4222#[derive(Debug, Clone, PartialEq, Eq)]
4223#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4224pub struct PriceRuleStack<CustomDataType = crate::NoCustomData> {
4225    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4226    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4227    pub custom_data: Option<CustomDataType>,
4228    /// Duration of the stack of price rules.  he amount of seconds that define the duration of the given PriceRule(s).
4229    pub duration: i64,
4230    #[cfg_attr(feature = "serde", serde(rename = "priceRule"))]
4231    pub price_rule: heapless::Vec<PriceRule<CustomDataType>, 8usize>,
4232}
4233#[cfg(feature = "validate")]
4234impl<CustomDataType> crate::validate::Validate for PriceRuleStack<CustomDataType> {
4235    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4236        crate::validate::check_min_items(self.price_rule.len(), 1usize)
4237            .map_err(|error| error.in_field("priceRule"))?;
4238        for (index, item) in self.price_rule.iter().enumerate() {
4239            crate::validate::Validate::validate(item)
4240                .map_err(|error| error.in_index(index).in_field("priceRule"))?;
4241        }
4242        Ok(())
4243    }
4244}
4245/// Part of ISO 15118-20 price schedule.
4246#[derive(Debug, Clone, PartialEq, Eq)]
4247#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4248pub struct TaxRule<CustomDataType = crate::NoCustomData> {
4249    /// Indicates whether this tax applies to Energy Fees.
4250    #[cfg_attr(feature = "serde", serde(rename = "appliesToEnergyFee"))]
4251    pub applies_to_energy_fee: bool,
4252    /// Indicates whether this tax applies to Minimum/Maximum Cost.
4253    #[cfg_attr(feature = "serde", serde(rename = "appliesToMinimumMaximumCost"))]
4254    pub applies_to_minimum_maximum_cost: bool,
4255    /// Indicates whether this tax applies to Overstay Fees.
4256    #[cfg_attr(feature = "serde", serde(rename = "appliesToOverstayFee"))]
4257    pub applies_to_overstay_fee: bool,
4258    /// Indicates whether this tax applies to Parking Fees.
4259    #[cfg_attr(feature = "serde", serde(rename = "appliesToParkingFee"))]
4260    pub applies_to_parking_fee: bool,
4261    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4262    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4263    pub custom_data: Option<CustomDataType>,
4264    /// Indicates whether the tax is included in any price or not.
4265    #[cfg_attr(feature = "serde", serde(rename = "taxIncludedInPrice"))]
4266    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4267    pub tax_included_in_price: Option<bool>,
4268    #[cfg_attr(feature = "serde", serde(rename = "taxRate"))]
4269    pub tax_rate: RationalNumber<CustomDataType>,
4270    /// Id for the tax rule.
4271    #[cfg_attr(feature = "serde", serde(rename = "taxRuleID"))]
4272    pub tax_rule_i_d: i64,
4273    /// Human readable string to identify the tax rule.
4274    #[cfg_attr(feature = "serde", serde(rename = "taxRuleName"))]
4275    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4276    pub tax_rule_name: Option<heapless::String<100usize>>,
4277}
4278#[cfg(feature = "validate")]
4279impl<CustomDataType> crate::validate::Validate for TaxRule<CustomDataType> {
4280    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4281        crate::validate::Validate::validate(&self.tax_rate)
4282            .map_err(|error| error.in_field("taxRate"))?;
4283        crate::validate::check_min_i64(self.tax_rule_i_d, 0i64)
4284            .map_err(|error| error.in_field("taxRuleID"))?;
4285        Ok(())
4286    }
4287}
4288#[cfg(feature = "alloc")]
4289/// The AbsolutePriceScheduleType is modeled after the same type that is defined in ISO 15118-20, such that if it is supplied by an EMSP as a signed EXI message, the conversion from EXI to JSON (in OCPP) and back to EXI (for ISO 15118-20) does not change the digest and therefore does not invalidate the signature.
4290///
4291/// image::images/AbsolutePriceSchedule-Simple.png\[\]
4292#[derive(Debug, Clone, PartialEq, Eq)]
4293#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4294pub struct AbsolutePriceSchedule<CustomDataType = crate::NoCustomData> {
4295    #[cfg_attr(feature = "serde", serde(rename = "additionalSelectedServices"))]
4296    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4297    pub additional_selected_services: Option<
4298        heapless::Vec<AdditionalSelectedServices<CustomDataType>, 5usize>,
4299    >,
4300    /// Currency according to ISO 4217.
4301    pub currency: heapless::String<3usize>,
4302    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4303    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4304    pub custom_data: Option<CustomDataType>,
4305    /// String that indicates what language is used for the human readable strings in the price schedule. Based on ISO 639.
4306    pub language: heapless::String<8usize>,
4307    #[cfg_attr(feature = "serde", serde(rename = "maximumCost"))]
4308    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4309    pub maximum_cost: Option<RationalNumber<CustomDataType>>,
4310    #[cfg_attr(feature = "serde", serde(rename = "minimumCost"))]
4311    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4312    pub minimum_cost: Option<RationalNumber<CustomDataType>>,
4313    #[cfg_attr(feature = "serde", serde(rename = "overstayRuleList"))]
4314    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4315    pub overstay_rule_list: Option<OverstayRuleList<CustomDataType>>,
4316    /// A string in URN notation which shall uniquely identify an algorithm that defines how to compute an energy fee sum for a specific power profile based on the EnergyFee information from the PriceRule elements.
4317    #[cfg_attr(feature = "serde", serde(rename = "priceAlgorithm"))]
4318    pub price_algorithm: alloc::string::String,
4319    #[cfg_attr(feature = "serde", serde(rename = "priceRuleStacks"))]
4320    pub price_rule_stacks: alloc::vec::Vec<PriceRuleStack<CustomDataType>>,
4321    /// Description of the price schedule.
4322    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleDescription"))]
4323    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4324    pub price_schedule_description: Option<heapless::String<160usize>>,
4325    /// Unique ID of price schedule
4326    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleID"))]
4327    pub price_schedule_i_d: i64,
4328    #[cfg_attr(feature = "serde", serde(rename = "taxRules"))]
4329    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4330    pub tax_rules: Option<heapless::Vec<TaxRule<CustomDataType>, 10usize>>,
4331    /// Starting point of price schedule.
4332    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
4333    pub time_anchor: crate::OcppTimestamp,
4334}
4335#[cfg(all(feature = "validate", feature = "alloc"))]
4336impl<CustomDataType> crate::validate::Validate
4337for AbsolutePriceSchedule<CustomDataType> {
4338    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4339        if let Some(value) = &self.additional_selected_services {
4340            crate::validate::check_min_items(value.len(), 1usize)
4341                .map_err(|error| error.in_field("additionalSelectedServices"))?;
4342            for (index, item) in value.iter().enumerate() {
4343                crate::validate::Validate::validate(item)
4344                    .map_err(|error| {
4345                        error.in_index(index).in_field("additionalSelectedServices")
4346                    })?;
4347            }
4348        }
4349        if let Some(value) = &self.maximum_cost {
4350            crate::validate::Validate::validate(value)
4351                .map_err(|error| error.in_field("maximumCost"))?;
4352        }
4353        if let Some(value) = &self.minimum_cost {
4354            crate::validate::Validate::validate(value)
4355                .map_err(|error| error.in_field("minimumCost"))?;
4356        }
4357        if let Some(value) = &self.overstay_rule_list {
4358            crate::validate::Validate::validate(value)
4359                .map_err(|error| error.in_field("overstayRuleList"))?;
4360        }
4361        crate::validate::check_max_length(&self.price_algorithm, 2000usize)
4362            .map_err(|error| error.in_field("priceAlgorithm"))?;
4363        crate::validate::check_min_items(self.price_rule_stacks.len(), 1usize)
4364            .map_err(|error| error.in_field("priceRuleStacks"))?;
4365        crate::validate::check_max_items(self.price_rule_stacks.len(), 1024usize)
4366            .map_err(|error| error.in_field("priceRuleStacks"))?;
4367        for (index, item) in self.price_rule_stacks.iter().enumerate() {
4368            crate::validate::Validate::validate(item)
4369                .map_err(|error| error.in_index(index).in_field("priceRuleStacks"))?;
4370        }
4371        crate::validate::check_min_i64(self.price_schedule_i_d, 0i64)
4372            .map_err(|error| error.in_field("priceScheduleID"))?;
4373        if let Some(value) = &self.tax_rules {
4374            crate::validate::check_min_items(value.len(), 1usize)
4375                .map_err(|error| error.in_field("taxRules"))?;
4376            for (index, item) in value.iter().enumerate() {
4377                crate::validate::Validate::validate(item)
4378                    .map_err(|error| error.in_index(index).in_field("taxRules"))?;
4379            }
4380        }
4381        Ok(())
4382    }
4383}
4384#[cfg(not(feature = "alloc"))]
4385/// The AbsolutePriceScheduleType is modeled after the same type that is defined in ISO 15118-20, such that if it is supplied by an EMSP as a signed EXI message, the conversion from EXI to JSON (in OCPP) and back to EXI (for ISO 15118-20) does not change the digest and therefore does not invalidate the signature.
4386///
4387/// image::images/AbsolutePriceSchedule-Simple.png\[\]
4388#[derive(Debug, Clone, PartialEq, Eq)]
4389#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4390pub struct AbsolutePriceSchedule<
4391    CustomDataType = crate::NoCustomData,
4392    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
4393    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize = 8usize,
4394> {
4395    #[cfg_attr(feature = "serde", serde(rename = "additionalSelectedServices"))]
4396    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4397    pub additional_selected_services: Option<
4398        heapless::Vec<AdditionalSelectedServices<CustomDataType>, 5usize>,
4399    >,
4400    /// Currency according to ISO 4217.
4401    pub currency: heapless::String<3usize>,
4402    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4403    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4404    pub custom_data: Option<CustomDataType>,
4405    /// String that indicates what language is used for the human readable strings in the price schedule. Based on ISO 639.
4406    pub language: heapless::String<8usize>,
4407    #[cfg_attr(feature = "serde", serde(rename = "maximumCost"))]
4408    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4409    pub maximum_cost: Option<RationalNumber<CustomDataType>>,
4410    #[cfg_attr(feature = "serde", serde(rename = "minimumCost"))]
4411    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4412    pub minimum_cost: Option<RationalNumber<CustomDataType>>,
4413    #[cfg_attr(feature = "serde", serde(rename = "overstayRuleList"))]
4414    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4415    pub overstay_rule_list: Option<OverstayRuleList<CustomDataType>>,
4416    /// A string in URN notation which shall uniquely identify an algorithm that defines how to compute an energy fee sum for a specific power profile based on the EnergyFee information from the PriceRule elements.
4417    #[cfg_attr(feature = "serde", serde(rename = "priceAlgorithm"))]
4418    pub price_algorithm: heapless::String<ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP>,
4419    #[cfg_attr(feature = "serde", serde(rename = "priceRuleStacks"))]
4420    pub price_rule_stacks: heapless::Vec<
4421        PriceRuleStack<CustomDataType>,
4422        ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
4423    >,
4424    /// Description of the price schedule.
4425    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleDescription"))]
4426    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4427    pub price_schedule_description: Option<heapless::String<160usize>>,
4428    /// Unique ID of price schedule
4429    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleID"))]
4430    pub price_schedule_i_d: i64,
4431    #[cfg_attr(feature = "serde", serde(rename = "taxRules"))]
4432    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4433    pub tax_rules: Option<heapless::Vec<TaxRule<CustomDataType>, 10usize>>,
4434    /// Starting point of price schedule.
4435    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
4436    pub time_anchor: crate::OcppTimestamp,
4437}
4438#[cfg(all(feature = "validate", not(feature = "alloc")))]
4439impl<
4440    CustomDataType,
4441    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
4442    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize,
4443> crate::validate::Validate
4444for AbsolutePriceSchedule<
4445    CustomDataType,
4446    ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
4447    ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
4448> {
4449    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4450        if let Some(value) = &self.additional_selected_services {
4451            crate::validate::check_min_items(value.len(), 1usize)
4452                .map_err(|error| error.in_field("additionalSelectedServices"))?;
4453            for (index, item) in value.iter().enumerate() {
4454                crate::validate::Validate::validate(item)
4455                    .map_err(|error| {
4456                        error.in_index(index).in_field("additionalSelectedServices")
4457                    })?;
4458            }
4459        }
4460        if let Some(value) = &self.maximum_cost {
4461            crate::validate::Validate::validate(value)
4462                .map_err(|error| error.in_field("maximumCost"))?;
4463        }
4464        if let Some(value) = &self.minimum_cost {
4465            crate::validate::Validate::validate(value)
4466                .map_err(|error| error.in_field("minimumCost"))?;
4467        }
4468        if let Some(value) = &self.overstay_rule_list {
4469            crate::validate::Validate::validate(value)
4470                .map_err(|error| error.in_field("overstayRuleList"))?;
4471        }
4472        crate::validate::check_max_length(&self.price_algorithm, 2000usize)
4473            .map_err(|error| error.in_field("priceAlgorithm"))?;
4474        crate::validate::check_min_items(self.price_rule_stacks.len(), 1usize)
4475            .map_err(|error| error.in_field("priceRuleStacks"))?;
4476        crate::validate::check_max_items(self.price_rule_stacks.len(), 1024usize)
4477            .map_err(|error| error.in_field("priceRuleStacks"))?;
4478        for (index, item) in self.price_rule_stacks.iter().enumerate() {
4479            crate::validate::Validate::validate(item)
4480                .map_err(|error| error.in_index(index).in_field("priceRuleStacks"))?;
4481        }
4482        crate::validate::check_min_i64(self.price_schedule_i_d, 0i64)
4483            .map_err(|error| error.in_field("priceScheduleID"))?;
4484        if let Some(value) = &self.tax_rules {
4485            crate::validate::check_min_items(value.len(), 1usize)
4486                .map_err(|error| error.in_field("taxRules"))?;
4487            for (index, item) in value.iter().enumerate() {
4488                crate::validate::Validate::validate(item)
4489                    .map_err(|error| error.in_index(index).in_field("taxRules"))?;
4490            }
4491        }
4492        Ok(())
4493    }
4494}
4495#[derive(Debug, Clone, PartialEq)]
4496#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4497pub struct LimitAtSoC<CustomDataType = crate::NoCustomData> {
4498    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4499    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4500    pub custom_data: Option<CustomDataType>,
4501    /// Charging rate limit beyond the SoC value.
4502    /// The unit is defined by _chargingSchedule.chargingRateUnit_.
4503    pub limit: f64,
4504    /// The SoC value beyond which the charging rate limit should be applied.
4505    pub soc: i64,
4506}
4507#[cfg(feature = "validate")]
4508impl<CustomDataType> crate::validate::Validate for LimitAtSoC<CustomDataType> {
4509    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4510        crate::validate::check_min_i64(self.soc, 0i64)
4511            .map_err(|error| error.in_field("soc"))?;
4512        crate::validate::check_max_i64(self.soc, 100i64)
4513            .map_err(|error| error.in_field("soc"))?;
4514        Ok(())
4515    }
4516}
4517/// Part of ISO 15118-20 price schedule.
4518#[derive(Debug, Clone, PartialEq, Eq)]
4519#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4520pub struct PriceLevelScheduleEntry<CustomDataType = crate::NoCustomData> {
4521    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4522    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4523    pub custom_data: Option<CustomDataType>,
4524    /// The amount of seconds that define the duration of this given PriceLevelScheduleEntry.
4525    pub duration: i64,
4526    /// Defines the price level of this PriceLevelScheduleEntry (referring to NumberOfPriceLevels). Small values for the PriceLevel represent a cheaper PriceLevelScheduleEntry. Large values for the PriceLevel represent a more expensive PriceLevelScheduleEntry.
4527    #[cfg_attr(feature = "serde", serde(rename = "priceLevel"))]
4528    pub price_level: i64,
4529}
4530#[cfg(feature = "validate")]
4531impl<CustomDataType> crate::validate::Validate
4532for PriceLevelScheduleEntry<CustomDataType> {
4533    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4534        crate::validate::check_min_i64(self.price_level, 0i64)
4535            .map_err(|error| error.in_field("priceLevel"))?;
4536        Ok(())
4537    }
4538}
4539#[cfg(feature = "alloc")]
4540/// The PriceLevelScheduleType is modeled after the same type that is defined in ISO 15118-20, such that if it is supplied by an EMSP as a signed EXI message, the conversion from EXI to JSON (in OCPP) and back to EXI (for ISO 15118-20) does not change the digest and therefore does not invalidate the signature.
4541#[derive(Debug, Clone, PartialEq, Eq)]
4542#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4543pub struct PriceLevelSchedule<CustomDataType = crate::NoCustomData> {
4544    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4545    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4546    pub custom_data: Option<CustomDataType>,
4547    /// Defines the overall number of distinct price level elements used across all PriceLevelSchedules.
4548    #[cfg_attr(feature = "serde", serde(rename = "numberOfPriceLevels"))]
4549    pub number_of_price_levels: i64,
4550    #[cfg_attr(feature = "serde", serde(rename = "priceLevelScheduleEntries"))]
4551    pub price_level_schedule_entries: alloc::vec::Vec<
4552        PriceLevelScheduleEntry<CustomDataType>,
4553    >,
4554    /// Description of the price schedule.
4555    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleDescription"))]
4556    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4557    pub price_schedule_description: Option<heapless::String<32usize>>,
4558    /// Unique ID of this price schedule.
4559    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleId"))]
4560    pub price_schedule_id: i64,
4561    /// Starting point of this price schedule.
4562    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
4563    pub time_anchor: crate::OcppTimestamp,
4564}
4565#[cfg(all(feature = "validate", feature = "alloc"))]
4566impl<CustomDataType> crate::validate::Validate for PriceLevelSchedule<CustomDataType> {
4567    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4568        crate::validate::check_min_i64(self.number_of_price_levels, 0i64)
4569            .map_err(|error| error.in_field("numberOfPriceLevels"))?;
4570        crate::validate::check_min_items(self.price_level_schedule_entries.len(), 1usize)
4571            .map_err(|error| error.in_field("priceLevelScheduleEntries"))?;
4572        crate::validate::check_max_items(
4573                self.price_level_schedule_entries.len(),
4574                100usize,
4575            )
4576            .map_err(|error| error.in_field("priceLevelScheduleEntries"))?;
4577        for (index, item) in self.price_level_schedule_entries.iter().enumerate() {
4578            crate::validate::Validate::validate(item)
4579                .map_err(|error| {
4580                    error.in_index(index).in_field("priceLevelScheduleEntries")
4581                })?;
4582        }
4583        crate::validate::check_min_i64(self.price_schedule_id, 0i64)
4584            .map_err(|error| error.in_field("priceScheduleId"))?;
4585        Ok(())
4586    }
4587}
4588#[cfg(not(feature = "alloc"))]
4589/// The PriceLevelScheduleType is modeled after the same type that is defined in ISO 15118-20, such that if it is supplied by an EMSP as a signed EXI message, the conversion from EXI to JSON (in OCPP) and back to EXI (for ISO 15118-20) does not change the digest and therefore does not invalidate the signature.
4590#[derive(Debug, Clone, PartialEq, Eq)]
4591#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4592pub struct PriceLevelSchedule<
4593    CustomDataType = crate::NoCustomData,
4594    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize = 8usize,
4595> {
4596    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4597    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4598    pub custom_data: Option<CustomDataType>,
4599    /// Defines the overall number of distinct price level elements used across all PriceLevelSchedules.
4600    #[cfg_attr(feature = "serde", serde(rename = "numberOfPriceLevels"))]
4601    pub number_of_price_levels: i64,
4602    #[cfg_attr(feature = "serde", serde(rename = "priceLevelScheduleEntries"))]
4603    pub price_level_schedule_entries: heapless::Vec<
4604        PriceLevelScheduleEntry<CustomDataType>,
4605        PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
4606    >,
4607    /// Description of the price schedule.
4608    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleDescription"))]
4609    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4610    pub price_schedule_description: Option<heapless::String<32usize>>,
4611    /// Unique ID of this price schedule.
4612    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleId"))]
4613    pub price_schedule_id: i64,
4614    /// Starting point of this price schedule.
4615    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
4616    pub time_anchor: crate::OcppTimestamp,
4617}
4618#[cfg(all(feature = "validate", not(feature = "alloc")))]
4619impl<
4620    CustomDataType,
4621    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize,
4622> crate::validate::Validate
4623for PriceLevelSchedule<
4624    CustomDataType,
4625    PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
4626> {
4627    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4628        crate::validate::check_min_i64(self.number_of_price_levels, 0i64)
4629            .map_err(|error| error.in_field("numberOfPriceLevels"))?;
4630        crate::validate::check_min_items(self.price_level_schedule_entries.len(), 1usize)
4631            .map_err(|error| error.in_field("priceLevelScheduleEntries"))?;
4632        crate::validate::check_max_items(
4633                self.price_level_schedule_entries.len(),
4634                100usize,
4635            )
4636            .map_err(|error| error.in_field("priceLevelScheduleEntries"))?;
4637        for (index, item) in self.price_level_schedule_entries.iter().enumerate() {
4638            crate::validate::Validate::validate(item)
4639                .map_err(|error| {
4640                    error.in_index(index).in_field("priceLevelScheduleEntries")
4641                })?;
4642        }
4643        crate::validate::check_min_i64(self.price_schedule_id, 0i64)
4644            .map_err(|error| error.in_field("priceScheduleId"))?;
4645        Ok(())
4646    }
4647}
4648/// The kind of cost referred to in the message element amount
4649#[derive(Debug, Clone, PartialEq, Eq)]
4650#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4651pub enum CostKindEnum {
4652    CarbonDioxideEmission,
4653    RelativePricePercentage,
4654    RenewableGenerationPercentage,
4655}
4656#[cfg(feature = "validate")]
4657impl crate::validate::Validate for CostKindEnum {
4658    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4659        Ok(())
4660    }
4661}
4662#[derive(Debug, Clone, PartialEq, Eq)]
4663#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4664pub struct Cost<CustomDataType = crate::NoCustomData> {
4665    /// The estimated or actual cost per kWh
4666    pub amount: i64,
4667    /// Values: -3..3, The amountMultiplier defines the exponent to base 10 (dec). The final value is determined by: amount * 10 ^ amountMultiplier
4668    #[cfg_attr(feature = "serde", serde(rename = "amountMultiplier"))]
4669    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4670    pub amount_multiplier: Option<i64>,
4671    #[cfg_attr(feature = "serde", serde(rename = "costKind"))]
4672    pub cost_kind: CostKindEnum,
4673    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4674    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4675    pub custom_data: Option<CustomDataType>,
4676}
4677#[cfg(feature = "validate")]
4678impl<CustomDataType> crate::validate::Validate for Cost<CustomDataType> {
4679    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4680        crate::validate::Validate::validate(&self.cost_kind)
4681            .map_err(|error| error.in_field("costKind"))?;
4682        Ok(())
4683    }
4684}
4685#[derive(Debug, Clone, PartialEq)]
4686#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4687pub struct ConsumptionCost<CustomDataType = crate::NoCustomData> {
4688    pub cost: heapless::Vec<Cost<CustomDataType>, 3usize>,
4689    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4690    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4691    pub custom_data: Option<CustomDataType>,
4692    /// The lowest level of consumption that defines the starting point of this consumption block. The block interval extends to the start of the next interval.
4693    #[cfg_attr(feature = "serde", serde(rename = "startValue"))]
4694    pub start_value: f64,
4695}
4696#[cfg(feature = "validate")]
4697impl<CustomDataType> crate::validate::Validate for ConsumptionCost<CustomDataType> {
4698    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4699        crate::validate::check_min_items(self.cost.len(), 1usize)
4700            .map_err(|error| error.in_field("cost"))?;
4701        for (index, item) in self.cost.iter().enumerate() {
4702            crate::validate::Validate::validate(item)
4703                .map_err(|error| error.in_index(index).in_field("cost"))?;
4704        }
4705        Ok(())
4706    }
4707}
4708#[derive(Debug, Clone, PartialEq, Eq)]
4709#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4710pub struct RelativeTimeInterval<CustomDataType = crate::NoCustomData> {
4711    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4712    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4713    pub custom_data: Option<CustomDataType>,
4714    /// Duration of the interval, in seconds.
4715    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4716    pub duration: Option<i64>,
4717    /// Start of the interval, in seconds from NOW.
4718    pub start: i64,
4719}
4720#[cfg(feature = "validate")]
4721impl<CustomDataType> crate::validate::Validate for RelativeTimeInterval<CustomDataType> {
4722    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4723        Ok(())
4724    }
4725}
4726#[derive(Debug, Clone, PartialEq)]
4727#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4728pub struct SalesTariffEntry<CustomDataType = crate::NoCustomData> {
4729    #[cfg_attr(feature = "serde", serde(rename = "consumptionCost"))]
4730    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4731    pub consumption_cost: Option<heapless::Vec<ConsumptionCost<CustomDataType>, 3usize>>,
4732    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4733    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4734    pub custom_data: Option<CustomDataType>,
4735    /// Defines the price level of this SalesTariffEntry (referring to NumEPriceLevels). Small values for the EPriceLevel represent a cheaper TariffEntry. Large values for the EPriceLevel represent a more expensive TariffEntry.
4736    #[cfg_attr(feature = "serde", serde(rename = "ePriceLevel"))]
4737    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4738    pub e_price_level: Option<i64>,
4739    #[cfg_attr(feature = "serde", serde(rename = "relativeTimeInterval"))]
4740    pub relative_time_interval: RelativeTimeInterval<CustomDataType>,
4741}
4742#[cfg(feature = "validate")]
4743impl<CustomDataType> crate::validate::Validate for SalesTariffEntry<CustomDataType> {
4744    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4745        if let Some(value) = &self.consumption_cost {
4746            crate::validate::check_min_items(value.len(), 1usize)
4747                .map_err(|error| error.in_field("consumptionCost"))?;
4748            for (index, item) in value.iter().enumerate() {
4749                crate::validate::Validate::validate(item)
4750                    .map_err(|error| error.in_index(index).in_field("consumptionCost"))?;
4751            }
4752        }
4753        if let Some(value) = self.e_price_level {
4754            crate::validate::check_min_i64(value, 0i64)
4755                .map_err(|error| error.in_field("ePriceLevel"))?;
4756        }
4757        crate::validate::Validate::validate(&self.relative_time_interval)
4758            .map_err(|error| error.in_field("relativeTimeInterval"))?;
4759        Ok(())
4760    }
4761}
4762#[cfg(feature = "alloc")]
4763/// A SalesTariff provided by a Mobility Operator (EMSP) .
4764/// NOTE: This dataType is based on dataTypes from &lt;&lt;ref-ISOIEC15118-2,ISO 15118-2&gt;&gt;.
4765#[derive(Debug, Clone, PartialEq)]
4766#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4767pub struct SalesTariff<CustomDataType = crate::NoCustomData> {
4768    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4769    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4770    pub custom_data: Option<CustomDataType>,
4771    /// SalesTariff identifier used to identify one sales tariff. An SAID remains a unique identifier for one schedule throughout a charging session.
4772    pub id: i64,
4773    /// Defines the overall number of distinct price levels used across all provided SalesTariff elements.
4774    #[cfg_attr(feature = "serde", serde(rename = "numEPriceLevels"))]
4775    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4776    pub num_e_price_levels: Option<i64>,
4777    /// A human readable title/short description of the sales tariff e.g. for HMI display purposes.
4778    #[cfg_attr(feature = "serde", serde(rename = "salesTariffDescription"))]
4779    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4780    pub sales_tariff_description: Option<heapless::String<32usize>>,
4781    #[cfg_attr(feature = "serde", serde(rename = "salesTariffEntry"))]
4782    pub sales_tariff_entry: alloc::vec::Vec<SalesTariffEntry<CustomDataType>>,
4783}
4784#[cfg(all(feature = "validate", feature = "alloc"))]
4785impl<CustomDataType> crate::validate::Validate for SalesTariff<CustomDataType> {
4786    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4787        crate::validate::check_min_i64(self.id, 0i64)
4788            .map_err(|error| error.in_field("id"))?;
4789        if let Some(value) = self.num_e_price_levels {
4790            crate::validate::check_min_i64(value, 0i64)
4791                .map_err(|error| error.in_field("numEPriceLevels"))?;
4792        }
4793        crate::validate::check_min_items(self.sales_tariff_entry.len(), 1usize)
4794            .map_err(|error| error.in_field("salesTariffEntry"))?;
4795        crate::validate::check_max_items(self.sales_tariff_entry.len(), 1024usize)
4796            .map_err(|error| error.in_field("salesTariffEntry"))?;
4797        for (index, item) in self.sales_tariff_entry.iter().enumerate() {
4798            crate::validate::Validate::validate(item)
4799                .map_err(|error| error.in_index(index).in_field("salesTariffEntry"))?;
4800        }
4801        Ok(())
4802    }
4803}
4804#[cfg(not(feature = "alloc"))]
4805/// A SalesTariff provided by a Mobility Operator (EMSP) .
4806/// NOTE: This dataType is based on dataTypes from &lt;&lt;ref-ISOIEC15118-2,ISO 15118-2&gt;&gt;.
4807#[derive(Debug, Clone, PartialEq)]
4808#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4809pub struct SalesTariff<
4810    CustomDataType = crate::NoCustomData,
4811    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize = 8usize,
4812> {
4813    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4814    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4815    pub custom_data: Option<CustomDataType>,
4816    /// SalesTariff identifier used to identify one sales tariff. An SAID remains a unique identifier for one schedule throughout a charging session.
4817    pub id: i64,
4818    /// Defines the overall number of distinct price levels used across all provided SalesTariff elements.
4819    #[cfg_attr(feature = "serde", serde(rename = "numEPriceLevels"))]
4820    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4821    pub num_e_price_levels: Option<i64>,
4822    /// A human readable title/short description of the sales tariff e.g. for HMI display purposes.
4823    #[cfg_attr(feature = "serde", serde(rename = "salesTariffDescription"))]
4824    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4825    pub sales_tariff_description: Option<heapless::String<32usize>>,
4826    #[cfg_attr(feature = "serde", serde(rename = "salesTariffEntry"))]
4827    pub sales_tariff_entry: heapless::Vec<
4828        SalesTariffEntry<CustomDataType>,
4829        SALES_TARIFF_SALES_TARIFF_ENTRY_CAP,
4830    >,
4831}
4832#[cfg(all(feature = "validate", not(feature = "alloc")))]
4833impl<
4834    CustomDataType,
4835    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize,
4836> crate::validate::Validate
4837for SalesTariff<CustomDataType, SALES_TARIFF_SALES_TARIFF_ENTRY_CAP> {
4838    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4839        crate::validate::check_min_i64(self.id, 0i64)
4840            .map_err(|error| error.in_field("id"))?;
4841        if let Some(value) = self.num_e_price_levels {
4842            crate::validate::check_min_i64(value, 0i64)
4843                .map_err(|error| error.in_field("numEPriceLevels"))?;
4844        }
4845        crate::validate::check_min_items(self.sales_tariff_entry.len(), 1usize)
4846            .map_err(|error| error.in_field("salesTariffEntry"))?;
4847        crate::validate::check_max_items(self.sales_tariff_entry.len(), 1024usize)
4848            .map_err(|error| error.in_field("salesTariffEntry"))?;
4849        for (index, item) in self.sales_tariff_entry.iter().enumerate() {
4850            crate::validate::Validate::validate(item)
4851                .map_err(|error| error.in_index(index).in_field("salesTariffEntry"))?;
4852        }
4853        Ok(())
4854    }
4855}
4856#[cfg(feature = "alloc")]
4857/// Charging schedule structure defines a list of charging periods, as used in: NotifyEVChargingScheduleRequest and ChargingProfileType. When used in a NotifyEVChargingScheduleRequest only _duration_ and _chargingSchedulePeriod_ are relevant and _chargingRateUnit_ must be 'W'. +
4858/// An ISO 15118-20 session may provide either an _absolutePriceSchedule_ or a _priceLevelSchedule_. An ISO 15118-2 session can only provide a_salesTariff_ element. The field _digestValue_ is used when price schedule or sales tariff are signed.
4859///
4860/// image::images/ChargingSchedule-Simple.png\[\]
4861#[derive(Debug, Clone, PartialEq)]
4862#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4863pub struct ChargingSchedule<CustomDataType = crate::NoCustomData> {
4864    #[cfg_attr(feature = "serde", serde(rename = "absolutePriceSchedule"))]
4865    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4866    pub absolute_price_schedule: Option<AbsolutePriceSchedule<CustomDataType>>,
4867    #[cfg_attr(feature = "serde", serde(rename = "chargingRateUnit"))]
4868    pub charging_rate_unit: ChargingRateUnitEnum,
4869    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedulePeriod"))]
4870    pub charging_schedule_period: alloc::vec::Vec<
4871        ChargingSchedulePeriod<CustomDataType>,
4872    >,
4873    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4874    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4875    pub custom_data: Option<CustomDataType>,
4876    /// *(2.1)* Base64 encoded hash (SHA256 for ISO 15118-2, SHA512 for ISO 15118-20) of the EXI price schedule element. Used in signature.
4877    #[cfg_attr(feature = "serde", serde(rename = "digestValue"))]
4878    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4879    pub digest_value: Option<heapless::String<88usize>>,
4880    /// Duration of the charging schedule in seconds. If the duration is left empty, the last period will continue indefinitely or until end of the transaction in case startSchedule is absent.
4881    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4882    pub duration: Option<i64>,
4883    pub id: i64,
4884    #[cfg_attr(feature = "serde", serde(rename = "limitAtSoC"))]
4885    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4886    pub limit_at_so_c: Option<LimitAtSoC<CustomDataType>>,
4887    /// Minimum charging rate supported by the EV. The unit of measure is defined by the chargingRateUnit. This parameter is intended to be used by a local smart charging algorithm to optimize the power allocation for in the case a charging process is inefficient at lower charging rates.
4888    #[cfg_attr(feature = "serde", serde(rename = "minChargingRate"))]
4889    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4890    pub min_charging_rate: Option<f64>,
4891    /// *(2.1)* Power tolerance when following EVPowerProfile.
4892    #[cfg_attr(feature = "serde", serde(rename = "powerTolerance"))]
4893    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4894    pub power_tolerance: Option<f64>,
4895    #[cfg_attr(feature = "serde", serde(rename = "priceLevelSchedule"))]
4896    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4897    pub price_level_schedule: Option<PriceLevelSchedule<CustomDataType>>,
4898    /// *(2.1)* Defaults to 0. When _randomizedDelay_ not equals zero, then the start of each &lt;&lt;cmn_chargingscheduleperiodtype,ChargingSchedulePeriodType&gt;&gt; is delayed by a randomly chosen number of seconds between 0 and _randomizedDelay_.  Only allowed for TxProfile and TxDefaultProfile.
4899    #[cfg_attr(feature = "serde", serde(rename = "randomizedDelay"))]
4900    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4901    pub randomized_delay: Option<i64>,
4902    #[cfg_attr(feature = "serde", serde(rename = "salesTariff"))]
4903    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4904    pub sales_tariff: Option<SalesTariff<CustomDataType>>,
4905    /// *(2.1)* Id of this element for referencing in a signature.
4906    #[cfg_attr(feature = "serde", serde(rename = "signatureId"))]
4907    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4908    pub signature_id: Option<i64>,
4909    /// Starting point of an absolute schedule or recurring schedule.
4910    #[cfg_attr(feature = "serde", serde(rename = "startSchedule"))]
4911    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4912    pub start_schedule: Option<crate::OcppTimestamp>,
4913    /// *(2.1)* Defaults to false. When true, disregard time zone offset in dateTime fields of  _ChargingScheduleType_ and use unqualified local time at Charging Station instead.
4914    ///  This allows the same `Absolute` or `Recurring` charging profile to be used in both summer and winter time.
4915    #[cfg_attr(feature = "serde", serde(rename = "useLocalTime"))]
4916    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4917    pub use_local_time: Option<bool>,
4918}
4919#[cfg(all(feature = "validate", feature = "alloc"))]
4920impl<CustomDataType> crate::validate::Validate for ChargingSchedule<CustomDataType> {
4921    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
4922        if let Some(value) = &self.absolute_price_schedule {
4923            crate::validate::Validate::validate(value)
4924                .map_err(|error| error.in_field("absolutePriceSchedule"))?;
4925        }
4926        crate::validate::Validate::validate(&self.charging_rate_unit)
4927            .map_err(|error| error.in_field("chargingRateUnit"))?;
4928        crate::validate::check_min_items(self.charging_schedule_period.len(), 1usize)
4929            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
4930        crate::validate::check_max_items(self.charging_schedule_period.len(), 1024usize)
4931            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
4932        for (index, item) in self.charging_schedule_period.iter().enumerate() {
4933            crate::validate::Validate::validate(item)
4934                .map_err(|error| {
4935                    error.in_index(index).in_field("chargingSchedulePeriod")
4936                })?;
4937        }
4938        if let Some(value) = &self.limit_at_so_c {
4939            crate::validate::Validate::validate(value)
4940                .map_err(|error| error.in_field("limitAtSoC"))?;
4941        }
4942        if let Some(value) = &self.price_level_schedule {
4943            crate::validate::Validate::validate(value)
4944                .map_err(|error| error.in_field("priceLevelSchedule"))?;
4945        }
4946        if let Some(value) = self.randomized_delay {
4947            crate::validate::check_min_i64(value, 0i64)
4948                .map_err(|error| error.in_field("randomizedDelay"))?;
4949        }
4950        if let Some(value) = &self.sales_tariff {
4951            crate::validate::Validate::validate(value)
4952                .map_err(|error| error.in_field("salesTariff"))?;
4953        }
4954        if let Some(value) = self.signature_id {
4955            crate::validate::check_min_i64(value, 0i64)
4956                .map_err(|error| error.in_field("signatureId"))?;
4957        }
4958        Ok(())
4959    }
4960}
4961#[cfg(not(feature = "alloc"))]
4962/// Charging schedule structure defines a list of charging periods, as used in: NotifyEVChargingScheduleRequest and ChargingProfileType. When used in a NotifyEVChargingScheduleRequest only _duration_ and _chargingSchedulePeriod_ are relevant and _chargingRateUnit_ must be 'W'. +
4963/// An ISO 15118-20 session may provide either an _absolutePriceSchedule_ or a _priceLevelSchedule_. An ISO 15118-2 session can only provide a_salesTariff_ element. The field _digestValue_ is used when price schedule or sales tariff are signed.
4964///
4965/// image::images/ChargingSchedule-Simple.png\[\]
4966#[derive(Debug, Clone, PartialEq)]
4967#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
4968pub struct ChargingSchedule<
4969    CustomDataType = crate::NoCustomData,
4970    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
4971    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize = 8usize,
4972    const CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize = 8usize,
4973    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize = 8usize,
4974    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize = 8usize,
4975    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize = 8usize,
4976    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize = 8usize,
4977> {
4978    #[cfg_attr(feature = "serde", serde(rename = "absolutePriceSchedule"))]
4979    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
4980    pub absolute_price_schedule: Option<
4981        AbsolutePriceSchedule<
4982            CustomDataType,
4983            ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
4984            ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
4985        >,
4986    >,
4987    #[cfg_attr(feature = "serde", serde(rename = "chargingRateUnit"))]
4988    pub charging_rate_unit: ChargingRateUnitEnum,
4989    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedulePeriod"))]
4990    pub charging_schedule_period: heapless::Vec<
4991        ChargingSchedulePeriod<
4992            CustomDataType,
4993            CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
4994            CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
4995        >,
4996        CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
4997    >,
4998    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
4999    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5000    pub custom_data: Option<CustomDataType>,
5001    /// *(2.1)* Base64 encoded hash (SHA256 for ISO 15118-2, SHA512 for ISO 15118-20) of the EXI price schedule element. Used in signature.
5002    #[cfg_attr(feature = "serde", serde(rename = "digestValue"))]
5003    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5004    pub digest_value: Option<heapless::String<88usize>>,
5005    /// Duration of the charging schedule in seconds. If the duration is left empty, the last period will continue indefinitely or until end of the transaction in case startSchedule is absent.
5006    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5007    pub duration: Option<i64>,
5008    pub id: i64,
5009    #[cfg_attr(feature = "serde", serde(rename = "limitAtSoC"))]
5010    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5011    pub limit_at_so_c: Option<LimitAtSoC<CustomDataType>>,
5012    /// Minimum charging rate supported by the EV. The unit of measure is defined by the chargingRateUnit. This parameter is intended to be used by a local smart charging algorithm to optimize the power allocation for in the case a charging process is inefficient at lower charging rates.
5013    #[cfg_attr(feature = "serde", serde(rename = "minChargingRate"))]
5014    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5015    pub min_charging_rate: Option<f64>,
5016    /// *(2.1)* Power tolerance when following EVPowerProfile.
5017    #[cfg_attr(feature = "serde", serde(rename = "powerTolerance"))]
5018    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5019    pub power_tolerance: Option<f64>,
5020    #[cfg_attr(feature = "serde", serde(rename = "priceLevelSchedule"))]
5021    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5022    pub price_level_schedule: Option<
5023        PriceLevelSchedule<
5024            CustomDataType,
5025            PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
5026        >,
5027    >,
5028    /// *(2.1)* Defaults to 0. When _randomizedDelay_ not equals zero, then the start of each &lt;&lt;cmn_chargingscheduleperiodtype,ChargingSchedulePeriodType&gt;&gt; is delayed by a randomly chosen number of seconds between 0 and _randomizedDelay_.  Only allowed for TxProfile and TxDefaultProfile.
5029    #[cfg_attr(feature = "serde", serde(rename = "randomizedDelay"))]
5030    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5031    pub randomized_delay: Option<i64>,
5032    #[cfg_attr(feature = "serde", serde(rename = "salesTariff"))]
5033    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5034    pub sales_tariff: Option<
5035        SalesTariff<CustomDataType, SALES_TARIFF_SALES_TARIFF_ENTRY_CAP>,
5036    >,
5037    /// *(2.1)* Id of this element for referencing in a signature.
5038    #[cfg_attr(feature = "serde", serde(rename = "signatureId"))]
5039    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5040    pub signature_id: Option<i64>,
5041    /// Starting point of an absolute schedule or recurring schedule.
5042    #[cfg_attr(feature = "serde", serde(rename = "startSchedule"))]
5043    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5044    pub start_schedule: Option<crate::OcppTimestamp>,
5045    /// *(2.1)* Defaults to false. When true, disregard time zone offset in dateTime fields of  _ChargingScheduleType_ and use unqualified local time at Charging Station instead.
5046    ///  This allows the same `Absolute` or `Recurring` charging profile to be used in both summer and winter time.
5047    #[cfg_attr(feature = "serde", serde(rename = "useLocalTime"))]
5048    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5049    pub use_local_time: Option<bool>,
5050}
5051#[cfg(all(feature = "validate", not(feature = "alloc")))]
5052impl<
5053    CustomDataType,
5054    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
5055    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize,
5056    const CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize,
5057    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize,
5058    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize,
5059    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize,
5060    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize,
5061> crate::validate::Validate
5062for ChargingSchedule<
5063    CustomDataType,
5064    ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
5065    ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
5066    CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
5067    CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
5068    CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
5069    PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
5070    SALES_TARIFF_SALES_TARIFF_ENTRY_CAP,
5071> {
5072    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5073        if let Some(value) = &self.absolute_price_schedule {
5074            crate::validate::Validate::validate(value)
5075                .map_err(|error| error.in_field("absolutePriceSchedule"))?;
5076        }
5077        crate::validate::Validate::validate(&self.charging_rate_unit)
5078            .map_err(|error| error.in_field("chargingRateUnit"))?;
5079        crate::validate::check_min_items(self.charging_schedule_period.len(), 1usize)
5080            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
5081        crate::validate::check_max_items(self.charging_schedule_period.len(), 1024usize)
5082            .map_err(|error| error.in_field("chargingSchedulePeriod"))?;
5083        for (index, item) in self.charging_schedule_period.iter().enumerate() {
5084            crate::validate::Validate::validate(item)
5085                .map_err(|error| {
5086                    error.in_index(index).in_field("chargingSchedulePeriod")
5087                })?;
5088        }
5089        if let Some(value) = &self.limit_at_so_c {
5090            crate::validate::Validate::validate(value)
5091                .map_err(|error| error.in_field("limitAtSoC"))?;
5092        }
5093        if let Some(value) = &self.price_level_schedule {
5094            crate::validate::Validate::validate(value)
5095                .map_err(|error| error.in_field("priceLevelSchedule"))?;
5096        }
5097        if let Some(value) = self.randomized_delay {
5098            crate::validate::check_min_i64(value, 0i64)
5099                .map_err(|error| error.in_field("randomizedDelay"))?;
5100        }
5101        if let Some(value) = &self.sales_tariff {
5102            crate::validate::Validate::validate(value)
5103                .map_err(|error| error.in_field("salesTariff"))?;
5104        }
5105        if let Some(value) = self.signature_id {
5106            crate::validate::check_min_i64(value, 0i64)
5107                .map_err(|error| error.in_field("signatureId"))?;
5108        }
5109        Ok(())
5110    }
5111}
5112/// Type of grid event that caused this
5113#[derive(Debug, Clone, PartialEq, Eq)]
5114#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5115pub enum GridEventFaultEnum {
5116    CurrentImbalance,
5117    LocalEmergency,
5118    LowInputPower,
5119    OverCurrent,
5120    OverFrequency,
5121    OverVoltage,
5122    PhaseRotation,
5123    RemoteEmergency,
5124    UnderFrequency,
5125    UnderVoltage,
5126    VoltageImbalance,
5127}
5128#[cfg(feature = "validate")]
5129impl crate::validate::Validate for GridEventFaultEnum {
5130    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5131        Ok(())
5132    }
5133}
5134#[cfg(feature = "alloc")]
5135/// Contains message details, for a message to be displayed on a Charging Station.
5136#[derive(Debug, Clone, PartialEq, Eq)]
5137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5138pub struct MessageInfo<CustomDataType = crate::NoCustomData> {
5139    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5140    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5141    pub custom_data: Option<CustomDataType>,
5142    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5143    pub display: Option<Component<CustomDataType>>,
5144    /// Until what date-time should this message be shown, after this date/time this message SHALL be removed.
5145    #[cfg_attr(feature = "serde", serde(rename = "endDateTime"))]
5146    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5147    pub end_date_time: Option<crate::OcppTimestamp>,
5148    /// Unique id within an exchange context. It is defined within the OCPP context as a positive Integer value (greater or equal to zero).
5149    pub id: i64,
5150    pub message: MessageContent<CustomDataType>,
5151    #[cfg_attr(feature = "serde", serde(rename = "messageExtra"))]
5152    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5153    pub message_extra: Option<heapless::Vec<MessageContent<CustomDataType>, 4usize>>,
5154    pub priority: MessagePriorityEnum,
5155    /// From what date-time should this message be shown. If omitted: directly.
5156    #[cfg_attr(feature = "serde", serde(rename = "startDateTime"))]
5157    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5158    pub start_date_time: Option<crate::OcppTimestamp>,
5159    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5160    pub state: Option<MessageStateEnum>,
5161    /// During which transaction shall this message be shown.
5162    /// Message SHALL be removed by the Charging Station after transaction has
5163    /// ended.
5164    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
5165    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5166    pub transaction_id: Option<heapless::String<36usize>>,
5167}
5168#[cfg(all(feature = "validate", feature = "alloc"))]
5169impl<CustomDataType> crate::validate::Validate for MessageInfo<CustomDataType> {
5170    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5171        if let Some(value) = &self.display {
5172            crate::validate::Validate::validate(value)
5173                .map_err(|error| error.in_field("display"))?;
5174        }
5175        crate::validate::check_min_i64(self.id, 0i64)
5176            .map_err(|error| error.in_field("id"))?;
5177        crate::validate::Validate::validate(&self.message)
5178            .map_err(|error| error.in_field("message"))?;
5179        if let Some(value) = &self.message_extra {
5180            crate::validate::check_min_items(value.len(), 1usize)
5181                .map_err(|error| error.in_field("messageExtra"))?;
5182            for (index, item) in value.iter().enumerate() {
5183                crate::validate::Validate::validate(item)
5184                    .map_err(|error| error.in_index(index).in_field("messageExtra"))?;
5185            }
5186        }
5187        crate::validate::Validate::validate(&self.priority)
5188            .map_err(|error| error.in_field("priority"))?;
5189        if let Some(value) = &self.state {
5190            crate::validate::Validate::validate(value)
5191                .map_err(|error| error.in_field("state"))?;
5192        }
5193        Ok(())
5194    }
5195}
5196#[cfg(not(feature = "alloc"))]
5197/// Contains message details, for a message to be displayed on a Charging Station.
5198#[derive(Debug, Clone, PartialEq, Eq)]
5199#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5200pub struct MessageInfo<
5201    CustomDataType = crate::NoCustomData,
5202    const MESSAGE_CONTENT_CONTENT_CAP: usize = 1024usize,
5203> {
5204    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5205    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5206    pub custom_data: Option<CustomDataType>,
5207    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5208    pub display: Option<Component<CustomDataType>>,
5209    /// Until what date-time should this message be shown, after this date/time this message SHALL be removed.
5210    #[cfg_attr(feature = "serde", serde(rename = "endDateTime"))]
5211    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5212    pub end_date_time: Option<crate::OcppTimestamp>,
5213    /// Unique id within an exchange context. It is defined within the OCPP context as a positive Integer value (greater or equal to zero).
5214    pub id: i64,
5215    pub message: MessageContent<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP>,
5216    #[cfg_attr(feature = "serde", serde(rename = "messageExtra"))]
5217    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5218    pub message_extra: Option<
5219        heapless::Vec<
5220            MessageContent<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP>,
5221            4usize,
5222        >,
5223    >,
5224    pub priority: MessagePriorityEnum,
5225    /// From what date-time should this message be shown. If omitted: directly.
5226    #[cfg_attr(feature = "serde", serde(rename = "startDateTime"))]
5227    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5228    pub start_date_time: Option<crate::OcppTimestamp>,
5229    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5230    pub state: Option<MessageStateEnum>,
5231    /// During which transaction shall this message be shown.
5232    /// Message SHALL be removed by the Charging Station after transaction has
5233    /// ended.
5234    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
5235    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5236    pub transaction_id: Option<heapless::String<36usize>>,
5237}
5238#[cfg(all(feature = "validate", not(feature = "alloc")))]
5239impl<CustomDataType, const MESSAGE_CONTENT_CONTENT_CAP: usize> crate::validate::Validate
5240for MessageInfo<CustomDataType, MESSAGE_CONTENT_CONTENT_CAP> {
5241    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5242        if let Some(value) = &self.display {
5243            crate::validate::Validate::validate(value)
5244                .map_err(|error| error.in_field("display"))?;
5245        }
5246        crate::validate::check_min_i64(self.id, 0i64)
5247            .map_err(|error| error.in_field("id"))?;
5248        crate::validate::Validate::validate(&self.message)
5249            .map_err(|error| error.in_field("message"))?;
5250        if let Some(value) = &self.message_extra {
5251            crate::validate::check_min_items(value.len(), 1usize)
5252                .map_err(|error| error.in_field("messageExtra"))?;
5253            for (index, item) in value.iter().enumerate() {
5254                crate::validate::Validate::validate(item)
5255                    .map_err(|error| error.in_index(index).in_field("messageExtra"))?;
5256            }
5257        }
5258        crate::validate::Validate::validate(&self.priority)
5259            .map_err(|error| error.in_field("priority"))?;
5260        if let Some(value) = &self.state {
5261            crate::validate::Validate::validate(value)
5262                .map_err(|error| error.in_field("state"))?;
5263        }
5264        Ok(())
5265    }
5266}
5267/// EV AC charging parameters for ISO 15118-2
5268#[derive(Debug, Clone, PartialEq)]
5269#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5270pub struct ACChargingParameters<CustomDataType = crate::NoCustomData> {
5271    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5272    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5273    pub custom_data: Option<CustomDataType>,
5274    /// Amount of energy requested (in Wh). This includes energy required for preconditioning.
5275    /// Relates to: +
5276    /// *ISO 15118-2*: AC_EVChargeParameterType: EAmount +
5277    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVTargetEnergyRequest
5278    #[cfg_attr(feature = "serde", serde(rename = "energyAmount"))]
5279    pub energy_amount: f64,
5280    /// Maximum current (amps) supported by the electric vehicle (per phase). Includes cable capacity.
5281    /// Relates to: +
5282    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMaxCurrent
5283    #[cfg_attr(feature = "serde", serde(rename = "evMaxCurrent"))]
5284    pub ev_max_current: f64,
5285    /// Maximum voltage supported by the electric vehicle.
5286    /// Relates to: +
5287    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMaxVoltage
5288    #[cfg_attr(feature = "serde", serde(rename = "evMaxVoltage"))]
5289    pub ev_max_voltage: f64,
5290    /// Minimum current (amps) supported by the electric vehicle (per phase).
5291    /// Relates to: +
5292    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMinCurrent
5293    #[cfg_attr(feature = "serde", serde(rename = "evMinCurrent"))]
5294    pub ev_min_current: f64,
5295}
5296#[cfg(feature = "validate")]
5297impl<CustomDataType> crate::validate::Validate for ACChargingParameters<CustomDataType> {
5298    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5299        Ok(())
5300    }
5301}
5302/// *(2.1)* Indicates whether EV wants to operate in Dynamic or Scheduled mode. When absent, Scheduled mode is assumed for backwards compatibility. +
5303/// *ISO 15118-20:* +
5304/// ServiceSelectionReq(SelectedEnergyTransferService)
5305#[derive(Debug, Clone, PartialEq, Eq)]
5306#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5307pub enum ControlModeEnum {
5308    ScheduledControl,
5309    DynamicControl,
5310}
5311#[cfg(feature = "validate")]
5312impl crate::validate::Validate for ControlModeEnum {
5313    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5314        Ok(())
5315    }
5316}
5317/// EV DC charging parameters for ISO 15118-2
5318#[derive(Debug, Clone, PartialEq)]
5319#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5320pub struct DCChargingParameters<CustomDataType = crate::NoCustomData> {
5321    /// Percentage of SoC at which the EV considers a fast charging process to end. (possible values: 0 - 100)
5322    /// Relates to: +
5323    /// *ISO 15118-2*: DC_EVChargeParameterType: BulkSOC
5324    #[cfg_attr(feature = "serde", serde(rename = "bulkSoC"))]
5325    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5326    pub bulk_so_c: Option<i64>,
5327    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5328    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5329    pub custom_data: Option<CustomDataType>,
5330    /// Amount of energy requested (in Wh). This inludes energy required for preconditioning.
5331    /// Relates to: +
5332    /// *ISO 15118-2*: DC_EVChargeParameterType: EVEnergyRequest
5333    #[cfg_attr(feature = "serde", serde(rename = "energyAmount"))]
5334    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5335    pub energy_amount: Option<f64>,
5336    /// Capacity of the electric vehicle battery (in Wh).
5337    /// Relates to: +
5338    /// *ISO 15118-2*: DC_EVChargeParameterType: EVEnergyCapacity
5339    #[cfg_attr(feature = "serde", serde(rename = "evEnergyCapacity"))]
5340    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5341    pub ev_energy_capacity: Option<f64>,
5342    /// Maximum current (in A) supported by the electric vehicle. Includes cable capacity.
5343    /// Relates to: +
5344    /// *ISO 15118-2*: DC_EVChargeParameterType:EVMaximumCurrentLimit
5345    #[cfg_attr(feature = "serde", serde(rename = "evMaxCurrent"))]
5346    pub ev_max_current: f64,
5347    /// Maximum power (in W) supported by the electric vehicle. Required for DC charging.
5348    /// Relates to: +
5349    /// *ISO 15118-2*: DC_EVChargeParameterType: EVMaximumPowerLimit
5350    #[cfg_attr(feature = "serde", serde(rename = "evMaxPower"))]
5351    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5352    pub ev_max_power: Option<f64>,
5353    /// Maximum voltage supported by the electric vehicle.
5354    /// Relates to: +
5355    /// *ISO 15118-2*: DC_EVChargeParameterType: EVMaximumVoltageLimit
5356    #[cfg_attr(feature = "serde", serde(rename = "evMaxVoltage"))]
5357    pub ev_max_voltage: f64,
5358    /// Percentage of SoC at which the EV considers the battery fully charged. (possible values: 0 - 100)
5359    /// Relates to: +
5360    /// *ISO 15118-2*: DC_EVChargeParameterType: FullSOC
5361    #[cfg_attr(feature = "serde", serde(rename = "fullSoC"))]
5362    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5363    pub full_so_c: Option<i64>,
5364    /// Energy available in the battery (in percent of the battery capacity)
5365    /// Relates to: +
5366    /// *ISO 15118-2*: DC_EVChargeParameterType: DC_EVStatus: EVRESSSOC
5367    #[cfg_attr(feature = "serde", serde(rename = "stateOfCharge"))]
5368    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5369    pub state_of_charge: Option<i64>,
5370}
5371#[cfg(feature = "validate")]
5372impl<CustomDataType> crate::validate::Validate for DCChargingParameters<CustomDataType> {
5373    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5374        if let Some(value) = self.bulk_so_c {
5375            crate::validate::check_min_i64(value, 0i64)
5376                .map_err(|error| error.in_field("bulkSoC"))?;
5377            crate::validate::check_max_i64(value, 100i64)
5378                .map_err(|error| error.in_field("bulkSoC"))?;
5379        }
5380        if let Some(value) = self.full_so_c {
5381            crate::validate::check_min_i64(value, 0i64)
5382                .map_err(|error| error.in_field("fullSoC"))?;
5383            crate::validate::check_max_i64(value, 100i64)
5384                .map_err(|error| error.in_field("fullSoC"))?;
5385        }
5386        if let Some(value) = self.state_of_charge {
5387            crate::validate::check_min_i64(value, 0i64)
5388                .map_err(|error| error.in_field("stateOfCharge"))?;
5389            crate::validate::check_max_i64(value, 100i64)
5390                .map_err(|error| error.in_field("stateOfCharge"))?;
5391        }
5392        Ok(())
5393    }
5394}
5395#[derive(Debug, Clone, PartialEq, Eq)]
5396#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5397pub enum IslandingDetectionEnum {
5398    NoAntiIslandingSupport,
5399    RoCoF,
5400    #[cfg_attr(feature = "serde", serde(rename = "UVP_OVP"))]
5401    UVPOVP,
5402    #[cfg_attr(feature = "serde", serde(rename = "UFP_OFP"))]
5403    UFPOFP,
5404    VoltageVectorShift,
5405    ZeroCrossingDetection,
5406    OtherPassive,
5407    ImpedanceMeasurement,
5408    ImpedanceAtFrequency,
5409    SlipModeFrequencyShift,
5410    SandiaFrequencyShift,
5411    SandiaVoltageShift,
5412    FrequencyJump,
5413    RCLQFactor,
5414    OtherActive,
5415}
5416#[cfg(feature = "validate")]
5417impl crate::validate::Validate for IslandingDetectionEnum {
5418    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5419        Ok(())
5420    }
5421}
5422#[cfg(feature = "alloc")]
5423/// *(2.1)* DERChargingParametersType is used in ChargingNeedsType during an ISO 15118-20 session for AC_BPT_DER to report the inverter settings related to DER control that were agreed between EVSE and EV.
5424///
5425/// Fields starting with "ev" contain values from the EV.
5426/// Other fields contain a value that is supported by both EV and EVSE.
5427///
5428/// DERChargingParametersType type is only relevant in case of an ISO 15118-20 AC_BPT_DER/AC_DER charging session.
5429///
5430/// NOTE: All these fields have values greater or equal to zero (i.e. are non-negative)
5431#[derive(Debug, Clone, PartialEq)]
5432#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5433pub struct DERChargingParameters<CustomDataType = crate::NoCustomData> {
5434    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5435    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5436    pub custom_data: Option<CustomDataType>,
5437    /// Maximum allowed duration of DC injection at level 1 charging. +
5438    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel1DCInjection
5439    #[cfg_attr(feature = "serde", serde(rename = "evDurationLevel1DCInjection"))]
5440    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5441    pub ev_duration_level1_d_c_injection: Option<f64>,
5442    /// Maximum allowed duration of DC injection at level 2 charging. +
5443    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel2DCInjection
5444    #[cfg_attr(feature = "serde", serde(rename = "evDurationLevel2DCInjection"))]
5445    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5446    pub ev_duration_level2_d_c_injection: Option<f64>,
5447    /// Hardware version of EV inverter. +
5448    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterHwVersion
5449    #[cfg_attr(feature = "serde", serde(rename = "evInverterHwVersion"))]
5450    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5451    pub ev_inverter_hw_version: Option<heapless::String<50usize>>,
5452    /// Manufacturer of the EV inverter. +
5453    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterManufacturer
5454    #[cfg_attr(feature = "serde", serde(rename = "evInverterManufacturer"))]
5455    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5456    pub ev_inverter_manufacturer: Option<heapless::String<50usize>>,
5457    /// Model name of the EV inverter. +
5458    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterModel
5459    #[cfg_attr(feature = "serde", serde(rename = "evInverterModel"))]
5460    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5461    pub ev_inverter_model: Option<heapless::String<50usize>>,
5462    /// Serial number of the EV inverter. +
5463    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSerialNumber
5464    #[cfg_attr(feature = "serde", serde(rename = "evInverterSerialNumber"))]
5465    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5466    pub ev_inverter_serial_number: Option<heapless::String<50usize>>,
5467    /// Software version of EV inverter. +
5468    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSwVersion
5469    #[cfg_attr(feature = "serde", serde(rename = "evInverterSwVersion"))]
5470    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5471    pub ev_inverter_sw_version: Option<heapless::String<50usize>>,
5472    /// Type of islanding detection method. Only mandatory when islanding detection is required at the site, as set in the ISO 15118 Service Details configuration. +
5473    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingDetectionMethod
5474    #[cfg_attr(feature = "serde", serde(rename = "evIslandingDetectionMethod"))]
5475    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5476    pub ev_islanding_detection_method: Option<alloc::vec::Vec<IslandingDetectionEnum>>,
5477    /// Time after which EV will trip if an island has been detected. +
5478    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingTripTime
5479    #[cfg_attr(feature = "serde", serde(rename = "evIslandingTripTime"))]
5480    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5481    pub ev_islanding_trip_time: Option<f64>,
5482    /// Maximum injected DC current allowed at level 1 charging. +
5483    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel1DCInjection
5484    #[cfg_attr(feature = "serde", serde(rename = "evMaximumLevel1DCInjection"))]
5485    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5486    pub ev_maximum_level1_d_c_injection: Option<f64>,
5487    /// Maximum injected DC current allowed at level 2 charging. +
5488    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel2DCInjection
5489    #[cfg_attr(feature = "serde", serde(rename = "evMaximumLevel2DCInjection"))]
5490    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5491    pub ev_maximum_level2_d_c_injection: Option<f64>,
5492    /// Rated maximum injected active power by EV, at specified over-excited power factor (overExcitedPowerFactor). +
5493    /// It can also be defined as the rated maximum discharge power at the rated minimum injected reactive power value. This means that if the EV is providing reactive power support, and it is requested to discharge at max power (e.g. to satisfy an EMS request), the EV may override the request and discharge up to overExcitedMaximumDischargePower to meet the minimum reactive power requirements. +
5494    /// Corresponds to the WOvPF attribute in IEC 61850. +
5495    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedMaximumDischargePower
5496    #[cfg_attr(feature = "serde", serde(rename = "evOverExcitedMaxDischargePower"))]
5497    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5498    pub ev_over_excited_max_discharge_power: Option<f64>,
5499    /// EV power factor when injecting (over excited) the minimum reactive power. +
5500    /// Corresponds to the OvPF attribute in IEC 61850. +
5501    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedPowerFactor
5502    #[cfg_attr(feature = "serde", serde(rename = "evOverExcitedPowerFactor"))]
5503    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5504    pub ev_over_excited_power_factor: Option<f64>,
5505    /// Measure of the susceptibility of the circuit to reactance, in Siemens (S). +
5506    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVReactiveSusceptance
5507    #[cfg_attr(feature = "serde", serde(rename = "evReactiveSusceptance"))]
5508    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5509    pub ev_reactive_susceptance: Option<f64>,
5510    /// Total energy value, in Wh, that EV is allowed to provide during the entire V2G session. The value is independent of the V2X Cycling area. Once this value reaches the value of 0, the EV may block any attempt to discharge in order to protect the battery health.
5511    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVSessionTotalDischargeEnergyAvailable
5512    #[cfg_attr(
5513        feature = "serde",
5514        serde(rename = "evSessionTotalDischargeEnergyAvailable")
5515    )]
5516    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5517    pub ev_session_total_discharge_energy_available: Option<f64>,
5518    /// DER control functions supported by EV. +
5519    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType:DERControlFunctions (bitmap)
5520    #[cfg_attr(feature = "serde", serde(rename = "evSupportedDERControl"))]
5521    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5522    pub ev_supported_d_e_r_control: Option<alloc::vec::Vec<DERControlEnum>>,
5523    /// Rated maximum injected active power by EV supported at specified under-excited power factor (EVUnderExcitedPowerFactor). +
5524    /// It can also be defined as the rated maximum dischargePower at the rated minimum absorbed reactive power value.
5525    /// This means that if the EV is providing reactive power support, and it is requested to discharge at max power (e.g. to satisfy an EMS request), the EV may override the request and discharge up to underExcitedMaximumDischargePower to meet the minimum reactive power requirements. +
5526    /// This corresponds to the WUnPF attribute in the IEC 61850. +
5527    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedMaximumDischargePower
5528    #[cfg_attr(feature = "serde", serde(rename = "evUnderExcitedMaxDischargePower"))]
5529    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5530    pub ev_under_excited_max_discharge_power: Option<f64>,
5531    /// EV power factor when injecting (under excited) the minimum reactive power. +
5532    /// Corresponds to the OvPF attribute in IEC 61850. +
5533    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedPowerFactor
5534    #[cfg_attr(feature = "serde", serde(rename = "evUnderExcitedPowerFactor"))]
5535    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5536    pub ev_under_excited_power_factor: Option<f64>,
5537    /// Rated maximum total apparent power, defined by min(EV, EVSE) in va.
5538    /// Corresponds to the VAMaxRtg in IEC 61850. +
5539    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumApparentPower
5540    #[cfg_attr(feature = "serde", serde(rename = "maxApparentPower"))]
5541    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5542    pub max_apparent_power: Option<f64>,
5543    /// Rated maximum absorbed apparent power, defined by min(EV, EVSE) in va. +
5544    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5545    ///     in which case this field represents phase L1. +
5546    ///     Corresponds to the ChaVAMaxRtg in IEC 61850. +
5547    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower
5548    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower"))]
5549    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5550    pub max_charge_apparent_power: Option<f64>,
5551    /// Rated maximum absorbed apparent power on phase L2, defined by min(EV, EVSE) in va.
5552    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
5553    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L2
5554    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower_L2"))]
5555    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5556    pub max_charge_apparent_power_l2: Option<f64>,
5557    /// Rated maximum absorbed apparent power on phase L3, defined by min(EV, EVSE) in va.
5558    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
5559    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L3
5560    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower_L3"))]
5561    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5562    pub max_charge_apparent_power_l3: Option<f64>,
5563    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars. +
5564    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5565    ///     in which case this field represents phase L1. +
5566    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5567    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower
5568    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower"))]
5569    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5570    pub max_charge_reactive_power: Option<f64>,
5571    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L2. +
5572    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5573    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L2
5574    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower_L2"))]
5575    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5576    pub max_charge_reactive_power_l2: Option<f64>,
5577    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L3. +
5578    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5579    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L3
5580    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower_L3"))]
5581    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5582    pub max_charge_reactive_power_l3: Option<f64>,
5583    /// Rated maximum injected apparent power, defined by min(EV, EVSE) in va. +
5584    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5585    ///     in which case this field represents phase L1. +
5586    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5587    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower
5588    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower"))]
5589    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5590    pub max_discharge_apparent_power: Option<f64>,
5591    /// Rated maximum injected apparent power on phase L2, defined by min(EV, EVSE) in va. +
5592    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5593    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L2
5594    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower_L2"))]
5595    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5596    pub max_discharge_apparent_power_l2: Option<f64>,
5597    /// Rated maximum injected apparent power on phase L3, defined by min(EV, EVSE) in va. +
5598    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5599    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L3
5600    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower_L3"))]
5601    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5602    pub max_discharge_apparent_power_l3: Option<f64>,
5603    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars. +
5604    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5605    ///     in which case this field represents phase L1. +
5606    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5607    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower
5608    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower"))]
5609    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5610    pub max_discharge_reactive_power: Option<f64>,
5611    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L2. +
5612    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5613    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L2
5614    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower_L2"))]
5615    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5616    pub max_discharge_reactive_power_l2: Option<f64>,
5617    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L3. +
5618    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5619    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L3
5620    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower_L3"))]
5621    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5622    pub max_discharge_reactive_power_l3: Option<f64>,
5623    /// Maximum AC rms voltage, as defined by min(EV, EVSE)  to operate with. +
5624    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumNominalVoltage
5625    #[cfg_attr(feature = "serde", serde(rename = "maxNominalVoltage"))]
5626    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5627    pub max_nominal_voltage: Option<f64>,
5628    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars. +
5629    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5630    ///     in which case this field represents phase L1. +
5631    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower
5632    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower"))]
5633    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5634    pub min_charge_reactive_power: Option<f64>,
5635    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L2. +
5636    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L2
5637    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower_L2"))]
5638    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5639    pub min_charge_reactive_power_l2: Option<f64>,
5640    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L3. +
5641    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L3
5642    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower_L3"))]
5643    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5644    pub min_charge_reactive_power_l3: Option<f64>,
5645    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in vars. +
5646    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5647    ///     in which case this field represents phase L1. +
5648    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower
5649    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower"))]
5650    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5651    pub min_discharge_reactive_power: Option<f64>,
5652    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L2. +
5653    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L2
5654    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower_L2"))]
5655    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5656    pub min_discharge_reactive_power_l2: Option<f64>,
5657    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L3. +
5658    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L3
5659    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower_L3"))]
5660    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5661    pub min_discharge_reactive_power_l3: Option<f64>,
5662    /// Minimum AC rms voltage, as defined by max(EV, EVSE)  to operate with. +
5663    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumNominalVoltage
5664    #[cfg_attr(feature = "serde", serde(rename = "minNominalVoltage"))]
5665    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5666    pub min_nominal_voltage: Option<f64>,
5667    /// Line voltage supported by EVSE and EV.
5668    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltage
5669    #[cfg_attr(feature = "serde", serde(rename = "nominalVoltage"))]
5670    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5671    pub nominal_voltage: Option<f64>,
5672    /// The nominal AC voltage (rms) offset between the Charging Station's electrical connection point and the utility’s point of common coupling. +
5673    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltageOffset
5674    #[cfg_attr(feature = "serde", serde(rename = "nominalVoltageOffset"))]
5675    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5676    pub nominal_voltage_offset: Option<f64>,
5677}
5678#[cfg(all(feature = "validate", feature = "alloc"))]
5679impl<CustomDataType> crate::validate::Validate
5680for DERChargingParameters<CustomDataType> {
5681    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5682        if let Some(value) = &self.ev_islanding_detection_method {
5683            crate::validate::check_min_items(value.len(), 1usize)
5684                .map_err(|error| error.in_field("evIslandingDetectionMethod"))?;
5685            for (index, item) in value.iter().enumerate() {
5686                crate::validate::Validate::validate(item)
5687                    .map_err(|error| {
5688                        error.in_index(index).in_field("evIslandingDetectionMethod")
5689                    })?;
5690            }
5691        }
5692        if let Some(value) = &self.ev_supported_d_e_r_control {
5693            crate::validate::check_min_items(value.len(), 1usize)
5694                .map_err(|error| error.in_field("evSupportedDERControl"))?;
5695            for (index, item) in value.iter().enumerate() {
5696                crate::validate::Validate::validate(item)
5697                    .map_err(|error| {
5698                        error.in_index(index).in_field("evSupportedDERControl")
5699                    })?;
5700            }
5701        }
5702        Ok(())
5703    }
5704}
5705#[cfg(not(feature = "alloc"))]
5706/// *(2.1)* DERChargingParametersType is used in ChargingNeedsType during an ISO 15118-20 session for AC_BPT_DER to report the inverter settings related to DER control that were agreed between EVSE and EV.
5707///
5708/// Fields starting with "ev" contain values from the EV.
5709/// Other fields contain a value that is supported by both EV and EVSE.
5710///
5711/// DERChargingParametersType type is only relevant in case of an ISO 15118-20 AC_BPT_DER/AC_DER charging session.
5712///
5713/// NOTE: All these fields have values greater or equal to zero (i.e. are non-negative)
5714#[derive(Debug, Clone, PartialEq)]
5715#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5716pub struct DERChargingParameters<
5717    CustomDataType = crate::NoCustomData,
5718    const D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP: usize = 8usize,
5719    const D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP: usize = 8usize,
5720> {
5721    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
5722    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5723    pub custom_data: Option<CustomDataType>,
5724    /// Maximum allowed duration of DC injection at level 1 charging. +
5725    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel1DCInjection
5726    #[cfg_attr(feature = "serde", serde(rename = "evDurationLevel1DCInjection"))]
5727    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5728    pub ev_duration_level1_d_c_injection: Option<f64>,
5729    /// Maximum allowed duration of DC injection at level 2 charging. +
5730    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel2DCInjection
5731    #[cfg_attr(feature = "serde", serde(rename = "evDurationLevel2DCInjection"))]
5732    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5733    pub ev_duration_level2_d_c_injection: Option<f64>,
5734    /// Hardware version of EV inverter. +
5735    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterHwVersion
5736    #[cfg_attr(feature = "serde", serde(rename = "evInverterHwVersion"))]
5737    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5738    pub ev_inverter_hw_version: Option<heapless::String<50usize>>,
5739    /// Manufacturer of the EV inverter. +
5740    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterManufacturer
5741    #[cfg_attr(feature = "serde", serde(rename = "evInverterManufacturer"))]
5742    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5743    pub ev_inverter_manufacturer: Option<heapless::String<50usize>>,
5744    /// Model name of the EV inverter. +
5745    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterModel
5746    #[cfg_attr(feature = "serde", serde(rename = "evInverterModel"))]
5747    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5748    pub ev_inverter_model: Option<heapless::String<50usize>>,
5749    /// Serial number of the EV inverter. +
5750    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSerialNumber
5751    #[cfg_attr(feature = "serde", serde(rename = "evInverterSerialNumber"))]
5752    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5753    pub ev_inverter_serial_number: Option<heapless::String<50usize>>,
5754    /// Software version of EV inverter. +
5755    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSwVersion
5756    #[cfg_attr(feature = "serde", serde(rename = "evInverterSwVersion"))]
5757    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5758    pub ev_inverter_sw_version: Option<heapless::String<50usize>>,
5759    /// Type of islanding detection method. Only mandatory when islanding detection is required at the site, as set in the ISO 15118 Service Details configuration. +
5760    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingDetectionMethod
5761    #[cfg_attr(feature = "serde", serde(rename = "evIslandingDetectionMethod"))]
5762    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5763    pub ev_islanding_detection_method: Option<
5764        heapless::Vec<
5765            IslandingDetectionEnum,
5766            D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP,
5767        >,
5768    >,
5769    /// Time after which EV will trip if an island has been detected. +
5770    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingTripTime
5771    #[cfg_attr(feature = "serde", serde(rename = "evIslandingTripTime"))]
5772    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5773    pub ev_islanding_trip_time: Option<f64>,
5774    /// Maximum injected DC current allowed at level 1 charging. +
5775    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel1DCInjection
5776    #[cfg_attr(feature = "serde", serde(rename = "evMaximumLevel1DCInjection"))]
5777    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5778    pub ev_maximum_level1_d_c_injection: Option<f64>,
5779    /// Maximum injected DC current allowed at level 2 charging. +
5780    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel2DCInjection
5781    #[cfg_attr(feature = "serde", serde(rename = "evMaximumLevel2DCInjection"))]
5782    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5783    pub ev_maximum_level2_d_c_injection: Option<f64>,
5784    /// Rated maximum injected active power by EV, at specified over-excited power factor (overExcitedPowerFactor). +
5785    /// It can also be defined as the rated maximum discharge power at the rated minimum injected reactive power value. This means that if the EV is providing reactive power support, and it is requested to discharge at max power (e.g. to satisfy an EMS request), the EV may override the request and discharge up to overExcitedMaximumDischargePower to meet the minimum reactive power requirements. +
5786    /// Corresponds to the WOvPF attribute in IEC 61850. +
5787    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedMaximumDischargePower
5788    #[cfg_attr(feature = "serde", serde(rename = "evOverExcitedMaxDischargePower"))]
5789    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5790    pub ev_over_excited_max_discharge_power: Option<f64>,
5791    /// EV power factor when injecting (over excited) the minimum reactive power. +
5792    /// Corresponds to the OvPF attribute in IEC 61850. +
5793    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedPowerFactor
5794    #[cfg_attr(feature = "serde", serde(rename = "evOverExcitedPowerFactor"))]
5795    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5796    pub ev_over_excited_power_factor: Option<f64>,
5797    /// Measure of the susceptibility of the circuit to reactance, in Siemens (S). +
5798    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVReactiveSusceptance
5799    #[cfg_attr(feature = "serde", serde(rename = "evReactiveSusceptance"))]
5800    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5801    pub ev_reactive_susceptance: Option<f64>,
5802    /// Total energy value, in Wh, that EV is allowed to provide during the entire V2G session. The value is independent of the V2X Cycling area. Once this value reaches the value of 0, the EV may block any attempt to discharge in order to protect the battery health.
5803    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVSessionTotalDischargeEnergyAvailable
5804    #[cfg_attr(
5805        feature = "serde",
5806        serde(rename = "evSessionTotalDischargeEnergyAvailable")
5807    )]
5808    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5809    pub ev_session_total_discharge_energy_available: Option<f64>,
5810    /// DER control functions supported by EV. +
5811    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType:DERControlFunctions (bitmap)
5812    #[cfg_attr(feature = "serde", serde(rename = "evSupportedDERControl"))]
5813    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5814    pub ev_supported_d_e_r_control: Option<
5815        heapless::Vec<
5816            DERControlEnum,
5817            D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP,
5818        >,
5819    >,
5820    /// Rated maximum injected active power by EV supported at specified under-excited power factor (EVUnderExcitedPowerFactor). +
5821    /// It can also be defined as the rated maximum dischargePower at the rated minimum absorbed reactive power value.
5822    /// This means that if the EV is providing reactive power support, and it is requested to discharge at max power (e.g. to satisfy an EMS request), the EV may override the request and discharge up to underExcitedMaximumDischargePower to meet the minimum reactive power requirements. +
5823    /// This corresponds to the WUnPF attribute in the IEC 61850. +
5824    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedMaximumDischargePower
5825    #[cfg_attr(feature = "serde", serde(rename = "evUnderExcitedMaxDischargePower"))]
5826    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5827    pub ev_under_excited_max_discharge_power: Option<f64>,
5828    /// EV power factor when injecting (under excited) the minimum reactive power. +
5829    /// Corresponds to the OvPF attribute in IEC 61850. +
5830    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedPowerFactor
5831    #[cfg_attr(feature = "serde", serde(rename = "evUnderExcitedPowerFactor"))]
5832    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5833    pub ev_under_excited_power_factor: Option<f64>,
5834    /// Rated maximum total apparent power, defined by min(EV, EVSE) in va.
5835    /// Corresponds to the VAMaxRtg in IEC 61850. +
5836    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumApparentPower
5837    #[cfg_attr(feature = "serde", serde(rename = "maxApparentPower"))]
5838    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5839    pub max_apparent_power: Option<f64>,
5840    /// Rated maximum absorbed apparent power, defined by min(EV, EVSE) in va. +
5841    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5842    ///     in which case this field represents phase L1. +
5843    ///     Corresponds to the ChaVAMaxRtg in IEC 61850. +
5844    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower
5845    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower"))]
5846    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5847    pub max_charge_apparent_power: Option<f64>,
5848    /// Rated maximum absorbed apparent power on phase L2, defined by min(EV, EVSE) in va.
5849    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
5850    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L2
5851    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower_L2"))]
5852    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5853    pub max_charge_apparent_power_l2: Option<f64>,
5854    /// Rated maximum absorbed apparent power on phase L3, defined by min(EV, EVSE) in va.
5855    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
5856    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L3
5857    #[cfg_attr(feature = "serde", serde(rename = "maxChargeApparentPower_L3"))]
5858    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5859    pub max_charge_apparent_power_l3: Option<f64>,
5860    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars. +
5861    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5862    ///     in which case this field represents phase L1. +
5863    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5864    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower
5865    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower"))]
5866    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5867    pub max_charge_reactive_power: Option<f64>,
5868    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L2. +
5869    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5870    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L2
5871    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower_L2"))]
5872    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5873    pub max_charge_reactive_power_l2: Option<f64>,
5874    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L3. +
5875    /// Corresponds to the AvarMax attribute in the IEC 61850. +
5876    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L3
5877    #[cfg_attr(feature = "serde", serde(rename = "maxChargeReactivePower_L3"))]
5878    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5879    pub max_charge_reactive_power_l3: Option<f64>,
5880    /// Rated maximum injected apparent power, defined by min(EV, EVSE) in va. +
5881    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5882    ///     in which case this field represents phase L1. +
5883    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5884    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower
5885    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower"))]
5886    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5887    pub max_discharge_apparent_power: Option<f64>,
5888    /// Rated maximum injected apparent power on phase L2, defined by min(EV, EVSE) in va. +
5889    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5890    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L2
5891    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower_L2"))]
5892    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5893    pub max_discharge_apparent_power_l2: Option<f64>,
5894    /// Rated maximum injected apparent power on phase L3, defined by min(EV, EVSE) in va. +
5895    ///     Corresponds to the DisVAMaxRtg in IEC 61850. +
5896    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L3
5897    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeApparentPower_L3"))]
5898    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5899    pub max_discharge_apparent_power_l3: Option<f64>,
5900    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars. +
5901    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5902    ///     in which case this field represents phase L1. +
5903    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5904    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower
5905    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower"))]
5906    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5907    pub max_discharge_reactive_power: Option<f64>,
5908    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L2. +
5909    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5910    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L2
5911    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower_L2"))]
5912    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5913    pub max_discharge_reactive_power_l2: Option<f64>,
5914    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L3. +
5915    /// Corresponds to the IvarMax attribute in the IEC 61850. +
5916    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L3
5917    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeReactivePower_L3"))]
5918    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5919    pub max_discharge_reactive_power_l3: Option<f64>,
5920    /// Maximum AC rms voltage, as defined by min(EV, EVSE)  to operate with. +
5921    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumNominalVoltage
5922    #[cfg_attr(feature = "serde", serde(rename = "maxNominalVoltage"))]
5923    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5924    pub max_nominal_voltage: Option<f64>,
5925    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars. +
5926    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5927    ///     in which case this field represents phase L1. +
5928    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower
5929    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower"))]
5930    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5931    pub min_charge_reactive_power: Option<f64>,
5932    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L2. +
5933    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L2
5934    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower_L2"))]
5935    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5936    pub min_charge_reactive_power_l2: Option<f64>,
5937    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L3. +
5938    ///     *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L3
5939    #[cfg_attr(feature = "serde", serde(rename = "minChargeReactivePower_L3"))]
5940    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5941    pub min_charge_reactive_power_l3: Option<f64>,
5942    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in vars. +
5943    ///     This field represents the sum of all phases, unless values are provided for L2 and L3,
5944    ///     in which case this field represents phase L1. +
5945    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower
5946    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower"))]
5947    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5948    pub min_discharge_reactive_power: Option<f64>,
5949    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L2. +
5950    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L2
5951    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower_L2"))]
5952    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5953    pub min_discharge_reactive_power_l2: Option<f64>,
5954    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L3. +
5955    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L3
5956    #[cfg_attr(feature = "serde", serde(rename = "minDischargeReactivePower_L3"))]
5957    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5958    pub min_discharge_reactive_power_l3: Option<f64>,
5959    /// Minimum AC rms voltage, as defined by max(EV, EVSE)  to operate with. +
5960    ///        *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumNominalVoltage
5961    #[cfg_attr(feature = "serde", serde(rename = "minNominalVoltage"))]
5962    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5963    pub min_nominal_voltage: Option<f64>,
5964    /// Line voltage supported by EVSE and EV.
5965    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltage
5966    #[cfg_attr(feature = "serde", serde(rename = "nominalVoltage"))]
5967    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5968    pub nominal_voltage: Option<f64>,
5969    /// The nominal AC voltage (rms) offset between the Charging Station's electrical connection point and the utility’s point of common coupling. +
5970    ///         *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltageOffset
5971    #[cfg_attr(feature = "serde", serde(rename = "nominalVoltageOffset"))]
5972    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
5973    pub nominal_voltage_offset: Option<f64>,
5974}
5975#[cfg(all(feature = "validate", not(feature = "alloc")))]
5976impl<
5977    CustomDataType,
5978    const D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP: usize,
5979    const D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP: usize,
5980> crate::validate::Validate
5981for DERChargingParameters<
5982    CustomDataType,
5983    D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP,
5984    D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP,
5985> {
5986    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
5987        if let Some(value) = &self.ev_islanding_detection_method {
5988            crate::validate::check_min_items(value.len(), 1usize)
5989                .map_err(|error| error.in_field("evIslandingDetectionMethod"))?;
5990            for (index, item) in value.iter().enumerate() {
5991                crate::validate::Validate::validate(item)
5992                    .map_err(|error| {
5993                        error.in_index(index).in_field("evIslandingDetectionMethod")
5994                    })?;
5995            }
5996        }
5997        if let Some(value) = &self.ev_supported_d_e_r_control {
5998            crate::validate::check_min_items(value.len(), 1usize)
5999                .map_err(|error| error.in_field("evSupportedDERControl"))?;
6000            for (index, item) in value.iter().enumerate() {
6001                crate::validate::Validate::validate(item)
6002                    .map_err(|error| {
6003                        error.in_index(index).in_field("evSupportedDERControl")
6004                    })?;
6005            }
6006        }
6007        Ok(())
6008    }
6009}
6010/// *(2.1)* An entry in price schedule over time for which EV is willing to discharge.
6011#[derive(Debug, Clone, PartialEq)]
6012#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6013pub struct EVPriceRule<CustomDataType = crate::NoCustomData> {
6014    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6015    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6016    pub custom_data: Option<CustomDataType>,
6017    /// Cost per kWh.
6018    #[cfg_attr(feature = "serde", serde(rename = "energyFee"))]
6019    pub energy_fee: f64,
6020    /// The EnergyFee applies between this value and the value of the PowerRangeStart of the subsequent EVPriceRule. If the power is below this value, the EnergyFee of the previous EVPriceRule applies. Negative values are used for discharging.
6021    #[cfg_attr(feature = "serde", serde(rename = "powerRangeStart"))]
6022    pub power_range_start: f64,
6023}
6024#[cfg(feature = "validate")]
6025impl<CustomDataType> crate::validate::Validate for EVPriceRule<CustomDataType> {
6026    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6027        Ok(())
6028    }
6029}
6030/// *(2.1)* An entry in price schedule over time for which EV is willing to discharge.
6031#[derive(Debug, Clone, PartialEq)]
6032#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6033pub struct EVAbsolutePriceScheduleEntry<CustomDataType = crate::NoCustomData> {
6034    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6035    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6036    pub custom_data: Option<CustomDataType>,
6037    /// The amount of seconds of this entry.
6038    pub duration: i64,
6039    #[cfg_attr(feature = "serde", serde(rename = "evPriceRule"))]
6040    pub ev_price_rule: heapless::Vec<EVPriceRule<CustomDataType>, 8usize>,
6041}
6042#[cfg(feature = "validate")]
6043impl<CustomDataType> crate::validate::Validate
6044for EVAbsolutePriceScheduleEntry<CustomDataType> {
6045    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6046        crate::validate::check_min_items(self.ev_price_rule.len(), 1usize)
6047            .map_err(|error| error.in_field("evPriceRule"))?;
6048        for (index, item) in self.ev_price_rule.iter().enumerate() {
6049            crate::validate::Validate::validate(item)
6050                .map_err(|error| error.in_index(index).in_field("evPriceRule"))?;
6051        }
6052        Ok(())
6053    }
6054}
6055#[cfg(feature = "alloc")]
6056/// *(2.1)* Price schedule of EV energy offer.
6057#[derive(Debug, Clone, PartialEq)]
6058#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6059pub struct EVAbsolutePriceSchedule<CustomDataType = crate::NoCustomData> {
6060    /// Currency code according to ISO 4217.
6061    pub currency: heapless::String<3usize>,
6062    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6063    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6064    pub custom_data: Option<CustomDataType>,
6065    #[cfg_attr(feature = "serde", serde(rename = "evAbsolutePriceScheduleEntries"))]
6066    pub ev_absolute_price_schedule_entries: alloc::vec::Vec<
6067        EVAbsolutePriceScheduleEntry<CustomDataType>,
6068    >,
6069    /// ISO 15118-20 URN of price algorithm: Power, PeakPower, StackedEnergy.
6070    #[cfg_attr(feature = "serde", serde(rename = "priceAlgorithm"))]
6071    pub price_algorithm: alloc::string::String,
6072    /// Starting point in time of the EVEnergyOffer.
6073    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
6074    pub time_anchor: crate::OcppTimestamp,
6075}
6076#[cfg(all(feature = "validate", feature = "alloc"))]
6077impl<CustomDataType> crate::validate::Validate
6078for EVAbsolutePriceSchedule<CustomDataType> {
6079    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6080        crate::validate::check_min_items(
6081                self.ev_absolute_price_schedule_entries.len(),
6082                1usize,
6083            )
6084            .map_err(|error| error.in_field("evAbsolutePriceScheduleEntries"))?;
6085        crate::validate::check_max_items(
6086                self.ev_absolute_price_schedule_entries.len(),
6087                1024usize,
6088            )
6089            .map_err(|error| error.in_field("evAbsolutePriceScheduleEntries"))?;
6090        for (index, item) in self.ev_absolute_price_schedule_entries.iter().enumerate() {
6091            crate::validate::Validate::validate(item)
6092                .map_err(|error| {
6093                    error.in_index(index).in_field("evAbsolutePriceScheduleEntries")
6094                })?;
6095        }
6096        crate::validate::check_max_length(&self.price_algorithm, 2000usize)
6097            .map_err(|error| error.in_field("priceAlgorithm"))?;
6098        Ok(())
6099    }
6100}
6101#[cfg(not(feature = "alloc"))]
6102/// *(2.1)* Price schedule of EV energy offer.
6103#[derive(Debug, Clone, PartialEq)]
6104#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6105pub struct EVAbsolutePriceSchedule<
6106    CustomDataType = crate::NoCustomData,
6107    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6108    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
6109> {
6110    /// Currency code according to ISO 4217.
6111    pub currency: heapless::String<3usize>,
6112    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6113    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6114    pub custom_data: Option<CustomDataType>,
6115    #[cfg_attr(feature = "serde", serde(rename = "evAbsolutePriceScheduleEntries"))]
6116    pub ev_absolute_price_schedule_entries: heapless::Vec<
6117        EVAbsolutePriceScheduleEntry<CustomDataType>,
6118        E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6119    >,
6120    /// ISO 15118-20 URN of price algorithm: Power, PeakPower, StackedEnergy.
6121    #[cfg_attr(feature = "serde", serde(rename = "priceAlgorithm"))]
6122    pub price_algorithm: heapless::String<
6123        E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6124    >,
6125    /// Starting point in time of the EVEnergyOffer.
6126    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
6127    pub time_anchor: crate::OcppTimestamp,
6128}
6129#[cfg(all(feature = "validate", not(feature = "alloc")))]
6130impl<
6131    CustomDataType,
6132    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize,
6133    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
6134> crate::validate::Validate
6135for EVAbsolutePriceSchedule<
6136    CustomDataType,
6137    E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6138    E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6139> {
6140    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6141        crate::validate::check_min_items(
6142                self.ev_absolute_price_schedule_entries.len(),
6143                1usize,
6144            )
6145            .map_err(|error| error.in_field("evAbsolutePriceScheduleEntries"))?;
6146        crate::validate::check_max_items(
6147                self.ev_absolute_price_schedule_entries.len(),
6148                1024usize,
6149            )
6150            .map_err(|error| error.in_field("evAbsolutePriceScheduleEntries"))?;
6151        for (index, item) in self.ev_absolute_price_schedule_entries.iter().enumerate() {
6152            crate::validate::Validate::validate(item)
6153                .map_err(|error| {
6154                    error.in_index(index).in_field("evAbsolutePriceScheduleEntries")
6155                })?;
6156        }
6157        crate::validate::check_max_length(&self.price_algorithm, 2000usize)
6158            .map_err(|error| error.in_field("priceAlgorithm"))?;
6159        Ok(())
6160    }
6161}
6162/// *(2.1)* An entry in schedule of the energy amount over time that EV is willing to discharge. A negative value indicates the willingness to discharge under specific conditions, a positive value indicates that the EV currently is not able to offer energy to discharge.
6163#[derive(Debug, Clone, PartialEq)]
6164#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6165pub struct EVPowerScheduleEntry<CustomDataType = crate::NoCustomData> {
6166    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6167    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6168    pub custom_data: Option<CustomDataType>,
6169    /// The duration of this entry.
6170    pub duration: i64,
6171    /// Defines maximum amount of power for the duration of this EVPowerScheduleEntry to be discharged from the EV battery through EVSE power outlet. Negative values are used for discharging.
6172    pub power: f64,
6173}
6174#[cfg(feature = "validate")]
6175impl<CustomDataType> crate::validate::Validate for EVPowerScheduleEntry<CustomDataType> {
6176    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6177        Ok(())
6178    }
6179}
6180#[cfg(feature = "alloc")]
6181/// *(2.1)* Schedule of EV energy offer.
6182#[derive(Debug, Clone, PartialEq)]
6183#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6184pub struct EVPowerSchedule<CustomDataType = crate::NoCustomData> {
6185    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6186    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6187    pub custom_data: Option<CustomDataType>,
6188    #[cfg_attr(feature = "serde", serde(rename = "evPowerScheduleEntries"))]
6189    pub ev_power_schedule_entries: alloc::vec::Vec<EVPowerScheduleEntry<CustomDataType>>,
6190    /// The time that defines the starting point for the EVEnergyOffer.
6191    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
6192    pub time_anchor: crate::OcppTimestamp,
6193}
6194#[cfg(all(feature = "validate", feature = "alloc"))]
6195impl<CustomDataType> crate::validate::Validate for EVPowerSchedule<CustomDataType> {
6196    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6197        crate::validate::check_min_items(self.ev_power_schedule_entries.len(), 1usize)
6198            .map_err(|error| error.in_field("evPowerScheduleEntries"))?;
6199        crate::validate::check_max_items(self.ev_power_schedule_entries.len(), 1024usize)
6200            .map_err(|error| error.in_field("evPowerScheduleEntries"))?;
6201        for (index, item) in self.ev_power_schedule_entries.iter().enumerate() {
6202            crate::validate::Validate::validate(item)
6203                .map_err(|error| {
6204                    error.in_index(index).in_field("evPowerScheduleEntries")
6205                })?;
6206        }
6207        Ok(())
6208    }
6209}
6210#[cfg(not(feature = "alloc"))]
6211/// *(2.1)* Schedule of EV energy offer.
6212#[derive(Debug, Clone, PartialEq)]
6213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6214pub struct EVPowerSchedule<
6215    CustomDataType = crate::NoCustomData,
6216    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6217> {
6218    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6219    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6220    pub custom_data: Option<CustomDataType>,
6221    #[cfg_attr(feature = "serde", serde(rename = "evPowerScheduleEntries"))]
6222    pub ev_power_schedule_entries: heapless::Vec<
6223        EVPowerScheduleEntry<CustomDataType>,
6224        E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP,
6225    >,
6226    /// The time that defines the starting point for the EVEnergyOffer.
6227    #[cfg_attr(feature = "serde", serde(rename = "timeAnchor"))]
6228    pub time_anchor: crate::OcppTimestamp,
6229}
6230#[cfg(all(feature = "validate", not(feature = "alloc")))]
6231impl<
6232    CustomDataType,
6233    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize,
6234> crate::validate::Validate
6235for EVPowerSchedule<CustomDataType, E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP> {
6236    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6237        crate::validate::check_min_items(self.ev_power_schedule_entries.len(), 1usize)
6238            .map_err(|error| error.in_field("evPowerScheduleEntries"))?;
6239        crate::validate::check_max_items(self.ev_power_schedule_entries.len(), 1024usize)
6240            .map_err(|error| error.in_field("evPowerScheduleEntries"))?;
6241        for (index, item) in self.ev_power_schedule_entries.iter().enumerate() {
6242            crate::validate::Validate::validate(item)
6243                .map_err(|error| {
6244                    error.in_index(index).in_field("evPowerScheduleEntries")
6245                })?;
6246        }
6247        Ok(())
6248    }
6249}
6250#[cfg(feature = "alloc")]
6251/// *(2.1)* A schedule of the energy amount over time that EV is willing to discharge. A negative value indicates the willingness to discharge under specific conditions, a positive value indicates that the EV currently is not able to offer energy to discharge.
6252#[derive(Debug, Clone, PartialEq)]
6253#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6254pub struct EVEnergyOffer<CustomDataType = crate::NoCustomData> {
6255    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6256    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6257    pub custom_data: Option<CustomDataType>,
6258    #[cfg_attr(feature = "serde", serde(rename = "evAbsolutePriceSchedule"))]
6259    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6260    pub ev_absolute_price_schedule: Option<EVAbsolutePriceSchedule<CustomDataType>>,
6261    #[cfg_attr(feature = "serde", serde(rename = "evPowerSchedule"))]
6262    pub ev_power_schedule: EVPowerSchedule<CustomDataType>,
6263}
6264#[cfg(all(feature = "validate", feature = "alloc"))]
6265impl<CustomDataType> crate::validate::Validate for EVEnergyOffer<CustomDataType> {
6266    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6267        if let Some(value) = &self.ev_absolute_price_schedule {
6268            crate::validate::Validate::validate(value)
6269                .map_err(|error| error.in_field("evAbsolutePriceSchedule"))?;
6270        }
6271        crate::validate::Validate::validate(&self.ev_power_schedule)
6272            .map_err(|error| error.in_field("evPowerSchedule"))?;
6273        Ok(())
6274    }
6275}
6276#[cfg(not(feature = "alloc"))]
6277/// *(2.1)* A schedule of the energy amount over time that EV is willing to discharge. A negative value indicates the willingness to discharge under specific conditions, a positive value indicates that the EV currently is not able to offer energy to discharge.
6278#[derive(Debug, Clone, PartialEq)]
6279#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6280pub struct EVEnergyOffer<
6281    CustomDataType = crate::NoCustomData,
6282    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6283    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
6284    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6285> {
6286    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6287    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6288    pub custom_data: Option<CustomDataType>,
6289    #[cfg_attr(feature = "serde", serde(rename = "evAbsolutePriceSchedule"))]
6290    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6291    pub ev_absolute_price_schedule: Option<
6292        EVAbsolutePriceSchedule<
6293            CustomDataType,
6294            E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6295            E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6296        >,
6297    >,
6298    #[cfg_attr(feature = "serde", serde(rename = "evPowerSchedule"))]
6299    pub ev_power_schedule: EVPowerSchedule<
6300        CustomDataType,
6301        E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP,
6302    >,
6303}
6304#[cfg(all(feature = "validate", not(feature = "alloc")))]
6305impl<
6306    CustomDataType,
6307    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize,
6308    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
6309    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize,
6310> crate::validate::Validate
6311for EVEnergyOffer<
6312    CustomDataType,
6313    E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6314    E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6315    E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP,
6316> {
6317    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6318        if let Some(value) = &self.ev_absolute_price_schedule {
6319            crate::validate::Validate::validate(value)
6320                .map_err(|error| error.in_field("evAbsolutePriceSchedule"))?;
6321        }
6322        crate::validate::Validate::validate(&self.ev_power_schedule)
6323            .map_err(|error| error.in_field("evPowerSchedule"))?;
6324        Ok(())
6325    }
6326}
6327/// *(2.1)* Value of EVCC indicates that EV determines min/target SOC and departure time. +
6328/// A value of EVCC_SECC indicates that charging station or CSMS may also update min/target SOC and departure time. +
6329/// *ISO 15118-20:* +
6330/// ServiceSelectionReq(SelectedEnergyTransferService)
6331#[derive(Debug, Clone, PartialEq, Eq)]
6332#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6333pub enum MobilityNeedsModeEnum {
6334    EVCC,
6335    #[cfg_attr(feature = "serde", serde(rename = "EVCC_SECC"))]
6336    EVCCSECC,
6337}
6338#[cfg(feature = "validate")]
6339impl crate::validate::Validate for MobilityNeedsModeEnum {
6340    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6341        Ok(())
6342    }
6343}
6344/// Charging parameters for ISO 15118-20, also supporting V2X charging/discharging.+
6345/// All values are greater or equal to zero, with the exception of EVMinEnergyRequest, EVMaxEnergyRequest, EVTargetEnergyRequest, EVMinV2XEnergyRequest and EVMaxV2XEnergyRequest.
6346#[derive(Debug, Clone, PartialEq)]
6347#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6348pub struct V2XChargingParameters<CustomDataType = crate::NoCustomData> {
6349    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6350    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6351    pub custom_data: Option<CustomDataType>,
6352    /// Energy to maximum state of charge in Wh
6353    /// Relates to:
6354    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVMaximumEnergyRequest
6355    #[cfg_attr(feature = "serde", serde(rename = "evMaxEnergyRequest"))]
6356    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6357    pub ev_max_energy_request: Option<f64>,
6358    /// Energy (in Wh) to maximum state of charge for cycling (V2X) activity.
6359    /// Negative value indicates that current state of charge is above V2X range.
6360    /// Relates to:
6361    /// *ISO 15118-20*: Dynamic_SEReqControlModeType: EVMaximumV2XEnergyRequest
6362    #[cfg_attr(feature = "serde", serde(rename = "evMaxV2XEnergyRequest"))]
6363    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6364    pub ev_max_v2_x_energy_request: Option<f64>,
6365    /// Energy to minimum allowed state of charge in Wh
6366    /// Relates to:
6367    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVMinimumEnergyRequest
6368    #[cfg_attr(feature = "serde", serde(rename = "evMinEnergyRequest"))]
6369    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6370    pub ev_min_energy_request: Option<f64>,
6371    /// Energy (in Wh) to minimum state of charge for cycling (V2X) activity.
6372    /// Positive value means that current state of charge is below V2X range.
6373    /// Relates to:
6374    /// *ISO 15118-20*: Dynamic_SEReqControlModeType: EVMinimumV2XEnergyRequest
6375    #[cfg_attr(feature = "serde", serde(rename = "evMinV2XEnergyRequest"))]
6376    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6377    pub ev_min_v2_x_energy_request: Option<f64>,
6378    /// Energy to requested state of charge in Wh
6379    /// Relates to:
6380    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVTargetEnergyRequest
6381    #[cfg_attr(feature = "serde", serde(rename = "evTargetEnergyRequest"))]
6382    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6383    pub ev_target_energy_request: Option<f64>,
6384    /// Maximum charge current in A, defined by min(EV, EVSE)
6385    /// Relates to:
6386    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumChargeCurrent
6387    #[cfg_attr(feature = "serde", serde(rename = "maxChargeCurrent"))]
6388    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6389    pub max_charge_current: Option<f64>,
6390    /// Maximum charge (absorbed) power in W, defined by min(EV, EVSE) at unity power factor. +
6391    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6392    /// It corresponds to the ChaWMax attribute in the IEC 61850.
6393    /// It is usually equivalent to the rated apparent power of the EV when discharging (ChaVAMax) in IEC 61850. +
6394    ///
6395    /// Relates to:
6396    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower
6397    #[cfg_attr(feature = "serde", serde(rename = "maxChargePower"))]
6398    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6399    pub max_charge_power: Option<f64>,
6400    /// Maximum charge power on phase L2 in W, defined by min(EV, EVSE)
6401    /// Relates to:
6402    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower_L2
6403    #[cfg_attr(feature = "serde", serde(rename = "maxChargePower_L2"))]
6404    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6405    pub max_charge_power_l2: Option<f64>,
6406    /// Maximum charge power on phase L3 in W, defined by min(EV, EVSE)
6407    /// Relates to:
6408    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower_L3
6409    #[cfg_attr(feature = "serde", serde(rename = "maxChargePower_L3"))]
6410    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6411    pub max_charge_power_l3: Option<f64>,
6412    /// Maximum discharge current in A, defined by min(EV, EVSE).  Value &gt;= 0.
6413    /// Relates to:
6414    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumDischargeCurrent
6415    #[cfg_attr(feature = "serde", serde(rename = "maxDischargeCurrent"))]
6416    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6417    pub max_discharge_current: Option<f64>,
6418    /// Maximum discharge (injected) power in W, defined by min(EV, EVSE) at unity power factor.  Value &gt;= 0.
6419    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6420    /// Relates to:
6421    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePower
6422    #[cfg_attr(feature = "serde", serde(rename = "maxDischargePower"))]
6423    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6424    pub max_discharge_power: Option<f64>,
6425    /// Maximum discharge power on phase L2 in W, defined by min(EV, EVSE).  Value &gt;= 0.
6426    /// Relates to:
6427    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePowe_L2
6428    #[cfg_attr(feature = "serde", serde(rename = "maxDischargePower_L2"))]
6429    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6430    pub max_discharge_power_l2: Option<f64>,
6431    /// Maximum discharge power on phase L3 in W, defined by min(EV, EVSE).  Value &gt;= 0.
6432    /// Relates to:
6433    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePower_L3
6434    #[cfg_attr(feature = "serde", serde(rename = "maxDischargePower_L3"))]
6435    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6436    pub max_discharge_power_l3: Option<f64>,
6437    /// Maximum voltage in V, defined by min(EV, EVSE)
6438    /// Relates to:
6439    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumVoltage
6440    #[cfg_attr(feature = "serde", serde(rename = "maxVoltage"))]
6441    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6442    pub max_voltage: Option<f64>,
6443    /// Minimum charge current in A, defined by max(EV, EVSE)
6444    /// Relates to:
6445    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumChargeCurrent
6446    #[cfg_attr(feature = "serde", serde(rename = "minChargeCurrent"))]
6447    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6448    pub min_charge_current: Option<f64>,
6449    /// Minimum charge power in W, defined by max(EV, EVSE).
6450    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6451    /// Relates to:
6452    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower
6453    #[cfg_attr(feature = "serde", serde(rename = "minChargePower"))]
6454    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6455    pub min_charge_power: Option<f64>,
6456    /// Minimum charge power on phase L2 in W, defined by max(EV, EVSE).
6457    /// Relates to:
6458    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower_L2
6459    #[cfg_attr(feature = "serde", serde(rename = "minChargePower_L2"))]
6460    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6461    pub min_charge_power_l2: Option<f64>,
6462    /// Minimum charge power on phase L3 in W, defined by max(EV, EVSE).
6463    /// Relates to:
6464    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower_L3
6465    #[cfg_attr(feature = "serde", serde(rename = "minChargePower_L3"))]
6466    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6467    pub min_charge_power_l3: Option<f64>,
6468    /// Minimum discharge current in A, defined by max(EV, EVSE).  Value &gt;= 0.
6469    /// Relates to:
6470    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumDischargeCurrent
6471    #[cfg_attr(feature = "serde", serde(rename = "minDischargeCurrent"))]
6472    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6473    pub min_discharge_current: Option<f64>,
6474    /// Minimum discharge (injected) power in W, defined by max(EV, EVSE) at unity power factor. Value &gt;= 0. +
6475    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1. +
6476    /// It corresponds to the WMax attribute in the IEC 61850.
6477    /// It is usually equivalent to the rated apparent power of the EV when discharging (VAMax attribute in the IEC 61850).
6478    ///
6479    /// Relates to:
6480    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower
6481    #[cfg_attr(feature = "serde", serde(rename = "minDischargePower"))]
6482    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6483    pub min_discharge_power: Option<f64>,
6484    /// Minimum discharge power on phase L2 in W, defined by max(EV, EVSE).  Value &gt;= 0.
6485    /// Relates to:
6486    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower_L2
6487    #[cfg_attr(feature = "serde", serde(rename = "minDischargePower_L2"))]
6488    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6489    pub min_discharge_power_l2: Option<f64>,
6490    /// Minimum discharge power on phase L3 in W, defined by max(EV, EVSE).  Value &gt;= 0.
6491    /// Relates to:
6492    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower_L3
6493    #[cfg_attr(feature = "serde", serde(rename = "minDischargePower_L3"))]
6494    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6495    pub min_discharge_power_l3: Option<f64>,
6496    /// Minimum voltage in V, defined by max(EV, EVSE)
6497    /// Relates to:
6498    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumVoltage
6499    #[cfg_attr(feature = "serde", serde(rename = "minVoltage"))]
6500    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6501    pub min_voltage: Option<f64>,
6502    /// Target state of charge at departure as percentage.
6503    /// Relates to:
6504    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: TargetSOC
6505    #[cfg_attr(feature = "serde", serde(rename = "targetSoC"))]
6506    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6507    pub target_so_c: Option<i64>,
6508}
6509#[cfg(feature = "validate")]
6510impl<CustomDataType> crate::validate::Validate
6511for V2XChargingParameters<CustomDataType> {
6512    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6513        if let Some(value) = self.target_so_c {
6514            crate::validate::check_min_i64(value, 0i64)
6515                .map_err(|error| error.in_field("targetSoC"))?;
6516            crate::validate::check_max_i64(value, 100i64)
6517                .map_err(|error| error.in_field("targetSoC"))?;
6518        }
6519        Ok(())
6520    }
6521}
6522#[cfg(feature = "alloc")]
6523#[derive(Debug, Clone, PartialEq)]
6524#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6525pub struct ChargingNeeds<CustomDataType = crate::NoCustomData> {
6526    #[cfg_attr(feature = "serde", serde(rename = "acChargingParameters"))]
6527    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6528    pub ac_charging_parameters: Option<ACChargingParameters<CustomDataType>>,
6529    /// *(2.1)* Modes of energy transfer that are marked as available by EV.
6530    #[cfg_attr(feature = "serde", serde(rename = "availableEnergyTransfer"))]
6531    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6532    pub available_energy_transfer: Option<alloc::vec::Vec<EnergyTransferModeEnum>>,
6533    #[cfg_attr(feature = "serde", serde(rename = "controlMode"))]
6534    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6535    pub control_mode: Option<ControlModeEnum>,
6536    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6537    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6538    pub custom_data: Option<CustomDataType>,
6539    #[cfg_attr(feature = "serde", serde(rename = "dcChargingParameters"))]
6540    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6541    pub dc_charging_parameters: Option<DCChargingParameters<CustomDataType>>,
6542    /// Estimated departure time of the EV. +
6543    /// *ISO 15118-2:* AC/DC_EVChargeParameterType: DepartureTime +
6544    /// *ISO 15118-20:* Dynamic/Scheduled_SEReqControlModeType: DepartureTIme
6545    #[cfg_attr(feature = "serde", serde(rename = "departureTime"))]
6546    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6547    pub departure_time: Option<crate::OcppTimestamp>,
6548    #[cfg_attr(feature = "serde", serde(rename = "derChargingParameters"))]
6549    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6550    pub der_charging_parameters: Option<DERChargingParameters<CustomDataType>>,
6551    #[cfg_attr(feature = "serde", serde(rename = "evEnergyOffer"))]
6552    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6553    pub ev_energy_offer: Option<EVEnergyOffer<CustomDataType>>,
6554    #[cfg_attr(feature = "serde", serde(rename = "mobilityNeedsMode"))]
6555    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6556    pub mobility_needs_mode: Option<MobilityNeedsModeEnum>,
6557    #[cfg_attr(feature = "serde", serde(rename = "requestedEnergyTransfer"))]
6558    pub requested_energy_transfer: EnergyTransferModeEnum,
6559    #[cfg_attr(feature = "serde", serde(rename = "v2xChargingParameters"))]
6560    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6561    pub v2x_charging_parameters: Option<V2XChargingParameters<CustomDataType>>,
6562}
6563#[cfg(all(feature = "validate", feature = "alloc"))]
6564impl<CustomDataType> crate::validate::Validate for ChargingNeeds<CustomDataType> {
6565    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6566        if let Some(value) = &self.ac_charging_parameters {
6567            crate::validate::Validate::validate(value)
6568                .map_err(|error| error.in_field("acChargingParameters"))?;
6569        }
6570        if let Some(value) = &self.available_energy_transfer {
6571            crate::validate::check_min_items(value.len(), 1usize)
6572                .map_err(|error| error.in_field("availableEnergyTransfer"))?;
6573            for (index, item) in value.iter().enumerate() {
6574                crate::validate::Validate::validate(item)
6575                    .map_err(|error| {
6576                        error.in_index(index).in_field("availableEnergyTransfer")
6577                    })?;
6578            }
6579        }
6580        if let Some(value) = &self.control_mode {
6581            crate::validate::Validate::validate(value)
6582                .map_err(|error| error.in_field("controlMode"))?;
6583        }
6584        if let Some(value) = &self.dc_charging_parameters {
6585            crate::validate::Validate::validate(value)
6586                .map_err(|error| error.in_field("dcChargingParameters"))?;
6587        }
6588        if let Some(value) = &self.der_charging_parameters {
6589            crate::validate::Validate::validate(value)
6590                .map_err(|error| error.in_field("derChargingParameters"))?;
6591        }
6592        if let Some(value) = &self.ev_energy_offer {
6593            crate::validate::Validate::validate(value)
6594                .map_err(|error| error.in_field("evEnergyOffer"))?;
6595        }
6596        if let Some(value) = &self.mobility_needs_mode {
6597            crate::validate::Validate::validate(value)
6598                .map_err(|error| error.in_field("mobilityNeedsMode"))?;
6599        }
6600        crate::validate::Validate::validate(&self.requested_energy_transfer)
6601            .map_err(|error| error.in_field("requestedEnergyTransfer"))?;
6602        if let Some(value) = &self.v2x_charging_parameters {
6603            crate::validate::Validate::validate(value)
6604                .map_err(|error| error.in_field("v2xChargingParameters"))?;
6605        }
6606        Ok(())
6607    }
6608}
6609#[cfg(not(feature = "alloc"))]
6610#[derive(Debug, Clone, PartialEq)]
6611#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6612pub struct ChargingNeeds<
6613    CustomDataType = crate::NoCustomData,
6614    const CHARGING_NEEDS_AVAILABLE_ENERGY_TRANSFER_CAP: usize = 8usize,
6615    const D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP: usize = 8usize,
6616    const D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP: usize = 8usize,
6617    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6618    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
6619    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize = 8usize,
6620> {
6621    #[cfg_attr(feature = "serde", serde(rename = "acChargingParameters"))]
6622    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6623    pub ac_charging_parameters: Option<ACChargingParameters<CustomDataType>>,
6624    /// *(2.1)* Modes of energy transfer that are marked as available by EV.
6625    #[cfg_attr(feature = "serde", serde(rename = "availableEnergyTransfer"))]
6626    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6627    pub available_energy_transfer: Option<
6628        heapless::Vec<
6629            EnergyTransferModeEnum,
6630            CHARGING_NEEDS_AVAILABLE_ENERGY_TRANSFER_CAP,
6631        >,
6632    >,
6633    #[cfg_attr(feature = "serde", serde(rename = "controlMode"))]
6634    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6635    pub control_mode: Option<ControlModeEnum>,
6636    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6637    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6638    pub custom_data: Option<CustomDataType>,
6639    #[cfg_attr(feature = "serde", serde(rename = "dcChargingParameters"))]
6640    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6641    pub dc_charging_parameters: Option<DCChargingParameters<CustomDataType>>,
6642    /// Estimated departure time of the EV. +
6643    /// *ISO 15118-2:* AC/DC_EVChargeParameterType: DepartureTime +
6644    /// *ISO 15118-20:* Dynamic/Scheduled_SEReqControlModeType: DepartureTIme
6645    #[cfg_attr(feature = "serde", serde(rename = "departureTime"))]
6646    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6647    pub departure_time: Option<crate::OcppTimestamp>,
6648    #[cfg_attr(feature = "serde", serde(rename = "derChargingParameters"))]
6649    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6650    pub der_charging_parameters: Option<
6651        DERChargingParameters<
6652            CustomDataType,
6653            D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP,
6654            D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP,
6655        >,
6656    >,
6657    #[cfg_attr(feature = "serde", serde(rename = "evEnergyOffer"))]
6658    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6659    pub ev_energy_offer: Option<
6660        EVEnergyOffer<
6661            CustomDataType,
6662            E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6663            E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6664            E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP,
6665        >,
6666    >,
6667    #[cfg_attr(feature = "serde", serde(rename = "mobilityNeedsMode"))]
6668    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6669    pub mobility_needs_mode: Option<MobilityNeedsModeEnum>,
6670    #[cfg_attr(feature = "serde", serde(rename = "requestedEnergyTransfer"))]
6671    pub requested_energy_transfer: EnergyTransferModeEnum,
6672    #[cfg_attr(feature = "serde", serde(rename = "v2xChargingParameters"))]
6673    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6674    pub v2x_charging_parameters: Option<V2XChargingParameters<CustomDataType>>,
6675}
6676#[cfg(all(feature = "validate", not(feature = "alloc")))]
6677impl<
6678    CustomDataType,
6679    const CHARGING_NEEDS_AVAILABLE_ENERGY_TRANSFER_CAP: usize,
6680    const D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP: usize,
6681    const D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP: usize,
6682    const E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP: usize,
6683    const E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
6684    const E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP: usize,
6685> crate::validate::Validate
6686for ChargingNeeds<
6687    CustomDataType,
6688    CHARGING_NEEDS_AVAILABLE_ENERGY_TRANSFER_CAP,
6689    D_E_R_CHARGING_PARAMETERS_EV_ISLANDING_DETECTION_METHOD_CAP,
6690    D_E_R_CHARGING_PARAMETERS_EV_SUPPORTED_D_E_R_CONTROL_CAP,
6691    E_V_ABSOLUTE_PRICE_SCHEDULE_EV_ABSOLUTE_PRICE_SCHEDULE_ENTRIES_CAP,
6692    E_V_ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
6693    E_V_POWER_SCHEDULE_EV_POWER_SCHEDULE_ENTRIES_CAP,
6694> {
6695    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6696        if let Some(value) = &self.ac_charging_parameters {
6697            crate::validate::Validate::validate(value)
6698                .map_err(|error| error.in_field("acChargingParameters"))?;
6699        }
6700        if let Some(value) = &self.available_energy_transfer {
6701            crate::validate::check_min_items(value.len(), 1usize)
6702                .map_err(|error| error.in_field("availableEnergyTransfer"))?;
6703            for (index, item) in value.iter().enumerate() {
6704                crate::validate::Validate::validate(item)
6705                    .map_err(|error| {
6706                        error.in_index(index).in_field("availableEnergyTransfer")
6707                    })?;
6708            }
6709        }
6710        if let Some(value) = &self.control_mode {
6711            crate::validate::Validate::validate(value)
6712                .map_err(|error| error.in_field("controlMode"))?;
6713        }
6714        if let Some(value) = &self.dc_charging_parameters {
6715            crate::validate::Validate::validate(value)
6716                .map_err(|error| error.in_field("dcChargingParameters"))?;
6717        }
6718        if let Some(value) = &self.der_charging_parameters {
6719            crate::validate::Validate::validate(value)
6720                .map_err(|error| error.in_field("derChargingParameters"))?;
6721        }
6722        if let Some(value) = &self.ev_energy_offer {
6723            crate::validate::Validate::validate(value)
6724                .map_err(|error| error.in_field("evEnergyOffer"))?;
6725        }
6726        if let Some(value) = &self.mobility_needs_mode {
6727            crate::validate::Validate::validate(value)
6728                .map_err(|error| error.in_field("mobilityNeedsMode"))?;
6729        }
6730        crate::validate::Validate::validate(&self.requested_energy_transfer)
6731            .map_err(|error| error.in_field("requestedEnergyTransfer"))?;
6732        if let Some(value) = &self.v2x_charging_parameters {
6733            crate::validate::Validate::validate(value)
6734                .map_err(|error| error.in_field("v2xChargingParameters"))?;
6735        }
6736        Ok(())
6737    }
6738}
6739/// Returns whether the CSMS has been able to process the message successfully. It does not imply that the evChargingNeeds can be met with the current charging profile.
6740#[derive(Debug, Clone, PartialEq, Eq)]
6741#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6742pub enum NotifyEVChargingNeedsStatusEnum {
6743    Accepted,
6744    Rejected,
6745    Processing,
6746    NoChargingProfile,
6747}
6748#[cfg(feature = "validate")]
6749impl crate::validate::Validate for NotifyEVChargingNeedsStatusEnum {
6750    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6751        Ok(())
6752    }
6753}
6754/// Specifies the event notification type of the message.
6755#[derive(Debug, Clone, PartialEq, Eq)]
6756#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6757pub enum EventNotificationEnum {
6758    HardWiredNotification,
6759    HardWiredMonitor,
6760    PreconfiguredMonitor,
6761    CustomMonitor,
6762}
6763#[cfg(feature = "validate")]
6764impl crate::validate::Validate for EventNotificationEnum {
6765    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6766        Ok(())
6767    }
6768}
6769/// Type of trigger for this event, e.g. exceeding a threshold value.
6770#[derive(Debug, Clone, PartialEq, Eq)]
6771#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6772pub enum EventTriggerEnum {
6773    Alerting,
6774    Delta,
6775    Periodic,
6776}
6777#[cfg(feature = "validate")]
6778impl crate::validate::Validate for EventTriggerEnum {
6779    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6780        Ok(())
6781    }
6782}
6783#[cfg(feature = "alloc")]
6784/// Class to report an event notification for a component-variable.
6785#[derive(Debug, Clone, PartialEq, Eq)]
6786#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6787pub struct EventData<CustomDataType = crate::NoCustomData> {
6788    /// Actual value (_attributeType_ Actual) of the variable.
6789    ///
6790    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
6791    #[cfg_attr(feature = "serde", serde(rename = "actualValue"))]
6792    pub actual_value: alloc::string::String,
6793    /// Refers to the Id of an event that is considered to be the cause for this event.
6794    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6795    pub cause: Option<i64>,
6796    /// _Cleared_ is set to true to report the clearing of a monitored situation, i.e. a 'return to normal'.
6797    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6798    pub cleared: Option<bool>,
6799    pub component: Component<CustomDataType>,
6800    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6801    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6802    pub custom_data: Option<CustomDataType>,
6803    /// Identifies the event. This field can be referred to as a cause by other events.
6804    #[cfg_attr(feature = "serde", serde(rename = "eventId"))]
6805    pub event_id: i64,
6806    #[cfg_attr(feature = "serde", serde(rename = "eventNotificationType"))]
6807    pub event_notification_type: EventNotificationEnum,
6808    /// *(2.1)* Severity associated with the monitor in _variableMonitoringId_ or with the hardwired notification.
6809    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6810    pub severity: Option<i64>,
6811    /// Technical (error) code as reported by component.
6812    #[cfg_attr(feature = "serde", serde(rename = "techCode"))]
6813    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6814    pub tech_code: Option<heapless::String<50usize>>,
6815    /// Technical detail information as reported by component.
6816    #[cfg_attr(feature = "serde", serde(rename = "techInfo"))]
6817    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6818    pub tech_info: Option<heapless::String<500usize>>,
6819    /// Timestamp of the moment the report was generated.
6820    pub timestamp: crate::OcppTimestamp,
6821    /// If an event notification is linked to a specific transaction, this field can be used to specify its transactionId.
6822    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
6823    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6824    pub transaction_id: Option<heapless::String<36usize>>,
6825    pub trigger: EventTriggerEnum,
6826    pub variable: Variable<CustomDataType>,
6827    /// Identifies the VariableMonitoring which triggered the event.
6828    #[cfg_attr(feature = "serde", serde(rename = "variableMonitoringId"))]
6829    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6830    pub variable_monitoring_id: Option<i64>,
6831}
6832#[cfg(all(feature = "validate", feature = "alloc"))]
6833impl<CustomDataType> crate::validate::Validate for EventData<CustomDataType> {
6834    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6835        crate::validate::check_max_length(&self.actual_value, 2500usize)
6836            .map_err(|error| error.in_field("actualValue"))?;
6837        if let Some(value) = self.cause {
6838            crate::validate::check_min_i64(value, 0i64)
6839                .map_err(|error| error.in_field("cause"))?;
6840        }
6841        crate::validate::Validate::validate(&self.component)
6842            .map_err(|error| error.in_field("component"))?;
6843        crate::validate::check_min_i64(self.event_id, 0i64)
6844            .map_err(|error| error.in_field("eventId"))?;
6845        crate::validate::Validate::validate(&self.event_notification_type)
6846            .map_err(|error| error.in_field("eventNotificationType"))?;
6847        if let Some(value) = self.severity {
6848            crate::validate::check_min_i64(value, 0i64)
6849                .map_err(|error| error.in_field("severity"))?;
6850        }
6851        crate::validate::Validate::validate(&self.trigger)
6852            .map_err(|error| error.in_field("trigger"))?;
6853        crate::validate::Validate::validate(&self.variable)
6854            .map_err(|error| error.in_field("variable"))?;
6855        if let Some(value) = self.variable_monitoring_id {
6856            crate::validate::check_min_i64(value, 0i64)
6857                .map_err(|error| error.in_field("variableMonitoringId"))?;
6858        }
6859        Ok(())
6860    }
6861}
6862#[cfg(not(feature = "alloc"))]
6863/// Class to report an event notification for a component-variable.
6864#[derive(Debug, Clone, PartialEq, Eq)]
6865#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6866pub struct EventData<
6867    CustomDataType = crate::NoCustomData,
6868    const EVENT_DATA_ACTUAL_VALUE_CAP: usize = 1024usize,
6869> {
6870    /// Actual value (_attributeType_ Actual) of the variable.
6871    ///
6872    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
6873    #[cfg_attr(feature = "serde", serde(rename = "actualValue"))]
6874    pub actual_value: heapless::String<EVENT_DATA_ACTUAL_VALUE_CAP>,
6875    /// Refers to the Id of an event that is considered to be the cause for this event.
6876    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6877    pub cause: Option<i64>,
6878    /// _Cleared_ is set to true to report the clearing of a monitored situation, i.e. a 'return to normal'.
6879    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6880    pub cleared: Option<bool>,
6881    pub component: Component<CustomDataType>,
6882    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6883    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6884    pub custom_data: Option<CustomDataType>,
6885    /// Identifies the event. This field can be referred to as a cause by other events.
6886    #[cfg_attr(feature = "serde", serde(rename = "eventId"))]
6887    pub event_id: i64,
6888    #[cfg_attr(feature = "serde", serde(rename = "eventNotificationType"))]
6889    pub event_notification_type: EventNotificationEnum,
6890    /// *(2.1)* Severity associated with the monitor in _variableMonitoringId_ or with the hardwired notification.
6891    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6892    pub severity: Option<i64>,
6893    /// Technical (error) code as reported by component.
6894    #[cfg_attr(feature = "serde", serde(rename = "techCode"))]
6895    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6896    pub tech_code: Option<heapless::String<50usize>>,
6897    /// Technical detail information as reported by component.
6898    #[cfg_attr(feature = "serde", serde(rename = "techInfo"))]
6899    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6900    pub tech_info: Option<heapless::String<500usize>>,
6901    /// Timestamp of the moment the report was generated.
6902    pub timestamp: crate::OcppTimestamp,
6903    /// If an event notification is linked to a specific transaction, this field can be used to specify its transactionId.
6904    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
6905    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6906    pub transaction_id: Option<heapless::String<36usize>>,
6907    pub trigger: EventTriggerEnum,
6908    pub variable: Variable<CustomDataType>,
6909    /// Identifies the VariableMonitoring which triggered the event.
6910    #[cfg_attr(feature = "serde", serde(rename = "variableMonitoringId"))]
6911    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6912    pub variable_monitoring_id: Option<i64>,
6913}
6914#[cfg(all(feature = "validate", not(feature = "alloc")))]
6915impl<CustomDataType, const EVENT_DATA_ACTUAL_VALUE_CAP: usize> crate::validate::Validate
6916for EventData<CustomDataType, EVENT_DATA_ACTUAL_VALUE_CAP> {
6917    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6918        crate::validate::check_max_length(&self.actual_value, 2500usize)
6919            .map_err(|error| error.in_field("actualValue"))?;
6920        if let Some(value) = self.cause {
6921            crate::validate::check_min_i64(value, 0i64)
6922                .map_err(|error| error.in_field("cause"))?;
6923        }
6924        crate::validate::Validate::validate(&self.component)
6925            .map_err(|error| error.in_field("component"))?;
6926        crate::validate::check_min_i64(self.event_id, 0i64)
6927            .map_err(|error| error.in_field("eventId"))?;
6928        crate::validate::Validate::validate(&self.event_notification_type)
6929            .map_err(|error| error.in_field("eventNotificationType"))?;
6930        if let Some(value) = self.severity {
6931            crate::validate::check_min_i64(value, 0i64)
6932                .map_err(|error| error.in_field("severity"))?;
6933        }
6934        crate::validate::Validate::validate(&self.trigger)
6935            .map_err(|error| error.in_field("trigger"))?;
6936        crate::validate::Validate::validate(&self.variable)
6937            .map_err(|error| error.in_field("variable"))?;
6938        if let Some(value) = self.variable_monitoring_id {
6939            crate::validate::check_min_i64(value, 0i64)
6940                .map_err(|error| error.in_field("variableMonitoringId"))?;
6941        }
6942        Ok(())
6943    }
6944}
6945/// The type of this monitor, e.g. a threshold, delta or periodic monitor.
6946#[derive(Debug, Clone, PartialEq, Eq)]
6947#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6948pub enum MonitorEnum {
6949    UpperThreshold,
6950    LowerThreshold,
6951    Delta,
6952    Periodic,
6953    PeriodicClockAligned,
6954    TargetDelta,
6955    TargetDeltaRelative,
6956}
6957#[cfg(feature = "validate")]
6958impl crate::validate::Validate for MonitorEnum {
6959    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
6960        Ok(())
6961    }
6962}
6963/// A monitoring setting for a variable.
6964#[derive(Debug, Clone, PartialEq)]
6965#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6966pub struct VariableMonitoring<CustomDataType = crate::NoCustomData> {
6967    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
6968    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
6969    pub custom_data: Option<CustomDataType>,
6970    #[cfg_attr(feature = "serde", serde(rename = "eventNotificationType"))]
6971    pub event_notification_type: EventNotificationEnum,
6972    /// Identifies the monitor.
6973    pub id: i64,
6974    /// The severity that will be assigned to an event that is triggered by this monitor. The severity range is 0-9, with 0 as the highest and 9 as the lowest severity level.
6975    ///
6976    /// The severity levels have the following meaning: +
6977    /// *0-Danger* +
6978    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
6979    /// *1-Hardware Failure* +
6980    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
6981    /// *2-System Failure* +
6982    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
6983    /// *3-Critical* +
6984    /// Indicates a critical error. Action is required. +
6985    /// *4-Error* +
6986    /// Indicates a non-urgent error. Action is required. +
6987    /// *5-Alert* +
6988    /// Indicates an alert event. Default severity for any type of monitoring event.  +
6989    /// *6-Warning* +
6990    /// Indicates a warning event. Action may be required. +
6991    /// *7-Notice* +
6992    /// Indicates an unusual event. No immediate action is required. +
6993    /// *8-Informational* +
6994    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
6995    /// *9-Debug* +
6996    /// Indicates information useful to developers for debugging, not useful during operations.
6997    pub severity: i64,
6998    /// Monitor only active when a transaction is ongoing on a component relevant to this transaction.
6999    pub transaction: bool,
7000    pub r#type: MonitorEnum,
7001    /// Value for threshold or delta monitoring.
7002    /// For Periodic or PeriodicClockAligned this is the interval in seconds.
7003    pub value: f64,
7004}
7005#[cfg(feature = "validate")]
7006impl<CustomDataType> crate::validate::Validate for VariableMonitoring<CustomDataType> {
7007    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7008        crate::validate::Validate::validate(&self.event_notification_type)
7009            .map_err(|error| error.in_field("eventNotificationType"))?;
7010        crate::validate::check_min_i64(self.id, 0i64)
7011            .map_err(|error| error.in_field("id"))?;
7012        crate::validate::check_min_i64(self.severity, 0i64)
7013            .map_err(|error| error.in_field("severity"))?;
7014        crate::validate::Validate::validate(&self.r#type)
7015            .map_err(|error| error.in_field("type"))?;
7016        Ok(())
7017    }
7018}
7019#[cfg(feature = "alloc")]
7020/// Class to hold parameters of SetVariableMonitoring request.
7021#[derive(Debug, Clone, PartialEq)]
7022#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7023pub struct MonitoringData<CustomDataType = crate::NoCustomData> {
7024    pub component: Component<CustomDataType>,
7025    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7026    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7027    pub custom_data: Option<CustomDataType>,
7028    pub variable: Variable<CustomDataType>,
7029    #[cfg_attr(feature = "serde", serde(rename = "variableMonitoring"))]
7030    pub variable_monitoring: alloc::vec::Vec<VariableMonitoring<CustomDataType>>,
7031}
7032#[cfg(all(feature = "validate", feature = "alloc"))]
7033impl<CustomDataType> crate::validate::Validate for MonitoringData<CustomDataType> {
7034    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7035        crate::validate::Validate::validate(&self.component)
7036            .map_err(|error| error.in_field("component"))?;
7037        crate::validate::Validate::validate(&self.variable)
7038            .map_err(|error| error.in_field("variable"))?;
7039        crate::validate::check_min_items(self.variable_monitoring.len(), 1usize)
7040            .map_err(|error| error.in_field("variableMonitoring"))?;
7041        for (index, item) in self.variable_monitoring.iter().enumerate() {
7042            crate::validate::Validate::validate(item)
7043                .map_err(|error| error.in_index(index).in_field("variableMonitoring"))?;
7044        }
7045        Ok(())
7046    }
7047}
7048#[cfg(not(feature = "alloc"))]
7049/// Class to hold parameters of SetVariableMonitoring request.
7050#[derive(Debug, Clone, PartialEq)]
7051#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7052pub struct MonitoringData<
7053    CustomDataType = crate::NoCustomData,
7054    const MONITORING_DATA_VARIABLE_MONITORING_CAP: usize = 8usize,
7055> {
7056    pub component: Component<CustomDataType>,
7057    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7058    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7059    pub custom_data: Option<CustomDataType>,
7060    pub variable: Variable<CustomDataType>,
7061    #[cfg_attr(feature = "serde", serde(rename = "variableMonitoring"))]
7062    pub variable_monitoring: heapless::Vec<
7063        VariableMonitoring<CustomDataType>,
7064        MONITORING_DATA_VARIABLE_MONITORING_CAP,
7065    >,
7066}
7067#[cfg(all(feature = "validate", not(feature = "alloc")))]
7068impl<
7069    CustomDataType,
7070    const MONITORING_DATA_VARIABLE_MONITORING_CAP: usize,
7071> crate::validate::Validate
7072for MonitoringData<CustomDataType, MONITORING_DATA_VARIABLE_MONITORING_CAP> {
7073    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7074        crate::validate::Validate::validate(&self.component)
7075            .map_err(|error| error.in_field("component"))?;
7076        crate::validate::Validate::validate(&self.variable)
7077            .map_err(|error| error.in_field("variable"))?;
7078        crate::validate::check_min_items(self.variable_monitoring.len(), 1usize)
7079            .map_err(|error| error.in_field("variableMonitoring"))?;
7080        for (index, item) in self.variable_monitoring.iter().enumerate() {
7081            crate::validate::Validate::validate(item)
7082                .map_err(|error| error.in_index(index).in_field("variableMonitoring"))?;
7083        }
7084        Ok(())
7085    }
7086}
7087#[cfg(feature = "alloc")]
7088#[derive(Debug, Clone, PartialEq)]
7089#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7090pub struct StreamDataElement<CustomDataType = crate::NoCustomData> {
7091    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7092    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7093    pub custom_data: Option<CustomDataType>,
7094    /// Offset relative to _basetime_ of this message. _basetime_ + _t_ is timestamp of recorded value.
7095    pub t: f64,
7096    pub v: alloc::string::String,
7097}
7098#[cfg(all(feature = "validate", feature = "alloc"))]
7099impl<CustomDataType> crate::validate::Validate for StreamDataElement<CustomDataType> {
7100    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7101        crate::validate::check_max_length(&self.v, 2500usize)
7102            .map_err(|error| error.in_field("v"))?;
7103        Ok(())
7104    }
7105}
7106#[cfg(not(feature = "alloc"))]
7107#[derive(Debug, Clone, PartialEq)]
7108#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7109pub struct StreamDataElement<
7110    CustomDataType = crate::NoCustomData,
7111    const STREAM_DATA_ELEMENT_V_CAP: usize = 1024usize,
7112> {
7113    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7114    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7115    pub custom_data: Option<CustomDataType>,
7116    /// Offset relative to _basetime_ of this message. _basetime_ + _t_ is timestamp of recorded value.
7117    pub t: f64,
7118    pub v: heapless::String<STREAM_DATA_ELEMENT_V_CAP>,
7119}
7120#[cfg(all(feature = "validate", not(feature = "alloc")))]
7121impl<CustomDataType, const STREAM_DATA_ELEMENT_V_CAP: usize> crate::validate::Validate
7122for StreamDataElement<CustomDataType, STREAM_DATA_ELEMENT_V_CAP> {
7123    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7124        crate::validate::check_max_length(&self.v, 2500usize)
7125            .map_err(|error| error.in_field("v"))?;
7126        Ok(())
7127    }
7128}
7129/// Defines the mutability of this attribute. Default is ReadWrite when omitted.
7130#[derive(Debug, Clone, PartialEq, Eq)]
7131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7132pub enum MutabilityEnum {
7133    ReadOnly,
7134    WriteOnly,
7135    ReadWrite,
7136}
7137#[cfg(feature = "validate")]
7138impl crate::validate::Validate for MutabilityEnum {
7139    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7140        Ok(())
7141    }
7142}
7143#[cfg(feature = "alloc")]
7144/// Attribute data of a variable.
7145#[derive(Debug, Clone, PartialEq, Eq)]
7146#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7147pub struct VariableAttribute<CustomDataType = crate::NoCustomData> {
7148    /// If true, value that will never be changed by the Charging Station at runtime. Default when omitted is false.
7149    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7150    pub constant: Option<bool>,
7151    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7152    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7153    pub custom_data: Option<CustomDataType>,
7154    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7155    pub mutability: Option<MutabilityEnum>,
7156    /// If true, value will be persistent across system reboots or power down. Default when omitted is false.
7157    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7158    pub persistent: Option<bool>,
7159    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7160    pub r#type: Option<AttributeEnum>,
7161    /// Value of the attribute. May only be omitted when mutability is set to 'WriteOnly'.
7162    ///
7163    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
7164    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7165    pub value: Option<alloc::string::String>,
7166}
7167#[cfg(all(feature = "validate", feature = "alloc"))]
7168impl<CustomDataType> crate::validate::Validate for VariableAttribute<CustomDataType> {
7169    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7170        if let Some(value) = &self.mutability {
7171            crate::validate::Validate::validate(value)
7172                .map_err(|error| error.in_field("mutability"))?;
7173        }
7174        if let Some(value) = &self.r#type {
7175            crate::validate::Validate::validate(value)
7176                .map_err(|error| error.in_field("type"))?;
7177        }
7178        if let Some(value) = &self.value {
7179            crate::validate::check_max_length(value, 2500usize)
7180                .map_err(|error| error.in_field("value"))?;
7181        }
7182        Ok(())
7183    }
7184}
7185#[cfg(not(feature = "alloc"))]
7186/// Attribute data of a variable.
7187#[derive(Debug, Clone, PartialEq, Eq)]
7188#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7189pub struct VariableAttribute<
7190    CustomDataType = crate::NoCustomData,
7191    const VARIABLE_ATTRIBUTE_VALUE_CAP: usize = 1024usize,
7192> {
7193    /// If true, value that will never be changed by the Charging Station at runtime. Default when omitted is false.
7194    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7195    pub constant: Option<bool>,
7196    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7197    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7198    pub custom_data: Option<CustomDataType>,
7199    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7200    pub mutability: Option<MutabilityEnum>,
7201    /// If true, value will be persistent across system reboots or power down. Default when omitted is false.
7202    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7203    pub persistent: Option<bool>,
7204    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7205    pub r#type: Option<AttributeEnum>,
7206    /// Value of the attribute. May only be omitted when mutability is set to 'WriteOnly'.
7207    ///
7208    /// The Configuration Variable &lt;&lt;configkey-reporting-value-size,ReportingValueSize&gt;&gt; can be used to limit GetVariableResult.attributeValue, VariableAttribute.value and EventData.actualValue. The max size of these values will always remain equal.
7209    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7210    pub value: Option<heapless::String<VARIABLE_ATTRIBUTE_VALUE_CAP>>,
7211}
7212#[cfg(all(feature = "validate", not(feature = "alloc")))]
7213impl<CustomDataType, const VARIABLE_ATTRIBUTE_VALUE_CAP: usize> crate::validate::Validate
7214for VariableAttribute<CustomDataType, VARIABLE_ATTRIBUTE_VALUE_CAP> {
7215    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7216        if let Some(value) = &self.mutability {
7217            crate::validate::Validate::validate(value)
7218                .map_err(|error| error.in_field("mutability"))?;
7219        }
7220        if let Some(value) = &self.r#type {
7221            crate::validate::Validate::validate(value)
7222                .map_err(|error| error.in_field("type"))?;
7223        }
7224        if let Some(value) = &self.value {
7225            crate::validate::check_max_length(value, 2500usize)
7226                .map_err(|error| error.in_field("value"))?;
7227        }
7228        Ok(())
7229    }
7230}
7231/// Data type of this variable.
7232#[derive(Debug, Clone, PartialEq, Eq)]
7233#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7234pub enum DataEnum {
7235    #[cfg_attr(feature = "serde", serde(rename = "string"))]
7236    String,
7237    #[cfg_attr(feature = "serde", serde(rename = "decimal"))]
7238    Decimal,
7239    #[cfg_attr(feature = "serde", serde(rename = "integer"))]
7240    Integer,
7241    #[cfg_attr(feature = "serde", serde(rename = "dateTime"))]
7242    DateTime,
7243    #[cfg_attr(feature = "serde", serde(rename = "boolean"))]
7244    Boolean,
7245    OptionList,
7246    SequenceList,
7247    MemberList,
7248}
7249#[cfg(feature = "validate")]
7250impl crate::validate::Validate for DataEnum {
7251    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7252        Ok(())
7253    }
7254}
7255#[cfg(feature = "alloc")]
7256/// Fixed read-only parameters of a variable.
7257#[derive(Debug, Clone, PartialEq)]
7258#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7259pub struct VariableCharacteristics<CustomDataType = crate::NoCustomData> {
7260    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7261    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7262    pub custom_data: Option<CustomDataType>,
7263    #[cfg_attr(feature = "serde", serde(rename = "dataType"))]
7264    pub data_type: DataEnum,
7265    /// *(2.1)* Maximum number of elements from _valuesList_ that are supported as _attributeValue_.
7266    #[cfg_attr(feature = "serde", serde(rename = "maxElements"))]
7267    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7268    pub max_elements: Option<i64>,
7269    /// Maximum possible value of this variable. When the datatype of this Variable is String, OptionList, SequenceList or MemberList, this field defines the maximum length of the (CSV) string.
7270    #[cfg_attr(feature = "serde", serde(rename = "maxLimit"))]
7271    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7272    pub max_limit: Option<f64>,
7273    /// Minimum possible value of this variable.
7274    #[cfg_attr(feature = "serde", serde(rename = "minLimit"))]
7275    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7276    pub min_limit: Option<f64>,
7277    /// Flag indicating if this variable supports monitoring.
7278    #[cfg_attr(feature = "serde", serde(rename = "supportsMonitoring"))]
7279    pub supports_monitoring: bool,
7280    /// Unit of the variable. When the transmitted value has a unit, this field SHALL be included.
7281    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7282    pub unit: Option<heapless::String<16usize>>,
7283    /// Mandatory when _dataType_ = OptionList, MemberList or SequenceList. In that case _valuesList_ specifies the allowed values for the type.
7284    ///
7285    /// The length of this field can be limited by DeviceDataCtrlr.ConfigurationValueSize.
7286    ///
7287    /// * OptionList: The (Actual) Variable value must be a single value from the reported (CSV) enumeration list.
7288    ///
7289    /// * MemberList: The (Actual) Variable value  may be an (unordered) (sub-)set of the reported (CSV) valid values list.
7290    ///
7291    /// * SequenceList: The (Actual) Variable value  may be an ordered (priority, etc)  (sub-)set of the reported (CSV) valid values.
7292    ///
7293    /// This is a comma separated list.
7294    ///
7295    /// The Configuration Variable &lt;&lt;configkey-configuration-value-size,ConfigurationValueSize&gt;&gt; can be used to limit SetVariableData.attributeValue and VariableCharacteristics.valuesList. The max size of these values will always remain equal.
7296    #[cfg_attr(feature = "serde", serde(rename = "valuesList"))]
7297    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7298    pub values_list: Option<alloc::string::String>,
7299}
7300#[cfg(all(feature = "validate", feature = "alloc"))]
7301impl<CustomDataType> crate::validate::Validate
7302for VariableCharacteristics<CustomDataType> {
7303    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7304        crate::validate::Validate::validate(&self.data_type)
7305            .map_err(|error| error.in_field("dataType"))?;
7306        if let Some(value) = self.max_elements {
7307            crate::validate::check_min_i64(value, 1i64)
7308                .map_err(|error| error.in_field("maxElements"))?;
7309        }
7310        if let Some(value) = &self.values_list {
7311            crate::validate::check_max_length(value, 1000usize)
7312                .map_err(|error| error.in_field("valuesList"))?;
7313        }
7314        Ok(())
7315    }
7316}
7317#[cfg(not(feature = "alloc"))]
7318/// Fixed read-only parameters of a variable.
7319#[derive(Debug, Clone, PartialEq)]
7320#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7321pub struct VariableCharacteristics<
7322    CustomDataType = crate::NoCustomData,
7323    const VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP: usize = 1000usize,
7324> {
7325    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7326    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7327    pub custom_data: Option<CustomDataType>,
7328    #[cfg_attr(feature = "serde", serde(rename = "dataType"))]
7329    pub data_type: DataEnum,
7330    /// *(2.1)* Maximum number of elements from _valuesList_ that are supported as _attributeValue_.
7331    #[cfg_attr(feature = "serde", serde(rename = "maxElements"))]
7332    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7333    pub max_elements: Option<i64>,
7334    /// Maximum possible value of this variable. When the datatype of this Variable is String, OptionList, SequenceList or MemberList, this field defines the maximum length of the (CSV) string.
7335    #[cfg_attr(feature = "serde", serde(rename = "maxLimit"))]
7336    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7337    pub max_limit: Option<f64>,
7338    /// Minimum possible value of this variable.
7339    #[cfg_attr(feature = "serde", serde(rename = "minLimit"))]
7340    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7341    pub min_limit: Option<f64>,
7342    /// Flag indicating if this variable supports monitoring.
7343    #[cfg_attr(feature = "serde", serde(rename = "supportsMonitoring"))]
7344    pub supports_monitoring: bool,
7345    /// Unit of the variable. When the transmitted value has a unit, this field SHALL be included.
7346    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7347    pub unit: Option<heapless::String<16usize>>,
7348    /// Mandatory when _dataType_ = OptionList, MemberList or SequenceList. In that case _valuesList_ specifies the allowed values for the type.
7349    ///
7350    /// The length of this field can be limited by DeviceDataCtrlr.ConfigurationValueSize.
7351    ///
7352    /// * OptionList: The (Actual) Variable value must be a single value from the reported (CSV) enumeration list.
7353    ///
7354    /// * MemberList: The (Actual) Variable value  may be an (unordered) (sub-)set of the reported (CSV) valid values list.
7355    ///
7356    /// * SequenceList: The (Actual) Variable value  may be an ordered (priority, etc)  (sub-)set of the reported (CSV) valid values.
7357    ///
7358    /// This is a comma separated list.
7359    ///
7360    /// The Configuration Variable &lt;&lt;configkey-configuration-value-size,ConfigurationValueSize&gt;&gt; can be used to limit SetVariableData.attributeValue and VariableCharacteristics.valuesList. The max size of these values will always remain equal.
7361    #[cfg_attr(feature = "serde", serde(rename = "valuesList"))]
7362    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7363    pub values_list: Option<heapless::String<VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP>>,
7364}
7365#[cfg(all(feature = "validate", not(feature = "alloc")))]
7366impl<
7367    CustomDataType,
7368    const VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP: usize,
7369> crate::validate::Validate
7370for VariableCharacteristics<CustomDataType, VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP> {
7371    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7372        crate::validate::Validate::validate(&self.data_type)
7373            .map_err(|error| error.in_field("dataType"))?;
7374        if let Some(value) = self.max_elements {
7375            crate::validate::check_min_i64(value, 1i64)
7376                .map_err(|error| error.in_field("maxElements"))?;
7377        }
7378        if let Some(value) = &self.values_list {
7379            crate::validate::check_max_length(value, 1000usize)
7380                .map_err(|error| error.in_field("valuesList"))?;
7381        }
7382        Ok(())
7383    }
7384}
7385#[cfg(feature = "alloc")]
7386/// Class to report components, variables and variable attributes and characteristics.
7387#[derive(Debug, Clone, PartialEq)]
7388#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7389pub struct ReportData<CustomDataType = crate::NoCustomData> {
7390    pub component: Component<CustomDataType>,
7391    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7392    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7393    pub custom_data: Option<CustomDataType>,
7394    pub variable: Variable<CustomDataType>,
7395    #[cfg_attr(feature = "serde", serde(rename = "variableAttribute"))]
7396    pub variable_attribute: heapless::Vec<VariableAttribute<CustomDataType>, 4usize>,
7397    #[cfg_attr(feature = "serde", serde(rename = "variableCharacteristics"))]
7398    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7399    pub variable_characteristics: Option<VariableCharacteristics<CustomDataType>>,
7400}
7401#[cfg(all(feature = "validate", feature = "alloc"))]
7402impl<CustomDataType> crate::validate::Validate for ReportData<CustomDataType> {
7403    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7404        crate::validate::Validate::validate(&self.component)
7405            .map_err(|error| error.in_field("component"))?;
7406        crate::validate::Validate::validate(&self.variable)
7407            .map_err(|error| error.in_field("variable"))?;
7408        crate::validate::check_min_items(self.variable_attribute.len(), 1usize)
7409            .map_err(|error| error.in_field("variableAttribute"))?;
7410        for (index, item) in self.variable_attribute.iter().enumerate() {
7411            crate::validate::Validate::validate(item)
7412                .map_err(|error| error.in_index(index).in_field("variableAttribute"))?;
7413        }
7414        if let Some(value) = &self.variable_characteristics {
7415            crate::validate::Validate::validate(value)
7416                .map_err(|error| error.in_field("variableCharacteristics"))?;
7417        }
7418        Ok(())
7419    }
7420}
7421#[cfg(not(feature = "alloc"))]
7422/// Class to report components, variables and variable attributes and characteristics.
7423#[derive(Debug, Clone, PartialEq)]
7424#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7425pub struct ReportData<
7426    CustomDataType = crate::NoCustomData,
7427    const VARIABLE_ATTRIBUTE_VALUE_CAP: usize = 1024usize,
7428    const VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP: usize = 1000usize,
7429> {
7430    pub component: Component<CustomDataType>,
7431    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7432    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7433    pub custom_data: Option<CustomDataType>,
7434    pub variable: Variable<CustomDataType>,
7435    #[cfg_attr(feature = "serde", serde(rename = "variableAttribute"))]
7436    pub variable_attribute: heapless::Vec<
7437        VariableAttribute<CustomDataType, VARIABLE_ATTRIBUTE_VALUE_CAP>,
7438        4usize,
7439    >,
7440    #[cfg_attr(feature = "serde", serde(rename = "variableCharacteristics"))]
7441    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7442    pub variable_characteristics: Option<
7443        VariableCharacteristics<CustomDataType, VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP>,
7444    >,
7445}
7446#[cfg(all(feature = "validate", not(feature = "alloc")))]
7447impl<
7448    CustomDataType,
7449    const VARIABLE_ATTRIBUTE_VALUE_CAP: usize,
7450    const VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP: usize,
7451> crate::validate::Validate
7452for ReportData<
7453    CustomDataType,
7454    VARIABLE_ATTRIBUTE_VALUE_CAP,
7455    VARIABLE_CHARACTERISTICS_VALUES_LIST_CAP,
7456> {
7457    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7458        crate::validate::Validate::validate(&self.component)
7459            .map_err(|error| error.in_field("component"))?;
7460        crate::validate::Validate::validate(&self.variable)
7461            .map_err(|error| error.in_field("variable"))?;
7462        crate::validate::check_min_items(self.variable_attribute.len(), 1usize)
7463            .map_err(|error| error.in_field("variableAttribute"))?;
7464        for (index, item) in self.variable_attribute.iter().enumerate() {
7465            crate::validate::Validate::validate(item)
7466                .map_err(|error| error.in_index(index).in_field("variableAttribute"))?;
7467        }
7468        if let Some(value) = &self.variable_characteristics {
7469            crate::validate::Validate::validate(value)
7470                .map_err(|error| error.in_field("variableCharacteristics"))?;
7471        }
7472        Ok(())
7473    }
7474}
7475/// The status of the settlement attempt.
7476#[derive(Debug, Clone, PartialEq, Eq)]
7477#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7478pub enum PaymentStatusEnum {
7479    Settled,
7480    Canceled,
7481    Rejected,
7482    Failed,
7483}
7484#[cfg(feature = "validate")]
7485impl crate::validate::Validate for PaymentStatusEnum {
7486    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7487        Ok(())
7488    }
7489}
7490/// *(2.1)* A generic address format.
7491#[derive(Debug, Clone, PartialEq, Eq)]
7492#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7493pub struct Address<CustomDataType = crate::NoCustomData> {
7494    /// Address line 1
7495    pub address1: heapless::String<100usize>,
7496    /// Address line 2
7497    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7498    pub address2: Option<heapless::String<100usize>>,
7499    /// City
7500    pub city: heapless::String<100usize>,
7501    /// Country name
7502    pub country: heapless::String<50usize>,
7503    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7504    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7505    pub custom_data: Option<CustomDataType>,
7506    /// Name of person/company
7507    pub name: heapless::String<50usize>,
7508    /// Postal code
7509    #[cfg_attr(feature = "serde", serde(rename = "postalCode"))]
7510    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7511    pub postal_code: Option<heapless::String<20usize>>,
7512}
7513#[cfg(feature = "validate")]
7514impl<CustomDataType> crate::validate::Validate for Address<CustomDataType> {
7515    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7516        Ok(())
7517    }
7518}
7519/// This contains the progress status of the publishfirmware
7520/// installation.
7521#[derive(Debug, Clone, PartialEq, Eq)]
7522#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7523pub enum PublishFirmwareStatusEnum {
7524    Idle,
7525    DownloadScheduled,
7526    Downloading,
7527    Downloaded,
7528    Published,
7529    DownloadFailed,
7530    DownloadPaused,
7531    InvalidChecksum,
7532    ChecksumVerified,
7533    PublishFailed,
7534}
7535#[cfg(feature = "validate")]
7536impl crate::validate::Validate for PublishFirmwareStatusEnum {
7537    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7538        Ok(())
7539    }
7540}
7541/// Updates to a ChargingSchedulePeriodType for dynamic charging profiles.
7542#[derive(Debug, Clone, PartialEq)]
7543#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7544pub struct ChargingScheduleUpdate<CustomDataType = crate::NoCustomData> {
7545    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7546    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7547    pub custom_data: Option<CustomDataType>,
7548    /// *(2.1)* Limit in _chargingRateUnit_ that the EV is allowed to discharge with. Note, these are negative values in order to be consistent with _setpoint_, which can be positive and negative.  +
7549    /// For AC this field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
7550    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit"))]
7551    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7552    pub discharge_limit: Option<f64>,
7553    /// *(2.1)* Limit in _chargingRateUnit_ on phase L2 that the EV is allowed to discharge with.
7554    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L2"))]
7555    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7556    pub discharge_limit_l2: Option<f64>,
7557    /// *(2.1)* Limit in _chargingRateUnit_ on phase L3 that the EV is allowed to discharge with.
7558    #[cfg_attr(feature = "serde", serde(rename = "dischargeLimit_L3"))]
7559    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7560    pub discharge_limit_l3: Option<f64>,
7561    /// Optional only when not required by the _operationMode_, as in CentralSetpoint, ExternalSetpoint, ExternalLimits, LocalFrequency,  LocalLoadBalancing. +
7562    /// Charging rate limit during the schedule period, in the applicable _chargingRateUnit_.
7563    /// This SHOULD be a non-negative value; a negative value is only supported for backwards compatibility with older systems that use a negative value to specify a discharging limit.
7564    /// For AC this field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
7565    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7566    pub limit: Option<f64>,
7567    /// *(2.1)* Charging rate limit on phase L2  in the applicable _chargingRateUnit_.
7568    #[cfg_attr(feature = "serde", serde(rename = "limit_L2"))]
7569    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7570    pub limit_l2: Option<f64>,
7571    /// *(2.1)* Charging rate limit on phase L3  in the applicable _chargingRateUnit_.
7572    #[cfg_attr(feature = "serde", serde(rename = "limit_L3"))]
7573    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7574    pub limit_l3: Option<f64>,
7575    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow as close as possible. Use negative values for discharging. +
7576    /// When a limit and/or _dischargeLimit_ are given the overshoot when following _setpoint_ must remain within these values.
7577    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
7578    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7579    pub setpoint: Option<f64>,
7580    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow as closely as possible. Positive values for inductive, negative for capacitive reactive power or current.  +
7581    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
7582    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive"))]
7583    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7584    pub setpoint_reactive: Option<f64>,
7585    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L2 as closely as possible.
7586    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L2"))]
7587    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7588    pub setpoint_reactive_l2: Option<f64>,
7589    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L3 as closely as possible.
7590    #[cfg_attr(feature = "serde", serde(rename = "setpointReactive_L3"))]
7591    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7592    pub setpoint_reactive_l3: Option<f64>,
7593    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L2 as close as possible.
7594    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L2"))]
7595    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7596    pub setpoint_l2: Option<f64>,
7597    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L3 as close as possible.
7598    #[cfg_attr(feature = "serde", serde(rename = "setpoint_L3"))]
7599    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7600    pub setpoint_l3: Option<f64>,
7601}
7602#[cfg(feature = "validate")]
7603impl<CustomDataType> crate::validate::Validate
7604for ChargingScheduleUpdate<CustomDataType> {
7605    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7606        if let Some(value) = self.discharge_limit {
7607            crate::validate::check_max_f64(value, 0f64)
7608                .map_err(|error| error.in_field("dischargeLimit"))?;
7609        }
7610        if let Some(value) = self.discharge_limit_l2 {
7611            crate::validate::check_max_f64(value, 0f64)
7612                .map_err(|error| error.in_field("dischargeLimit_L2"))?;
7613        }
7614        if let Some(value) = self.discharge_limit_l3 {
7615            crate::validate::check_max_f64(value, 0f64)
7616                .map_err(|error| error.in_field("dischargeLimit_L3"))?;
7617        }
7618        Ok(())
7619    }
7620}
7621/// Result of request.
7622#[derive(Debug, Clone, PartialEq, Eq)]
7623#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7624pub enum ChargingProfileStatusEnum {
7625    Accepted,
7626    Rejected,
7627}
7628#[cfg(feature = "validate")]
7629impl crate::validate::Validate for ChargingProfileStatusEnum {
7630    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7631        Ok(())
7632    }
7633}
7634/// Indicates the kind of schedule.
7635#[derive(Debug, Clone, PartialEq, Eq)]
7636#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7637pub enum ChargingProfileKindEnum {
7638    Absolute,
7639    Recurring,
7640    Relative,
7641    Dynamic,
7642}
7643#[cfg(feature = "validate")]
7644impl crate::validate::Validate for ChargingProfileKindEnum {
7645    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7646        Ok(())
7647    }
7648}
7649/// Indicates the start point of a recurrence.
7650#[derive(Debug, Clone, PartialEq, Eq)]
7651#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7652pub enum RecurrencyKindEnum {
7653    Daily,
7654    Weekly,
7655}
7656#[cfg(feature = "validate")]
7657impl crate::validate::Validate for RecurrencyKindEnum {
7658    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7659        Ok(())
7660    }
7661}
7662#[cfg(feature = "alloc")]
7663/// A ChargingProfile consists of 1 to 3 ChargingSchedules with a list of ChargingSchedulePeriods, describing the amount of power or current that can be delivered per time interval.
7664///
7665/// image::images/ChargingProfile-Simple.png\[\]
7666#[derive(Debug, Clone, PartialEq)]
7667#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7668pub struct ChargingProfile<CustomDataType = crate::NoCustomData> {
7669    #[cfg_attr(feature = "serde", serde(rename = "chargingProfileKind"))]
7670    pub charging_profile_kind: ChargingProfileKindEnum,
7671    #[cfg_attr(feature = "serde", serde(rename = "chargingProfilePurpose"))]
7672    pub charging_profile_purpose: ChargingProfilePurposeEnum,
7673    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedule"))]
7674    pub charging_schedule: heapless::Vec<ChargingSchedule<CustomDataType>, 3usize>,
7675    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7676    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7677    pub custom_data: Option<CustomDataType>,
7678    /// *(2.1)*  Interval in seconds after receipt of last update, when to request a profile update by sending a PullDynamicScheduleUpdateRequest message.
7679    ///     A value of 0 or no value means that no update interval applies. +
7680    ///     Only relevant in a dynamic charging profile.
7681    #[cfg_attr(feature = "serde", serde(rename = "dynUpdateInterval"))]
7682    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7683    pub dyn_update_interval: Option<i64>,
7684    /// *(2.1)* Time at which limits or setpoints in this charging profile were last updated by a PullDynamicScheduleUpdateRequest or UpdateDynamicScheduleRequest or by an external actor. +
7685    ///     Only relevant in a dynamic charging profile.
7686    #[cfg_attr(feature = "serde", serde(rename = "dynUpdateTime"))]
7687    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7688    pub dyn_update_time: Option<crate::OcppTimestamp>,
7689    /// Id of ChargingProfile. Unique within charging station. Id can have a negative value. This is useful to distinguish charging profiles from an external actor (external constraints) from charging profiles received from CSMS.
7690    pub id: i64,
7691    /// *(2.1)* When set to true this charging profile will not be valid anymore after being offline for more than _maxOfflineDuration_. +
7692    ///     When absent defaults to false.
7693    #[cfg_attr(feature = "serde", serde(rename = "invalidAfterOfflineDuration"))]
7694    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7695    pub invalid_after_offline_duration: Option<bool>,
7696    /// *(2.1)* Period in seconds that this charging profile remains valid after the Charging Station has gone offline. After this period the charging profile becomes invalid for as long as it is offline and the Charging Station reverts back to a valid profile with a lower stack level.
7697    /// If _invalidAfterOfflineDuration_ is true, then this charging profile will become permanently invalid.
7698    /// A value of 0 means that the charging profile is immediately invalid while offline. When the field is absent, then  no timeout applies and the charging profile remains valid when offline.
7699    #[cfg_attr(feature = "serde", serde(rename = "maxOfflineDuration"))]
7700    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7701    pub max_offline_duration: Option<i64>,
7702    /// *(2.1)* ISO 15118-20 signature for all price schedules in _chargingSchedules_. +
7703    /// Note: for 256-bit elliptic curves (like secp256k1) the ECDSA signature is 512 bits (64 bytes) and for 521-bit curves (like secp521r1) the signature is 1042 bits. This equals 131 bytes, which can be encoded as base64 in 176 bytes.
7704    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleSignature"))]
7705    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7706    pub price_schedule_signature: Option<heapless::String<256usize>>,
7707    #[cfg_attr(feature = "serde", serde(rename = "recurrencyKind"))]
7708    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7709    pub recurrency_kind: Option<RecurrencyKindEnum>,
7710    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
7711    #[cfg_attr(feature = "serde", serde(rename = "stackLevel"))]
7712    pub stack_level: i64,
7713    /// SHALL only be included if ChargingProfilePurpose is set to TxProfile in a SetChargingProfileRequest. The transactionId is used to match the profile to a specific transaction.
7714    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
7715    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7716    pub transaction_id: Option<heapless::String<36usize>>,
7717    /// Point in time at which the profile starts to be valid. If absent, the profile is valid as soon as it is received by the Charging Station.
7718    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
7719    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7720    pub valid_from: Option<crate::OcppTimestamp>,
7721    /// Point in time at which the profile stops to be valid. If absent, the profile is valid until it is replaced by another profile.
7722    #[cfg_attr(feature = "serde", serde(rename = "validTo"))]
7723    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7724    pub valid_to: Option<crate::OcppTimestamp>,
7725}
7726#[cfg(all(feature = "validate", feature = "alloc"))]
7727impl<CustomDataType> crate::validate::Validate for ChargingProfile<CustomDataType> {
7728    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7729        crate::validate::Validate::validate(&self.charging_profile_kind)
7730            .map_err(|error| error.in_field("chargingProfileKind"))?;
7731        crate::validate::Validate::validate(&self.charging_profile_purpose)
7732            .map_err(|error| error.in_field("chargingProfilePurpose"))?;
7733        crate::validate::check_min_items(self.charging_schedule.len(), 1usize)
7734            .map_err(|error| error.in_field("chargingSchedule"))?;
7735        for (index, item) in self.charging_schedule.iter().enumerate() {
7736            crate::validate::Validate::validate(item)
7737                .map_err(|error| error.in_index(index).in_field("chargingSchedule"))?;
7738        }
7739        if let Some(value) = &self.recurrency_kind {
7740            crate::validate::Validate::validate(value)
7741                .map_err(|error| error.in_field("recurrencyKind"))?;
7742        }
7743        crate::validate::check_min_i64(self.stack_level, 0i64)
7744            .map_err(|error| error.in_field("stackLevel"))?;
7745        Ok(())
7746    }
7747}
7748#[cfg(not(feature = "alloc"))]
7749/// A ChargingProfile consists of 1 to 3 ChargingSchedules with a list of ChargingSchedulePeriods, describing the amount of power or current that can be delivered per time interval.
7750///
7751/// image::images/ChargingProfile-Simple.png\[\]
7752#[derive(Debug, Clone, PartialEq)]
7753#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7754pub struct ChargingProfile<
7755    CustomDataType = crate::NoCustomData,
7756    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize = 1024usize,
7757    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize = 8usize,
7758    const CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize = 8usize,
7759    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize = 8usize,
7760    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize = 8usize,
7761    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize = 8usize,
7762    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize = 8usize,
7763> {
7764    #[cfg_attr(feature = "serde", serde(rename = "chargingProfileKind"))]
7765    pub charging_profile_kind: ChargingProfileKindEnum,
7766    #[cfg_attr(feature = "serde", serde(rename = "chargingProfilePurpose"))]
7767    pub charging_profile_purpose: ChargingProfilePurposeEnum,
7768    #[cfg_attr(feature = "serde", serde(rename = "chargingSchedule"))]
7769    pub charging_schedule: heapless::Vec<
7770        ChargingSchedule<
7771            CustomDataType,
7772            ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
7773            ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
7774            CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
7775            CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
7776            CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
7777            PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
7778            SALES_TARIFF_SALES_TARIFF_ENTRY_CAP,
7779        >,
7780        3usize,
7781    >,
7782    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7783    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7784    pub custom_data: Option<CustomDataType>,
7785    /// *(2.1)*  Interval in seconds after receipt of last update, when to request a profile update by sending a PullDynamicScheduleUpdateRequest message.
7786    ///     A value of 0 or no value means that no update interval applies. +
7787    ///     Only relevant in a dynamic charging profile.
7788    #[cfg_attr(feature = "serde", serde(rename = "dynUpdateInterval"))]
7789    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7790    pub dyn_update_interval: Option<i64>,
7791    /// *(2.1)* Time at which limits or setpoints in this charging profile were last updated by a PullDynamicScheduleUpdateRequest or UpdateDynamicScheduleRequest or by an external actor. +
7792    ///     Only relevant in a dynamic charging profile.
7793    #[cfg_attr(feature = "serde", serde(rename = "dynUpdateTime"))]
7794    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7795    pub dyn_update_time: Option<crate::OcppTimestamp>,
7796    /// Id of ChargingProfile. Unique within charging station. Id can have a negative value. This is useful to distinguish charging profiles from an external actor (external constraints) from charging profiles received from CSMS.
7797    pub id: i64,
7798    /// *(2.1)* When set to true this charging profile will not be valid anymore after being offline for more than _maxOfflineDuration_. +
7799    ///     When absent defaults to false.
7800    #[cfg_attr(feature = "serde", serde(rename = "invalidAfterOfflineDuration"))]
7801    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7802    pub invalid_after_offline_duration: Option<bool>,
7803    /// *(2.1)* Period in seconds that this charging profile remains valid after the Charging Station has gone offline. After this period the charging profile becomes invalid for as long as it is offline and the Charging Station reverts back to a valid profile with a lower stack level.
7804    /// If _invalidAfterOfflineDuration_ is true, then this charging profile will become permanently invalid.
7805    /// A value of 0 means that the charging profile is immediately invalid while offline. When the field is absent, then  no timeout applies and the charging profile remains valid when offline.
7806    #[cfg_attr(feature = "serde", serde(rename = "maxOfflineDuration"))]
7807    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7808    pub max_offline_duration: Option<i64>,
7809    /// *(2.1)* ISO 15118-20 signature for all price schedules in _chargingSchedules_. +
7810    /// Note: for 256-bit elliptic curves (like secp256k1) the ECDSA signature is 512 bits (64 bytes) and for 521-bit curves (like secp521r1) the signature is 1042 bits. This equals 131 bytes, which can be encoded as base64 in 176 bytes.
7811    #[cfg_attr(feature = "serde", serde(rename = "priceScheduleSignature"))]
7812    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7813    pub price_schedule_signature: Option<heapless::String<256usize>>,
7814    #[cfg_attr(feature = "serde", serde(rename = "recurrencyKind"))]
7815    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7816    pub recurrency_kind: Option<RecurrencyKindEnum>,
7817    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
7818    #[cfg_attr(feature = "serde", serde(rename = "stackLevel"))]
7819    pub stack_level: i64,
7820    /// SHALL only be included if ChargingProfilePurpose is set to TxProfile in a SetChargingProfileRequest. The transactionId is used to match the profile to a specific transaction.
7821    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
7822    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7823    pub transaction_id: Option<heapless::String<36usize>>,
7824    /// Point in time at which the profile starts to be valid. If absent, the profile is valid as soon as it is received by the Charging Station.
7825    #[cfg_attr(feature = "serde", serde(rename = "validFrom"))]
7826    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7827    pub valid_from: Option<crate::OcppTimestamp>,
7828    /// Point in time at which the profile stops to be valid. If absent, the profile is valid until it is replaced by another profile.
7829    #[cfg_attr(feature = "serde", serde(rename = "validTo"))]
7830    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7831    pub valid_to: Option<crate::OcppTimestamp>,
7832}
7833#[cfg(all(feature = "validate", not(feature = "alloc")))]
7834impl<
7835    CustomDataType,
7836    const ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP: usize,
7837    const ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP: usize,
7838    const CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP: usize,
7839    const CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP: usize,
7840    const CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP: usize,
7841    const PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP: usize,
7842    const SALES_TARIFF_SALES_TARIFF_ENTRY_CAP: usize,
7843> crate::validate::Validate
7844for ChargingProfile<
7845    CustomDataType,
7846    ABSOLUTE_PRICE_SCHEDULE_PRICE_ALGORITHM_CAP,
7847    ABSOLUTE_PRICE_SCHEDULE_PRICE_RULE_STACKS_CAP,
7848    CHARGING_SCHEDULE_CHARGING_SCHEDULE_PERIOD_CAP,
7849    CHARGING_SCHEDULE_PERIOD_V2X_FREQ_WATT_CURVE_CAP,
7850    CHARGING_SCHEDULE_PERIOD_V2X_SIGNAL_WATT_CURVE_CAP,
7851    PRICE_LEVEL_SCHEDULE_PRICE_LEVEL_SCHEDULE_ENTRIES_CAP,
7852    SALES_TARIFF_SALES_TARIFF_ENTRY_CAP,
7853> {
7854    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7855        crate::validate::Validate::validate(&self.charging_profile_kind)
7856            .map_err(|error| error.in_field("chargingProfileKind"))?;
7857        crate::validate::Validate::validate(&self.charging_profile_purpose)
7858            .map_err(|error| error.in_field("chargingProfilePurpose"))?;
7859        crate::validate::check_min_items(self.charging_schedule.len(), 1usize)
7860            .map_err(|error| error.in_field("chargingSchedule"))?;
7861        for (index, item) in self.charging_schedule.iter().enumerate() {
7862            crate::validate::Validate::validate(item)
7863                .map_err(|error| error.in_index(index).in_field("chargingSchedule"))?;
7864        }
7865        if let Some(value) = &self.recurrency_kind {
7866            crate::validate::Validate::validate(value)
7867                .map_err(|error| error.in_field("recurrencyKind"))?;
7868        }
7869        crate::validate::check_min_i64(self.stack_level, 0i64)
7870            .map_err(|error| error.in_field("stackLevel"))?;
7871        Ok(())
7872    }
7873}
7874#[derive(Debug, Clone, PartialEq)]
7875#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7876pub struct DERCurvePoints<CustomDataType = crate::NoCustomData> {
7877    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7878    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7879    pub custom_data: Option<CustomDataType>,
7880    /// The data value of the X-axis (independent) variable, depending on the curve type.
7881    pub x: f64,
7882    /// The data value of the Y-axis (dependent) variable, depending on the  &lt;&lt;cmn_derunitenumtype&gt;&gt; of the curve. If _y_ is power factor, then a positive value means DER is absorbing reactive power (under-excited), a negative value when DER is injecting reactive power (over-excited).
7883    pub y: f64,
7884}
7885#[cfg(feature = "validate")]
7886impl<CustomDataType> crate::validate::Validate for DERCurvePoints<CustomDataType> {
7887    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7888        Ok(())
7889    }
7890}
7891#[derive(Debug, Clone, PartialEq)]
7892#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7893pub struct Hysteresis<CustomDataType = crate::NoCustomData> {
7894    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7895    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7896    pub custom_data: Option<CustomDataType>,
7897    /// Delay in seconds, once grid parameter within HysteresisLow and HysteresisHigh, for the EV to return to normal operation after a grid event.
7898    #[cfg_attr(feature = "serde", serde(rename = "hysteresisDelay"))]
7899    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7900    pub hysteresis_delay: Option<f64>,
7901    /// Set default rate of change (ramp rate %/s) for the EV to return to normal operation after a grid event
7902    #[cfg_attr(feature = "serde", serde(rename = "hysteresisGradient"))]
7903    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7904    pub hysteresis_gradient: Option<f64>,
7905    /// High value for return to normal operation after a grid event, in absolute value. This value adopts the same unit as defined by yUnit
7906    #[cfg_attr(feature = "serde", serde(rename = "hysteresisHigh"))]
7907    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7908    pub hysteresis_high: Option<f64>,
7909    /// Low value for return to normal operation after a grid event, in absolute value. This value adopts the same unit as defined by yUnit
7910    #[cfg_attr(feature = "serde", serde(rename = "hysteresisLow"))]
7911    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7912    pub hysteresis_low: Option<f64>,
7913}
7914#[cfg(feature = "validate")]
7915impl<CustomDataType> crate::validate::Validate for Hysteresis<CustomDataType> {
7916    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7917        Ok(())
7918    }
7919}
7920#[derive(Debug, Clone, PartialEq)]
7921#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7922pub struct ReactivePowerParams<CustomDataType = crate::NoCustomData> {
7923    /// Only for VoltVar: Enable/disable autonomous VRef adjustment
7924    #[cfg_attr(feature = "serde", serde(rename = "autonomousVRefEnable"))]
7925    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7926    pub autonomous_v_ref_enable: Option<bool>,
7927    /// Only for VoltVar: Adjustment range for VRef time constant
7928    #[cfg_attr(feature = "serde", serde(rename = "autonomousVRefTimeConstant"))]
7929    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7930    pub autonomous_v_ref_time_constant: Option<f64>,
7931    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7932    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7933    pub custom_data: Option<CustomDataType>,
7934    /// Only for VoltVar curve: The nominal ac voltage (rms) adjustment to the voltage curve points for Volt-Var curves (percentage).
7935    #[cfg_attr(feature = "serde", serde(rename = "vRef"))]
7936    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7937    pub v_ref: Option<f64>,
7938}
7939#[cfg(feature = "validate")]
7940impl<CustomDataType> crate::validate::Validate for ReactivePowerParams<CustomDataType> {
7941    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7942        Ok(())
7943    }
7944}
7945/// Parameter is only sent, if the EV has to feed-in power or reactive power during fault-ride through (FRT) as defined by HVMomCess curve and LVMomCess curve.
7946#[derive(Debug, Clone, PartialEq, Eq)]
7947#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7948pub enum PowerDuringCessationEnum {
7949    Active,
7950    Reactive,
7951}
7952#[cfg(feature = "validate")]
7953impl crate::validate::Validate for PowerDuringCessationEnum {
7954    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7955        Ok(())
7956    }
7957}
7958#[derive(Debug, Clone, PartialEq)]
7959#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7960pub struct VoltageParams<CustomDataType = crate::NoCustomData> {
7961    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
7962    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7963    pub custom_data: Option<CustomDataType>,
7964    /// Time for which the voltage is allowed to stay above the 10 min mean value.
7965    ///     After this time, the EV must trip.
7966    ///     This value is mandatory if OverVoltageMeanValue10min is set.
7967    #[cfg_attr(feature = "serde", serde(rename = "hv10MinMeanTripDelay"))]
7968    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7969    pub hv10_min_mean_trip_delay: Option<f64>,
7970    /// EN 50549-1 chapter 4.9.3.4
7971    ///     Voltage threshold for the 10 min time window mean value monitoring.
7972    ///     The 10 min mean is recalculated up to every 3 s.
7973    ///     If the present voltage is above this threshold for more than the time defined by _hv10MinMeanValue_, the EV must trip.
7974    ///     This value is mandatory if _hv10MinMeanTripDelay_ is set.
7975    #[cfg_attr(feature = "serde", serde(rename = "hv10MinMeanValue"))]
7976    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7977    pub hv10_min_mean_value: Option<f64>,
7978    #[cfg_attr(feature = "serde", serde(rename = "powerDuringCessation"))]
7979    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
7980    pub power_during_cessation: Option<PowerDuringCessationEnum>,
7981}
7982#[cfg(feature = "validate")]
7983impl<CustomDataType> crate::validate::Validate for VoltageParams<CustomDataType> {
7984    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
7985        if let Some(value) = &self.power_during_cessation {
7986            crate::validate::Validate::validate(value)
7987                .map_err(|error| error.in_field("powerDuringCessation"))?;
7988        }
7989        Ok(())
7990    }
7991}
7992/// Unit of the Y-axis of DER curve
7993#[derive(Debug, Clone, PartialEq, Eq)]
7994#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7995pub enum DERUnitEnum {
7996    #[cfg_attr(feature = "serde", serde(rename = "Not_Applicable"))]
7997    NotApplicable,
7998    PctMaxW,
7999    PctMaxVar,
8000    PctWAvail,
8001    PctVarAvail,
8002    PctEffectiveV,
8003}
8004#[cfg(feature = "validate")]
8005impl crate::validate::Validate for DERUnitEnum {
8006    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8007        Ok(())
8008    }
8009}
8010#[derive(Debug, Clone, PartialEq)]
8011#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8012pub struct DERCurve<CustomDataType = crate::NoCustomData> {
8013    #[cfg_attr(feature = "serde", serde(rename = "curveData"))]
8014    pub curve_data: heapless::Vec<DERCurvePoints<CustomDataType>, 10usize>,
8015    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8016    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8017    pub custom_data: Option<CustomDataType>,
8018    /// Duration in seconds that this curve will be active. Only absent when _default_ is true.
8019    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8020    pub duration: Option<f64>,
8021    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8022    pub hysteresis: Option<Hysteresis<CustomDataType>>,
8023    /// Priority of curve (0=highest)
8024    pub priority: i64,
8025    #[cfg_attr(feature = "serde", serde(rename = "reactivePowerParams"))]
8026    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8027    pub reactive_power_params: Option<ReactivePowerParams<CustomDataType>>,
8028    /// Open loop response time, the time to ramp up to 90% of the new target in response to the change in voltage, in seconds. A value of 0 is used to mean no limit. When not present, the device should follow its default behavior.
8029    #[cfg_attr(feature = "serde", serde(rename = "responseTime"))]
8030    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8031    pub response_time: Option<f64>,
8032    /// Point in time when this curve will become activated. Only absent when _default_ is true.
8033    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
8034    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8035    pub start_time: Option<crate::OcppTimestamp>,
8036    #[cfg_attr(feature = "serde", serde(rename = "voltageParams"))]
8037    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8038    pub voltage_params: Option<VoltageParams<CustomDataType>>,
8039    #[cfg_attr(feature = "serde", serde(rename = "yUnit"))]
8040    pub y_unit: DERUnitEnum,
8041}
8042#[cfg(feature = "validate")]
8043impl<CustomDataType> crate::validate::Validate for DERCurve<CustomDataType> {
8044    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8045        crate::validate::check_min_items(self.curve_data.len(), 1usize)
8046            .map_err(|error| error.in_field("curveData"))?;
8047        for (index, item) in self.curve_data.iter().enumerate() {
8048            crate::validate::Validate::validate(item)
8049                .map_err(|error| error.in_index(index).in_field("curveData"))?;
8050        }
8051        if let Some(value) = &self.hysteresis {
8052            crate::validate::Validate::validate(value)
8053                .map_err(|error| error.in_field("hysteresis"))?;
8054        }
8055        crate::validate::check_min_i64(self.priority, 0i64)
8056            .map_err(|error| error.in_field("priority"))?;
8057        if let Some(value) = &self.reactive_power_params {
8058            crate::validate::Validate::validate(value)
8059                .map_err(|error| error.in_field("reactivePowerParams"))?;
8060        }
8061        if let Some(value) = &self.voltage_params {
8062            crate::validate::Validate::validate(value)
8063                .map_err(|error| error.in_field("voltageParams"))?;
8064        }
8065        crate::validate::Validate::validate(&self.y_unit)
8066            .map_err(|error| error.in_field("yUnit"))?;
8067        Ok(())
8068    }
8069}
8070#[derive(Debug, Clone, PartialEq)]
8071#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8072pub struct DERCurveGet<CustomDataType = crate::NoCustomData> {
8073    pub curve: DERCurve<CustomDataType>,
8074    #[cfg_attr(feature = "serde", serde(rename = "curveType"))]
8075    pub curve_type: DERControlEnum,
8076    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8077    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8078    pub custom_data: Option<CustomDataType>,
8079    /// Id of DER curve
8080    pub id: heapless::String<36usize>,
8081    /// True if this is a default curve
8082    #[cfg_attr(feature = "serde", serde(rename = "isDefault"))]
8083    pub is_default: bool,
8084    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
8085    #[cfg_attr(feature = "serde", serde(rename = "isSuperseded"))]
8086    pub is_superseded: bool,
8087}
8088#[cfg(feature = "validate")]
8089impl<CustomDataType> crate::validate::Validate for DERCurveGet<CustomDataType> {
8090    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8091        crate::validate::Validate::validate(&self.curve)
8092            .map_err(|error| error.in_field("curve"))?;
8093        crate::validate::Validate::validate(&self.curve_type)
8094            .map_err(|error| error.in_field("curveType"))?;
8095        Ok(())
8096    }
8097}
8098#[derive(Debug, Clone, PartialEq)]
8099#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8100pub struct EnterService<CustomDataType = crate::NoCustomData> {
8101    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8102    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8103    pub custom_data: Option<CustomDataType>,
8104    /// Enter service delay
8105    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8106    pub delay: Option<f64>,
8107    /// Enter service frequency high
8108    #[cfg_attr(feature = "serde", serde(rename = "highFreq"))]
8109    pub high_freq: f64,
8110    /// Enter service voltage high
8111    #[cfg_attr(feature = "serde", serde(rename = "highVoltage"))]
8112    pub high_voltage: f64,
8113    /// Enter service frequency low
8114    #[cfg_attr(feature = "serde", serde(rename = "lowFreq"))]
8115    pub low_freq: f64,
8116    /// Enter service voltage low
8117    #[cfg_attr(feature = "serde", serde(rename = "lowVoltage"))]
8118    pub low_voltage: f64,
8119    /// Priority of setting (0=highest)
8120    pub priority: i64,
8121    /// Enter service ramp rate in seconds
8122    #[cfg_attr(feature = "serde", serde(rename = "rampRate"))]
8123    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8124    pub ramp_rate: Option<f64>,
8125    /// Enter service randomized delay
8126    #[cfg_attr(feature = "serde", serde(rename = "randomDelay"))]
8127    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8128    pub random_delay: Option<f64>,
8129}
8130#[cfg(feature = "validate")]
8131impl<CustomDataType> crate::validate::Validate for EnterService<CustomDataType> {
8132    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8133        crate::validate::check_min_i64(self.priority, 0i64)
8134            .map_err(|error| error.in_field("priority"))?;
8135        Ok(())
8136    }
8137}
8138#[derive(Debug, Clone, PartialEq)]
8139#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8140pub struct EnterServiceGet<CustomDataType = crate::NoCustomData> {
8141    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8142    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8143    pub custom_data: Option<CustomDataType>,
8144    #[cfg_attr(feature = "serde", serde(rename = "enterService"))]
8145    pub enter_service: EnterService<CustomDataType>,
8146    /// Id of setting
8147    pub id: heapless::String<36usize>,
8148}
8149#[cfg(feature = "validate")]
8150impl<CustomDataType> crate::validate::Validate for EnterServiceGet<CustomDataType> {
8151    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8152        crate::validate::Validate::validate(&self.enter_service)
8153            .map_err(|error| error.in_field("enterService"))?;
8154        Ok(())
8155    }
8156}
8157#[derive(Debug, Clone, PartialEq)]
8158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8159pub struct FixedPF<CustomDataType = crate::NoCustomData> {
8160    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8161    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8162    pub custom_data: Option<CustomDataType>,
8163    /// Power factor, cos(phi), as value between 0..1.
8164    pub displacement: f64,
8165    /// Duration in seconds that this setting is active.
8166    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8167    pub duration: Option<f64>,
8168    /// True when absorbing reactive power (under-excited), false when injecting reactive power (over-excited).
8169    pub excitation: bool,
8170    /// Priority of setting (0=highest)
8171    pub priority: i64,
8172    /// Time when this setting becomes active
8173    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
8174    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8175    pub start_time: Option<crate::OcppTimestamp>,
8176}
8177#[cfg(feature = "validate")]
8178impl<CustomDataType> crate::validate::Validate for FixedPF<CustomDataType> {
8179    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8180        crate::validate::check_min_i64(self.priority, 0i64)
8181            .map_err(|error| error.in_field("priority"))?;
8182        Ok(())
8183    }
8184}
8185#[derive(Debug, Clone, PartialEq)]
8186#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8187pub struct FixedPFGet<CustomDataType = crate::NoCustomData> {
8188    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8189    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8190    pub custom_data: Option<CustomDataType>,
8191    #[cfg_attr(feature = "serde", serde(rename = "fixedPF"))]
8192    pub fixed_p_f: FixedPF<CustomDataType>,
8193    /// Id of setting.
8194    pub id: heapless::String<36usize>,
8195    /// True if setting is a default control.
8196    #[cfg_attr(feature = "serde", serde(rename = "isDefault"))]
8197    pub is_default: bool,
8198    /// True if this setting is superseded by a lower priority setting.
8199    #[cfg_attr(feature = "serde", serde(rename = "isSuperseded"))]
8200    pub is_superseded: bool,
8201}
8202#[cfg(feature = "validate")]
8203impl<CustomDataType> crate::validate::Validate for FixedPFGet<CustomDataType> {
8204    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8205        crate::validate::Validate::validate(&self.fixed_p_f)
8206            .map_err(|error| error.in_field("fixedPF"))?;
8207        Ok(())
8208    }
8209}
8210#[derive(Debug, Clone, PartialEq)]
8211#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8212pub struct FixedVar<CustomDataType = crate::NoCustomData> {
8213    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8214    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8215    pub custom_data: Option<CustomDataType>,
8216    /// Duration in seconds that this setting is active.
8217    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8218    pub duration: Option<f64>,
8219    /// Priority of setting (0=highest)
8220    pub priority: i64,
8221    /// The value specifies a target var output interpreted as a signed percentage (-100 to 100).
8222    ///     A negative value refers to charging, whereas a positive one refers to discharging.
8223    ///     The value type is determined by the unit field.
8224    pub setpoint: f64,
8225    /// Time when this setting becomes active.
8226    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
8227    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8228    pub start_time: Option<crate::OcppTimestamp>,
8229    pub unit: DERUnitEnum,
8230}
8231#[cfg(feature = "validate")]
8232impl<CustomDataType> crate::validate::Validate for FixedVar<CustomDataType> {
8233    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8234        crate::validate::check_min_i64(self.priority, 0i64)
8235            .map_err(|error| error.in_field("priority"))?;
8236        crate::validate::Validate::validate(&self.unit)
8237            .map_err(|error| error.in_field("unit"))?;
8238        Ok(())
8239    }
8240}
8241#[derive(Debug, Clone, PartialEq)]
8242#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8243pub struct FixedVarGet<CustomDataType = crate::NoCustomData> {
8244    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8245    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8246    pub custom_data: Option<CustomDataType>,
8247    #[cfg_attr(feature = "serde", serde(rename = "fixedVar"))]
8248    pub fixed_var: FixedVar<CustomDataType>,
8249    /// Id of setting
8250    pub id: heapless::String<36usize>,
8251    /// True if setting is a default control.
8252    #[cfg_attr(feature = "serde", serde(rename = "isDefault"))]
8253    pub is_default: bool,
8254    /// True if this setting is superseded by a lower priority setting
8255    #[cfg_attr(feature = "serde", serde(rename = "isSuperseded"))]
8256    pub is_superseded: bool,
8257}
8258#[cfg(feature = "validate")]
8259impl<CustomDataType> crate::validate::Validate for FixedVarGet<CustomDataType> {
8260    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8261        crate::validate::Validate::validate(&self.fixed_var)
8262            .map_err(|error| error.in_field("fixedVar"))?;
8263        Ok(())
8264    }
8265}
8266#[derive(Debug, Clone, PartialEq)]
8267#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8268pub struct FreqDroop<CustomDataType = crate::NoCustomData> {
8269    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8270    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8271    pub custom_data: Option<CustomDataType>,
8272    /// Duration in seconds that this setting is active
8273    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8274    pub duration: Option<f64>,
8275    /// Over-frequency droop per unit, oFDroop
8276    #[cfg_attr(feature = "serde", serde(rename = "overDroop"))]
8277    pub over_droop: f64,
8278    /// Over-frequency start of droop
8279    #[cfg_attr(feature = "serde", serde(rename = "overFreq"))]
8280    pub over_freq: f64,
8281    /// Priority of setting (0=highest)
8282    pub priority: i64,
8283    /// Open loop response time in seconds
8284    #[cfg_attr(feature = "serde", serde(rename = "responseTime"))]
8285    pub response_time: f64,
8286    /// Time when this setting becomes active
8287    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
8288    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8289    pub start_time: Option<crate::OcppTimestamp>,
8290    /// Under-frequency droop per unit, uFDroop
8291    #[cfg_attr(feature = "serde", serde(rename = "underDroop"))]
8292    pub under_droop: f64,
8293    /// Under-frequency start of droop
8294    #[cfg_attr(feature = "serde", serde(rename = "underFreq"))]
8295    pub under_freq: f64,
8296}
8297#[cfg(feature = "validate")]
8298impl<CustomDataType> crate::validate::Validate for FreqDroop<CustomDataType> {
8299    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8300        crate::validate::check_min_i64(self.priority, 0i64)
8301            .map_err(|error| error.in_field("priority"))?;
8302        Ok(())
8303    }
8304}
8305#[derive(Debug, Clone, PartialEq)]
8306#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8307pub struct FreqDroopGet<CustomDataType = crate::NoCustomData> {
8308    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8309    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8310    pub custom_data: Option<CustomDataType>,
8311    #[cfg_attr(feature = "serde", serde(rename = "freqDroop"))]
8312    pub freq_droop: FreqDroop<CustomDataType>,
8313    /// Id of setting
8314    pub id: heapless::String<36usize>,
8315    /// True if setting is a default control.
8316    #[cfg_attr(feature = "serde", serde(rename = "isDefault"))]
8317    pub is_default: bool,
8318    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
8319    #[cfg_attr(feature = "serde", serde(rename = "isSuperseded"))]
8320    pub is_superseded: bool,
8321}
8322#[cfg(feature = "validate")]
8323impl<CustomDataType> crate::validate::Validate for FreqDroopGet<CustomDataType> {
8324    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8325        crate::validate::Validate::validate(&self.freq_droop)
8326            .map_err(|error| error.in_field("freqDroop"))?;
8327        Ok(())
8328    }
8329}
8330#[derive(Debug, Clone, PartialEq)]
8331#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8332pub struct Gradient<CustomDataType = crate::NoCustomData> {
8333    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8334    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8335    pub custom_data: Option<CustomDataType>,
8336    /// Default ramp rate in seconds (0 if not applicable)
8337    pub gradient: f64,
8338    /// Id of setting
8339    pub priority: i64,
8340    /// Soft-start ramp rate in seconds (0 if not applicable)
8341    #[cfg_attr(feature = "serde", serde(rename = "softGradient"))]
8342    pub soft_gradient: f64,
8343}
8344#[cfg(feature = "validate")]
8345impl<CustomDataType> crate::validate::Validate for Gradient<CustomDataType> {
8346    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8347        crate::validate::check_min_i64(self.priority, 0i64)
8348            .map_err(|error| error.in_field("priority"))?;
8349        Ok(())
8350    }
8351}
8352#[derive(Debug, Clone, PartialEq)]
8353#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8354pub struct GradientGet<CustomDataType = crate::NoCustomData> {
8355    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8356    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8357    pub custom_data: Option<CustomDataType>,
8358    pub gradient: Gradient<CustomDataType>,
8359    /// Id of setting
8360    pub id: heapless::String<36usize>,
8361}
8362#[cfg(feature = "validate")]
8363impl<CustomDataType> crate::validate::Validate for GradientGet<CustomDataType> {
8364    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8365        crate::validate::Validate::validate(&self.gradient)
8366            .map_err(|error| error.in_field("gradient"))?;
8367        Ok(())
8368    }
8369}
8370#[derive(Debug, Clone, PartialEq)]
8371#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8372pub struct LimitMaxDischarge<CustomDataType = crate::NoCustomData> {
8373    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8374    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8375    pub custom_data: Option<CustomDataType>,
8376    /// Duration in seconds that this setting is active
8377    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8378    pub duration: Option<f64>,
8379    /// Only for PowerMonitoring. +
8380    ///     The value specifies a percentage (0 to 100) of the rated maximum discharge power of EV.
8381    ///     The PowerMonitoring curve becomes active when power exceeds this percentage.
8382    #[cfg_attr(feature = "serde", serde(rename = "pctMaxDischargePower"))]
8383    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8384    pub pct_max_discharge_power: Option<f64>,
8385    #[cfg_attr(feature = "serde", serde(rename = "powerMonitoringMustTrip"))]
8386    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8387    pub power_monitoring_must_trip: Option<DERCurve<CustomDataType>>,
8388    /// Priority of setting (0=highest)
8389    pub priority: i64,
8390    /// Time when this setting becomes active
8391    #[cfg_attr(feature = "serde", serde(rename = "startTime"))]
8392    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8393    pub start_time: Option<crate::OcppTimestamp>,
8394}
8395#[cfg(feature = "validate")]
8396impl<CustomDataType> crate::validate::Validate for LimitMaxDischarge<CustomDataType> {
8397    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8398        if let Some(value) = &self.power_monitoring_must_trip {
8399            crate::validate::Validate::validate(value)
8400                .map_err(|error| error.in_field("powerMonitoringMustTrip"))?;
8401        }
8402        crate::validate::check_min_i64(self.priority, 0i64)
8403            .map_err(|error| error.in_field("priority"))?;
8404        Ok(())
8405    }
8406}
8407#[derive(Debug, Clone, PartialEq)]
8408#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8409pub struct LimitMaxDischargeGet<CustomDataType = crate::NoCustomData> {
8410    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8411    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8412    pub custom_data: Option<CustomDataType>,
8413    /// Id of setting
8414    pub id: heapless::String<36usize>,
8415    /// True if setting is a default control.
8416    #[cfg_attr(feature = "serde", serde(rename = "isDefault"))]
8417    pub is_default: bool,
8418    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
8419    #[cfg_attr(feature = "serde", serde(rename = "isSuperseded"))]
8420    pub is_superseded: bool,
8421    #[cfg_attr(feature = "serde", serde(rename = "limitMaxDischarge"))]
8422    pub limit_max_discharge: LimitMaxDischarge<CustomDataType>,
8423}
8424#[cfg(feature = "validate")]
8425impl<CustomDataType> crate::validate::Validate for LimitMaxDischargeGet<CustomDataType> {
8426    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8427        crate::validate::Validate::validate(&self.limit_max_discharge)
8428            .map_err(|error| error.in_field("limitMaxDischarge"))?;
8429        Ok(())
8430    }
8431}
8432/// Status indicating whether the Charging Station accepts the request to start a transaction.
8433#[derive(Debug, Clone, PartialEq, Eq)]
8434#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8435pub enum RequestStartStopStatusEnum {
8436    Accepted,
8437    Rejected,
8438}
8439#[cfg(feature = "validate")]
8440impl crate::validate::Validate for RequestStartStopStatusEnum {
8441    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8442        Ok(())
8443    }
8444}
8445/// The updated reservation status.
8446#[derive(Debug, Clone, PartialEq, Eq)]
8447#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8448pub enum ReservationUpdateStatusEnum {
8449    Expired,
8450    Removed,
8451    NoTransaction,
8452}
8453#[cfg(feature = "validate")]
8454impl crate::validate::Validate for ReservationUpdateStatusEnum {
8455    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8456        Ok(())
8457    }
8458}
8459/// This indicates the success or failure of the reservation.
8460#[derive(Debug, Clone, PartialEq, Eq)]
8461#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8462pub enum ReserveNowStatusEnum {
8463    Accepted,
8464    Faulted,
8465    Occupied,
8466    Rejected,
8467    Unavailable,
8468}
8469#[cfg(feature = "validate")]
8470impl crate::validate::Validate for ReserveNowStatusEnum {
8471    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8472        Ok(())
8473    }
8474}
8475/// This contains the type of reset that the Charging Station or EVSE should perform.
8476#[derive(Debug, Clone, PartialEq, Eq)]
8477#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8478pub enum ResetEnum {
8479    Immediate,
8480    OnIdle,
8481    ImmediateAndResume,
8482}
8483#[cfg(feature = "validate")]
8484impl crate::validate::Validate for ResetEnum {
8485    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8486        Ok(())
8487    }
8488}
8489/// This indicates whether the Charging Station is able to perform the reset.
8490#[derive(Debug, Clone, PartialEq, Eq)]
8491#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8492pub enum ResetStatusEnum {
8493    Accepted,
8494    Rejected,
8495    Scheduled,
8496}
8497#[cfg(feature = "validate")]
8498impl crate::validate::Validate for ResetStatusEnum {
8499    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8500        Ok(())
8501    }
8502}
8503#[cfg(feature = "alloc")]
8504/// Contains the identifier to use for authorization.
8505#[derive(Debug, Clone, PartialEq, Eq)]
8506#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8507pub struct AuthorizationData<CustomDataType = crate::NoCustomData> {
8508    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8509    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8510    pub custom_data: Option<CustomDataType>,
8511    #[cfg_attr(feature = "serde", serde(rename = "idToken"))]
8512    pub id_token: IdToken<CustomDataType>,
8513    #[cfg_attr(feature = "serde", serde(rename = "idTokenInfo"))]
8514    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8515    pub id_token_info: Option<IdTokenInfo<CustomDataType>>,
8516}
8517#[cfg(all(feature = "validate", feature = "alloc"))]
8518impl<CustomDataType> crate::validate::Validate for AuthorizationData<CustomDataType> {
8519    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8520        crate::validate::Validate::validate(&self.id_token)
8521            .map_err(|error| error.in_field("idToken"))?;
8522        if let Some(value) = &self.id_token_info {
8523            crate::validate::Validate::validate(value)
8524                .map_err(|error| error.in_field("idTokenInfo"))?;
8525        }
8526        Ok(())
8527    }
8528}
8529#[cfg(not(feature = "alloc"))]
8530/// Contains the identifier to use for authorization.
8531#[derive(Debug, Clone, PartialEq, Eq)]
8532#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8533pub struct AuthorizationData<
8534    CustomDataType = crate::NoCustomData,
8535    const ID_TOKEN_ADDITIONAL_INFO_CAP: usize = 8usize,
8536    const ID_TOKEN_INFO_EVSE_ID_CAP: usize = 8usize,
8537    const MESSAGE_CONTENT_CONTENT_CAP: usize = 1024usize,
8538> {
8539    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8540    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8541    pub custom_data: Option<CustomDataType>,
8542    #[cfg_attr(feature = "serde", serde(rename = "idToken"))]
8543    pub id_token: IdToken<CustomDataType, ID_TOKEN_ADDITIONAL_INFO_CAP>,
8544    #[cfg_attr(feature = "serde", serde(rename = "idTokenInfo"))]
8545    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8546    pub id_token_info: Option<
8547        IdTokenInfo<
8548            CustomDataType,
8549            ID_TOKEN_INFO_EVSE_ID_CAP,
8550            ID_TOKEN_ADDITIONAL_INFO_CAP,
8551            MESSAGE_CONTENT_CONTENT_CAP,
8552        >,
8553    >,
8554}
8555#[cfg(all(feature = "validate", not(feature = "alloc")))]
8556impl<
8557    CustomDataType,
8558    const ID_TOKEN_ADDITIONAL_INFO_CAP: usize,
8559    const ID_TOKEN_INFO_EVSE_ID_CAP: usize,
8560    const MESSAGE_CONTENT_CONTENT_CAP: usize,
8561> crate::validate::Validate
8562for AuthorizationData<
8563    CustomDataType,
8564    ID_TOKEN_ADDITIONAL_INFO_CAP,
8565    ID_TOKEN_INFO_EVSE_ID_CAP,
8566    MESSAGE_CONTENT_CONTENT_CAP,
8567> {
8568    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8569        crate::validate::Validate::validate(&self.id_token)
8570            .map_err(|error| error.in_field("idToken"))?;
8571        if let Some(value) = &self.id_token_info {
8572            crate::validate::Validate::validate(value)
8573                .map_err(|error| error.in_field("idTokenInfo"))?;
8574        }
8575        Ok(())
8576    }
8577}
8578/// This contains the type of update (full or differential) of this request.
8579#[derive(Debug, Clone, PartialEq, Eq)]
8580#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8581pub enum UpdateEnum {
8582    Differential,
8583    Full,
8584}
8585#[cfg(feature = "validate")]
8586impl crate::validate::Validate for UpdateEnum {
8587    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8588        Ok(())
8589    }
8590}
8591/// This indicates whether the Charging Station has successfully received and applied the update of the Local Authorization List.
8592#[derive(Debug, Clone, PartialEq, Eq)]
8593#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8594pub enum SendLocalListStatusEnum {
8595    Accepted,
8596    Failed,
8597    VersionMismatch,
8598}
8599#[cfg(feature = "validate")]
8600impl crate::validate::Validate for SendLocalListStatusEnum {
8601    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8602        Ok(())
8603    }
8604}
8605#[derive(Debug, Clone, PartialEq, Eq)]
8606#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8607pub enum TariffSetStatusEnum {
8608    Accepted,
8609    Rejected,
8610    TooManyElements,
8611    ConditionNotSupported,
8612    DuplicateTariffId,
8613}
8614#[cfg(feature = "validate")]
8615impl crate::validate::Validate for TariffSetStatusEnum {
8616    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8617        Ok(())
8618    }
8619}
8620/// This indicates whether the Charging Station is able to display the message.
8621#[derive(Debug, Clone, PartialEq, Eq)]
8622#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8623pub enum DisplayMessageStatusEnum {
8624    Accepted,
8625    NotSupportedMessageFormat,
8626    Rejected,
8627    NotSupportedPriority,
8628    NotSupportedState,
8629    UnknownTransaction,
8630    LanguageNotSupported,
8631}
8632#[cfg(feature = "validate")]
8633impl crate::validate::Validate for DisplayMessageStatusEnum {
8634    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8635        Ok(())
8636    }
8637}
8638/// Specify which monitoring base will be set
8639#[derive(Debug, Clone, PartialEq, Eq)]
8640#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8641pub enum MonitoringBaseEnum {
8642    All,
8643    FactoryDefault,
8644    HardWiredOnly,
8645}
8646#[cfg(feature = "validate")]
8647impl crate::validate::Validate for MonitoringBaseEnum {
8648    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8649        Ok(())
8650    }
8651}
8652/// Authentication method.
8653#[derive(Debug, Clone, PartialEq, Eq)]
8654#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8655pub enum APNAuthenticationEnum {
8656    PAP,
8657    CHAP,
8658    NONE,
8659    AUTO,
8660}
8661#[cfg(feature = "validate")]
8662impl crate::validate::Validate for APNAuthenticationEnum {
8663    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8664        Ok(())
8665    }
8666}
8667#[cfg(feature = "alloc")]
8668/// Collection of configuration data needed to make a data-connection over a cellular network.
8669///
8670/// NOTE: When asking a GSM modem to dial in, it is possible to specify which mobile operator should be used. This can be done with the mobile country code (MCC) in combination with a mobile network code (MNC). Example: If your preferred network is Vodafone Netherlands, the MCC=204 and the MNC=04 which means the key PreferredNetwork = 20404 Some modems allows to specify a preferred network, which means, if this network is not available, a different network is used. If you specify UseOnlyPreferredNetwork and this network is not available, the modem will not dial in.
8671#[derive(Debug, Clone, PartialEq, Eq)]
8672#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8673pub struct APN<CustomDataType = crate::NoCustomData> {
8674    /// The Access Point Name as an URL.
8675    pub apn: alloc::string::String,
8676    #[cfg_attr(feature = "serde", serde(rename = "apnAuthentication"))]
8677    pub apn_authentication: APNAuthenticationEnum,
8678    /// *(2.1)* APN Password.
8679    #[cfg_attr(feature = "serde", serde(rename = "apnPassword"))]
8680    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8681    pub apn_password: Option<heapless::String<64usize>>,
8682    /// APN username.
8683    #[cfg_attr(feature = "serde", serde(rename = "apnUserName"))]
8684    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8685    pub apn_user_name: Option<heapless::String<50usize>>,
8686    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8687    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8688    pub custom_data: Option<CustomDataType>,
8689    /// Preferred network, written as MCC and MNC concatenated. See note.
8690    #[cfg_attr(feature = "serde", serde(rename = "preferredNetwork"))]
8691    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8692    pub preferred_network: Option<heapless::String<6usize>>,
8693    /// SIM card pin code.
8694    #[cfg_attr(feature = "serde", serde(rename = "simPin"))]
8695    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8696    pub sim_pin: Option<i64>,
8697    /// Default: false. Use only the preferred Network, do
8698    /// not dial in when not available. See Note.
8699    #[cfg_attr(feature = "serde", serde(rename = "useOnlyPreferredNetwork"))]
8700    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8701    pub use_only_preferred_network: Option<bool>,
8702}
8703#[cfg(all(feature = "validate", feature = "alloc"))]
8704impl<CustomDataType> crate::validate::Validate for APN<CustomDataType> {
8705    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8706        crate::validate::check_max_length(&self.apn, 2000usize)
8707            .map_err(|error| error.in_field("apn"))?;
8708        crate::validate::Validate::validate(&self.apn_authentication)
8709            .map_err(|error| error.in_field("apnAuthentication"))?;
8710        Ok(())
8711    }
8712}
8713#[cfg(not(feature = "alloc"))]
8714/// Collection of configuration data needed to make a data-connection over a cellular network.
8715///
8716/// NOTE: When asking a GSM modem to dial in, it is possible to specify which mobile operator should be used. This can be done with the mobile country code (MCC) in combination with a mobile network code (MNC). Example: If your preferred network is Vodafone Netherlands, the MCC=204 and the MNC=04 which means the key PreferredNetwork = 20404 Some modems allows to specify a preferred network, which means, if this network is not available, a different network is used. If you specify UseOnlyPreferredNetwork and this network is not available, the modem will not dial in.
8717#[derive(Debug, Clone, PartialEq, Eq)]
8718#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8719pub struct APN<
8720    CustomDataType = crate::NoCustomData,
8721    const A_P_N_APN_CAP: usize = 1024usize,
8722> {
8723    /// The Access Point Name as an URL.
8724    pub apn: heapless::String<A_P_N_APN_CAP>,
8725    #[cfg_attr(feature = "serde", serde(rename = "apnAuthentication"))]
8726    pub apn_authentication: APNAuthenticationEnum,
8727    /// *(2.1)* APN Password.
8728    #[cfg_attr(feature = "serde", serde(rename = "apnPassword"))]
8729    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8730    pub apn_password: Option<heapless::String<64usize>>,
8731    /// APN username.
8732    #[cfg_attr(feature = "serde", serde(rename = "apnUserName"))]
8733    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8734    pub apn_user_name: Option<heapless::String<50usize>>,
8735    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8736    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8737    pub custom_data: Option<CustomDataType>,
8738    /// Preferred network, written as MCC and MNC concatenated. See note.
8739    #[cfg_attr(feature = "serde", serde(rename = "preferredNetwork"))]
8740    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8741    pub preferred_network: Option<heapless::String<6usize>>,
8742    /// SIM card pin code.
8743    #[cfg_attr(feature = "serde", serde(rename = "simPin"))]
8744    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8745    pub sim_pin: Option<i64>,
8746    /// Default: false. Use only the preferred Network, do
8747    /// not dial in when not available. See Note.
8748    #[cfg_attr(feature = "serde", serde(rename = "useOnlyPreferredNetwork"))]
8749    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8750    pub use_only_preferred_network: Option<bool>,
8751}
8752#[cfg(all(feature = "validate", not(feature = "alloc")))]
8753impl<CustomDataType, const A_P_N_APN_CAP: usize> crate::validate::Validate
8754for APN<CustomDataType, A_P_N_APN_CAP> {
8755    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8756        crate::validate::check_max_length(&self.apn, 2000usize)
8757            .map_err(|error| error.in_field("apn"))?;
8758        crate::validate::Validate::validate(&self.apn_authentication)
8759            .map_err(|error| error.in_field("apnAuthentication"))?;
8760        Ok(())
8761    }
8762}
8763/// Applicable Network Interface. Charging Station is allowed to use a different network interface to connect if the given one does not work.
8764#[derive(Debug, Clone, PartialEq, Eq)]
8765#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8766pub enum OCPPInterfaceEnum {
8767    Wired0,
8768    Wired1,
8769    Wired2,
8770    Wired3,
8771    Wireless0,
8772    Wireless1,
8773    Wireless2,
8774    Wireless3,
8775    Any,
8776}
8777#[cfg(feature = "validate")]
8778impl crate::validate::Validate for OCPPInterfaceEnum {
8779    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8780        Ok(())
8781    }
8782}
8783/// Defines the transport protocol (e.g. SOAP or JSON). Note: SOAP is not supported in OCPP 2.x, but is supported by earlier versions of OCPP.
8784#[derive(Debug, Clone, PartialEq, Eq)]
8785#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8786pub enum OCPPTransportEnum {
8787    SOAP,
8788    JSON,
8789}
8790#[cfg(feature = "validate")]
8791impl crate::validate::Validate for OCPPTransportEnum {
8792    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8793        Ok(())
8794    }
8795}
8796/// *(2.1)* This field is ignored, since the OCPP version to use is determined during the websocket handshake. The field is only kept for backwards compatibility with the OCPP 2.0.1 JSON schema.
8797#[derive(Debug, Clone, PartialEq, Eq)]
8798#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8799pub enum OCPPVersionEnum {
8800    OCPP12,
8801    OCPP15,
8802    OCPP16,
8803    OCPP20,
8804    OCPP201,
8805    OCPP21,
8806}
8807#[cfg(feature = "validate")]
8808impl crate::validate::Validate for OCPPVersionEnum {
8809    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8810        Ok(())
8811    }
8812}
8813/// Type of VPN
8814#[derive(Debug, Clone, PartialEq, Eq)]
8815#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8816pub enum VPNEnum {
8817    IKEv2,
8818    IPSec,
8819    L2TP,
8820    PPTP,
8821}
8822#[cfg(feature = "validate")]
8823impl crate::validate::Validate for VPNEnum {
8824    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8825        Ok(())
8826    }
8827}
8828#[cfg(feature = "alloc")]
8829/// VPN Configuration settings
8830#[derive(Debug, Clone, PartialEq, Eq)]
8831#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8832pub struct VPN<CustomDataType = crate::NoCustomData> {
8833    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8834    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8835    pub custom_data: Option<CustomDataType>,
8836    /// VPN group.
8837    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8838    pub group: Option<heapless::String<50usize>>,
8839    /// VPN shared secret.
8840    pub key: heapless::String<255usize>,
8841    /// *(2.1)* VPN Password.
8842    pub password: heapless::String<64usize>,
8843    /// VPN Server Address
8844    pub server: alloc::string::String,
8845    pub r#type: VPNEnum,
8846    /// VPN User
8847    pub user: heapless::String<50usize>,
8848}
8849#[cfg(all(feature = "validate", feature = "alloc"))]
8850impl<CustomDataType> crate::validate::Validate for VPN<CustomDataType> {
8851    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8852        crate::validate::check_max_length(&self.server, 2000usize)
8853            .map_err(|error| error.in_field("server"))?;
8854        crate::validate::Validate::validate(&self.r#type)
8855            .map_err(|error| error.in_field("type"))?;
8856        Ok(())
8857    }
8858}
8859#[cfg(not(feature = "alloc"))]
8860/// VPN Configuration settings
8861#[derive(Debug, Clone, PartialEq, Eq)]
8862#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8863pub struct VPN<
8864    CustomDataType = crate::NoCustomData,
8865    const V_P_N_SERVER_CAP: usize = 1024usize,
8866> {
8867    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8868    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8869    pub custom_data: Option<CustomDataType>,
8870    /// VPN group.
8871    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8872    pub group: Option<heapless::String<50usize>>,
8873    /// VPN shared secret.
8874    pub key: heapless::String<255usize>,
8875    /// *(2.1)* VPN Password.
8876    pub password: heapless::String<64usize>,
8877    /// VPN Server Address
8878    pub server: heapless::String<V_P_N_SERVER_CAP>,
8879    pub r#type: VPNEnum,
8880    /// VPN User
8881    pub user: heapless::String<50usize>,
8882}
8883#[cfg(all(feature = "validate", not(feature = "alloc")))]
8884impl<CustomDataType, const V_P_N_SERVER_CAP: usize> crate::validate::Validate
8885for VPN<CustomDataType, V_P_N_SERVER_CAP> {
8886    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8887        crate::validate::check_max_length(&self.server, 2000usize)
8888            .map_err(|error| error.in_field("server"))?;
8889        crate::validate::Validate::validate(&self.r#type)
8890            .map_err(|error| error.in_field("type"))?;
8891        Ok(())
8892    }
8893}
8894#[cfg(feature = "alloc")]
8895/// The NetworkConnectionProfile defines the functional and technical parameters of a communication link.
8896#[derive(Debug, Clone, PartialEq, Eq)]
8897#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8898pub struct NetworkConnectionProfile<CustomDataType = crate::NoCustomData> {
8899    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8900    pub apn: Option<APN<CustomDataType>>,
8901    /// *(2.1)* BasicAuthPassword to use for security profile 1 or 2.
8902    #[cfg_attr(feature = "serde", serde(rename = "basicAuthPassword"))]
8903    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8904    pub basic_auth_password: Option<heapless::String<64usize>>,
8905    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8906    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8907    pub custom_data: Option<CustomDataType>,
8908    /// *(2.1)* Charging Station identity to be used as the basic authentication username.
8909    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8910    pub identity: Option<heapless::String<48usize>>,
8911    /// Duration in seconds before a message send by the Charging Station via this network connection times-out.
8912    /// The best setting depends on the underlying network and response times of the CSMS.
8913    /// If you are looking for a some guideline: use 30 seconds as a starting point.
8914    #[cfg_attr(feature = "serde", serde(rename = "messageTimeout"))]
8915    pub message_timeout: i64,
8916    /// URL of the CSMS(s) that this Charging Station communicates with, without the Charging Station identity part. +
8917    /// The SecurityCtrlr.Identity field is appended to _ocppCsmsUrl_ to provide the full websocket URL.
8918    #[cfg_attr(feature = "serde", serde(rename = "ocppCsmsUrl"))]
8919    pub ocpp_csms_url: alloc::string::String,
8920    #[cfg_attr(feature = "serde", serde(rename = "ocppInterface"))]
8921    pub ocpp_interface: OCPPInterfaceEnum,
8922    #[cfg_attr(feature = "serde", serde(rename = "ocppTransport"))]
8923    pub ocpp_transport: OCPPTransportEnum,
8924    #[cfg_attr(feature = "serde", serde(rename = "ocppVersion"))]
8925    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8926    pub ocpp_version: Option<OCPPVersionEnum>,
8927    /// This field specifies the security profile used when connecting to the CSMS with this NetworkConnectionProfile.
8928    #[cfg_attr(feature = "serde", serde(rename = "securityProfile"))]
8929    pub security_profile: i64,
8930    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8931    pub vpn: Option<VPN<CustomDataType>>,
8932}
8933#[cfg(all(feature = "validate", feature = "alloc"))]
8934impl<CustomDataType> crate::validate::Validate
8935for NetworkConnectionProfile<CustomDataType> {
8936    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
8937        if let Some(value) = &self.apn {
8938            crate::validate::Validate::validate(value)
8939                .map_err(|error| error.in_field("apn"))?;
8940        }
8941        crate::validate::check_max_length(&self.ocpp_csms_url, 2000usize)
8942            .map_err(|error| error.in_field("ocppCsmsUrl"))?;
8943        crate::validate::Validate::validate(&self.ocpp_interface)
8944            .map_err(|error| error.in_field("ocppInterface"))?;
8945        crate::validate::Validate::validate(&self.ocpp_transport)
8946            .map_err(|error| error.in_field("ocppTransport"))?;
8947        if let Some(value) = &self.ocpp_version {
8948            crate::validate::Validate::validate(value)
8949                .map_err(|error| error.in_field("ocppVersion"))?;
8950        }
8951        crate::validate::check_min_i64(self.security_profile, 0i64)
8952            .map_err(|error| error.in_field("securityProfile"))?;
8953        if let Some(value) = &self.vpn {
8954            crate::validate::Validate::validate(value)
8955                .map_err(|error| error.in_field("vpn"))?;
8956        }
8957        Ok(())
8958    }
8959}
8960#[cfg(not(feature = "alloc"))]
8961/// The NetworkConnectionProfile defines the functional and technical parameters of a communication link.
8962#[derive(Debug, Clone, PartialEq, Eq)]
8963#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
8964pub struct NetworkConnectionProfile<
8965    CustomDataType = crate::NoCustomData,
8966    const A_P_N_APN_CAP: usize = 1024usize,
8967    const NETWORK_CONNECTION_PROFILE_OCPP_CSMS_URL_CAP: usize = 1024usize,
8968    const V_P_N_SERVER_CAP: usize = 1024usize,
8969> {
8970    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8971    pub apn: Option<APN<CustomDataType, A_P_N_APN_CAP>>,
8972    /// *(2.1)* BasicAuthPassword to use for security profile 1 or 2.
8973    #[cfg_attr(feature = "serde", serde(rename = "basicAuthPassword"))]
8974    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8975    pub basic_auth_password: Option<heapless::String<64usize>>,
8976    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
8977    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8978    pub custom_data: Option<CustomDataType>,
8979    /// *(2.1)* Charging Station identity to be used as the basic authentication username.
8980    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8981    pub identity: Option<heapless::String<48usize>>,
8982    /// Duration in seconds before a message send by the Charging Station via this network connection times-out.
8983    /// The best setting depends on the underlying network and response times of the CSMS.
8984    /// If you are looking for a some guideline: use 30 seconds as a starting point.
8985    #[cfg_attr(feature = "serde", serde(rename = "messageTimeout"))]
8986    pub message_timeout: i64,
8987    /// URL of the CSMS(s) that this Charging Station communicates with, without the Charging Station identity part. +
8988    /// The SecurityCtrlr.Identity field is appended to _ocppCsmsUrl_ to provide the full websocket URL.
8989    #[cfg_attr(feature = "serde", serde(rename = "ocppCsmsUrl"))]
8990    pub ocpp_csms_url: heapless::String<NETWORK_CONNECTION_PROFILE_OCPP_CSMS_URL_CAP>,
8991    #[cfg_attr(feature = "serde", serde(rename = "ocppInterface"))]
8992    pub ocpp_interface: OCPPInterfaceEnum,
8993    #[cfg_attr(feature = "serde", serde(rename = "ocppTransport"))]
8994    pub ocpp_transport: OCPPTransportEnum,
8995    #[cfg_attr(feature = "serde", serde(rename = "ocppVersion"))]
8996    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
8997    pub ocpp_version: Option<OCPPVersionEnum>,
8998    /// This field specifies the security profile used when connecting to the CSMS with this NetworkConnectionProfile.
8999    #[cfg_attr(feature = "serde", serde(rename = "securityProfile"))]
9000    pub security_profile: i64,
9001    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9002    pub vpn: Option<VPN<CustomDataType, V_P_N_SERVER_CAP>>,
9003}
9004#[cfg(all(feature = "validate", not(feature = "alloc")))]
9005impl<
9006    CustomDataType,
9007    const A_P_N_APN_CAP: usize,
9008    const NETWORK_CONNECTION_PROFILE_OCPP_CSMS_URL_CAP: usize,
9009    const V_P_N_SERVER_CAP: usize,
9010> crate::validate::Validate
9011for NetworkConnectionProfile<
9012    CustomDataType,
9013    A_P_N_APN_CAP,
9014    NETWORK_CONNECTION_PROFILE_OCPP_CSMS_URL_CAP,
9015    V_P_N_SERVER_CAP,
9016> {
9017    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9018        if let Some(value) = &self.apn {
9019            crate::validate::Validate::validate(value)
9020                .map_err(|error| error.in_field("apn"))?;
9021        }
9022        crate::validate::check_max_length(&self.ocpp_csms_url, 2000usize)
9023            .map_err(|error| error.in_field("ocppCsmsUrl"))?;
9024        crate::validate::Validate::validate(&self.ocpp_interface)
9025            .map_err(|error| error.in_field("ocppInterface"))?;
9026        crate::validate::Validate::validate(&self.ocpp_transport)
9027            .map_err(|error| error.in_field("ocppTransport"))?;
9028        if let Some(value) = &self.ocpp_version {
9029            crate::validate::Validate::validate(value)
9030                .map_err(|error| error.in_field("ocppVersion"))?;
9031        }
9032        crate::validate::check_min_i64(self.security_profile, 0i64)
9033            .map_err(|error| error.in_field("securityProfile"))?;
9034        if let Some(value) = &self.vpn {
9035            crate::validate::Validate::validate(value)
9036                .map_err(|error| error.in_field("vpn"))?;
9037        }
9038        Ok(())
9039    }
9040}
9041/// Result of operation.
9042#[derive(Debug, Clone, PartialEq, Eq)]
9043#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9044pub enum SetNetworkProfileStatusEnum {
9045    Accepted,
9046    Rejected,
9047    Failed,
9048}
9049#[cfg(feature = "validate")]
9050impl crate::validate::Validate for SetNetworkProfileStatusEnum {
9051    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9052        Ok(())
9053    }
9054}
9055/// Class to hold parameters of SetVariableMonitoring request.
9056#[derive(Debug, Clone, PartialEq)]
9057#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9058pub struct SetMonitoringData<CustomDataType = crate::NoCustomData> {
9059    pub component: Component<CustomDataType>,
9060    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9061    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9062    pub custom_data: Option<CustomDataType>,
9063    /// An id SHALL only be given to replace an existing monitor. The Charging Station handles the generation of id's for new monitors.
9064    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9065    pub id: Option<i64>,
9066    #[cfg_attr(feature = "serde", serde(rename = "periodicEventStream"))]
9067    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9068    pub periodic_event_stream: Option<PeriodicEventStreamParams<CustomDataType>>,
9069    /// The severity that will be assigned to an event that is triggered by this monitor. The severity range is 0-9, with 0 as the highest and 9 as the lowest severity level.
9070    ///
9071    /// The severity levels have the following meaning: +
9072    /// *0-Danger* +
9073    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
9074    /// *1-Hardware Failure* +
9075    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
9076    /// *2-System Failure* +
9077    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
9078    /// *3-Critical* +
9079    /// Indicates a critical error. Action is required. +
9080    /// *4-Error* +
9081    /// Indicates a non-urgent error. Action is required. +
9082    /// *5-Alert* +
9083    /// Indicates an alert event. Default severity for any type of monitoring event.  +
9084    /// *6-Warning* +
9085    /// Indicates a warning event. Action may be required. +
9086    /// *7-Notice* +
9087    /// Indicates an unusual event. No immediate action is required. +
9088    /// *8-Informational* +
9089    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
9090    /// *9-Debug* +
9091    /// Indicates information useful to developers for debugging, not useful during operations.
9092    pub severity: i64,
9093    /// Monitor only active when a transaction is ongoing on a component relevant to this transaction. Default = false.
9094    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9095    pub transaction: Option<bool>,
9096    pub r#type: MonitorEnum,
9097    /// Value for threshold or delta monitoring.
9098    /// For Periodic or PeriodicClockAligned this is the interval in seconds.
9099    pub value: f64,
9100    pub variable: Variable<CustomDataType>,
9101}
9102#[cfg(feature = "validate")]
9103impl<CustomDataType> crate::validate::Validate for SetMonitoringData<CustomDataType> {
9104    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9105        crate::validate::Validate::validate(&self.component)
9106            .map_err(|error| error.in_field("component"))?;
9107        if let Some(value) = self.id {
9108            crate::validate::check_min_i64(value, 0i64)
9109                .map_err(|error| error.in_field("id"))?;
9110        }
9111        if let Some(value) = &self.periodic_event_stream {
9112            crate::validate::Validate::validate(value)
9113                .map_err(|error| error.in_field("periodicEventStream"))?;
9114        }
9115        crate::validate::check_min_i64(self.severity, 0i64)
9116            .map_err(|error| error.in_field("severity"))?;
9117        crate::validate::Validate::validate(&self.r#type)
9118            .map_err(|error| error.in_field("type"))?;
9119        crate::validate::Validate::validate(&self.variable)
9120            .map_err(|error| error.in_field("variable"))?;
9121        Ok(())
9122    }
9123}
9124/// Status is OK if a value could be returned. Otherwise this will indicate the reason why a value could not be returned.
9125#[derive(Debug, Clone, PartialEq, Eq)]
9126#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9127pub enum SetMonitoringStatusEnum {
9128    Accepted,
9129    UnknownComponent,
9130    UnknownVariable,
9131    UnsupportedMonitorType,
9132    Rejected,
9133    Duplicate,
9134}
9135#[cfg(feature = "validate")]
9136impl crate::validate::Validate for SetMonitoringStatusEnum {
9137    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9138        Ok(())
9139    }
9140}
9141#[cfg(feature = "alloc")]
9142/// Class to hold result of SetVariableMonitoring request.
9143#[derive(Debug, Clone, PartialEq, Eq)]
9144#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9145pub struct SetMonitoringResult<CustomDataType = crate::NoCustomData> {
9146    pub component: Component<CustomDataType>,
9147    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9148    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9149    pub custom_data: Option<CustomDataType>,
9150    /// Id given to the VariableMonitor by the Charging Station. The Id is only returned when status is accepted. Installed VariableMonitors should have unique id's but the id's of removed Installed monitors should have unique id's but the id's of removed monitors MAY be reused.
9151    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9152    pub id: Option<i64>,
9153    /// The severity that will be assigned to an event that is triggered by this monitor. The severity range is 0-9, with 0 as the highest and 9 as the lowest severity level.
9154    ///
9155    /// The severity levels have the following meaning: +
9156    /// *0-Danger* +
9157    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
9158    /// *1-Hardware Failure* +
9159    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
9160    /// *2-System Failure* +
9161    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
9162    /// *3-Critical* +
9163    /// Indicates a critical error. Action is required. +
9164    /// *4-Error* +
9165    /// Indicates a non-urgent error. Action is required. +
9166    /// *5-Alert* +
9167    /// Indicates an alert event. Default severity for any type of monitoring event.  +
9168    /// *6-Warning* +
9169    /// Indicates a warning event. Action may be required. +
9170    /// *7-Notice* +
9171    /// Indicates an unusual event. No immediate action is required. +
9172    /// *8-Informational* +
9173    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
9174    /// *9-Debug* +
9175    /// Indicates information useful to developers for debugging, not useful during operations.
9176    pub severity: i64,
9177    pub status: SetMonitoringStatusEnum,
9178    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
9179    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9180    pub status_info: Option<StatusInfo<CustomDataType>>,
9181    pub r#type: MonitorEnum,
9182    pub variable: Variable<CustomDataType>,
9183}
9184#[cfg(all(feature = "validate", feature = "alloc"))]
9185impl<CustomDataType> crate::validate::Validate for SetMonitoringResult<CustomDataType> {
9186    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9187        crate::validate::Validate::validate(&self.component)
9188            .map_err(|error| error.in_field("component"))?;
9189        if let Some(value) = self.id {
9190            crate::validate::check_min_i64(value, 0i64)
9191                .map_err(|error| error.in_field("id"))?;
9192        }
9193        crate::validate::check_min_i64(self.severity, 0i64)
9194            .map_err(|error| error.in_field("severity"))?;
9195        crate::validate::Validate::validate(&self.status)
9196            .map_err(|error| error.in_field("status"))?;
9197        if let Some(value) = &self.status_info {
9198            crate::validate::Validate::validate(value)
9199                .map_err(|error| error.in_field("statusInfo"))?;
9200        }
9201        crate::validate::Validate::validate(&self.r#type)
9202            .map_err(|error| error.in_field("type"))?;
9203        crate::validate::Validate::validate(&self.variable)
9204            .map_err(|error| error.in_field("variable"))?;
9205        Ok(())
9206    }
9207}
9208#[cfg(not(feature = "alloc"))]
9209/// Class to hold result of SetVariableMonitoring request.
9210#[derive(Debug, Clone, PartialEq, Eq)]
9211#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9212pub struct SetMonitoringResult<
9213    CustomDataType = crate::NoCustomData,
9214    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
9215> {
9216    pub component: Component<CustomDataType>,
9217    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9218    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9219    pub custom_data: Option<CustomDataType>,
9220    /// Id given to the VariableMonitor by the Charging Station. The Id is only returned when status is accepted. Installed VariableMonitors should have unique id's but the id's of removed Installed monitors should have unique id's but the id's of removed monitors MAY be reused.
9221    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9222    pub id: Option<i64>,
9223    /// The severity that will be assigned to an event that is triggered by this monitor. The severity range is 0-9, with 0 as the highest and 9 as the lowest severity level.
9224    ///
9225    /// The severity levels have the following meaning: +
9226    /// *0-Danger* +
9227    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
9228    /// *1-Hardware Failure* +
9229    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
9230    /// *2-System Failure* +
9231    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
9232    /// *3-Critical* +
9233    /// Indicates a critical error. Action is required. +
9234    /// *4-Error* +
9235    /// Indicates a non-urgent error. Action is required. +
9236    /// *5-Alert* +
9237    /// Indicates an alert event. Default severity for any type of monitoring event.  +
9238    /// *6-Warning* +
9239    /// Indicates a warning event. Action may be required. +
9240    /// *7-Notice* +
9241    /// Indicates an unusual event. No immediate action is required. +
9242    /// *8-Informational* +
9243    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
9244    /// *9-Debug* +
9245    /// Indicates information useful to developers for debugging, not useful during operations.
9246    pub severity: i64,
9247    pub status: SetMonitoringStatusEnum,
9248    #[cfg_attr(feature = "serde", serde(rename = "statusInfo"))]
9249    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9250    pub status_info: Option<StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP>>,
9251    pub r#type: MonitorEnum,
9252    pub variable: Variable<CustomDataType>,
9253}
9254#[cfg(all(feature = "validate", not(feature = "alloc")))]
9255impl<
9256    CustomDataType,
9257    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
9258> crate::validate::Validate
9259for SetMonitoringResult<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP> {
9260    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9261        crate::validate::Validate::validate(&self.component)
9262            .map_err(|error| error.in_field("component"))?;
9263        if let Some(value) = self.id {
9264            crate::validate::check_min_i64(value, 0i64)
9265                .map_err(|error| error.in_field("id"))?;
9266        }
9267        crate::validate::check_min_i64(self.severity, 0i64)
9268            .map_err(|error| error.in_field("severity"))?;
9269        crate::validate::Validate::validate(&self.status)
9270            .map_err(|error| error.in_field("status"))?;
9271        if let Some(value) = &self.status_info {
9272            crate::validate::Validate::validate(value)
9273                .map_err(|error| error.in_field("statusInfo"))?;
9274        }
9275        crate::validate::Validate::validate(&self.r#type)
9276            .map_err(|error| error.in_field("type"))?;
9277        crate::validate::Validate::validate(&self.variable)
9278            .map_err(|error| error.in_field("variable"))?;
9279        Ok(())
9280    }
9281}
9282#[cfg(feature = "alloc")]
9283#[derive(Debug, Clone, PartialEq, Eq)]
9284#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9285pub struct SetVariableData<CustomDataType = crate::NoCustomData> {
9286    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
9287    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9288    pub attribute_type: Option<AttributeEnum>,
9289    /// Value to be assigned to attribute of variable.
9290    /// This value is allowed to be an empty string ("").
9291    ///
9292    /// The Configuration Variable &lt;&lt;configkey-configuration-value-size,ConfigurationValueSize&gt;&gt; can be used to limit SetVariableData.attributeValue and VariableCharacteristics.valuesList. The max size of these values will always remain equal.
9293    #[cfg_attr(feature = "serde", serde(rename = "attributeValue"))]
9294    pub attribute_value: alloc::string::String,
9295    pub component: Component<CustomDataType>,
9296    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9297    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9298    pub custom_data: Option<CustomDataType>,
9299    pub variable: Variable<CustomDataType>,
9300}
9301#[cfg(all(feature = "validate", feature = "alloc"))]
9302impl<CustomDataType> crate::validate::Validate for SetVariableData<CustomDataType> {
9303    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9304        if let Some(value) = &self.attribute_type {
9305            crate::validate::Validate::validate(value)
9306                .map_err(|error| error.in_field("attributeType"))?;
9307        }
9308        crate::validate::check_max_length(&self.attribute_value, 2500usize)
9309            .map_err(|error| error.in_field("attributeValue"))?;
9310        crate::validate::Validate::validate(&self.component)
9311            .map_err(|error| error.in_field("component"))?;
9312        crate::validate::Validate::validate(&self.variable)
9313            .map_err(|error| error.in_field("variable"))?;
9314        Ok(())
9315    }
9316}
9317#[cfg(not(feature = "alloc"))]
9318#[derive(Debug, Clone, PartialEq, Eq)]
9319#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9320pub struct SetVariableData<
9321    CustomDataType = crate::NoCustomData,
9322    const SET_VARIABLE_DATA_ATTRIBUTE_VALUE_CAP: usize = 1024usize,
9323> {
9324    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
9325    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9326    pub attribute_type: Option<AttributeEnum>,
9327    /// Value to be assigned to attribute of variable.
9328    /// This value is allowed to be an empty string ("").
9329    ///
9330    /// The Configuration Variable &lt;&lt;configkey-configuration-value-size,ConfigurationValueSize&gt;&gt; can be used to limit SetVariableData.attributeValue and VariableCharacteristics.valuesList. The max size of these values will always remain equal.
9331    #[cfg_attr(feature = "serde", serde(rename = "attributeValue"))]
9332    pub attribute_value: heapless::String<SET_VARIABLE_DATA_ATTRIBUTE_VALUE_CAP>,
9333    pub component: Component<CustomDataType>,
9334    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9335    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9336    pub custom_data: Option<CustomDataType>,
9337    pub variable: Variable<CustomDataType>,
9338}
9339#[cfg(all(feature = "validate", not(feature = "alloc")))]
9340impl<
9341    CustomDataType,
9342    const SET_VARIABLE_DATA_ATTRIBUTE_VALUE_CAP: usize,
9343> crate::validate::Validate
9344for SetVariableData<CustomDataType, SET_VARIABLE_DATA_ATTRIBUTE_VALUE_CAP> {
9345    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9346        if let Some(value) = &self.attribute_type {
9347            crate::validate::Validate::validate(value)
9348                .map_err(|error| error.in_field("attributeType"))?;
9349        }
9350        crate::validate::check_max_length(&self.attribute_value, 2500usize)
9351            .map_err(|error| error.in_field("attributeValue"))?;
9352        crate::validate::Validate::validate(&self.component)
9353            .map_err(|error| error.in_field("component"))?;
9354        crate::validate::Validate::validate(&self.variable)
9355            .map_err(|error| error.in_field("variable"))?;
9356        Ok(())
9357    }
9358}
9359/// Result status of setting the variable.
9360#[derive(Debug, Clone, PartialEq, Eq)]
9361#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9362pub enum SetVariableStatusEnum {
9363    Accepted,
9364    Rejected,
9365    UnknownComponent,
9366    UnknownVariable,
9367    NotSupportedAttributeType,
9368    RebootRequired,
9369}
9370#[cfg(feature = "validate")]
9371impl crate::validate::Validate for SetVariableStatusEnum {
9372    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9373        Ok(())
9374    }
9375}
9376#[cfg(feature = "alloc")]
9377#[derive(Debug, Clone, PartialEq, Eq)]
9378#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9379pub struct SetVariableResult<CustomDataType = crate::NoCustomData> {
9380    #[cfg_attr(feature = "serde", serde(rename = "attributeStatus"))]
9381    pub attribute_status: SetVariableStatusEnum,
9382    #[cfg_attr(feature = "serde", serde(rename = "attributeStatusInfo"))]
9383    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9384    pub attribute_status_info: Option<StatusInfo<CustomDataType>>,
9385    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
9386    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9387    pub attribute_type: Option<AttributeEnum>,
9388    pub component: Component<CustomDataType>,
9389    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9390    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9391    pub custom_data: Option<CustomDataType>,
9392    pub variable: Variable<CustomDataType>,
9393}
9394#[cfg(all(feature = "validate", feature = "alloc"))]
9395impl<CustomDataType> crate::validate::Validate for SetVariableResult<CustomDataType> {
9396    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9397        crate::validate::Validate::validate(&self.attribute_status)
9398            .map_err(|error| error.in_field("attributeStatus"))?;
9399        if let Some(value) = &self.attribute_status_info {
9400            crate::validate::Validate::validate(value)
9401                .map_err(|error| error.in_field("attributeStatusInfo"))?;
9402        }
9403        if let Some(value) = &self.attribute_type {
9404            crate::validate::Validate::validate(value)
9405                .map_err(|error| error.in_field("attributeType"))?;
9406        }
9407        crate::validate::Validate::validate(&self.component)
9408            .map_err(|error| error.in_field("component"))?;
9409        crate::validate::Validate::validate(&self.variable)
9410            .map_err(|error| error.in_field("variable"))?;
9411        Ok(())
9412    }
9413}
9414#[cfg(not(feature = "alloc"))]
9415#[derive(Debug, Clone, PartialEq, Eq)]
9416#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9417pub struct SetVariableResult<
9418    CustomDataType = crate::NoCustomData,
9419    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize = 1024usize,
9420> {
9421    #[cfg_attr(feature = "serde", serde(rename = "attributeStatus"))]
9422    pub attribute_status: SetVariableStatusEnum,
9423    #[cfg_attr(feature = "serde", serde(rename = "attributeStatusInfo"))]
9424    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9425    pub attribute_status_info: Option<
9426        StatusInfo<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP>,
9427    >,
9428    #[cfg_attr(feature = "serde", serde(rename = "attributeType"))]
9429    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9430    pub attribute_type: Option<AttributeEnum>,
9431    pub component: Component<CustomDataType>,
9432    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9433    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9434    pub custom_data: Option<CustomDataType>,
9435    pub variable: Variable<CustomDataType>,
9436}
9437#[cfg(all(feature = "validate", not(feature = "alloc")))]
9438impl<
9439    CustomDataType,
9440    const STATUS_INFO_ADDITIONAL_INFO_CAP: usize,
9441> crate::validate::Validate
9442for SetVariableResult<CustomDataType, STATUS_INFO_ADDITIONAL_INFO_CAP> {
9443    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9444        crate::validate::Validate::validate(&self.attribute_status)
9445            .map_err(|error| error.in_field("attributeStatus"))?;
9446        if let Some(value) = &self.attribute_status_info {
9447            crate::validate::Validate::validate(value)
9448                .map_err(|error| error.in_field("attributeStatusInfo"))?;
9449        }
9450        if let Some(value) = &self.attribute_type {
9451            crate::validate::Validate::validate(value)
9452                .map_err(|error| error.in_field("attributeType"))?;
9453        }
9454        crate::validate::Validate::validate(&self.component)
9455            .map_err(|error| error.in_field("component"))?;
9456        crate::validate::Validate::validate(&self.variable)
9457            .map_err(|error| error.in_field("variable"))?;
9458        Ok(())
9459    }
9460}
9461/// This contains the current status of the Connector.
9462#[derive(Debug, Clone, PartialEq, Eq)]
9463#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9464pub enum ConnectorStatusEnum {
9465    Available,
9466    Occupied,
9467    Reserved,
9468    Unavailable,
9469    Faulted,
9470}
9471#[cfg(feature = "validate")]
9472impl crate::validate::Validate for ConnectorStatusEnum {
9473    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9474        Ok(())
9475    }
9476}
9477/// Type of cost dimension: energy, power, time, etc.
9478#[derive(Debug, Clone, PartialEq, Eq)]
9479#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9480pub enum CostDimensionEnum {
9481    Energy,
9482    MaxCurrent,
9483    MinCurrent,
9484    MaxPower,
9485    MinPower,
9486    IdleTIme,
9487    ChargingTime,
9488}
9489#[cfg(feature = "validate")]
9490impl crate::validate::Validate for CostDimensionEnum {
9491    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9492        Ok(())
9493    }
9494}
9495/// Volume consumed of cost dimension.
9496#[derive(Debug, Clone, PartialEq)]
9497#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9498pub struct CostDimension<CustomDataType = crate::NoCustomData> {
9499    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9500    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9501    pub custom_data: Option<CustomDataType>,
9502    pub r#type: CostDimensionEnum,
9503    /// Volume of the dimension consumed, measured according to the dimension type.
9504    pub volume: f64,
9505}
9506#[cfg(feature = "validate")]
9507impl<CustomDataType> crate::validate::Validate for CostDimension<CustomDataType> {
9508    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9509        crate::validate::Validate::validate(&self.r#type)
9510            .map_err(|error| error.in_field("type"))?;
9511        Ok(())
9512    }
9513}
9514#[cfg(feature = "alloc")]
9515/// A ChargingPeriodType consists of a start time, and a list of possible values that influence this period, for example: amount of energy charged this period, maximum current during this period etc.
9516#[derive(Debug, Clone, PartialEq)]
9517#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9518pub struct ChargingPeriod<CustomDataType = crate::NoCustomData> {
9519    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9520    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9521    pub custom_data: Option<CustomDataType>,
9522    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9523    pub dimensions: Option<alloc::vec::Vec<CostDimension<CustomDataType>>>,
9524    /// Start timestamp of charging period. A period ends when the next period starts. The last period ends when the session ends.
9525    #[cfg_attr(feature = "serde", serde(rename = "startPeriod"))]
9526    pub start_period: crate::OcppTimestamp,
9527    /// Unique identifier of the Tariff that was used to calculate cost. If not provided, then cost was calculated by some other means.
9528    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
9529    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9530    pub tariff_id: Option<heapless::String<60usize>>,
9531}
9532#[cfg(all(feature = "validate", feature = "alloc"))]
9533impl<CustomDataType> crate::validate::Validate for ChargingPeriod<CustomDataType> {
9534    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9535        if let Some(value) = &self.dimensions {
9536            crate::validate::check_min_items(value.len(), 1usize)
9537                .map_err(|error| error.in_field("dimensions"))?;
9538            for (index, item) in value.iter().enumerate() {
9539                crate::validate::Validate::validate(item)
9540                    .map_err(|error| error.in_index(index).in_field("dimensions"))?;
9541            }
9542        }
9543        Ok(())
9544    }
9545}
9546#[cfg(not(feature = "alloc"))]
9547/// A ChargingPeriodType consists of a start time, and a list of possible values that influence this period, for example: amount of energy charged this period, maximum current during this period etc.
9548#[derive(Debug, Clone, PartialEq)]
9549#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9550pub struct ChargingPeriod<
9551    CustomDataType = crate::NoCustomData,
9552    const CHARGING_PERIOD_DIMENSIONS_CAP: usize = 8usize,
9553> {
9554    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9555    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9556    pub custom_data: Option<CustomDataType>,
9557    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9558    pub dimensions: Option<
9559        heapless::Vec<CostDimension<CustomDataType>, CHARGING_PERIOD_DIMENSIONS_CAP>,
9560    >,
9561    /// Start timestamp of charging period. A period ends when the next period starts. The last period ends when the session ends.
9562    #[cfg_attr(feature = "serde", serde(rename = "startPeriod"))]
9563    pub start_period: crate::OcppTimestamp,
9564    /// Unique identifier of the Tariff that was used to calculate cost. If not provided, then cost was calculated by some other means.
9565    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
9566    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9567    pub tariff_id: Option<heapless::String<60usize>>,
9568}
9569#[cfg(all(feature = "validate", not(feature = "alloc")))]
9570impl<
9571    CustomDataType,
9572    const CHARGING_PERIOD_DIMENSIONS_CAP: usize,
9573> crate::validate::Validate
9574for ChargingPeriod<CustomDataType, CHARGING_PERIOD_DIMENSIONS_CAP> {
9575    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9576        if let Some(value) = &self.dimensions {
9577            crate::validate::check_min_items(value.len(), 1usize)
9578                .map_err(|error| error.in_field("dimensions"))?;
9579            for (index, item) in value.iter().enumerate() {
9580                crate::validate::Validate::validate(item)
9581                    .map_err(|error| error.in_index(index).in_field("dimensions"))?;
9582            }
9583        }
9584        Ok(())
9585    }
9586}
9587/// Total cost with and without tax. Contains the total of energy, charging time, idle time, fixed and reservation costs including and/or excluding tax.
9588#[derive(Debug, Clone, PartialEq)]
9589#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9590pub struct TotalPrice<CustomDataType = crate::NoCustomData> {
9591    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9592    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9593    pub custom_data: Option<CustomDataType>,
9594    /// Price/cost excluding tax. Can be absent if _inclTax_ is present.
9595    #[cfg_attr(feature = "serde", serde(rename = "exclTax"))]
9596    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9597    pub excl_tax: Option<f64>,
9598    /// Price/cost including tax. Can be absent if _exclTax_ is present.
9599    #[cfg_attr(feature = "serde", serde(rename = "inclTax"))]
9600    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9601    pub incl_tax: Option<f64>,
9602}
9603#[cfg(feature = "validate")]
9604impl<CustomDataType> crate::validate::Validate for TotalPrice<CustomDataType> {
9605    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9606        Ok(())
9607    }
9608}
9609/// Type of cost: normal or the minimum or maximum cost.
9610#[derive(Debug, Clone, PartialEq, Eq)]
9611#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9612pub enum TariffCostEnum {
9613    NormalCost,
9614    MinCost,
9615    MaxCost,
9616}
9617#[cfg(feature = "validate")]
9618impl crate::validate::Validate for TariffCostEnum {
9619    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9620        Ok(())
9621    }
9622}
9623/// This contains the cost calculated during a transaction. It is used both for running cost and final cost of the transaction.
9624#[derive(Debug, Clone, PartialEq)]
9625#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9626pub struct TotalCost<CustomDataType = crate::NoCustomData> {
9627    #[cfg_attr(feature = "serde", serde(rename = "chargingTime"))]
9628    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9629    pub charging_time: Option<Price<CustomDataType>>,
9630    /// Currency of the costs in ISO 4217 Code.
9631    pub currency: heapless::String<3usize>,
9632    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9633    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9634    pub custom_data: Option<CustomDataType>,
9635    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9636    pub energy: Option<Price<CustomDataType>>,
9637    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9638    pub fixed: Option<Price<CustomDataType>>,
9639    #[cfg_attr(feature = "serde", serde(rename = "idleTime"))]
9640    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9641    pub idle_time: Option<Price<CustomDataType>>,
9642    #[cfg_attr(feature = "serde", serde(rename = "reservationFixed"))]
9643    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9644    pub reservation_fixed: Option<Price<CustomDataType>>,
9645    #[cfg_attr(feature = "serde", serde(rename = "reservationTime"))]
9646    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9647    pub reservation_time: Option<Price<CustomDataType>>,
9648    pub total: TotalPrice<CustomDataType>,
9649    #[cfg_attr(feature = "serde", serde(rename = "typeOfCost"))]
9650    pub type_of_cost: TariffCostEnum,
9651}
9652#[cfg(feature = "validate")]
9653impl<CustomDataType> crate::validate::Validate for TotalCost<CustomDataType> {
9654    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9655        if let Some(value) = &self.charging_time {
9656            crate::validate::Validate::validate(value)
9657                .map_err(|error| error.in_field("chargingTime"))?;
9658        }
9659        if let Some(value) = &self.energy {
9660            crate::validate::Validate::validate(value)
9661                .map_err(|error| error.in_field("energy"))?;
9662        }
9663        if let Some(value) = &self.fixed {
9664            crate::validate::Validate::validate(value)
9665                .map_err(|error| error.in_field("fixed"))?;
9666        }
9667        if let Some(value) = &self.idle_time {
9668            crate::validate::Validate::validate(value)
9669                .map_err(|error| error.in_field("idleTime"))?;
9670        }
9671        if let Some(value) = &self.reservation_fixed {
9672            crate::validate::Validate::validate(value)
9673                .map_err(|error| error.in_field("reservationFixed"))?;
9674        }
9675        if let Some(value) = &self.reservation_time {
9676            crate::validate::Validate::validate(value)
9677                .map_err(|error| error.in_field("reservationTime"))?;
9678        }
9679        crate::validate::Validate::validate(&self.total)
9680            .map_err(|error| error.in_field("total"))?;
9681        crate::validate::Validate::validate(&self.type_of_cost)
9682            .map_err(|error| error.in_field("typeOfCost"))?;
9683        Ok(())
9684    }
9685}
9686/// This contains the calculated usage of energy, charging time and idle time during a transaction.
9687#[derive(Debug, Clone, PartialEq)]
9688#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9689pub struct TotalUsage<CustomDataType = crate::NoCustomData> {
9690    /// Total duration of the charging session (including the duration of charging and not charging), in seconds.
9691    #[cfg_attr(feature = "serde", serde(rename = "chargingTime"))]
9692    pub charging_time: i64,
9693    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9694    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9695    pub custom_data: Option<CustomDataType>,
9696    pub energy: f64,
9697    /// Total duration of the charging session where the EV was not charging (no energy was transferred between EVSE and EV), in seconds.
9698    #[cfg_attr(feature = "serde", serde(rename = "idleTime"))]
9699    pub idle_time: i64,
9700    /// Total time of reservation in seconds.
9701    #[cfg_attr(feature = "serde", serde(rename = "reservationTime"))]
9702    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9703    pub reservation_time: Option<i64>,
9704}
9705#[cfg(feature = "validate")]
9706impl<CustomDataType> crate::validate::Validate for TotalUsage<CustomDataType> {
9707    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9708        Ok(())
9709    }
9710}
9711#[cfg(feature = "alloc")]
9712/// CostDetailsType contains the cost as calculated by Charging Station based on provided TariffType.
9713///
9714/// NOTE: Reservation is not shown as a _chargingPeriod_, because it took place outside of the transaction.
9715#[derive(Debug, Clone, PartialEq)]
9716#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9717pub struct CostDetails<CustomDataType = crate::NoCustomData> {
9718    #[cfg_attr(feature = "serde", serde(rename = "chargingPeriods"))]
9719    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9720    pub charging_periods: Option<alloc::vec::Vec<ChargingPeriod<CustomDataType>>>,
9721    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9722    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9723    pub custom_data: Option<CustomDataType>,
9724    /// Optional human-readable reason text in case of failure to calculate.
9725    #[cfg_attr(feature = "serde", serde(rename = "failureReason"))]
9726    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9727    pub failure_reason: Option<heapless::String<500usize>>,
9728    /// If set to true, then Charging Station has failed to calculate the cost.
9729    #[cfg_attr(feature = "serde", serde(rename = "failureToCalculate"))]
9730    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9731    pub failure_to_calculate: Option<bool>,
9732    #[cfg_attr(feature = "serde", serde(rename = "totalCost"))]
9733    pub total_cost: TotalCost<CustomDataType>,
9734    #[cfg_attr(feature = "serde", serde(rename = "totalUsage"))]
9735    pub total_usage: TotalUsage<CustomDataType>,
9736}
9737#[cfg(all(feature = "validate", feature = "alloc"))]
9738impl<CustomDataType> crate::validate::Validate for CostDetails<CustomDataType> {
9739    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9740        if let Some(value) = &self.charging_periods {
9741            crate::validate::check_min_items(value.len(), 1usize)
9742                .map_err(|error| error.in_field("chargingPeriods"))?;
9743            for (index, item) in value.iter().enumerate() {
9744                crate::validate::Validate::validate(item)
9745                    .map_err(|error| error.in_index(index).in_field("chargingPeriods"))?;
9746            }
9747        }
9748        crate::validate::Validate::validate(&self.total_cost)
9749            .map_err(|error| error.in_field("totalCost"))?;
9750        crate::validate::Validate::validate(&self.total_usage)
9751            .map_err(|error| error.in_field("totalUsage"))?;
9752        Ok(())
9753    }
9754}
9755#[cfg(not(feature = "alloc"))]
9756/// CostDetailsType contains the cost as calculated by Charging Station based on provided TariffType.
9757///
9758/// NOTE: Reservation is not shown as a _chargingPeriod_, because it took place outside of the transaction.
9759#[derive(Debug, Clone, PartialEq)]
9760#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9761pub struct CostDetails<
9762    CustomDataType = crate::NoCustomData,
9763    const COST_DETAILS_CHARGING_PERIODS_CAP: usize = 8usize,
9764    const CHARGING_PERIOD_DIMENSIONS_CAP: usize = 8usize,
9765> {
9766    #[cfg_attr(feature = "serde", serde(rename = "chargingPeriods"))]
9767    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9768    pub charging_periods: Option<
9769        heapless::Vec<
9770            ChargingPeriod<CustomDataType, CHARGING_PERIOD_DIMENSIONS_CAP>,
9771            COST_DETAILS_CHARGING_PERIODS_CAP,
9772        >,
9773    >,
9774    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9775    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9776    pub custom_data: Option<CustomDataType>,
9777    /// Optional human-readable reason text in case of failure to calculate.
9778    #[cfg_attr(feature = "serde", serde(rename = "failureReason"))]
9779    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9780    pub failure_reason: Option<heapless::String<500usize>>,
9781    /// If set to true, then Charging Station has failed to calculate the cost.
9782    #[cfg_attr(feature = "serde", serde(rename = "failureToCalculate"))]
9783    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9784    pub failure_to_calculate: Option<bool>,
9785    #[cfg_attr(feature = "serde", serde(rename = "totalCost"))]
9786    pub total_cost: TotalCost<CustomDataType>,
9787    #[cfg_attr(feature = "serde", serde(rename = "totalUsage"))]
9788    pub total_usage: TotalUsage<CustomDataType>,
9789}
9790#[cfg(all(feature = "validate", not(feature = "alloc")))]
9791impl<
9792    CustomDataType,
9793    const COST_DETAILS_CHARGING_PERIODS_CAP: usize,
9794    const CHARGING_PERIOD_DIMENSIONS_CAP: usize,
9795> crate::validate::Validate
9796for CostDetails<
9797    CustomDataType,
9798    COST_DETAILS_CHARGING_PERIODS_CAP,
9799    CHARGING_PERIOD_DIMENSIONS_CAP,
9800> {
9801    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9802        if let Some(value) = &self.charging_periods {
9803            crate::validate::check_min_items(value.len(), 1usize)
9804                .map_err(|error| error.in_field("chargingPeriods"))?;
9805            for (index, item) in value.iter().enumerate() {
9806                crate::validate::Validate::validate(item)
9807                    .map_err(|error| error.in_index(index).in_field("chargingPeriods"))?;
9808            }
9809        }
9810        crate::validate::Validate::validate(&self.total_cost)
9811            .map_err(|error| error.in_field("totalCost"))?;
9812        crate::validate::Validate::validate(&self.total_usage)
9813            .map_err(|error| error.in_field("totalUsage"))?;
9814        Ok(())
9815    }
9816}
9817/// This contains the type of this event.
9818/// The first TransactionEvent of a transaction SHALL contain: "Started" The last TransactionEvent of a transaction SHALL contain: "Ended" All others SHALL contain: "Updated"
9819#[derive(Debug, Clone, PartialEq, Eq)]
9820#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9821pub enum TransactionEventEnum {
9822    Ended,
9823    Started,
9824    Updated,
9825}
9826#[cfg(feature = "validate")]
9827impl crate::validate::Validate for TransactionEventEnum {
9828    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9829        Ok(())
9830    }
9831}
9832/// *(2.1)* The current preconditioning status of the BMS in the EV. Default value is Unknown.
9833#[derive(Debug, Clone, PartialEq, Eq)]
9834#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9835pub enum PreconditioningStatusEnum {
9836    Unknown,
9837    Ready,
9838    NotReady,
9839    Preconditioning,
9840}
9841#[cfg(feature = "validate")]
9842impl crate::validate::Validate for PreconditioningStatusEnum {
9843    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9844        Ok(())
9845    }
9846}
9847/// Current charging state, is required when state
9848/// has changed. Omitted when there is no communication between EVSE and EV, because no cable is plugged in.
9849#[derive(Debug, Clone, PartialEq, Eq)]
9850#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9851pub enum ChargingStateEnum {
9852    EVConnected,
9853    Charging,
9854    SuspendedEV,
9855    SuspendedEVSE,
9856    Idle,
9857}
9858#[cfg(feature = "validate")]
9859impl crate::validate::Validate for ChargingStateEnum {
9860    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9861        Ok(())
9862    }
9863}
9864/// The _stoppedReason_ is the reason/event that initiated the process of stopping the transaction. It will normally be the user stopping authorization via card (Local or MasterPass) or app (Remote), but it can also be CSMS revoking authorization (DeAuthorized), or disconnecting the EV when TxStopPoint = EVConnected (EVDisconnected). Most other reasons are related to technical faults or energy limitations. +
9865/// MAY only be omitted when _stoppedReason_ is "Local"
9866#[derive(Debug, Clone, PartialEq, Eq)]
9867#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9868pub enum ReasonEnum {
9869    DeAuthorized,
9870    EmergencyStop,
9871    EnergyLimitReached,
9872    EVDisconnected,
9873    GroundFault,
9874    ImmediateReset,
9875    MasterPass,
9876    Local,
9877    LocalOutOfCredit,
9878    Other,
9879    OvercurrentFault,
9880    PowerLoss,
9881    PowerQuality,
9882    Reboot,
9883    Remote,
9884    SOCLimitReached,
9885    StoppedByEV,
9886    TimeLimitReached,
9887    Timeout,
9888    ReqEnergyTransferRejected,
9889}
9890#[cfg(feature = "validate")]
9891impl crate::validate::Validate for ReasonEnum {
9892    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9893        Ok(())
9894    }
9895}
9896/// Cost, energy, time or SoC limit for a transaction.
9897#[derive(Debug, Clone, PartialEq)]
9898#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9899pub struct TransactionLimit<CustomDataType = crate::NoCustomData> {
9900    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9901    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9902    pub custom_data: Option<CustomDataType>,
9903    /// Maximum allowed cost of transaction in currency of tariff.
9904    #[cfg_attr(feature = "serde", serde(rename = "maxCost"))]
9905    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9906    pub max_cost: Option<f64>,
9907    /// Maximum allowed energy in Wh to charge in transaction.
9908    #[cfg_attr(feature = "serde", serde(rename = "maxEnergy"))]
9909    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9910    pub max_energy: Option<f64>,
9911    /// Maximum State of Charge of EV in percentage.
9912    #[cfg_attr(feature = "serde", serde(rename = "maxSoC"))]
9913    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9914    pub max_so_c: Option<i64>,
9915    /// Maximum duration of transaction in seconds from start to end.
9916    #[cfg_attr(feature = "serde", serde(rename = "maxTime"))]
9917    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9918    pub max_time: Option<i64>,
9919}
9920#[cfg(feature = "validate")]
9921impl<CustomDataType> crate::validate::Validate for TransactionLimit<CustomDataType> {
9922    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9923        if let Some(value) = self.max_so_c {
9924            crate::validate::check_min_i64(value, 0i64)
9925                .map_err(|error| error.in_field("maxSoC"))?;
9926            crate::validate::check_max_i64(value, 100i64)
9927                .map_err(|error| error.in_field("maxSoC"))?;
9928        }
9929        Ok(())
9930    }
9931}
9932#[derive(Debug, Clone, PartialEq)]
9933#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9934pub struct Transaction<CustomDataType = crate::NoCustomData> {
9935    #[cfg_attr(feature = "serde", serde(rename = "chargingState"))]
9936    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9937    pub charging_state: Option<ChargingStateEnum>,
9938    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
9939    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9940    pub custom_data: Option<CustomDataType>,
9941    #[cfg_attr(feature = "serde", serde(rename = "operationMode"))]
9942    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9943    pub operation_mode: Option<OperationModeEnum>,
9944    /// The ID given to remote start request (&lt;&lt;requeststarttransactionrequest, RequestStartTransactionRequest&gt;&gt;. This enables to CSMS to match the started transaction to the given start request.
9945    #[cfg_attr(feature = "serde", serde(rename = "remoteStartId"))]
9946    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9947    pub remote_start_id: Option<i64>,
9948    #[cfg_attr(feature = "serde", serde(rename = "stoppedReason"))]
9949    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9950    pub stopped_reason: Option<ReasonEnum>,
9951    /// *(2.1)* Id of tariff in use for transaction
9952    #[cfg_attr(feature = "serde", serde(rename = "tariffId"))]
9953    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9954    pub tariff_id: Option<heapless::String<60usize>>,
9955    /// Contains the total time that energy flowed from EVSE to EV during the transaction (in seconds). Note that timeSpentCharging is smaller or equal to the duration of the transaction.
9956    #[cfg_attr(feature = "serde", serde(rename = "timeSpentCharging"))]
9957    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9958    pub time_spent_charging: Option<i64>,
9959    /// This contains the Id of the transaction.
9960    #[cfg_attr(feature = "serde", serde(rename = "transactionId"))]
9961    pub transaction_id: heapless::String<36usize>,
9962    #[cfg_attr(feature = "serde", serde(rename = "transactionLimit"))]
9963    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
9964    pub transaction_limit: Option<TransactionLimit<CustomDataType>>,
9965}
9966#[cfg(feature = "validate")]
9967impl<CustomDataType> crate::validate::Validate for Transaction<CustomDataType> {
9968    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
9969        if let Some(value) = &self.charging_state {
9970            crate::validate::Validate::validate(value)
9971                .map_err(|error| error.in_field("chargingState"))?;
9972        }
9973        if let Some(value) = &self.operation_mode {
9974            crate::validate::Validate::validate(value)
9975                .map_err(|error| error.in_field("operationMode"))?;
9976        }
9977        if let Some(value) = &self.stopped_reason {
9978            crate::validate::Validate::validate(value)
9979                .map_err(|error| error.in_field("stoppedReason"))?;
9980        }
9981        if let Some(value) = &self.transaction_limit {
9982            crate::validate::Validate::validate(value)
9983                .map_err(|error| error.in_field("transactionLimit"))?;
9984        }
9985        Ok(())
9986    }
9987}
9988/// Reason the Charging Station sends this message to the CSMS
9989#[derive(Debug, Clone, PartialEq, Eq)]
9990#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9991pub enum TriggerReasonEnum {
9992    AbnormalCondition,
9993    Authorized,
9994    CablePluggedIn,
9995    ChargingRateChanged,
9996    ChargingStateChanged,
9997    CostLimitReached,
9998    Deauthorized,
9999    EnergyLimitReached,
10000    EVCommunicationLost,
10001    EVConnectTimeout,
10002    EVDeparted,
10003    EVDetected,
10004    LimitSet,
10005    MeterValueClock,
10006    MeterValuePeriodic,
10007    OperationModeChanged,
10008    RemoteStart,
10009    RemoteStop,
10010    ResetCommand,
10011    RunningCost,
10012    SignedDataReceived,
10013    SoCLimitReached,
10014    StopAuthorized,
10015    TariffChanged,
10016    TariffNotAccepted,
10017    TimeLimitReached,
10018    Trigger,
10019    TxResumed,
10020    UnlockCommand,
10021}
10022#[cfg(feature = "validate")]
10023impl crate::validate::Validate for TriggerReasonEnum {
10024    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10025        Ok(())
10026    }
10027}
10028/// Type of message to be triggered.
10029#[derive(Debug, Clone, PartialEq, Eq)]
10030#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10031pub enum MessageTriggerEnum {
10032    BootNotification,
10033    LogStatusNotification,
10034    FirmwareStatusNotification,
10035    Heartbeat,
10036    MeterValues,
10037    SignChargingStationCertificate,
10038    SignV2GCertificate,
10039    SignV2G20Certificate,
10040    StatusNotification,
10041    TransactionEvent,
10042    SignCombinedCertificate,
10043    PublishFirmwareStatusNotification,
10044    CustomTrigger,
10045}
10046#[cfg(feature = "validate")]
10047impl crate::validate::Validate for MessageTriggerEnum {
10048    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10049        Ok(())
10050    }
10051}
10052/// Indicates whether the Charging Station will send the requested notification or not.
10053#[derive(Debug, Clone, PartialEq, Eq)]
10054#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10055pub enum TriggerMessageStatusEnum {
10056    Accepted,
10057    Rejected,
10058    NotImplemented,
10059}
10060#[cfg(feature = "validate")]
10061impl crate::validate::Validate for TriggerMessageStatusEnum {
10062    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10063        Ok(())
10064    }
10065}
10066/// This indicates whether the Charging Station has unlocked the connector.
10067#[derive(Debug, Clone, PartialEq, Eq)]
10068#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10069pub enum UnlockStatusEnum {
10070    Unlocked,
10071    UnlockFailed,
10072    OngoingAuthorizedTransaction,
10073    UnknownConnector,
10074}
10075#[cfg(feature = "validate")]
10076impl crate::validate::Validate for UnlockStatusEnum {
10077    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10078        Ok(())
10079    }
10080}
10081/// Indicates whether the Local Controller succeeded in unpublishing the firmware.
10082#[derive(Debug, Clone, PartialEq, Eq)]
10083#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10084pub enum UnpublishFirmwareStatusEnum {
10085    DownloadOngoing,
10086    NoFirmware,
10087    Unpublished,
10088}
10089#[cfg(feature = "validate")]
10090impl crate::validate::Validate for UnpublishFirmwareStatusEnum {
10091    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10092        Ok(())
10093    }
10094}
10095#[cfg(feature = "alloc")]
10096/// Represents a copy of the firmware that can be loaded/updated on the Charging Station.
10097#[derive(Debug, Clone, PartialEq, Eq)]
10098#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10099pub struct Firmware<CustomDataType = crate::NoCustomData> {
10100    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
10101    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10102    pub custom_data: Option<CustomDataType>,
10103    /// Date and time at which the firmware shall be installed.
10104    #[cfg_attr(feature = "serde", serde(rename = "installDateTime"))]
10105    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10106    pub install_date_time: Option<crate::OcppTimestamp>,
10107    /// URI defining the origin of the firmware.
10108    pub location: alloc::string::String,
10109    /// Date and time at which the firmware shall be retrieved.
10110    #[cfg_attr(feature = "serde", serde(rename = "retrieveDateTime"))]
10111    pub retrieve_date_time: crate::OcppTimestamp,
10112    /// Base64 encoded firmware signature.
10113    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10114    pub signature: Option<alloc::string::String>,
10115    /// Certificate with which the firmware was signed.
10116    /// PEM encoded X.509 certificate.
10117    #[cfg_attr(feature = "serde", serde(rename = "signingCertificate"))]
10118    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10119    pub signing_certificate: Option<alloc::string::String>,
10120}
10121#[cfg(all(feature = "validate", feature = "alloc"))]
10122impl<CustomDataType> crate::validate::Validate for Firmware<CustomDataType> {
10123    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10124        crate::validate::check_max_length(&self.location, 2000usize)
10125            .map_err(|error| error.in_field("location"))?;
10126        if let Some(value) = &self.signature {
10127            crate::validate::check_max_length(value, 800usize)
10128                .map_err(|error| error.in_field("signature"))?;
10129        }
10130        if let Some(value) = &self.signing_certificate {
10131            crate::validate::check_max_length(value, 5500usize)
10132                .map_err(|error| error.in_field("signingCertificate"))?;
10133        }
10134        Ok(())
10135    }
10136}
10137#[cfg(not(feature = "alloc"))]
10138/// Represents a copy of the firmware that can be loaded/updated on the Charging Station.
10139#[derive(Debug, Clone, PartialEq, Eq)]
10140#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10141pub struct Firmware<
10142    CustomDataType = crate::NoCustomData,
10143    const FIRMWARE_LOCATION_CAP: usize = 1024usize,
10144    const FIRMWARE_SIGNATURE_CAP: usize = 800usize,
10145    const FIRMWARE_SIGNING_CERTIFICATE_CAP: usize = 1024usize,
10146> {
10147    #[cfg_attr(feature = "serde", serde(rename = "customData"))]
10148    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10149    pub custom_data: Option<CustomDataType>,
10150    /// Date and time at which the firmware shall be installed.
10151    #[cfg_attr(feature = "serde", serde(rename = "installDateTime"))]
10152    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10153    pub install_date_time: Option<crate::OcppTimestamp>,
10154    /// URI defining the origin of the firmware.
10155    pub location: heapless::String<FIRMWARE_LOCATION_CAP>,
10156    /// Date and time at which the firmware shall be retrieved.
10157    #[cfg_attr(feature = "serde", serde(rename = "retrieveDateTime"))]
10158    pub retrieve_date_time: crate::OcppTimestamp,
10159    /// Base64 encoded firmware signature.
10160    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10161    pub signature: Option<heapless::String<FIRMWARE_SIGNATURE_CAP>>,
10162    /// Certificate with which the firmware was signed.
10163    /// PEM encoded X.509 certificate.
10164    #[cfg_attr(feature = "serde", serde(rename = "signingCertificate"))]
10165    #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
10166    pub signing_certificate: Option<heapless::String<FIRMWARE_SIGNING_CERTIFICATE_CAP>>,
10167}
10168#[cfg(all(feature = "validate", not(feature = "alloc")))]
10169impl<
10170    CustomDataType,
10171    const FIRMWARE_LOCATION_CAP: usize,
10172    const FIRMWARE_SIGNATURE_CAP: usize,
10173    const FIRMWARE_SIGNING_CERTIFICATE_CAP: usize,
10174> crate::validate::Validate
10175for Firmware<
10176    CustomDataType,
10177    FIRMWARE_LOCATION_CAP,
10178    FIRMWARE_SIGNATURE_CAP,
10179    FIRMWARE_SIGNING_CERTIFICATE_CAP,
10180> {
10181    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10182        crate::validate::check_max_length(&self.location, 2000usize)
10183            .map_err(|error| error.in_field("location"))?;
10184        if let Some(value) = &self.signature {
10185            crate::validate::check_max_length(value, 800usize)
10186                .map_err(|error| error.in_field("signature"))?;
10187        }
10188        if let Some(value) = &self.signing_certificate {
10189            crate::validate::check_max_length(value, 5500usize)
10190                .map_err(|error| error.in_field("signingCertificate"))?;
10191        }
10192        Ok(())
10193    }
10194}
10195/// This field indicates whether the Charging Station was able to accept the request.
10196#[derive(Debug, Clone, PartialEq, Eq)]
10197#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10198pub enum UpdateFirmwareStatusEnum {
10199    Accepted,
10200    Rejected,
10201    AcceptedCanceled,
10202    InvalidCertificate,
10203    RevokedCertificate,
10204}
10205#[cfg(feature = "validate")]
10206impl crate::validate::Validate for UpdateFirmwareStatusEnum {
10207    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10208        Ok(())
10209    }
10210}
10211/// Result of the request.
10212#[derive(Debug, Clone, PartialEq, Eq)]
10213#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10214pub enum PriorityChargingStatusEnum {
10215    Accepted,
10216    Rejected,
10217    NoProfile,
10218}
10219#[cfg(feature = "validate")]
10220impl crate::validate::Validate for PriorityChargingStatusEnum {
10221    fn validate(&self) -> Result<(), crate::validate::ValidationError> {
10222        Ok(())
10223    }
10224}