Skip to main content

codetics_ocpp21/
datatypes.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Kevin Vavelin, Codetics (https://codetics.fr)
3
4//! OCPP 2.1 composite datatypes.
5
6use ocpp_core::DateTime;
7use ocpp_core::validate::{self as v, Path, Validate, Violation};
8use serde::{Deserialize, Serialize};
9
10use crate::enums::*;
11
12/// EV AC charging parameters for ISO 15118-2
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14#[serde(deny_unknown_fields)]
15pub struct ACChargingParameters {
16    /// Amount of energy requested (in Wh). This includes energy required for preconditioning.
17    /// Relates to: +
18    /// *ISO 15118-2*: AC_EVChargeParameterType: EAmount +
19    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVTargetEnergyRequest
20    #[serde(rename = "energyAmount")]
21    pub energy_amount: f64,
22    /// Minimum current (amps) supported by the electric vehicle (per phase).
23    /// Relates to: +
24    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMinCurrent
25    #[serde(rename = "evMinCurrent")]
26    pub ev_min_current: f64,
27    /// Maximum current (amps) supported by the electric vehicle (per phase). Includes cable capacity.
28    /// Relates to: +
29    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMaxCurrent
30    #[serde(rename = "evMaxCurrent")]
31    pub ev_max_current: f64,
32    /// Maximum voltage supported by the electric vehicle.
33    /// Relates to: +
34    /// *ISO 15118-2*: AC_EVChargeParameterType: EVMaxVoltage
35    #[serde(rename = "evMaxVoltage")]
36    pub ev_max_voltage: f64,
37    #[serde(
38        rename = "customData",
39        default,
40        skip_serializing_if = "Option::is_none"
41    )]
42    pub custom_data: Option<CustomData>,
43}
44
45impl Validate for ACChargingParameters {
46    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
47        if let Some(x) = &self.custom_data {
48            let p = path.field("customData");
49            x.validate(&p)?;
50        }
51        Ok(())
52    }
53}
54
55/// Collection of configuration data needed to make a data-connection over a cellular network.
56/// 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.
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
58#[serde(deny_unknown_fields)]
59pub struct APN {
60    /// The Access Point Name as an URL.
61    #[serde(rename = "apn")]
62    pub apn: String,
63    /// APN username.
64    #[serde(
65        rename = "apnUserName",
66        default,
67        skip_serializing_if = "Option::is_none"
68    )]
69    pub apn_user_name: Option<String>,
70    /// *(2.1)* APN Password.
71    #[serde(
72        rename = "apnPassword",
73        default,
74        skip_serializing_if = "Option::is_none"
75    )]
76    pub apn_password: Option<String>,
77    /// SIM card pin code.
78    #[serde(rename = "simPin", default, skip_serializing_if = "Option::is_none")]
79    pub sim_pin: Option<i64>,
80    /// Preferred network, written as MCC and MNC concatenated. See note.
81    #[serde(
82        rename = "preferredNetwork",
83        default,
84        skip_serializing_if = "Option::is_none"
85    )]
86    pub preferred_network: Option<String>,
87    /// Default: false. Use only the preferred Network, do
88    /// not dial in when not available. See Note.
89    #[serde(
90        rename = "useOnlyPreferredNetwork",
91        default,
92        skip_serializing_if = "Option::is_none"
93    )]
94    pub use_only_preferred_network: Option<bool>,
95    #[serde(rename = "apnAuthentication")]
96    pub apn_authentication: APNAuthenticationEnum,
97    #[serde(
98        rename = "customData",
99        default,
100        skip_serializing_if = "Option::is_none"
101    )]
102    pub custom_data: Option<CustomData>,
103}
104
105impl Validate for APN {
106    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
107        {
108            let x = &self.apn;
109            let p = path.field("apn");
110            v::max_length(x, 2000, &p)?;
111        }
112        if let Some(x) = &self.apn_user_name {
113            let p = path.field("apnUserName");
114            v::max_length(x, 50, &p)?;
115        }
116        if let Some(x) = &self.apn_password {
117            let p = path.field("apnPassword");
118            v::max_length(x, 64, &p)?;
119        }
120        if let Some(x) = &self.preferred_network {
121            let p = path.field("preferredNetwork");
122            v::max_length(x, 6, &p)?;
123        }
124        if let Some(x) = &self.custom_data {
125            let p = path.field("customData");
126            x.validate(&p)?;
127        }
128        Ok(())
129    }
130}
131
132/// 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.
133/// image::images/AbsolutePriceSchedule-Simple.png\[\]
134#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
135#[serde(deny_unknown_fields)]
136pub struct AbsolutePriceSchedule {
137    /// Starting point of price schedule.
138    #[serde(rename = "timeAnchor")]
139    pub time_anchor: DateTime,
140    /// Unique ID of price schedule
141    #[serde(rename = "priceScheduleID")]
142    pub price_schedule_id: i64,
143    /// Description of the price schedule.
144    #[serde(
145        rename = "priceScheduleDescription",
146        default,
147        skip_serializing_if = "Option::is_none"
148    )]
149    pub price_schedule_description: Option<String>,
150    /// Currency according to ISO 4217.
151    #[serde(rename = "currency")]
152    pub currency: String,
153    /// String that indicates what language is used for the human readable strings in the price schedule. Based on ISO 639.
154    #[serde(rename = "language")]
155    pub language: String,
156    /// 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.
157    #[serde(rename = "priceAlgorithm")]
158    pub price_algorithm: String,
159    #[serde(
160        rename = "minimumCost",
161        default,
162        skip_serializing_if = "Option::is_none"
163    )]
164    pub minimum_cost: Option<RationalNumber>,
165    #[serde(
166        rename = "maximumCost",
167        default,
168        skip_serializing_if = "Option::is_none"
169    )]
170    pub maximum_cost: Option<RationalNumber>,
171    #[serde(rename = "priceRuleStacks")]
172    pub price_rule_stacks: Vec<PriceRuleStack>,
173    #[serde(rename = "taxRules", default, skip_serializing_if = "Option::is_none")]
174    pub tax_rules: Option<Vec<TaxRule>>,
175    #[serde(
176        rename = "overstayRuleList",
177        default,
178        skip_serializing_if = "Option::is_none"
179    )]
180    pub overstay_rule_list: Option<OverstayRuleList>,
181    #[serde(
182        rename = "additionalSelectedServices",
183        default,
184        skip_serializing_if = "Option::is_none"
185    )]
186    pub additional_selected_services: Option<Vec<AdditionalSelectedServices>>,
187    #[serde(
188        rename = "customData",
189        default,
190        skip_serializing_if = "Option::is_none"
191    )]
192    pub custom_data: Option<CustomData>,
193}
194
195impl Validate for AbsolutePriceSchedule {
196    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
197        {
198            let x = &self.price_schedule_id;
199            let p = path.field("priceScheduleID");
200            v::minimum(*x, 0i64, &p)?;
201        }
202        if let Some(x) = &self.price_schedule_description {
203            let p = path.field("priceScheduleDescription");
204            v::max_length(x, 160, &p)?;
205        }
206        {
207            let x = &self.currency;
208            let p = path.field("currency");
209            v::max_length(x, 3, &p)?;
210        }
211        {
212            let x = &self.language;
213            let p = path.field("language");
214            v::max_length(x, 8, &p)?;
215        }
216        {
217            let x = &self.price_algorithm;
218            let p = path.field("priceAlgorithm");
219            v::max_length(x, 2000, &p)?;
220        }
221        if let Some(x) = &self.minimum_cost {
222            let p = path.field("minimumCost");
223            x.validate(&p)?;
224        }
225        if let Some(x) = &self.maximum_cost {
226            let p = path.field("maximumCost");
227            x.validate(&p)?;
228        }
229        {
230            let x = &self.price_rule_stacks;
231            let p = path.field("priceRuleStacks");
232            v::items(x, Some(1), Some(1024), &p)?;
233            for (i0, it0) in x.iter().enumerate() {
234                let p0 = p.index(i0);
235                it0.validate(&p0)?;
236            }
237        }
238        if let Some(x) = &self.tax_rules {
239            let p = path.field("taxRules");
240            v::items(x, Some(1), Some(10), &p)?;
241            for (i0, it0) in x.iter().enumerate() {
242                let p0 = p.index(i0);
243                it0.validate(&p0)?;
244            }
245        }
246        if let Some(x) = &self.overstay_rule_list {
247            let p = path.field("overstayRuleList");
248            x.validate(&p)?;
249        }
250        if let Some(x) = &self.additional_selected_services {
251            let p = path.field("additionalSelectedServices");
252            v::items(x, Some(1), Some(5), &p)?;
253            for (i0, it0) in x.iter().enumerate() {
254                let p0 = p.index(i0);
255                it0.validate(&p0)?;
256            }
257        }
258        if let Some(x) = &self.custom_data {
259            let p = path.field("customData");
260            x.validate(&p)?;
261        }
262        Ok(())
263    }
264}
265
266/// Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
267#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
268#[serde(deny_unknown_fields)]
269pub struct AdditionalInfo {
270    /// *(2.1)* This field specifies the additional IdToken.
271    #[serde(rename = "additionalIdToken")]
272    pub additional_id_token: String,
273    /// _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_.
274    #[serde(rename = "type")]
275    pub r#type: String,
276    #[serde(
277        rename = "customData",
278        default,
279        skip_serializing_if = "Option::is_none"
280    )]
281    pub custom_data: Option<CustomData>,
282}
283
284impl Validate for AdditionalInfo {
285    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
286        {
287            let x = &self.additional_id_token;
288            let p = path.field("additionalIdToken");
289            v::max_length(x, 255, &p)?;
290        }
291        {
292            let x = &self.r#type;
293            let p = path.field("type");
294            v::max_length(x, 50, &p)?;
295        }
296        if let Some(x) = &self.custom_data {
297            let p = path.field("customData");
298            x.validate(&p)?;
299        }
300        Ok(())
301    }
302}
303
304/// Part of ISO 15118-20 price schedule.
305#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
306#[serde(deny_unknown_fields)]
307pub struct AdditionalSelectedServices {
308    #[serde(rename = "serviceFee")]
309    pub service_fee: RationalNumber,
310    /// Human readable string to identify this service.
311    #[serde(rename = "serviceName")]
312    pub service_name: String,
313    #[serde(
314        rename = "customData",
315        default,
316        skip_serializing_if = "Option::is_none"
317    )]
318    pub custom_data: Option<CustomData>,
319}
320
321impl Validate for AdditionalSelectedServices {
322    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
323        {
324            let x = &self.service_fee;
325            let p = path.field("serviceFee");
326            x.validate(&p)?;
327        }
328        {
329            let x = &self.service_name;
330            let p = path.field("serviceName");
331            v::max_length(x, 80, &p)?;
332        }
333        if let Some(x) = &self.custom_data {
334            let p = path.field("customData");
335            x.validate(&p)?;
336        }
337        Ok(())
338    }
339}
340
341/// *(2.1)* A generic address format.
342#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
343#[serde(deny_unknown_fields)]
344pub struct Address {
345    /// Name of person/company
346    #[serde(rename = "name")]
347    pub name: String,
348    /// Address line 1
349    #[serde(rename = "address1")]
350    pub address1: String,
351    /// Address line 2
352    #[serde(rename = "address2", default, skip_serializing_if = "Option::is_none")]
353    pub address2: Option<String>,
354    /// City
355    #[serde(rename = "city")]
356    pub city: String,
357    /// Postal code
358    #[serde(
359        rename = "postalCode",
360        default,
361        skip_serializing_if = "Option::is_none"
362    )]
363    pub postal_code: Option<String>,
364    /// Country name
365    #[serde(rename = "country")]
366    pub country: String,
367    #[serde(
368        rename = "customData",
369        default,
370        skip_serializing_if = "Option::is_none"
371    )]
372    pub custom_data: Option<CustomData>,
373}
374
375impl Validate for Address {
376    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
377        {
378            let x = &self.name;
379            let p = path.field("name");
380            v::max_length(x, 50, &p)?;
381        }
382        {
383            let x = &self.address1;
384            let p = path.field("address1");
385            v::max_length(x, 100, &p)?;
386        }
387        if let Some(x) = &self.address2 {
388            let p = path.field("address2");
389            v::max_length(x, 100, &p)?;
390        }
391        {
392            let x = &self.city;
393            let p = path.field("city");
394            v::max_length(x, 100, &p)?;
395        }
396        if let Some(x) = &self.postal_code {
397            let p = path.field("postalCode");
398            v::max_length(x, 20, &p)?;
399        }
400        {
401            let x = &self.country;
402            let p = path.field("country");
403            v::max_length(x, 50, &p)?;
404        }
405        if let Some(x) = &self.custom_data {
406            let p = path.field("customData");
407            x.validate(&p)?;
408        }
409        Ok(())
410    }
411}
412
413/// Contains the identifier to use for authorization.
414#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
415#[serde(deny_unknown_fields)]
416pub struct AuthorizationData {
417    #[serde(rename = "idToken")]
418    pub id_token: IdToken,
419    #[serde(
420        rename = "idTokenInfo",
421        default,
422        skip_serializing_if = "Option::is_none"
423    )]
424    pub id_token_info: Option<IdTokenInfo>,
425    #[serde(
426        rename = "customData",
427        default,
428        skip_serializing_if = "Option::is_none"
429    )]
430    pub custom_data: Option<CustomData>,
431}
432
433impl Validate for AuthorizationData {
434    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
435        {
436            let x = &self.id_token;
437            let p = path.field("idToken");
438            x.validate(&p)?;
439        }
440        if let Some(x) = &self.id_token_info {
441            let p = path.field("idTokenInfo");
442            x.validate(&p)?;
443        }
444        if let Some(x) = &self.custom_data {
445            let p = path.field("customData");
446            x.validate(&p)?;
447        }
448        Ok(())
449    }
450}
451
452#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
453#[serde(deny_unknown_fields)]
454pub struct BatteryData {
455    /// Slot number where battery is inserted or removed.
456    #[serde(rename = "evseId")]
457    pub evse_id: i64,
458    /// Serial number of battery.
459    #[serde(rename = "serialNumber")]
460    pub serial_number: String,
461    /// State of charge
462    #[serde(rename = "soC")]
463    pub so_c: f64,
464    /// State of health
465    #[serde(rename = "soH")]
466    pub so_h: f64,
467    /// Production date of battery.
468    #[serde(
469        rename = "productionDate",
470        default,
471        skip_serializing_if = "Option::is_none"
472    )]
473    pub production_date: Option<DateTime>,
474    /// Vendor-specific info from battery in undefined format.
475    #[serde(
476        rename = "vendorInfo",
477        default,
478        skip_serializing_if = "Option::is_none"
479    )]
480    pub vendor_info: Option<String>,
481    #[serde(
482        rename = "customData",
483        default,
484        skip_serializing_if = "Option::is_none"
485    )]
486    pub custom_data: Option<CustomData>,
487}
488
489impl Validate for BatteryData {
490    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
491        {
492            let x = &self.evse_id;
493            let p = path.field("evseId");
494            v::minimum(*x, 0i64, &p)?;
495        }
496        {
497            let x = &self.serial_number;
498            let p = path.field("serialNumber");
499            v::max_length(x, 50, &p)?;
500        }
501        {
502            let x = &self.so_c;
503            let p = path.field("soC");
504            v::minimum(*x, 0.0, &p)?;
505            v::maximum(*x, 100.0, &p)?;
506        }
507        {
508            let x = &self.so_h;
509            let p = path.field("soH");
510            v::minimum(*x, 0.0, &p)?;
511            v::maximum(*x, 100.0, &p)?;
512        }
513        if let Some(x) = &self.vendor_info {
514            let p = path.field("vendorInfo");
515            v::max_length(x, 500, &p)?;
516        }
517        if let Some(x) = &self.custom_data {
518            let p = path.field("customData");
519            x.validate(&p)?;
520        }
521        Ok(())
522    }
523}
524
525#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
526#[serde(deny_unknown_fields)]
527pub struct CertificateHashData {
528    #[serde(rename = "hashAlgorithm")]
529    pub hash_algorithm: HashAlgorithmEnum,
530    /// The hash of the issuer’s distinguished
531    /// name (DN), that must be calculated over the DER
532    /// encoding of the issuer’s name field in the certificate
533    /// being checked.
534    #[serde(rename = "issuerNameHash")]
535    pub issuer_name_hash: String,
536    /// The hash of the DER encoded public key:
537    /// the value (excluding tag and length) of the subject
538    /// public key field in the issuer’s certificate.
539    #[serde(rename = "issuerKeyHash")]
540    pub issuer_key_hash: String,
541    /// The string representation of the
542    /// hexadecimal value of the serial number without the
543    /// prefix "0x" and without leading zeroes.
544    #[serde(rename = "serialNumber")]
545    pub serial_number: String,
546    #[serde(
547        rename = "customData",
548        default,
549        skip_serializing_if = "Option::is_none"
550    )]
551    pub custom_data: Option<CustomData>,
552}
553
554impl Validate for CertificateHashData {
555    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
556        {
557            let x = &self.issuer_name_hash;
558            let p = path.field("issuerNameHash");
559            v::max_length(x, 128, &p)?;
560        }
561        {
562            let x = &self.issuer_key_hash;
563            let p = path.field("issuerKeyHash");
564            v::max_length(x, 128, &p)?;
565        }
566        {
567            let x = &self.serial_number;
568            let p = path.field("serialNumber");
569            v::max_length(x, 40, &p)?;
570        }
571        if let Some(x) = &self.custom_data {
572            let p = path.field("customData");
573            x.validate(&p)?;
574        }
575        Ok(())
576    }
577}
578
579#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
580#[serde(deny_unknown_fields)]
581pub struct CertificateHashDataChain {
582    #[serde(rename = "certificateHashData")]
583    pub certificate_hash_data: CertificateHashData,
584    #[serde(rename = "certificateType")]
585    pub certificate_type: GetCertificateIdUseEnum,
586    #[serde(
587        rename = "childCertificateHashData",
588        default,
589        skip_serializing_if = "Option::is_none"
590    )]
591    pub child_certificate_hash_data: Option<Vec<CertificateHashData>>,
592    #[serde(
593        rename = "customData",
594        default,
595        skip_serializing_if = "Option::is_none"
596    )]
597    pub custom_data: Option<CustomData>,
598}
599
600impl Validate for CertificateHashDataChain {
601    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
602        {
603            let x = &self.certificate_hash_data;
604            let p = path.field("certificateHashData");
605            x.validate(&p)?;
606        }
607        if let Some(x) = &self.child_certificate_hash_data {
608            let p = path.field("childCertificateHashData");
609            v::items(x, Some(1), Some(4), &p)?;
610            for (i0, it0) in x.iter().enumerate() {
611                let p0 = p.index(i0);
612                it0.validate(&p0)?;
613            }
614        }
615        if let Some(x) = &self.custom_data {
616            let p = path.field("customData");
617            x.validate(&p)?;
618        }
619        Ok(())
620    }
621}
622
623/// Revocation status of certificate
624#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
625#[serde(deny_unknown_fields)]
626pub struct CertificateStatus {
627    #[serde(rename = "certificateHashData")]
628    pub certificate_hash_data: CertificateHashData,
629    #[serde(rename = "source")]
630    pub source: CertificateStatusSourceEnum,
631    #[serde(rename = "status")]
632    pub status: CertificateStatusEnum,
633    #[serde(rename = "nextUpdate")]
634    pub next_update: DateTime,
635    #[serde(
636        rename = "customData",
637        default,
638        skip_serializing_if = "Option::is_none"
639    )]
640    pub custom_data: Option<CustomData>,
641}
642
643impl Validate for CertificateStatus {
644    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
645        {
646            let x = &self.certificate_hash_data;
647            let p = path.field("certificateHashData");
648            x.validate(&p)?;
649        }
650        if let Some(x) = &self.custom_data {
651            let p = path.field("customData");
652            x.validate(&p)?;
653        }
654        Ok(())
655    }
656}
657
658/// Data necessary to request the revocation status of a certificate.
659#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
660#[serde(deny_unknown_fields)]
661pub struct CertificateStatusRequestInfo {
662    #[serde(rename = "certificateHashData")]
663    pub certificate_hash_data: CertificateHashData,
664    #[serde(rename = "source")]
665    pub source: CertificateStatusSourceEnum,
666    /// URL(s) of _source_.
667    #[serde(rename = "urls")]
668    pub urls: Vec<String>,
669    #[serde(
670        rename = "customData",
671        default,
672        skip_serializing_if = "Option::is_none"
673    )]
674    pub custom_data: Option<CustomData>,
675}
676
677impl Validate for CertificateStatusRequestInfo {
678    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
679        {
680            let x = &self.certificate_hash_data;
681            let p = path.field("certificateHashData");
682            x.validate(&p)?;
683        }
684        {
685            let x = &self.urls;
686            let p = path.field("urls");
687            v::items(x, Some(1), Some(5), &p)?;
688            for (i0, it0) in x.iter().enumerate() {
689                let p0 = p.index(i0);
690                v::max_length(it0, 2000, &p0)?;
691            }
692        }
693        if let Some(x) = &self.custom_data {
694            let p = path.field("customData");
695            x.validate(&p)?;
696        }
697        Ok(())
698    }
699}
700
701#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
702#[serde(deny_unknown_fields)]
703pub struct ChargingLimit {
704    /// Represents the source of the charging limit. Values defined in appendix as ChargingLimitSourceEnumStringType.
705    #[serde(rename = "chargingLimitSource")]
706    pub charging_limit_source: String,
707    /// *(2.1)* True when the reported limit concerns local generation that is providing extra capacity, instead of a limitation.
708    #[serde(
709        rename = "isLocalGeneration",
710        default,
711        skip_serializing_if = "Option::is_none"
712    )]
713    pub is_local_generation: Option<bool>,
714    /// Indicates whether the charging limit is critical for the grid.
715    #[serde(
716        rename = "isGridCritical",
717        default,
718        skip_serializing_if = "Option::is_none"
719    )]
720    pub is_grid_critical: Option<bool>,
721    #[serde(
722        rename = "customData",
723        default,
724        skip_serializing_if = "Option::is_none"
725    )]
726    pub custom_data: Option<CustomData>,
727}
728
729impl Validate for ChargingLimit {
730    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
731        {
732            let x = &self.charging_limit_source;
733            let p = path.field("chargingLimitSource");
734            v::max_length(x, 20, &p)?;
735        }
736        if let Some(x) = &self.custom_data {
737            let p = path.field("customData");
738            x.validate(&p)?;
739        }
740        Ok(())
741    }
742}
743
744#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
745#[serde(deny_unknown_fields)]
746pub struct ChargingNeeds {
747    #[serde(
748        rename = "acChargingParameters",
749        default,
750        skip_serializing_if = "Option::is_none"
751    )]
752    pub ac_charging_parameters: Option<ACChargingParameters>,
753    #[serde(
754        rename = "derChargingParameters",
755        default,
756        skip_serializing_if = "Option::is_none"
757    )]
758    pub der_charging_parameters: Option<DERChargingParameters>,
759    #[serde(
760        rename = "evEnergyOffer",
761        default,
762        skip_serializing_if = "Option::is_none"
763    )]
764    pub ev_energy_offer: Option<EVEnergyOffer>,
765    #[serde(rename = "requestedEnergyTransfer")]
766    pub requested_energy_transfer: EnergyTransferModeEnum,
767    #[serde(
768        rename = "dcChargingParameters",
769        default,
770        skip_serializing_if = "Option::is_none"
771    )]
772    pub dc_charging_parameters: Option<DCChargingParameters>,
773    #[serde(
774        rename = "v2xChargingParameters",
775        default,
776        skip_serializing_if = "Option::is_none"
777    )]
778    pub v2x_charging_parameters: Option<V2XChargingParameters>,
779    /// *(2.1)* Modes of energy transfer that are marked as available by EV.
780    #[serde(
781        rename = "availableEnergyTransfer",
782        default,
783        skip_serializing_if = "Option::is_none"
784    )]
785    pub available_energy_transfer: Option<Vec<EnergyTransferModeEnum>>,
786    #[serde(
787        rename = "controlMode",
788        default,
789        skip_serializing_if = "Option::is_none"
790    )]
791    pub control_mode: Option<ControlModeEnum>,
792    #[serde(
793        rename = "mobilityNeedsMode",
794        default,
795        skip_serializing_if = "Option::is_none"
796    )]
797    pub mobility_needs_mode: Option<MobilityNeedsModeEnum>,
798    /// Estimated departure time of the EV. +
799    /// *ISO 15118-2:* AC/DC_EVChargeParameterType: DepartureTime +
800    /// *ISO 15118-20:* Dynamic/Scheduled_SEReqControlModeType: DepartureTIme
801    #[serde(
802        rename = "departureTime",
803        default,
804        skip_serializing_if = "Option::is_none"
805    )]
806    pub departure_time: Option<DateTime>,
807    #[serde(
808        rename = "customData",
809        default,
810        skip_serializing_if = "Option::is_none"
811    )]
812    pub custom_data: Option<CustomData>,
813}
814
815impl Validate for ChargingNeeds {
816    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
817        if let Some(x) = &self.ac_charging_parameters {
818            let p = path.field("acChargingParameters");
819            x.validate(&p)?;
820        }
821        if let Some(x) = &self.der_charging_parameters {
822            let p = path.field("derChargingParameters");
823            x.validate(&p)?;
824        }
825        if let Some(x) = &self.ev_energy_offer {
826            let p = path.field("evEnergyOffer");
827            x.validate(&p)?;
828        }
829        if let Some(x) = &self.dc_charging_parameters {
830            let p = path.field("dcChargingParameters");
831            x.validate(&p)?;
832        }
833        if let Some(x) = &self.v2x_charging_parameters {
834            let p = path.field("v2xChargingParameters");
835            x.validate(&p)?;
836        }
837        if let Some(x) = &self.available_energy_transfer {
838            let p = path.field("availableEnergyTransfer");
839            v::items(x, Some(1), None, &p)?;
840        }
841        if let Some(x) = &self.custom_data {
842            let p = path.field("customData");
843            x.validate(&p)?;
844        }
845        Ok(())
846    }
847}
848
849/// 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.
850#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
851#[serde(deny_unknown_fields)]
852pub struct ChargingPeriod {
853    #[serde(
854        rename = "dimensions",
855        default,
856        skip_serializing_if = "Option::is_none"
857    )]
858    pub dimensions: Option<Vec<CostDimension>>,
859    /// Unique identifier of the Tariff that was used to calculate cost. If not provided, then cost was calculated by some other means.
860    #[serde(rename = "tariffId", default, skip_serializing_if = "Option::is_none")]
861    pub tariff_id: Option<String>,
862    /// Start timestamp of charging period. A period ends when the next period starts. The last period ends when the session ends.
863    #[serde(rename = "startPeriod")]
864    pub start_period: DateTime,
865    #[serde(
866        rename = "customData",
867        default,
868        skip_serializing_if = "Option::is_none"
869    )]
870    pub custom_data: Option<CustomData>,
871}
872
873impl Validate for ChargingPeriod {
874    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
875        if let Some(x) = &self.dimensions {
876            let p = path.field("dimensions");
877            v::items(x, Some(1), None, &p)?;
878            for (i0, it0) in x.iter().enumerate() {
879                let p0 = p.index(i0);
880                it0.validate(&p0)?;
881            }
882        }
883        if let Some(x) = &self.tariff_id {
884            let p = path.field("tariffId");
885            v::max_length(x, 60, &p)?;
886        }
887        if let Some(x) = &self.custom_data {
888            let p = path.field("customData");
889            x.validate(&p)?;
890        }
891        Ok(())
892    }
893}
894
895/// 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.
896/// image::images/ChargingProfile-Simple.png\[\]
897#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
898#[serde(deny_unknown_fields)]
899pub struct ChargingProfile {
900    /// 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.
901    #[serde(rename = "id")]
902    pub id: i64,
903    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
904    #[serde(rename = "stackLevel")]
905    pub stack_level: i64,
906    #[serde(rename = "chargingProfilePurpose")]
907    pub charging_profile_purpose: ChargingProfilePurposeEnum,
908    #[serde(rename = "chargingProfileKind")]
909    pub charging_profile_kind: ChargingProfileKindEnum,
910    #[serde(
911        rename = "recurrencyKind",
912        default,
913        skip_serializing_if = "Option::is_none"
914    )]
915    pub recurrency_kind: Option<RecurrencyKindEnum>,
916    /// 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.
917    #[serde(rename = "validFrom", default, skip_serializing_if = "Option::is_none")]
918    pub valid_from: Option<DateTime>,
919    /// Point in time at which the profile stops to be valid. If absent, the profile is valid until it is replaced by another profile.
920    #[serde(rename = "validTo", default, skip_serializing_if = "Option::is_none")]
921    pub valid_to: Option<DateTime>,
922    /// 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.
923    #[serde(
924        rename = "transactionId",
925        default,
926        skip_serializing_if = "Option::is_none"
927    )]
928    pub transaction_id: Option<String>,
929    /// *(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.
930    /// If _invalidAfterOfflineDuration_ is true, then this charging profile will become permanently invalid.
931    /// 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.
932    #[serde(
933        rename = "maxOfflineDuration",
934        default,
935        skip_serializing_if = "Option::is_none"
936    )]
937    pub max_offline_duration: Option<i64>,
938    #[serde(rename = "chargingSchedule")]
939    pub charging_schedule: Vec<ChargingSchedule>,
940    /// *(2.1)* When set to true this charging profile will not be valid anymore after being offline for more than _maxOfflineDuration_. +
941    /// When absent defaults to false.
942    #[serde(
943        rename = "invalidAfterOfflineDuration",
944        default,
945        skip_serializing_if = "Option::is_none"
946    )]
947    pub invalid_after_offline_duration: Option<bool>,
948    /// *(2.1)*  Interval in seconds after receipt of last update, when to request a profile update by sending a PullDynamicScheduleUpdateRequest message.
949    /// A value of 0 or no value means that no update interval applies. +
950    /// Only relevant in a dynamic charging profile.
951    #[serde(
952        rename = "dynUpdateInterval",
953        default,
954        skip_serializing_if = "Option::is_none"
955    )]
956    pub dyn_update_interval: Option<i64>,
957    /// *(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. +
958    /// Only relevant in a dynamic charging profile.
959    #[serde(
960        rename = "dynUpdateTime",
961        default,
962        skip_serializing_if = "Option::is_none"
963    )]
964    pub dyn_update_time: Option<DateTime>,
965    /// *(2.1)* ISO 15118-20 signature for all price schedules in _chargingSchedules_. +
966    /// 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.
967    #[serde(
968        rename = "priceScheduleSignature",
969        default,
970        skip_serializing_if = "Option::is_none"
971    )]
972    pub price_schedule_signature: Option<String>,
973    #[serde(
974        rename = "customData",
975        default,
976        skip_serializing_if = "Option::is_none"
977    )]
978    pub custom_data: Option<CustomData>,
979}
980
981impl Validate for ChargingProfile {
982    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
983        {
984            let x = &self.stack_level;
985            let p = path.field("stackLevel");
986            v::minimum(*x, 0i64, &p)?;
987        }
988        if let Some(x) = &self.transaction_id {
989            let p = path.field("transactionId");
990            v::max_length(x, 36, &p)?;
991        }
992        {
993            let x = &self.charging_schedule;
994            let p = path.field("chargingSchedule");
995            v::items(x, Some(1), Some(3), &p)?;
996            for (i0, it0) in x.iter().enumerate() {
997                let p0 = p.index(i0);
998                it0.validate(&p0)?;
999            }
1000        }
1001        if let Some(x) = &self.price_schedule_signature {
1002            let p = path.field("priceScheduleSignature");
1003            v::max_length(x, 256, &p)?;
1004        }
1005        if let Some(x) = &self.custom_data {
1006            let p = path.field("customData");
1007            x.validate(&p)?;
1008        }
1009        Ok(())
1010    }
1011}
1012
1013/// A ChargingProfileCriterionType is a filter for charging profiles to be selected by a GetChargingProfilesRequest.
1014#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
1015#[serde(deny_unknown_fields)]
1016pub struct ChargingProfileCriterion {
1017    #[serde(
1018        rename = "chargingProfilePurpose",
1019        default,
1020        skip_serializing_if = "Option::is_none"
1021    )]
1022    pub charging_profile_purpose: Option<ChargingProfilePurposeEnum>,
1023    /// Value determining level in hierarchy stack of profiles. Higher values have precedence over lower values. Lowest level is 0.
1024    #[serde(
1025        rename = "stackLevel",
1026        default,
1027        skip_serializing_if = "Option::is_none"
1028    )]
1029    pub stack_level: Option<i64>,
1030    /// 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;
1031    #[serde(
1032        rename = "chargingProfileId",
1033        default,
1034        skip_serializing_if = "Option::is_none"
1035    )]
1036    pub charging_profile_id: Option<Vec<i64>>,
1037    /// 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.
1038    #[serde(
1039        rename = "chargingLimitSource",
1040        default,
1041        skip_serializing_if = "Option::is_none"
1042    )]
1043    pub charging_limit_source: Option<Vec<String>>,
1044    #[serde(
1045        rename = "customData",
1046        default,
1047        skip_serializing_if = "Option::is_none"
1048    )]
1049    pub custom_data: Option<CustomData>,
1050}
1051
1052impl Validate for ChargingProfileCriterion {
1053    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1054        if let Some(x) = &self.stack_level {
1055            let p = path.field("stackLevel");
1056            v::minimum(*x, 0i64, &p)?;
1057        }
1058        if let Some(x) = &self.charging_profile_id {
1059            let p = path.field("chargingProfileId");
1060            v::items(x, Some(1), None, &p)?;
1061        }
1062        if let Some(x) = &self.charging_limit_source {
1063            let p = path.field("chargingLimitSource");
1064            v::items(x, Some(1), Some(4), &p)?;
1065            for (i0, it0) in x.iter().enumerate() {
1066                let p0 = p.index(i0);
1067                v::max_length(it0, 20, &p0)?;
1068            }
1069        }
1070        if let Some(x) = &self.custom_data {
1071            let p = path.field("customData");
1072            x.validate(&p)?;
1073        }
1074        Ok(())
1075    }
1076}
1077
1078/// 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'. +
1079/// 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.
1080/// image::images/ChargingSchedule-Simple.png\[\]
1081#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1082#[serde(deny_unknown_fields)]
1083pub struct ChargingSchedule {
1084    #[serde(rename = "id")]
1085    pub id: i64,
1086    #[serde(
1087        rename = "limitAtSoC",
1088        default,
1089        skip_serializing_if = "Option::is_none"
1090    )]
1091    pub limit_at_so_c: Option<LimitAtSoC>,
1092    /// Starting point of an absolute schedule or recurring schedule.
1093    #[serde(
1094        rename = "startSchedule",
1095        default,
1096        skip_serializing_if = "Option::is_none"
1097    )]
1098    pub start_schedule: Option<DateTime>,
1099    /// 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.
1100    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
1101    pub duration: Option<i64>,
1102    #[serde(rename = "chargingRateUnit")]
1103    pub charging_rate_unit: ChargingRateUnitEnum,
1104    /// 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.
1105    #[serde(
1106        rename = "minChargingRate",
1107        default,
1108        skip_serializing_if = "Option::is_none"
1109    )]
1110    pub min_charging_rate: Option<f64>,
1111    /// *(2.1)* Power tolerance when following EVPowerProfile.
1112    #[serde(
1113        rename = "powerTolerance",
1114        default,
1115        skip_serializing_if = "Option::is_none"
1116    )]
1117    pub power_tolerance: Option<f64>,
1118    /// *(2.1)* Id of this element for referencing in a signature.
1119    #[serde(
1120        rename = "signatureId",
1121        default,
1122        skip_serializing_if = "Option::is_none"
1123    )]
1124    pub signature_id: Option<i64>,
1125    /// *(2.1)* Base64 encoded hash (SHA256 for ISO 15118-2, SHA512 for ISO 15118-20) of the EXI price schedule element. Used in signature.
1126    #[serde(
1127        rename = "digestValue",
1128        default,
1129        skip_serializing_if = "Option::is_none"
1130    )]
1131    pub digest_value: Option<String>,
1132    /// *(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.
1133    /// This allows the same `Absolute` or `Recurring` charging profile to be used in both summer and winter time.
1134    #[serde(
1135        rename = "useLocalTime",
1136        default,
1137        skip_serializing_if = "Option::is_none"
1138    )]
1139    pub use_local_time: Option<bool>,
1140    #[serde(rename = "chargingSchedulePeriod")]
1141    pub charging_schedule_period: Vec<ChargingSchedulePeriod>,
1142    /// *(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.
1143    #[serde(
1144        rename = "randomizedDelay",
1145        default,
1146        skip_serializing_if = "Option::is_none"
1147    )]
1148    pub randomized_delay: Option<i64>,
1149    #[serde(
1150        rename = "salesTariff",
1151        default,
1152        skip_serializing_if = "Option::is_none"
1153    )]
1154    pub sales_tariff: Option<SalesTariff>,
1155    #[serde(
1156        rename = "absolutePriceSchedule",
1157        default,
1158        skip_serializing_if = "Option::is_none"
1159    )]
1160    pub absolute_price_schedule: Option<AbsolutePriceSchedule>,
1161    #[serde(
1162        rename = "priceLevelSchedule",
1163        default,
1164        skip_serializing_if = "Option::is_none"
1165    )]
1166    pub price_level_schedule: Option<PriceLevelSchedule>,
1167    #[serde(
1168        rename = "customData",
1169        default,
1170        skip_serializing_if = "Option::is_none"
1171    )]
1172    pub custom_data: Option<CustomData>,
1173}
1174
1175impl Validate for ChargingSchedule {
1176    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1177        if let Some(x) = &self.limit_at_so_c {
1178            let p = path.field("limitAtSoC");
1179            x.validate(&p)?;
1180        }
1181        if let Some(x) = &self.signature_id {
1182            let p = path.field("signatureId");
1183            v::minimum(*x, 0i64, &p)?;
1184        }
1185        if let Some(x) = &self.digest_value {
1186            let p = path.field("digestValue");
1187            v::max_length(x, 88, &p)?;
1188        }
1189        {
1190            let x = &self.charging_schedule_period;
1191            let p = path.field("chargingSchedulePeriod");
1192            v::items(x, Some(1), Some(1024), &p)?;
1193            for (i0, it0) in x.iter().enumerate() {
1194                let p0 = p.index(i0);
1195                it0.validate(&p0)?;
1196            }
1197        }
1198        if let Some(x) = &self.randomized_delay {
1199            let p = path.field("randomizedDelay");
1200            v::minimum(*x, 0i64, &p)?;
1201        }
1202        if let Some(x) = &self.sales_tariff {
1203            let p = path.field("salesTariff");
1204            x.validate(&p)?;
1205        }
1206        if let Some(x) = &self.absolute_price_schedule {
1207            let p = path.field("absolutePriceSchedule");
1208            x.validate(&p)?;
1209        }
1210        if let Some(x) = &self.price_level_schedule {
1211            let p = path.field("priceLevelSchedule");
1212            x.validate(&p)?;
1213        }
1214        if let Some(x) = &self.custom_data {
1215            let p = path.field("customData");
1216            x.validate(&p)?;
1217        }
1218        Ok(())
1219    }
1220}
1221
1222/// 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.
1223#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1224#[serde(deny_unknown_fields)]
1225pub struct ChargingSchedulePeriod {
1226    /// Start of the period, in seconds from the start of schedule. The value of StartPeriod also defines the stop time of the previous period.
1227    #[serde(rename = "startPeriod")]
1228    pub start_period: i64,
1229    /// Optional only when not required by the _operationMode_, as in CentralSetpoint, ExternalSetpoint, ExternalLimits, LocalFrequency,  LocalLoadBalancing. +
1230    /// Charging rate limit during the schedule period, in the applicable _chargingRateUnit_.
1231    /// 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.
1232    /// 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.
1233    #[serde(rename = "limit", default, skip_serializing_if = "Option::is_none")]
1234    pub limit: Option<f64>,
1235    /// *(2.1)* Charging rate limit on phase L2  in the applicable _chargingRateUnit_.
1236    #[serde(rename = "limit_L2", default, skip_serializing_if = "Option::is_none")]
1237    pub limit_l2: Option<f64>,
1238    /// *(2.1)* Charging rate limit on phase L3  in the applicable _chargingRateUnit_.
1239    #[serde(rename = "limit_L3", default, skip_serializing_if = "Option::is_none")]
1240    pub limit_l3: Option<f64>,
1241    /// The number of phases that can be used for charging. +
1242    /// For a DC EVSE this field should be omitted. +
1243    /// For an AC EVSE a default value of _numberPhases_ = 3 will be assumed if the field is absent.
1244    #[serde(
1245        rename = "numberPhases",
1246        default,
1247        skip_serializing_if = "Option::is_none"
1248    )]
1249    pub number_phases: Option<i64>,
1250    /// 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.
1251    #[serde(
1252        rename = "phaseToUse",
1253        default,
1254        skip_serializing_if = "Option::is_none"
1255    )]
1256    pub phase_to_use: Option<i64>,
1257    /// *(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.  +
1258    /// 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.
1259    #[serde(
1260        rename = "dischargeLimit",
1261        default,
1262        skip_serializing_if = "Option::is_none"
1263    )]
1264    pub discharge_limit: Option<f64>,
1265    /// *(2.1)* Limit in _chargingRateUnit_ on phase L2 that the EV is allowed to discharge with.
1266    #[serde(
1267        rename = "dischargeLimit_L2",
1268        default,
1269        skip_serializing_if = "Option::is_none"
1270    )]
1271    pub discharge_limit_l2: Option<f64>,
1272    /// *(2.1)* Limit in _chargingRateUnit_ on phase L3 that the EV is allowed to discharge with.
1273    #[serde(
1274        rename = "dischargeLimit_L3",
1275        default,
1276        skip_serializing_if = "Option::is_none"
1277    )]
1278    pub discharge_limit_l3: Option<f64>,
1279    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow as close as possible. Use negative values for discharging. +
1280    /// When a limit and/or _dischargeLimit_ are given the overshoot when following _setpoint_ must remain within these values.
1281    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
1282    #[serde(rename = "setpoint", default, skip_serializing_if = "Option::is_none")]
1283    pub setpoint: Option<f64>,
1284    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L2 as close as possible.
1285    #[serde(
1286        rename = "setpoint_L2",
1287        default,
1288        skip_serializing_if = "Option::is_none"
1289    )]
1290    pub setpoint_l2: Option<f64>,
1291    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L3 as close as possible.
1292    #[serde(
1293        rename = "setpoint_L3",
1294        default,
1295        skip_serializing_if = "Option::is_none"
1296    )]
1297    pub setpoint_l3: Option<f64>,
1298    /// *(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.  +
1299    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
1300    #[serde(
1301        rename = "setpointReactive",
1302        default,
1303        skip_serializing_if = "Option::is_none"
1304    )]
1305    pub setpoint_reactive: Option<f64>,
1306    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L2 as closely as possible.
1307    #[serde(
1308        rename = "setpointReactive_L2",
1309        default,
1310        skip_serializing_if = "Option::is_none"
1311    )]
1312    pub setpoint_reactive_l2: Option<f64>,
1313    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L3 as closely as possible.
1314    #[serde(
1315        rename = "setpointReactive_L3",
1316        default,
1317        skip_serializing_if = "Option::is_none"
1318    )]
1319    pub setpoint_reactive_l3: Option<f64>,
1320    /// *(2.1)* If  true, the EV should attempt to keep the BMS preconditioned for this time interval.
1321    #[serde(
1322        rename = "preconditioningRequest",
1323        default,
1324        skip_serializing_if = "Option::is_none"
1325    )]
1326    pub preconditioning_request: Option<bool>,
1327    /// *(2.1)* If true, the EVSE must turn off power electronics/modules associated with this transaction. Default value when absent is false.
1328    #[serde(rename = "evseSleep", default, skip_serializing_if = "Option::is_none")]
1329    pub evse_sleep: Option<bool>,
1330    /// *(2.1)* Power value that, when present, is used as a baseline on top of which values from _v2xFreqWattCurve_ and _v2xSignalWattCurve_ are added.
1331    #[serde(
1332        rename = "v2xBaseline",
1333        default,
1334        skip_serializing_if = "Option::is_none"
1335    )]
1336    pub v2x_baseline: Option<f64>,
1337    #[serde(
1338        rename = "operationMode",
1339        default,
1340        skip_serializing_if = "Option::is_none"
1341    )]
1342    pub operation_mode: Option<OperationModeEnum>,
1343    #[serde(
1344        rename = "v2xFreqWattCurve",
1345        default,
1346        skip_serializing_if = "Option::is_none"
1347    )]
1348    pub v2x_freq_watt_curve: Option<Vec<V2XFreqWattPoint>>,
1349    #[serde(
1350        rename = "v2xSignalWattCurve",
1351        default,
1352        skip_serializing_if = "Option::is_none"
1353    )]
1354    pub v2x_signal_watt_curve: Option<Vec<V2XSignalWattPoint>>,
1355    #[serde(
1356        rename = "customData",
1357        default,
1358        skip_serializing_if = "Option::is_none"
1359    )]
1360    pub custom_data: Option<CustomData>,
1361}
1362
1363impl Validate for ChargingSchedulePeriod {
1364    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1365        if let Some(x) = &self.number_phases {
1366            let p = path.field("numberPhases");
1367            v::minimum(*x, 0i64, &p)?;
1368            v::maximum(*x, 3i64, &p)?;
1369        }
1370        if let Some(x) = &self.phase_to_use {
1371            let p = path.field("phaseToUse");
1372            v::minimum(*x, 0i64, &p)?;
1373            v::maximum(*x, 3i64, &p)?;
1374        }
1375        if let Some(x) = &self.discharge_limit {
1376            let p = path.field("dischargeLimit");
1377            v::maximum(*x, 0.0, &p)?;
1378        }
1379        if let Some(x) = &self.discharge_limit_l2 {
1380            let p = path.field("dischargeLimit_L2");
1381            v::maximum(*x, 0.0, &p)?;
1382        }
1383        if let Some(x) = &self.discharge_limit_l3 {
1384            let p = path.field("dischargeLimit_L3");
1385            v::maximum(*x, 0.0, &p)?;
1386        }
1387        if let Some(x) = &self.v2x_freq_watt_curve {
1388            let p = path.field("v2xFreqWattCurve");
1389            v::items(x, Some(1), Some(20), &p)?;
1390            for (i0, it0) in x.iter().enumerate() {
1391                let p0 = p.index(i0);
1392                it0.validate(&p0)?;
1393            }
1394        }
1395        if let Some(x) = &self.v2x_signal_watt_curve {
1396            let p = path.field("v2xSignalWattCurve");
1397            v::items(x, Some(1), Some(20), &p)?;
1398            for (i0, it0) in x.iter().enumerate() {
1399                let p0 = p.index(i0);
1400                it0.validate(&p0)?;
1401            }
1402        }
1403        if let Some(x) = &self.custom_data {
1404            let p = path.field("customData");
1405            x.validate(&p)?;
1406        }
1407        Ok(())
1408    }
1409}
1410
1411/// Updates to a ChargingSchedulePeriodType for dynamic charging profiles.
1412#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
1413#[serde(deny_unknown_fields)]
1414pub struct ChargingScheduleUpdate {
1415    /// Optional only when not required by the _operationMode_, as in CentralSetpoint, ExternalSetpoint, ExternalLimits, LocalFrequency,  LocalLoadBalancing. +
1416    /// Charging rate limit during the schedule period, in the applicable _chargingRateUnit_.
1417    /// 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.
1418    /// 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.
1419    #[serde(rename = "limit", default, skip_serializing_if = "Option::is_none")]
1420    pub limit: Option<f64>,
1421    /// *(2.1)* Charging rate limit on phase L2  in the applicable _chargingRateUnit_.
1422    #[serde(rename = "limit_L2", default, skip_serializing_if = "Option::is_none")]
1423    pub limit_l2: Option<f64>,
1424    /// *(2.1)* Charging rate limit on phase L3  in the applicable _chargingRateUnit_.
1425    #[serde(rename = "limit_L3", default, skip_serializing_if = "Option::is_none")]
1426    pub limit_l3: Option<f64>,
1427    /// *(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.  +
1428    /// 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.
1429    #[serde(
1430        rename = "dischargeLimit",
1431        default,
1432        skip_serializing_if = "Option::is_none"
1433    )]
1434    pub discharge_limit: Option<f64>,
1435    /// *(2.1)* Limit in _chargingRateUnit_ on phase L2 that the EV is allowed to discharge with.
1436    #[serde(
1437        rename = "dischargeLimit_L2",
1438        default,
1439        skip_serializing_if = "Option::is_none"
1440    )]
1441    pub discharge_limit_l2: Option<f64>,
1442    /// *(2.1)* Limit in _chargingRateUnit_ on phase L3 that the EV is allowed to discharge with.
1443    #[serde(
1444        rename = "dischargeLimit_L3",
1445        default,
1446        skip_serializing_if = "Option::is_none"
1447    )]
1448    pub discharge_limit_l3: Option<f64>,
1449    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow as close as possible. Use negative values for discharging. +
1450    /// When a limit and/or _dischargeLimit_ are given the overshoot when following _setpoint_ must remain within these values.
1451    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
1452    #[serde(rename = "setpoint", default, skip_serializing_if = "Option::is_none")]
1453    pub setpoint: Option<f64>,
1454    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L2 as close as possible.
1455    #[serde(
1456        rename = "setpoint_L2",
1457        default,
1458        skip_serializing_if = "Option::is_none"
1459    )]
1460    pub setpoint_l2: Option<f64>,
1461    /// *(2.1)* Setpoint in _chargingRateUnit_ that the EV should follow on phase L3 as close as possible.
1462    #[serde(
1463        rename = "setpoint_L3",
1464        default,
1465        skip_serializing_if = "Option::is_none"
1466    )]
1467    pub setpoint_l3: Option<f64>,
1468    /// *(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.  +
1469    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
1470    #[serde(
1471        rename = "setpointReactive",
1472        default,
1473        skip_serializing_if = "Option::is_none"
1474    )]
1475    pub setpoint_reactive: Option<f64>,
1476    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L2 as closely as possible.
1477    #[serde(
1478        rename = "setpointReactive_L2",
1479        default,
1480        skip_serializing_if = "Option::is_none"
1481    )]
1482    pub setpoint_reactive_l2: Option<f64>,
1483    /// *(2.1)* Setpoint for reactive power (or current) in _chargingRateUnit_ that the EV should follow on phase L3 as closely as possible.
1484    #[serde(
1485        rename = "setpointReactive_L3",
1486        default,
1487        skip_serializing_if = "Option::is_none"
1488    )]
1489    pub setpoint_reactive_l3: Option<f64>,
1490    #[serde(
1491        rename = "customData",
1492        default,
1493        skip_serializing_if = "Option::is_none"
1494    )]
1495    pub custom_data: Option<CustomData>,
1496}
1497
1498impl Validate for ChargingScheduleUpdate {
1499    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1500        if let Some(x) = &self.discharge_limit {
1501            let p = path.field("dischargeLimit");
1502            v::maximum(*x, 0.0, &p)?;
1503        }
1504        if let Some(x) = &self.discharge_limit_l2 {
1505            let p = path.field("dischargeLimit_L2");
1506            v::maximum(*x, 0.0, &p)?;
1507        }
1508        if let Some(x) = &self.discharge_limit_l3 {
1509            let p = path.field("dischargeLimit_L3");
1510            v::maximum(*x, 0.0, &p)?;
1511        }
1512        if let Some(x) = &self.custom_data {
1513            let p = path.field("customData");
1514            x.validate(&p)?;
1515        }
1516        Ok(())
1517    }
1518}
1519
1520/// The physical system where an Electrical Vehicle (EV) can be charged.
1521#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1522#[serde(deny_unknown_fields)]
1523pub struct ChargingStation {
1524    /// Vendor-specific device identifier.
1525    #[serde(
1526        rename = "serialNumber",
1527        default,
1528        skip_serializing_if = "Option::is_none"
1529    )]
1530    pub serial_number: Option<String>,
1531    /// Defines the model of the device.
1532    #[serde(rename = "model")]
1533    pub model: String,
1534    #[serde(rename = "modem", default, skip_serializing_if = "Option::is_none")]
1535    pub modem: Option<Modem>,
1536    /// Identifies the vendor (not necessarily in a unique manner).
1537    #[serde(rename = "vendorName")]
1538    pub vendor_name: String,
1539    /// This contains the firmware version of the Charging Station.
1540    #[serde(
1541        rename = "firmwareVersion",
1542        default,
1543        skip_serializing_if = "Option::is_none"
1544    )]
1545    pub firmware_version: Option<String>,
1546    #[serde(
1547        rename = "customData",
1548        default,
1549        skip_serializing_if = "Option::is_none"
1550    )]
1551    pub custom_data: Option<CustomData>,
1552}
1553
1554impl Validate for ChargingStation {
1555    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1556        if let Some(x) = &self.serial_number {
1557            let p = path.field("serialNumber");
1558            v::max_length(x, 25, &p)?;
1559        }
1560        {
1561            let x = &self.model;
1562            let p = path.field("model");
1563            v::max_length(x, 20, &p)?;
1564        }
1565        if let Some(x) = &self.modem {
1566            let p = path.field("modem");
1567            x.validate(&p)?;
1568        }
1569        {
1570            let x = &self.vendor_name;
1571            let p = path.field("vendorName");
1572            v::max_length(x, 50, &p)?;
1573        }
1574        if let Some(x) = &self.firmware_version {
1575            let p = path.field("firmwareVersion");
1576            v::max_length(x, 50, &p)?;
1577        }
1578        if let Some(x) = &self.custom_data {
1579            let p = path.field("customData");
1580            x.validate(&p)?;
1581        }
1582        Ok(())
1583    }
1584}
1585
1586/// A ClearChargingProfileType is a filter for charging profiles to be cleared by ClearChargingProfileRequest.
1587#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
1588#[serde(deny_unknown_fields)]
1589pub struct ClearChargingProfile {
1590    /// 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.
1591    #[serde(rename = "evseId", default, skip_serializing_if = "Option::is_none")]
1592    pub evse_id: Option<i64>,
1593    #[serde(
1594        rename = "chargingProfilePurpose",
1595        default,
1596        skip_serializing_if = "Option::is_none"
1597    )]
1598    pub charging_profile_purpose: Option<ChargingProfilePurposeEnum>,
1599    /// Specifies the stackLevel for which charging profiles will be cleared, if they meet the other criteria in the request.
1600    #[serde(
1601        rename = "stackLevel",
1602        default,
1603        skip_serializing_if = "Option::is_none"
1604    )]
1605    pub stack_level: Option<i64>,
1606    #[serde(
1607        rename = "customData",
1608        default,
1609        skip_serializing_if = "Option::is_none"
1610    )]
1611    pub custom_data: Option<CustomData>,
1612}
1613
1614impl Validate for ClearChargingProfile {
1615    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1616        if let Some(x) = &self.evse_id {
1617            let p = path.field("evseId");
1618            v::minimum(*x, 0i64, &p)?;
1619        }
1620        if let Some(x) = &self.stack_level {
1621            let p = path.field("stackLevel");
1622            v::minimum(*x, 0i64, &p)?;
1623        }
1624        if let Some(x) = &self.custom_data {
1625            let p = path.field("customData");
1626            x.validate(&p)?;
1627        }
1628        Ok(())
1629    }
1630}
1631
1632#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1633#[serde(deny_unknown_fields)]
1634pub struct ClearMonitoringResult {
1635    #[serde(rename = "status")]
1636    pub status: ClearMonitoringStatusEnum,
1637    /// Id of the monitor of which a clear was requested.
1638    #[serde(rename = "id")]
1639    pub id: i64,
1640    #[serde(
1641        rename = "statusInfo",
1642        default,
1643        skip_serializing_if = "Option::is_none"
1644    )]
1645    pub status_info: Option<StatusInfo>,
1646    #[serde(
1647        rename = "customData",
1648        default,
1649        skip_serializing_if = "Option::is_none"
1650    )]
1651    pub custom_data: Option<CustomData>,
1652}
1653
1654impl Validate for ClearMonitoringResult {
1655    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1656        {
1657            let x = &self.id;
1658            let p = path.field("id");
1659            v::minimum(*x, 0i64, &p)?;
1660        }
1661        if let Some(x) = &self.status_info {
1662            let p = path.field("statusInfo");
1663            x.validate(&p)?;
1664        }
1665        if let Some(x) = &self.custom_data {
1666            let p = path.field("customData");
1667            x.validate(&p)?;
1668        }
1669        Ok(())
1670    }
1671}
1672
1673#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1674#[serde(deny_unknown_fields)]
1675pub struct ClearTariffsResult {
1676    #[serde(
1677        rename = "statusInfo",
1678        default,
1679        skip_serializing_if = "Option::is_none"
1680    )]
1681    pub status_info: Option<StatusInfo>,
1682    /// Id of tariff for which _status_ is reported. If no tariffs were found, then this field is absent, and _status_ will be `NoTariff`.
1683    #[serde(rename = "tariffId", default, skip_serializing_if = "Option::is_none")]
1684    pub tariff_id: Option<String>,
1685    #[serde(rename = "status")]
1686    pub status: TariffClearStatusEnum,
1687    #[serde(
1688        rename = "customData",
1689        default,
1690        skip_serializing_if = "Option::is_none"
1691    )]
1692    pub custom_data: Option<CustomData>,
1693}
1694
1695impl Validate for ClearTariffsResult {
1696    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1697        if let Some(x) = &self.status_info {
1698            let p = path.field("statusInfo");
1699            x.validate(&p)?;
1700        }
1701        if let Some(x) = &self.tariff_id {
1702            let p = path.field("tariffId");
1703            v::max_length(x, 60, &p)?;
1704        }
1705        if let Some(x) = &self.custom_data {
1706            let p = path.field("customData");
1707            x.validate(&p)?;
1708        }
1709        Ok(())
1710    }
1711}
1712
1713/// A physical or logical component
1714#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1715#[serde(deny_unknown_fields)]
1716pub struct Component {
1717    #[serde(rename = "evse", default, skip_serializing_if = "Option::is_none")]
1718    pub evse: Option<EVSE>,
1719    /// 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.
1720    #[serde(rename = "name")]
1721    pub name: String,
1722    /// Name of instance in case the component exists as multiple instances. Case Insensitive. strongly advised to use Camel Case.
1723    #[serde(rename = "instance", default, skip_serializing_if = "Option::is_none")]
1724    pub instance: Option<String>,
1725    #[serde(
1726        rename = "customData",
1727        default,
1728        skip_serializing_if = "Option::is_none"
1729    )]
1730    pub custom_data: Option<CustomData>,
1731}
1732
1733impl Validate for Component {
1734    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1735        if let Some(x) = &self.evse {
1736            let p = path.field("evse");
1737            x.validate(&p)?;
1738        }
1739        {
1740            let x = &self.name;
1741            let p = path.field("name");
1742            v::max_length(x, 50, &p)?;
1743        }
1744        if let Some(x) = &self.instance {
1745            let p = path.field("instance");
1746            v::max_length(x, 50, &p)?;
1747        }
1748        if let Some(x) = &self.custom_data {
1749            let p = path.field("customData");
1750            x.validate(&p)?;
1751        }
1752        Ok(())
1753    }
1754}
1755
1756/// Class to report components, variables and variable attributes and characteristics.
1757#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1758#[serde(deny_unknown_fields)]
1759pub struct ComponentVariable {
1760    #[serde(rename = "component")]
1761    pub component: Component,
1762    #[serde(rename = "variable", default, skip_serializing_if = "Option::is_none")]
1763    pub variable: Option<Variable>,
1764    #[serde(
1765        rename = "customData",
1766        default,
1767        skip_serializing_if = "Option::is_none"
1768    )]
1769    pub custom_data: Option<CustomData>,
1770}
1771
1772impl Validate for ComponentVariable {
1773    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1774        {
1775            let x = &self.component;
1776            let p = path.field("component");
1777            x.validate(&p)?;
1778        }
1779        if let Some(x) = &self.variable {
1780            let p = path.field("variable");
1781            x.validate(&p)?;
1782        }
1783        if let Some(x) = &self.custom_data {
1784            let p = path.field("customData");
1785            x.validate(&p)?;
1786        }
1787        Ok(())
1788    }
1789}
1790
1791#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1792#[serde(deny_unknown_fields)]
1793pub struct CompositeSchedule {
1794    #[serde(rename = "evseId")]
1795    pub evse_id: i64,
1796    #[serde(rename = "duration")]
1797    pub duration: i64,
1798    #[serde(rename = "scheduleStart")]
1799    pub schedule_start: DateTime,
1800    #[serde(rename = "chargingRateUnit")]
1801    pub charging_rate_unit: ChargingRateUnitEnum,
1802    #[serde(rename = "chargingSchedulePeriod")]
1803    pub charging_schedule_period: Vec<ChargingSchedulePeriod>,
1804    #[serde(
1805        rename = "customData",
1806        default,
1807        skip_serializing_if = "Option::is_none"
1808    )]
1809    pub custom_data: Option<CustomData>,
1810}
1811
1812impl Validate for CompositeSchedule {
1813    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1814        {
1815            let x = &self.evse_id;
1816            let p = path.field("evseId");
1817            v::minimum(*x, 0i64, &p)?;
1818        }
1819        {
1820            let x = &self.charging_schedule_period;
1821            let p = path.field("chargingSchedulePeriod");
1822            v::items(x, Some(1), None, &p)?;
1823            for (i0, it0) in x.iter().enumerate() {
1824                let p0 = p.index(i0);
1825                it0.validate(&p0)?;
1826            }
1827        }
1828        if let Some(x) = &self.custom_data {
1829            let p = path.field("customData");
1830            x.validate(&p)?;
1831        }
1832        Ok(())
1833    }
1834}
1835
1836#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1837#[serde(deny_unknown_fields)]
1838pub struct ConstantStreamData {
1839    /// Uniquely identifies the stream
1840    #[serde(rename = "id")]
1841    pub id: i64,
1842    #[serde(rename = "params")]
1843    pub params: PeriodicEventStreamParams,
1844    /// Id of monitor used to report his event. It can be a preconfigured or hardwired monitor.
1845    #[serde(rename = "variableMonitoringId")]
1846    pub variable_monitoring_id: i64,
1847    #[serde(
1848        rename = "customData",
1849        default,
1850        skip_serializing_if = "Option::is_none"
1851    )]
1852    pub custom_data: Option<CustomData>,
1853}
1854
1855impl Validate for ConstantStreamData {
1856    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1857        {
1858            let x = &self.id;
1859            let p = path.field("id");
1860            v::minimum(*x, 0i64, &p)?;
1861        }
1862        {
1863            let x = &self.params;
1864            let p = path.field("params");
1865            x.validate(&p)?;
1866        }
1867        {
1868            let x = &self.variable_monitoring_id;
1869            let p = path.field("variableMonitoringId");
1870            v::minimum(*x, 0i64, &p)?;
1871        }
1872        if let Some(x) = &self.custom_data {
1873            let p = path.field("customData");
1874            x.validate(&p)?;
1875        }
1876        Ok(())
1877    }
1878}
1879
1880#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1881#[serde(deny_unknown_fields)]
1882pub struct ConsumptionCost {
1883    /// 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.
1884    #[serde(rename = "startValue")]
1885    pub start_value: f64,
1886    #[serde(rename = "cost")]
1887    pub cost: Vec<Cost>,
1888    #[serde(
1889        rename = "customData",
1890        default,
1891        skip_serializing_if = "Option::is_none"
1892    )]
1893    pub custom_data: Option<CustomData>,
1894}
1895
1896impl Validate for ConsumptionCost {
1897    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1898        {
1899            let x = &self.cost;
1900            let p = path.field("cost");
1901            v::items(x, Some(1), Some(3), &p)?;
1902            for (i0, it0) in x.iter().enumerate() {
1903                let p0 = p.index(i0);
1904                it0.validate(&p0)?;
1905            }
1906        }
1907        if let Some(x) = &self.custom_data {
1908            let p = path.field("customData");
1909            x.validate(&p)?;
1910        }
1911        Ok(())
1912    }
1913}
1914
1915#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1916#[serde(deny_unknown_fields)]
1917pub struct Cost {
1918    #[serde(rename = "costKind")]
1919    pub cost_kind: CostKindEnum,
1920    /// The estimated or actual cost per kWh
1921    #[serde(rename = "amount")]
1922    pub amount: i64,
1923    /// Values: -3..3, The amountMultiplier defines the exponent to base 10 (dec). The final value is determined by: amount * 10 ^ amountMultiplier
1924    #[serde(
1925        rename = "amountMultiplier",
1926        default,
1927        skip_serializing_if = "Option::is_none"
1928    )]
1929    pub amount_multiplier: Option<i64>,
1930    #[serde(
1931        rename = "customData",
1932        default,
1933        skip_serializing_if = "Option::is_none"
1934    )]
1935    pub custom_data: Option<CustomData>,
1936}
1937
1938impl Validate for Cost {
1939    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1940        if let Some(x) = &self.custom_data {
1941            let p = path.field("customData");
1942            x.validate(&p)?;
1943        }
1944        Ok(())
1945    }
1946}
1947
1948/// CostDetailsType contains the cost as calculated by Charging Station based on provided TariffType.
1949/// NOTE: Reservation is not shown as a _chargingPeriod_, because it took place outside of the transaction.
1950#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1951#[serde(deny_unknown_fields)]
1952pub struct CostDetails {
1953    #[serde(
1954        rename = "chargingPeriods",
1955        default,
1956        skip_serializing_if = "Option::is_none"
1957    )]
1958    pub charging_periods: Option<Vec<ChargingPeriod>>,
1959    #[serde(rename = "totalCost")]
1960    pub total_cost: TotalCost,
1961    #[serde(rename = "totalUsage")]
1962    pub total_usage: TotalUsage,
1963    /// If set to true, then Charging Station has failed to calculate the cost.
1964    #[serde(
1965        rename = "failureToCalculate",
1966        default,
1967        skip_serializing_if = "Option::is_none"
1968    )]
1969    pub failure_to_calculate: Option<bool>,
1970    /// Optional human-readable reason text in case of failure to calculate.
1971    #[serde(
1972        rename = "failureReason",
1973        default,
1974        skip_serializing_if = "Option::is_none"
1975    )]
1976    pub failure_reason: Option<String>,
1977    #[serde(
1978        rename = "customData",
1979        default,
1980        skip_serializing_if = "Option::is_none"
1981    )]
1982    pub custom_data: Option<CustomData>,
1983}
1984
1985impl Validate for CostDetails {
1986    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
1987        if let Some(x) = &self.charging_periods {
1988            let p = path.field("chargingPeriods");
1989            v::items(x, Some(1), None, &p)?;
1990            for (i0, it0) in x.iter().enumerate() {
1991                let p0 = p.index(i0);
1992                it0.validate(&p0)?;
1993            }
1994        }
1995        {
1996            let x = &self.total_cost;
1997            let p = path.field("totalCost");
1998            x.validate(&p)?;
1999        }
2000        {
2001            let x = &self.total_usage;
2002            let p = path.field("totalUsage");
2003            x.validate(&p)?;
2004        }
2005        if let Some(x) = &self.failure_reason {
2006            let p = path.field("failureReason");
2007            v::max_length(x, 500, &p)?;
2008        }
2009        if let Some(x) = &self.custom_data {
2010            let p = path.field("customData");
2011            x.validate(&p)?;
2012        }
2013        Ok(())
2014    }
2015}
2016
2017/// Volume consumed of cost dimension.
2018#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2019#[serde(deny_unknown_fields)]
2020pub struct CostDimension {
2021    #[serde(rename = "type")]
2022    pub r#type: CostDimensionEnum,
2023    /// Volume of the dimension consumed, measured according to the dimension type.
2024    #[serde(rename = "volume")]
2025    pub volume: f64,
2026    #[serde(
2027        rename = "customData",
2028        default,
2029        skip_serializing_if = "Option::is_none"
2030    )]
2031    pub custom_data: Option<CustomData>,
2032}
2033
2034impl Validate for CostDimension {
2035    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2036        if let Some(x) = &self.custom_data {
2037            let p = path.field("customData");
2038            x.validate(&p)?;
2039        }
2040        Ok(())
2041    }
2042}
2043
2044/// 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.
2045#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2046pub struct CustomData {
2047    #[serde(rename = "vendorId")]
2048    pub vendor_id: String,
2049    /// Vendor-specific properties.
2050    #[serde(flatten)]
2051    pub extra: serde_json::Map<String, serde_json::Value>,
2052}
2053
2054impl Validate for CustomData {
2055    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2056        {
2057            let x = &self.vendor_id;
2058            let p = path.field("vendorId");
2059            v::max_length(x, 255, &p)?;
2060        }
2061        Ok(())
2062    }
2063}
2064
2065/// EV DC charging parameters for ISO 15118-2
2066#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2067#[serde(deny_unknown_fields)]
2068pub struct DCChargingParameters {
2069    /// Maximum current (in A) supported by the electric vehicle. Includes cable capacity.
2070    /// Relates to: +
2071    /// *ISO 15118-2*: DC_EVChargeParameterType:EVMaximumCurrentLimit
2072    #[serde(rename = "evMaxCurrent")]
2073    pub ev_max_current: f64,
2074    /// Maximum voltage supported by the electric vehicle.
2075    /// Relates to: +
2076    /// *ISO 15118-2*: DC_EVChargeParameterType: EVMaximumVoltageLimit
2077    #[serde(rename = "evMaxVoltage")]
2078    pub ev_max_voltage: f64,
2079    /// Maximum power (in W) supported by the electric vehicle. Required for DC charging.
2080    /// Relates to: +
2081    /// *ISO 15118-2*: DC_EVChargeParameterType: EVMaximumPowerLimit
2082    #[serde(
2083        rename = "evMaxPower",
2084        default,
2085        skip_serializing_if = "Option::is_none"
2086    )]
2087    pub ev_max_power: Option<f64>,
2088    /// Capacity of the electric vehicle battery (in Wh).
2089    /// Relates to: +
2090    /// *ISO 15118-2*: DC_EVChargeParameterType: EVEnergyCapacity
2091    #[serde(
2092        rename = "evEnergyCapacity",
2093        default,
2094        skip_serializing_if = "Option::is_none"
2095    )]
2096    pub ev_energy_capacity: Option<f64>,
2097    /// Amount of energy requested (in Wh). This inludes energy required for preconditioning.
2098    /// Relates to: +
2099    /// *ISO 15118-2*: DC_EVChargeParameterType: EVEnergyRequest
2100    #[serde(
2101        rename = "energyAmount",
2102        default,
2103        skip_serializing_if = "Option::is_none"
2104    )]
2105    pub energy_amount: Option<f64>,
2106    /// Energy available in the battery (in percent of the battery capacity)
2107    /// Relates to: +
2108    /// *ISO 15118-2*: DC_EVChargeParameterType: DC_EVStatus: EVRESSSOC
2109    #[serde(
2110        rename = "stateOfCharge",
2111        default,
2112        skip_serializing_if = "Option::is_none"
2113    )]
2114    pub state_of_charge: Option<i64>,
2115    /// Percentage of SoC at which the EV considers the battery fully charged. (possible values: 0 - 100)
2116    /// Relates to: +
2117    /// *ISO 15118-2*: DC_EVChargeParameterType: FullSOC
2118    #[serde(rename = "fullSoC", default, skip_serializing_if = "Option::is_none")]
2119    pub full_so_c: Option<i64>,
2120    /// Percentage of SoC at which the EV considers a fast charging process to end. (possible values: 0 - 100)
2121    /// Relates to: +
2122    /// *ISO 15118-2*: DC_EVChargeParameterType: BulkSOC
2123    #[serde(rename = "bulkSoC", default, skip_serializing_if = "Option::is_none")]
2124    pub bulk_so_c: Option<i64>,
2125    #[serde(
2126        rename = "customData",
2127        default,
2128        skip_serializing_if = "Option::is_none"
2129    )]
2130    pub custom_data: Option<CustomData>,
2131}
2132
2133impl Validate for DCChargingParameters {
2134    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2135        if let Some(x) = &self.state_of_charge {
2136            let p = path.field("stateOfCharge");
2137            v::minimum(*x, 0i64, &p)?;
2138            v::maximum(*x, 100i64, &p)?;
2139        }
2140        if let Some(x) = &self.full_so_c {
2141            let p = path.field("fullSoC");
2142            v::minimum(*x, 0i64, &p)?;
2143            v::maximum(*x, 100i64, &p)?;
2144        }
2145        if let Some(x) = &self.bulk_so_c {
2146            let p = path.field("bulkSoC");
2147            v::minimum(*x, 0i64, &p)?;
2148            v::maximum(*x, 100i64, &p)?;
2149        }
2150        if let Some(x) = &self.custom_data {
2151            let p = path.field("customData");
2152            x.validate(&p)?;
2153        }
2154        Ok(())
2155    }
2156}
2157
2158/// *(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.
2159/// Fields starting with "ev" contain values from the EV.
2160/// Other fields contain a value that is supported by both EV and EVSE.
2161/// DERChargingParametersType type is only relevant in case of an ISO 15118-20 AC_BPT_DER/AC_DER charging session.
2162/// NOTE: All these fields have values greater or equal to zero (i.e. are non-negative)
2163#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
2164#[serde(deny_unknown_fields)]
2165pub struct DERChargingParameters {
2166    /// DER control functions supported by EV. +
2167    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType:DERControlFunctions (bitmap)
2168    #[serde(
2169        rename = "evSupportedDERControl",
2170        default,
2171        skip_serializing_if = "Option::is_none"
2172    )]
2173    pub ev_supported_der_control: Option<Vec<DERControlEnum>>,
2174    /// Rated maximum injected active power by EV, at specified over-excited power factor (overExcitedPowerFactor). +
2175    /// 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. +
2176    /// Corresponds to the WOvPF attribute in IEC 61850. +
2177    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedMaximumDischargePower
2178    #[serde(
2179        rename = "evOverExcitedMaxDischargePower",
2180        default,
2181        skip_serializing_if = "Option::is_none"
2182    )]
2183    pub ev_over_excited_max_discharge_power: Option<f64>,
2184    /// EV power factor when injecting (over excited) the minimum reactive power. +
2185    /// Corresponds to the OvPF attribute in IEC 61850. +
2186    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVOverExcitedPowerFactor
2187    #[serde(
2188        rename = "evOverExcitedPowerFactor",
2189        default,
2190        skip_serializing_if = "Option::is_none"
2191    )]
2192    pub ev_over_excited_power_factor: Option<f64>,
2193    /// Rated maximum injected active power by EV supported at specified under-excited power factor (EVUnderExcitedPowerFactor). +
2194    /// It can also be defined as the rated maximum dischargePower at the rated minimum absorbed reactive power value.
2195    /// 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. +
2196    /// This corresponds to the WUnPF attribute in the IEC 61850. +
2197    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedMaximumDischargePower
2198    #[serde(
2199        rename = "evUnderExcitedMaxDischargePower",
2200        default,
2201        skip_serializing_if = "Option::is_none"
2202    )]
2203    pub ev_under_excited_max_discharge_power: Option<f64>,
2204    /// EV power factor when injecting (under excited) the minimum reactive power. +
2205    /// Corresponds to the OvPF attribute in IEC 61850. +
2206    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVUnderExcitedPowerFactor
2207    #[serde(
2208        rename = "evUnderExcitedPowerFactor",
2209        default,
2210        skip_serializing_if = "Option::is_none"
2211    )]
2212    pub ev_under_excited_power_factor: Option<f64>,
2213    /// Rated maximum total apparent power, defined by min(EV, EVSE) in va.
2214    /// Corresponds to the VAMaxRtg in IEC 61850. +
2215    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumApparentPower
2216    #[serde(
2217        rename = "maxApparentPower",
2218        default,
2219        skip_serializing_if = "Option::is_none"
2220    )]
2221    pub max_apparent_power: Option<f64>,
2222    /// Rated maximum absorbed apparent power, defined by min(EV, EVSE) in va. +
2223    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2224    /// in which case this field represents phase L1. +
2225    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
2226    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower
2227    #[serde(
2228        rename = "maxChargeApparentPower",
2229        default,
2230        skip_serializing_if = "Option::is_none"
2231    )]
2232    pub max_charge_apparent_power: Option<f64>,
2233    /// Rated maximum absorbed apparent power on phase L2, defined by min(EV, EVSE) in va.
2234    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
2235    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L2
2236    #[serde(
2237        rename = "maxChargeApparentPower_L2",
2238        default,
2239        skip_serializing_if = "Option::is_none"
2240    )]
2241    pub max_charge_apparent_power_l2: Option<f64>,
2242    /// Rated maximum absorbed apparent power on phase L3, defined by min(EV, EVSE) in va.
2243    /// Corresponds to the ChaVAMaxRtg in IEC 61850. +
2244    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeApparentPower_L3
2245    #[serde(
2246        rename = "maxChargeApparentPower_L3",
2247        default,
2248        skip_serializing_if = "Option::is_none"
2249    )]
2250    pub max_charge_apparent_power_l3: Option<f64>,
2251    /// Rated maximum injected apparent power, defined by min(EV, EVSE) in va. +
2252    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2253    /// in which case this field represents phase L1. +
2254    /// Corresponds to the DisVAMaxRtg in IEC 61850. +
2255    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower
2256    #[serde(
2257        rename = "maxDischargeApparentPower",
2258        default,
2259        skip_serializing_if = "Option::is_none"
2260    )]
2261    pub max_discharge_apparent_power: Option<f64>,
2262    /// Rated maximum injected apparent power on phase L2, defined by min(EV, EVSE) in va. +
2263    /// Corresponds to the DisVAMaxRtg in IEC 61850. +
2264    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L2
2265    #[serde(
2266        rename = "maxDischargeApparentPower_L2",
2267        default,
2268        skip_serializing_if = "Option::is_none"
2269    )]
2270    pub max_discharge_apparent_power_l2: Option<f64>,
2271    /// Rated maximum injected apparent power on phase L3, defined by min(EV, EVSE) in va. +
2272    /// Corresponds to the DisVAMaxRtg in IEC 61850. +
2273    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeApparentPower_L3
2274    #[serde(
2275        rename = "maxDischargeApparentPower_L3",
2276        default,
2277        skip_serializing_if = "Option::is_none"
2278    )]
2279    pub max_discharge_apparent_power_l3: Option<f64>,
2280    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars. +
2281    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2282    /// in which case this field represents phase L1. +
2283    /// Corresponds to the AvarMax attribute in the IEC 61850. +
2284    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower
2285    #[serde(
2286        rename = "maxChargeReactivePower",
2287        default,
2288        skip_serializing_if = "Option::is_none"
2289    )]
2290    pub max_charge_reactive_power: Option<f64>,
2291    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L2. +
2292    /// Corresponds to the AvarMax attribute in the IEC 61850. +
2293    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L2
2294    #[serde(
2295        rename = "maxChargeReactivePower_L2",
2296        default,
2297        skip_serializing_if = "Option::is_none"
2298    )]
2299    pub max_charge_reactive_power_l2: Option<f64>,
2300    /// Rated maximum absorbed reactive power, defined by min(EV, EVSE), in vars on phase L3. +
2301    /// Corresponds to the AvarMax attribute in the IEC 61850. +
2302    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumChargeReactivePower_L3
2303    #[serde(
2304        rename = "maxChargeReactivePower_L3",
2305        default,
2306        skip_serializing_if = "Option::is_none"
2307    )]
2308    pub max_charge_reactive_power_l3: Option<f64>,
2309    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars. +
2310    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2311    /// in which case this field represents phase L1. +
2312    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower
2313    #[serde(
2314        rename = "minChargeReactivePower",
2315        default,
2316        skip_serializing_if = "Option::is_none"
2317    )]
2318    pub min_charge_reactive_power: Option<f64>,
2319    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L2. +
2320    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L2
2321    #[serde(
2322        rename = "minChargeReactivePower_L2",
2323        default,
2324        skip_serializing_if = "Option::is_none"
2325    )]
2326    pub min_charge_reactive_power_l2: Option<f64>,
2327    /// Rated minimum absorbed reactive power, defined by max(EV, EVSE), in vars on phase L3. +
2328    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumChargeReactivePower_L3
2329    #[serde(
2330        rename = "minChargeReactivePower_L3",
2331        default,
2332        skip_serializing_if = "Option::is_none"
2333    )]
2334    pub min_charge_reactive_power_l3: Option<f64>,
2335    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars. +
2336    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2337    /// in which case this field represents phase L1. +
2338    /// Corresponds to the IvarMax attribute in the IEC 61850. +
2339    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower
2340    #[serde(
2341        rename = "maxDischargeReactivePower",
2342        default,
2343        skip_serializing_if = "Option::is_none"
2344    )]
2345    pub max_discharge_reactive_power: Option<f64>,
2346    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L2. +
2347    /// Corresponds to the IvarMax attribute in the IEC 61850. +
2348    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L2
2349    #[serde(
2350        rename = "maxDischargeReactivePower_L2",
2351        default,
2352        skip_serializing_if = "Option::is_none"
2353    )]
2354    pub max_discharge_reactive_power_l2: Option<f64>,
2355    /// Rated maximum injected reactive power, defined by min(EV, EVSE), in vars on phase L3. +
2356    /// Corresponds to the IvarMax attribute in the IEC 61850. +
2357    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumDischargeReactivePower_L3
2358    #[serde(
2359        rename = "maxDischargeReactivePower_L3",
2360        default,
2361        skip_serializing_if = "Option::is_none"
2362    )]
2363    pub max_discharge_reactive_power_l3: Option<f64>,
2364    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in vars. +
2365    /// This field represents the sum of all phases, unless values are provided for L2 and L3,
2366    /// in which case this field represents phase L1. +
2367    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower
2368    #[serde(
2369        rename = "minDischargeReactivePower",
2370        default,
2371        skip_serializing_if = "Option::is_none"
2372    )]
2373    pub min_discharge_reactive_power: Option<f64>,
2374    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L2. +
2375    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L2
2376    #[serde(
2377        rename = "minDischargeReactivePower_L2",
2378        default,
2379        skip_serializing_if = "Option::is_none"
2380    )]
2381    pub min_discharge_reactive_power_l2: Option<f64>,
2382    /// Rated minimum injected reactive power, defined by max(EV, EVSE), in var on phase L3. +
2383    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumDischargeReactivePower_L3
2384    #[serde(
2385        rename = "minDischargeReactivePower_L3",
2386        default,
2387        skip_serializing_if = "Option::is_none"
2388    )]
2389    pub min_discharge_reactive_power_l3: Option<f64>,
2390    /// Line voltage supported by EVSE and EV.
2391    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltage
2392    #[serde(
2393        rename = "nominalVoltage",
2394        default,
2395        skip_serializing_if = "Option::is_none"
2396    )]
2397    pub nominal_voltage: Option<f64>,
2398    /// The nominal AC voltage (rms) offset between the Charging Station's electrical connection point and the utility’s point of common coupling. +
2399    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVNominalVoltageOffset
2400    #[serde(
2401        rename = "nominalVoltageOffset",
2402        default,
2403        skip_serializing_if = "Option::is_none"
2404    )]
2405    pub nominal_voltage_offset: Option<f64>,
2406    /// Maximum AC rms voltage, as defined by min(EV, EVSE)  to operate with. +
2407    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumNominalVoltage
2408    #[serde(
2409        rename = "maxNominalVoltage",
2410        default,
2411        skip_serializing_if = "Option::is_none"
2412    )]
2413    pub max_nominal_voltage: Option<f64>,
2414    /// Minimum AC rms voltage, as defined by max(EV, EVSE)  to operate with. +
2415    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMinimumNominalVoltage
2416    #[serde(
2417        rename = "minNominalVoltage",
2418        default,
2419        skip_serializing_if = "Option::is_none"
2420    )]
2421    pub min_nominal_voltage: Option<f64>,
2422    /// Manufacturer of the EV inverter. +
2423    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterManufacturer
2424    #[serde(
2425        rename = "evInverterManufacturer",
2426        default,
2427        skip_serializing_if = "Option::is_none"
2428    )]
2429    pub ev_inverter_manufacturer: Option<String>,
2430    /// Model name of the EV inverter. +
2431    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterModel
2432    #[serde(
2433        rename = "evInverterModel",
2434        default,
2435        skip_serializing_if = "Option::is_none"
2436    )]
2437    pub ev_inverter_model: Option<String>,
2438    /// Serial number of the EV inverter. +
2439    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSerialNumber
2440    #[serde(
2441        rename = "evInverterSerialNumber",
2442        default,
2443        skip_serializing_if = "Option::is_none"
2444    )]
2445    pub ev_inverter_serial_number: Option<String>,
2446    /// Software version of EV inverter. +
2447    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterSwVersion
2448    #[serde(
2449        rename = "evInverterSwVersion",
2450        default,
2451        skip_serializing_if = "Option::is_none"
2452    )]
2453    pub ev_inverter_sw_version: Option<String>,
2454    /// Hardware version of EV inverter. +
2455    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVInverterHwVersion
2456    #[serde(
2457        rename = "evInverterHwVersion",
2458        default,
2459        skip_serializing_if = "Option::is_none"
2460    )]
2461    pub ev_inverter_hw_version: Option<String>,
2462    /// Type of islanding detection method. Only mandatory when islanding detection is required at the site, as set in the ISO 15118 Service Details configuration. +
2463    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingDetectionMethod
2464    #[serde(
2465        rename = "evIslandingDetectionMethod",
2466        default,
2467        skip_serializing_if = "Option::is_none"
2468    )]
2469    pub ev_islanding_detection_method: Option<Vec<IslandingDetectionEnum>>,
2470    /// Time after which EV will trip if an island has been detected. +
2471    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVIslandingTripTime
2472    #[serde(
2473        rename = "evIslandingTripTime",
2474        default,
2475        skip_serializing_if = "Option::is_none"
2476    )]
2477    pub ev_islanding_trip_time: Option<f64>,
2478    /// Maximum injected DC current allowed at level 1 charging. +
2479    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel1DCInjection
2480    #[serde(
2481        rename = "evMaximumLevel1DCInjection",
2482        default,
2483        skip_serializing_if = "Option::is_none"
2484    )]
2485    pub ev_maximum_level1_dc_injection: Option<f64>,
2486    /// Maximum allowed duration of DC injection at level 1 charging. +
2487    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel1DCInjection
2488    #[serde(
2489        rename = "evDurationLevel1DCInjection",
2490        default,
2491        skip_serializing_if = "Option::is_none"
2492    )]
2493    pub ev_duration_level1_dc_injection: Option<f64>,
2494    /// Maximum injected DC current allowed at level 2 charging. +
2495    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVMaximumLevel2DCInjection
2496    #[serde(
2497        rename = "evMaximumLevel2DCInjection",
2498        default,
2499        skip_serializing_if = "Option::is_none"
2500    )]
2501    pub ev_maximum_level2_dc_injection: Option<f64>,
2502    /// Maximum allowed duration of DC injection at level 2 charging. +
2503    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVDurationLevel2DCInjection
2504    #[serde(
2505        rename = "evDurationLevel2DCInjection",
2506        default,
2507        skip_serializing_if = "Option::is_none"
2508    )]
2509    pub ev_duration_level2_dc_injection: Option<f64>,
2510    /// Measure of the susceptibility of the circuit to reactance, in Siemens (S). +
2511    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVReactiveSusceptance
2512    #[serde(
2513        rename = "evReactiveSusceptance",
2514        default,
2515        skip_serializing_if = "Option::is_none"
2516    )]
2517    pub ev_reactive_susceptance: Option<f64>,
2518    /// 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.
2519    /// *ISO 15118-20*: DER_BPT_AC_CPDReqEnergyTransferModeType: EVSessionTotalDischargeEnergyAvailable
2520    #[serde(
2521        rename = "evSessionTotalDischargeEnergyAvailable",
2522        default,
2523        skip_serializing_if = "Option::is_none"
2524    )]
2525    pub ev_session_total_discharge_energy_available: Option<f64>,
2526    #[serde(
2527        rename = "customData",
2528        default,
2529        skip_serializing_if = "Option::is_none"
2530    )]
2531    pub custom_data: Option<CustomData>,
2532}
2533
2534impl Validate for DERChargingParameters {
2535    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2536        if let Some(x) = &self.ev_supported_der_control {
2537            let p = path.field("evSupportedDERControl");
2538            v::items(x, Some(1), None, &p)?;
2539        }
2540        if let Some(x) = &self.ev_inverter_manufacturer {
2541            let p = path.field("evInverterManufacturer");
2542            v::max_length(x, 50, &p)?;
2543        }
2544        if let Some(x) = &self.ev_inverter_model {
2545            let p = path.field("evInverterModel");
2546            v::max_length(x, 50, &p)?;
2547        }
2548        if let Some(x) = &self.ev_inverter_serial_number {
2549            let p = path.field("evInverterSerialNumber");
2550            v::max_length(x, 50, &p)?;
2551        }
2552        if let Some(x) = &self.ev_inverter_sw_version {
2553            let p = path.field("evInverterSwVersion");
2554            v::max_length(x, 50, &p)?;
2555        }
2556        if let Some(x) = &self.ev_inverter_hw_version {
2557            let p = path.field("evInverterHwVersion");
2558            v::max_length(x, 50, &p)?;
2559        }
2560        if let Some(x) = &self.ev_islanding_detection_method {
2561            let p = path.field("evIslandingDetectionMethod");
2562            v::items(x, Some(1), None, &p)?;
2563        }
2564        if let Some(x) = &self.custom_data {
2565            let p = path.field("customData");
2566            x.validate(&p)?;
2567        }
2568        Ok(())
2569    }
2570}
2571
2572#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2573#[serde(deny_unknown_fields)]
2574pub struct DERCurve {
2575    #[serde(rename = "curveData")]
2576    pub curve_data: Vec<DERCurvePoints>,
2577    #[serde(
2578        rename = "hysteresis",
2579        default,
2580        skip_serializing_if = "Option::is_none"
2581    )]
2582    pub hysteresis: Option<Hysteresis>,
2583    /// Priority of curve (0=highest)
2584    #[serde(rename = "priority")]
2585    pub priority: i64,
2586    #[serde(
2587        rename = "reactivePowerParams",
2588        default,
2589        skip_serializing_if = "Option::is_none"
2590    )]
2591    pub reactive_power_params: Option<ReactivePowerParams>,
2592    #[serde(
2593        rename = "voltageParams",
2594        default,
2595        skip_serializing_if = "Option::is_none"
2596    )]
2597    pub voltage_params: Option<VoltageParams>,
2598    #[serde(rename = "yUnit")]
2599    pub y_unit: DERUnitEnum,
2600    /// 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.
2601    #[serde(
2602        rename = "responseTime",
2603        default,
2604        skip_serializing_if = "Option::is_none"
2605    )]
2606    pub response_time: Option<f64>,
2607    /// Point in time when this curve will become activated. Only absent when _default_ is true.
2608    #[serde(rename = "startTime", default, skip_serializing_if = "Option::is_none")]
2609    pub start_time: Option<DateTime>,
2610    /// Duration in seconds that this curve will be active. Only absent when _default_ is true.
2611    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
2612    pub duration: Option<f64>,
2613    #[serde(
2614        rename = "customData",
2615        default,
2616        skip_serializing_if = "Option::is_none"
2617    )]
2618    pub custom_data: Option<CustomData>,
2619}
2620
2621impl Validate for DERCurve {
2622    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2623        {
2624            let x = &self.curve_data;
2625            let p = path.field("curveData");
2626            v::items(x, Some(1), Some(10), &p)?;
2627            for (i0, it0) in x.iter().enumerate() {
2628                let p0 = p.index(i0);
2629                it0.validate(&p0)?;
2630            }
2631        }
2632        if let Some(x) = &self.hysteresis {
2633            let p = path.field("hysteresis");
2634            x.validate(&p)?;
2635        }
2636        {
2637            let x = &self.priority;
2638            let p = path.field("priority");
2639            v::minimum(*x, 0i64, &p)?;
2640        }
2641        if let Some(x) = &self.reactive_power_params {
2642            let p = path.field("reactivePowerParams");
2643            x.validate(&p)?;
2644        }
2645        if let Some(x) = &self.voltage_params {
2646            let p = path.field("voltageParams");
2647            x.validate(&p)?;
2648        }
2649        if let Some(x) = &self.custom_data {
2650            let p = path.field("customData");
2651            x.validate(&p)?;
2652        }
2653        Ok(())
2654    }
2655}
2656
2657#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2658#[serde(deny_unknown_fields)]
2659pub struct DERCurveGet {
2660    #[serde(rename = "curve")]
2661    pub curve: DERCurve,
2662    /// Id of DER curve
2663    #[serde(rename = "id")]
2664    pub id: String,
2665    #[serde(rename = "curveType")]
2666    pub curve_type: DERControlEnum,
2667    /// True if this is a default curve
2668    #[serde(rename = "isDefault")]
2669    pub is_default: bool,
2670    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
2671    #[serde(rename = "isSuperseded")]
2672    pub is_superseded: bool,
2673    #[serde(
2674        rename = "customData",
2675        default,
2676        skip_serializing_if = "Option::is_none"
2677    )]
2678    pub custom_data: Option<CustomData>,
2679}
2680
2681impl Validate for DERCurveGet {
2682    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2683        {
2684            let x = &self.curve;
2685            let p = path.field("curve");
2686            x.validate(&p)?;
2687        }
2688        {
2689            let x = &self.id;
2690            let p = path.field("id");
2691            v::max_length(x, 36, &p)?;
2692        }
2693        if let Some(x) = &self.custom_data {
2694            let p = path.field("customData");
2695            x.validate(&p)?;
2696        }
2697        Ok(())
2698    }
2699}
2700
2701#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2702#[serde(deny_unknown_fields)]
2703pub struct DERCurvePoints {
2704    /// The data value of the X-axis (independent) variable, depending on the curve type.
2705    #[serde(rename = "x")]
2706    pub x: f64,
2707    /// 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).
2708    #[serde(rename = "y")]
2709    pub y: f64,
2710    #[serde(
2711        rename = "customData",
2712        default,
2713        skip_serializing_if = "Option::is_none"
2714    )]
2715    pub custom_data: Option<CustomData>,
2716}
2717
2718impl Validate for DERCurvePoints {
2719    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2720        if let Some(x) = &self.custom_data {
2721            let p = path.field("customData");
2722            x.validate(&p)?;
2723        }
2724        Ok(())
2725    }
2726}
2727
2728/// *(2.1)* Price schedule of EV energy offer.
2729#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2730#[serde(deny_unknown_fields)]
2731pub struct EVAbsolutePriceSchedule {
2732    /// Starting point in time of the EVEnergyOffer.
2733    #[serde(rename = "timeAnchor")]
2734    pub time_anchor: DateTime,
2735    /// Currency code according to ISO 4217.
2736    #[serde(rename = "currency")]
2737    pub currency: String,
2738    #[serde(rename = "evAbsolutePriceScheduleEntries")]
2739    pub ev_absolute_price_schedule_entries: Vec<EVAbsolutePriceScheduleEntry>,
2740    /// ISO 15118-20 URN of price algorithm: Power, PeakPower, StackedEnergy.
2741    #[serde(rename = "priceAlgorithm")]
2742    pub price_algorithm: String,
2743    #[serde(
2744        rename = "customData",
2745        default,
2746        skip_serializing_if = "Option::is_none"
2747    )]
2748    pub custom_data: Option<CustomData>,
2749}
2750
2751impl Validate for EVAbsolutePriceSchedule {
2752    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2753        {
2754            let x = &self.currency;
2755            let p = path.field("currency");
2756            v::max_length(x, 3, &p)?;
2757        }
2758        {
2759            let x = &self.ev_absolute_price_schedule_entries;
2760            let p = path.field("evAbsolutePriceScheduleEntries");
2761            v::items(x, Some(1), Some(1024), &p)?;
2762            for (i0, it0) in x.iter().enumerate() {
2763                let p0 = p.index(i0);
2764                it0.validate(&p0)?;
2765            }
2766        }
2767        {
2768            let x = &self.price_algorithm;
2769            let p = path.field("priceAlgorithm");
2770            v::max_length(x, 2000, &p)?;
2771        }
2772        if let Some(x) = &self.custom_data {
2773            let p = path.field("customData");
2774            x.validate(&p)?;
2775        }
2776        Ok(())
2777    }
2778}
2779
2780/// *(2.1)* An entry in price schedule over time for which EV is willing to discharge.
2781#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2782#[serde(deny_unknown_fields)]
2783pub struct EVAbsolutePriceScheduleEntry {
2784    /// The amount of seconds of this entry.
2785    #[serde(rename = "duration")]
2786    pub duration: i64,
2787    #[serde(rename = "evPriceRule")]
2788    pub ev_price_rule: Vec<EVPriceRule>,
2789    #[serde(
2790        rename = "customData",
2791        default,
2792        skip_serializing_if = "Option::is_none"
2793    )]
2794    pub custom_data: Option<CustomData>,
2795}
2796
2797impl Validate for EVAbsolutePriceScheduleEntry {
2798    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2799        {
2800            let x = &self.ev_price_rule;
2801            let p = path.field("evPriceRule");
2802            v::items(x, Some(1), Some(8), &p)?;
2803            for (i0, it0) in x.iter().enumerate() {
2804                let p0 = p.index(i0);
2805                it0.validate(&p0)?;
2806            }
2807        }
2808        if let Some(x) = &self.custom_data {
2809            let p = path.field("customData");
2810            x.validate(&p)?;
2811        }
2812        Ok(())
2813    }
2814}
2815
2816/// *(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.
2817#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2818#[serde(deny_unknown_fields)]
2819pub struct EVEnergyOffer {
2820    #[serde(
2821        rename = "evAbsolutePriceSchedule",
2822        default,
2823        skip_serializing_if = "Option::is_none"
2824    )]
2825    pub ev_absolute_price_schedule: Option<EVAbsolutePriceSchedule>,
2826    #[serde(rename = "evPowerSchedule")]
2827    pub ev_power_schedule: EVPowerSchedule,
2828    #[serde(
2829        rename = "customData",
2830        default,
2831        skip_serializing_if = "Option::is_none"
2832    )]
2833    pub custom_data: Option<CustomData>,
2834}
2835
2836impl Validate for EVEnergyOffer {
2837    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2838        if let Some(x) = &self.ev_absolute_price_schedule {
2839            let p = path.field("evAbsolutePriceSchedule");
2840            x.validate(&p)?;
2841        }
2842        {
2843            let x = &self.ev_power_schedule;
2844            let p = path.field("evPowerSchedule");
2845            x.validate(&p)?;
2846        }
2847        if let Some(x) = &self.custom_data {
2848            let p = path.field("customData");
2849            x.validate(&p)?;
2850        }
2851        Ok(())
2852    }
2853}
2854
2855/// *(2.1)* Schedule of EV energy offer.
2856#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2857#[serde(deny_unknown_fields)]
2858pub struct EVPowerSchedule {
2859    #[serde(rename = "evPowerScheduleEntries")]
2860    pub ev_power_schedule_entries: Vec<EVPowerScheduleEntry>,
2861    /// The time that defines the starting point for the EVEnergyOffer.
2862    #[serde(rename = "timeAnchor")]
2863    pub time_anchor: DateTime,
2864    #[serde(
2865        rename = "customData",
2866        default,
2867        skip_serializing_if = "Option::is_none"
2868    )]
2869    pub custom_data: Option<CustomData>,
2870}
2871
2872impl Validate for EVPowerSchedule {
2873    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2874        {
2875            let x = &self.ev_power_schedule_entries;
2876            let p = path.field("evPowerScheduleEntries");
2877            v::items(x, Some(1), Some(1024), &p)?;
2878            for (i0, it0) in x.iter().enumerate() {
2879                let p0 = p.index(i0);
2880                it0.validate(&p0)?;
2881            }
2882        }
2883        if let Some(x) = &self.custom_data {
2884            let p = path.field("customData");
2885            x.validate(&p)?;
2886        }
2887        Ok(())
2888    }
2889}
2890
2891/// *(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.
2892#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2893#[serde(deny_unknown_fields)]
2894pub struct EVPowerScheduleEntry {
2895    /// The duration of this entry.
2896    #[serde(rename = "duration")]
2897    pub duration: i64,
2898    /// 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.
2899    #[serde(rename = "power")]
2900    pub power: f64,
2901    #[serde(
2902        rename = "customData",
2903        default,
2904        skip_serializing_if = "Option::is_none"
2905    )]
2906    pub custom_data: Option<CustomData>,
2907}
2908
2909impl Validate for EVPowerScheduleEntry {
2910    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2911        if let Some(x) = &self.custom_data {
2912            let p = path.field("customData");
2913            x.validate(&p)?;
2914        }
2915        Ok(())
2916    }
2917}
2918
2919/// *(2.1)* An entry in price schedule over time for which EV is willing to discharge.
2920#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2921#[serde(deny_unknown_fields)]
2922pub struct EVPriceRule {
2923    /// Cost per kWh.
2924    #[serde(rename = "energyFee")]
2925    pub energy_fee: f64,
2926    /// 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.
2927    #[serde(rename = "powerRangeStart")]
2928    pub power_range_start: f64,
2929    #[serde(
2930        rename = "customData",
2931        default,
2932        skip_serializing_if = "Option::is_none"
2933    )]
2934    pub custom_data: Option<CustomData>,
2935}
2936
2937impl Validate for EVPriceRule {
2938    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2939        if let Some(x) = &self.custom_data {
2940            let p = path.field("customData");
2941            x.validate(&p)?;
2942        }
2943        Ok(())
2944    }
2945}
2946
2947/// Electric Vehicle Supply Equipment
2948#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2949#[serde(deny_unknown_fields)]
2950pub struct EVSE {
2951    /// EVSE Identifier. This contains a number (&gt; 0) designating an EVSE of the Charging Station.
2952    #[serde(rename = "id")]
2953    pub id: i64,
2954    /// An id to designate a specific connector (on an EVSE) by connector index number.
2955    #[serde(
2956        rename = "connectorId",
2957        default,
2958        skip_serializing_if = "Option::is_none"
2959    )]
2960    pub connector_id: Option<i64>,
2961    #[serde(
2962        rename = "customData",
2963        default,
2964        skip_serializing_if = "Option::is_none"
2965    )]
2966    pub custom_data: Option<CustomData>,
2967}
2968
2969impl Validate for EVSE {
2970    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
2971        {
2972            let x = &self.id;
2973            let p = path.field("id");
2974            v::minimum(*x, 0i64, &p)?;
2975        }
2976        if let Some(x) = &self.connector_id {
2977            let p = path.field("connectorId");
2978            v::minimum(*x, 0i64, &p)?;
2979        }
2980        if let Some(x) = &self.custom_data {
2981            let p = path.field("customData");
2982            x.validate(&p)?;
2983        }
2984        Ok(())
2985    }
2986}
2987
2988#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
2989#[serde(deny_unknown_fields)]
2990pub struct EnterService {
2991    /// Priority of setting (0=highest)
2992    #[serde(rename = "priority")]
2993    pub priority: i64,
2994    /// Enter service voltage high
2995    #[serde(rename = "highVoltage")]
2996    pub high_voltage: f64,
2997    /// Enter service voltage low
2998    #[serde(rename = "lowVoltage")]
2999    pub low_voltage: f64,
3000    /// Enter service frequency high
3001    #[serde(rename = "highFreq")]
3002    pub high_freq: f64,
3003    /// Enter service frequency low
3004    #[serde(rename = "lowFreq")]
3005    pub low_freq: f64,
3006    /// Enter service delay
3007    #[serde(rename = "delay", default, skip_serializing_if = "Option::is_none")]
3008    pub delay: Option<f64>,
3009    /// Enter service randomized delay
3010    #[serde(
3011        rename = "randomDelay",
3012        default,
3013        skip_serializing_if = "Option::is_none"
3014    )]
3015    pub random_delay: Option<f64>,
3016    /// Enter service ramp rate in seconds
3017    #[serde(rename = "rampRate", default, skip_serializing_if = "Option::is_none")]
3018    pub ramp_rate: Option<f64>,
3019    #[serde(
3020        rename = "customData",
3021        default,
3022        skip_serializing_if = "Option::is_none"
3023    )]
3024    pub custom_data: Option<CustomData>,
3025}
3026
3027impl Validate for EnterService {
3028    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3029        {
3030            let x = &self.priority;
3031            let p = path.field("priority");
3032            v::minimum(*x, 0i64, &p)?;
3033        }
3034        if let Some(x) = &self.custom_data {
3035            let p = path.field("customData");
3036            x.validate(&p)?;
3037        }
3038        Ok(())
3039    }
3040}
3041
3042#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3043#[serde(deny_unknown_fields)]
3044pub struct EnterServiceGet {
3045    #[serde(rename = "enterService")]
3046    pub enter_service: EnterService,
3047    /// Id of setting
3048    #[serde(rename = "id")]
3049    pub id: String,
3050    #[serde(
3051        rename = "customData",
3052        default,
3053        skip_serializing_if = "Option::is_none"
3054    )]
3055    pub custom_data: Option<CustomData>,
3056}
3057
3058impl Validate for EnterServiceGet {
3059    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3060        {
3061            let x = &self.enter_service;
3062            let p = path.field("enterService");
3063            x.validate(&p)?;
3064        }
3065        {
3066            let x = &self.id;
3067            let p = path.field("id");
3068            v::max_length(x, 36, &p)?;
3069        }
3070        if let Some(x) = &self.custom_data {
3071            let p = path.field("customData");
3072            x.validate(&p)?;
3073        }
3074        Ok(())
3075    }
3076}
3077
3078/// Class to report an event notification for a component-variable.
3079#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3080#[serde(deny_unknown_fields)]
3081pub struct EventData {
3082    /// Identifies the event. This field can be referred to as a cause by other events.
3083    #[serde(rename = "eventId")]
3084    pub event_id: i64,
3085    /// Timestamp of the moment the report was generated.
3086    #[serde(rename = "timestamp")]
3087    pub timestamp: DateTime,
3088    #[serde(rename = "trigger")]
3089    pub trigger: EventTriggerEnum,
3090    /// Refers to the Id of an event that is considered to be the cause for this event.
3091    #[serde(rename = "cause", default, skip_serializing_if = "Option::is_none")]
3092    pub cause: Option<i64>,
3093    /// Actual value (_attributeType_ Actual) of the variable.
3094    /// 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.
3095    #[serde(rename = "actualValue")]
3096    pub actual_value: String,
3097    /// Technical (error) code as reported by component.
3098    #[serde(rename = "techCode", default, skip_serializing_if = "Option::is_none")]
3099    pub tech_code: Option<String>,
3100    /// Technical detail information as reported by component.
3101    #[serde(rename = "techInfo", default, skip_serializing_if = "Option::is_none")]
3102    pub tech_info: Option<String>,
3103    /// _Cleared_ is set to true to report the clearing of a monitored situation, i.e. a 'return to normal'.
3104    #[serde(rename = "cleared", default, skip_serializing_if = "Option::is_none")]
3105    pub cleared: Option<bool>,
3106    /// If an event notification is linked to a specific transaction, this field can be used to specify its transactionId.
3107    #[serde(
3108        rename = "transactionId",
3109        default,
3110        skip_serializing_if = "Option::is_none"
3111    )]
3112    pub transaction_id: Option<String>,
3113    #[serde(rename = "component")]
3114    pub component: Component,
3115    /// Identifies the VariableMonitoring which triggered the event.
3116    #[serde(
3117        rename = "variableMonitoringId",
3118        default,
3119        skip_serializing_if = "Option::is_none"
3120    )]
3121    pub variable_monitoring_id: Option<i64>,
3122    #[serde(rename = "eventNotificationType")]
3123    pub event_notification_type: EventNotificationEnum,
3124    #[serde(rename = "variable")]
3125    pub variable: Variable,
3126    /// *(2.1)* Severity associated with the monitor in _variableMonitoringId_ or with the hardwired notification.
3127    #[serde(rename = "severity", default, skip_serializing_if = "Option::is_none")]
3128    pub severity: Option<i64>,
3129    #[serde(
3130        rename = "customData",
3131        default,
3132        skip_serializing_if = "Option::is_none"
3133    )]
3134    pub custom_data: Option<CustomData>,
3135}
3136
3137impl Validate for EventData {
3138    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3139        {
3140            let x = &self.event_id;
3141            let p = path.field("eventId");
3142            v::minimum(*x, 0i64, &p)?;
3143        }
3144        if let Some(x) = &self.cause {
3145            let p = path.field("cause");
3146            v::minimum(*x, 0i64, &p)?;
3147        }
3148        {
3149            let x = &self.actual_value;
3150            let p = path.field("actualValue");
3151            v::max_length(x, 2500, &p)?;
3152        }
3153        if let Some(x) = &self.tech_code {
3154            let p = path.field("techCode");
3155            v::max_length(x, 50, &p)?;
3156        }
3157        if let Some(x) = &self.tech_info {
3158            let p = path.field("techInfo");
3159            v::max_length(x, 500, &p)?;
3160        }
3161        if let Some(x) = &self.transaction_id {
3162            let p = path.field("transactionId");
3163            v::max_length(x, 36, &p)?;
3164        }
3165        {
3166            let x = &self.component;
3167            let p = path.field("component");
3168            x.validate(&p)?;
3169        }
3170        if let Some(x) = &self.variable_monitoring_id {
3171            let p = path.field("variableMonitoringId");
3172            v::minimum(*x, 0i64, &p)?;
3173        }
3174        {
3175            let x = &self.variable;
3176            let p = path.field("variable");
3177            x.validate(&p)?;
3178        }
3179        if let Some(x) = &self.severity {
3180            let p = path.field("severity");
3181            v::minimum(*x, 0i64, &p)?;
3182        }
3183        if let Some(x) = &self.custom_data {
3184            let p = path.field("customData");
3185            x.validate(&p)?;
3186        }
3187        Ok(())
3188    }
3189}
3190
3191/// Represents a copy of the firmware that can be loaded/updated on the Charging Station.
3192#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3193#[serde(deny_unknown_fields)]
3194pub struct Firmware {
3195    /// URI defining the origin of the firmware.
3196    #[serde(rename = "location")]
3197    pub location: String,
3198    /// Date and time at which the firmware shall be retrieved.
3199    #[serde(rename = "retrieveDateTime")]
3200    pub retrieve_date_time: DateTime,
3201    /// Date and time at which the firmware shall be installed.
3202    #[serde(
3203        rename = "installDateTime",
3204        default,
3205        skip_serializing_if = "Option::is_none"
3206    )]
3207    pub install_date_time: Option<DateTime>,
3208    /// Certificate with which the firmware was signed.
3209    /// PEM encoded X.509 certificate.
3210    #[serde(
3211        rename = "signingCertificate",
3212        default,
3213        skip_serializing_if = "Option::is_none"
3214    )]
3215    pub signing_certificate: Option<String>,
3216    /// Base64 encoded firmware signature.
3217    #[serde(rename = "signature", default, skip_serializing_if = "Option::is_none")]
3218    pub signature: Option<String>,
3219    #[serde(
3220        rename = "customData",
3221        default,
3222        skip_serializing_if = "Option::is_none"
3223    )]
3224    pub custom_data: Option<CustomData>,
3225}
3226
3227impl Validate for Firmware {
3228    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3229        {
3230            let x = &self.location;
3231            let p = path.field("location");
3232            v::max_length(x, 2000, &p)?;
3233        }
3234        if let Some(x) = &self.signing_certificate {
3235            let p = path.field("signingCertificate");
3236            v::max_length(x, 5500, &p)?;
3237        }
3238        if let Some(x) = &self.signature {
3239            let p = path.field("signature");
3240            v::max_length(x, 800, &p)?;
3241        }
3242        if let Some(x) = &self.custom_data {
3243            let p = path.field("customData");
3244            x.validate(&p)?;
3245        }
3246        Ok(())
3247    }
3248}
3249
3250#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3251#[serde(deny_unknown_fields)]
3252pub struct FixedPF {
3253    /// Priority of setting (0=highest)
3254    #[serde(rename = "priority")]
3255    pub priority: i64,
3256    /// Power factor, cos(phi), as value between 0..1.
3257    #[serde(rename = "displacement")]
3258    pub displacement: f64,
3259    /// True when absorbing reactive power (under-excited), false when injecting reactive power (over-excited).
3260    #[serde(rename = "excitation")]
3261    pub excitation: bool,
3262    /// Time when this setting becomes active
3263    #[serde(rename = "startTime", default, skip_serializing_if = "Option::is_none")]
3264    pub start_time: Option<DateTime>,
3265    /// Duration in seconds that this setting is active.
3266    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
3267    pub duration: Option<f64>,
3268    #[serde(
3269        rename = "customData",
3270        default,
3271        skip_serializing_if = "Option::is_none"
3272    )]
3273    pub custom_data: Option<CustomData>,
3274}
3275
3276impl Validate for FixedPF {
3277    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3278        {
3279            let x = &self.priority;
3280            let p = path.field("priority");
3281            v::minimum(*x, 0i64, &p)?;
3282        }
3283        if let Some(x) = &self.custom_data {
3284            let p = path.field("customData");
3285            x.validate(&p)?;
3286        }
3287        Ok(())
3288    }
3289}
3290
3291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3292#[serde(deny_unknown_fields)]
3293pub struct FixedPFGet {
3294    #[serde(rename = "fixedPF")]
3295    pub fixed_pf: FixedPF,
3296    /// Id of setting.
3297    #[serde(rename = "id")]
3298    pub id: String,
3299    /// True if setting is a default control.
3300    #[serde(rename = "isDefault")]
3301    pub is_default: bool,
3302    /// True if this setting is superseded by a lower priority setting.
3303    #[serde(rename = "isSuperseded")]
3304    pub is_superseded: bool,
3305    #[serde(
3306        rename = "customData",
3307        default,
3308        skip_serializing_if = "Option::is_none"
3309    )]
3310    pub custom_data: Option<CustomData>,
3311}
3312
3313impl Validate for FixedPFGet {
3314    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3315        {
3316            let x = &self.fixed_pf;
3317            let p = path.field("fixedPF");
3318            x.validate(&p)?;
3319        }
3320        {
3321            let x = &self.id;
3322            let p = path.field("id");
3323            v::max_length(x, 36, &p)?;
3324        }
3325        if let Some(x) = &self.custom_data {
3326            let p = path.field("customData");
3327            x.validate(&p)?;
3328        }
3329        Ok(())
3330    }
3331}
3332
3333#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3334#[serde(deny_unknown_fields)]
3335pub struct FixedVar {
3336    /// Priority of setting (0=highest)
3337    #[serde(rename = "priority")]
3338    pub priority: i64,
3339    /// The value specifies a target var output interpreted as a signed percentage (-100 to 100).
3340    /// A negative value refers to charging, whereas a positive one refers to discharging.
3341    /// The value type is determined by the unit field.
3342    #[serde(rename = "setpoint")]
3343    pub setpoint: f64,
3344    #[serde(rename = "unit")]
3345    pub unit: DERUnitEnum,
3346    /// Time when this setting becomes active.
3347    #[serde(rename = "startTime", default, skip_serializing_if = "Option::is_none")]
3348    pub start_time: Option<DateTime>,
3349    /// Duration in seconds that this setting is active.
3350    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
3351    pub duration: Option<f64>,
3352    #[serde(
3353        rename = "customData",
3354        default,
3355        skip_serializing_if = "Option::is_none"
3356    )]
3357    pub custom_data: Option<CustomData>,
3358}
3359
3360impl Validate for FixedVar {
3361    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3362        {
3363            let x = &self.priority;
3364            let p = path.field("priority");
3365            v::minimum(*x, 0i64, &p)?;
3366        }
3367        if let Some(x) = &self.custom_data {
3368            let p = path.field("customData");
3369            x.validate(&p)?;
3370        }
3371        Ok(())
3372    }
3373}
3374
3375#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3376#[serde(deny_unknown_fields)]
3377pub struct FixedVarGet {
3378    #[serde(rename = "fixedVar")]
3379    pub fixed_var: FixedVar,
3380    /// Id of setting
3381    #[serde(rename = "id")]
3382    pub id: String,
3383    /// True if setting is a default control.
3384    #[serde(rename = "isDefault")]
3385    pub is_default: bool,
3386    /// True if this setting is superseded by a lower priority setting
3387    #[serde(rename = "isSuperseded")]
3388    pub is_superseded: bool,
3389    #[serde(
3390        rename = "customData",
3391        default,
3392        skip_serializing_if = "Option::is_none"
3393    )]
3394    pub custom_data: Option<CustomData>,
3395}
3396
3397impl Validate for FixedVarGet {
3398    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3399        {
3400            let x = &self.fixed_var;
3401            let p = path.field("fixedVar");
3402            x.validate(&p)?;
3403        }
3404        {
3405            let x = &self.id;
3406            let p = path.field("id");
3407            v::max_length(x, 36, &p)?;
3408        }
3409        if let Some(x) = &self.custom_data {
3410            let p = path.field("customData");
3411            x.validate(&p)?;
3412        }
3413        Ok(())
3414    }
3415}
3416
3417#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3418#[serde(deny_unknown_fields)]
3419pub struct FreqDroop {
3420    /// Priority of setting (0=highest)
3421    #[serde(rename = "priority")]
3422    pub priority: i64,
3423    /// Over-frequency start of droop
3424    #[serde(rename = "overFreq")]
3425    pub over_freq: f64,
3426    /// Under-frequency start of droop
3427    #[serde(rename = "underFreq")]
3428    pub under_freq: f64,
3429    /// Over-frequency droop per unit, oFDroop
3430    #[serde(rename = "overDroop")]
3431    pub over_droop: f64,
3432    /// Under-frequency droop per unit, uFDroop
3433    #[serde(rename = "underDroop")]
3434    pub under_droop: f64,
3435    /// Open loop response time in seconds
3436    #[serde(rename = "responseTime")]
3437    pub response_time: f64,
3438    /// Time when this setting becomes active
3439    #[serde(rename = "startTime", default, skip_serializing_if = "Option::is_none")]
3440    pub start_time: Option<DateTime>,
3441    /// Duration in seconds that this setting is active
3442    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
3443    pub duration: Option<f64>,
3444    #[serde(
3445        rename = "customData",
3446        default,
3447        skip_serializing_if = "Option::is_none"
3448    )]
3449    pub custom_data: Option<CustomData>,
3450}
3451
3452impl Validate for FreqDroop {
3453    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3454        {
3455            let x = &self.priority;
3456            let p = path.field("priority");
3457            v::minimum(*x, 0i64, &p)?;
3458        }
3459        if let Some(x) = &self.custom_data {
3460            let p = path.field("customData");
3461            x.validate(&p)?;
3462        }
3463        Ok(())
3464    }
3465}
3466
3467#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3468#[serde(deny_unknown_fields)]
3469pub struct FreqDroopGet {
3470    #[serde(rename = "freqDroop")]
3471    pub freq_droop: FreqDroop,
3472    /// Id of setting
3473    #[serde(rename = "id")]
3474    pub id: String,
3475    /// True if setting is a default control.
3476    #[serde(rename = "isDefault")]
3477    pub is_default: bool,
3478    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
3479    #[serde(rename = "isSuperseded")]
3480    pub is_superseded: bool,
3481    #[serde(
3482        rename = "customData",
3483        default,
3484        skip_serializing_if = "Option::is_none"
3485    )]
3486    pub custom_data: Option<CustomData>,
3487}
3488
3489impl Validate for FreqDroopGet {
3490    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3491        {
3492            let x = &self.freq_droop;
3493            let p = path.field("freqDroop");
3494            x.validate(&p)?;
3495        }
3496        {
3497            let x = &self.id;
3498            let p = path.field("id");
3499            v::max_length(x, 36, &p)?;
3500        }
3501        if let Some(x) = &self.custom_data {
3502            let p = path.field("customData");
3503            x.validate(&p)?;
3504        }
3505        Ok(())
3506    }
3507}
3508
3509/// Class to hold parameters for GetVariables request.
3510#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3511#[serde(deny_unknown_fields)]
3512pub struct GetVariableData {
3513    #[serde(
3514        rename = "attributeType",
3515        default,
3516        skip_serializing_if = "Option::is_none"
3517    )]
3518    pub attribute_type: Option<AttributeEnum>,
3519    #[serde(rename = "component")]
3520    pub component: Component,
3521    #[serde(rename = "variable")]
3522    pub variable: Variable,
3523    #[serde(
3524        rename = "customData",
3525        default,
3526        skip_serializing_if = "Option::is_none"
3527    )]
3528    pub custom_data: Option<CustomData>,
3529}
3530
3531impl Validate for GetVariableData {
3532    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3533        {
3534            let x = &self.component;
3535            let p = path.field("component");
3536            x.validate(&p)?;
3537        }
3538        {
3539            let x = &self.variable;
3540            let p = path.field("variable");
3541            x.validate(&p)?;
3542        }
3543        if let Some(x) = &self.custom_data {
3544            let p = path.field("customData");
3545            x.validate(&p)?;
3546        }
3547        Ok(())
3548    }
3549}
3550
3551/// Class to hold results of GetVariables request.
3552#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3553#[serde(deny_unknown_fields)]
3554pub struct GetVariableResult {
3555    #[serde(rename = "attributeStatus")]
3556    pub attribute_status: GetVariableStatusEnum,
3557    #[serde(
3558        rename = "attributeStatusInfo",
3559        default,
3560        skip_serializing_if = "Option::is_none"
3561    )]
3562    pub attribute_status_info: Option<StatusInfo>,
3563    #[serde(
3564        rename = "attributeType",
3565        default,
3566        skip_serializing_if = "Option::is_none"
3567    )]
3568    pub attribute_type: Option<AttributeEnum>,
3569    /// Value of requested attribute type of component-variable. This field can only be empty when the given status is NOT accepted.
3570    /// 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.
3571    #[serde(
3572        rename = "attributeValue",
3573        default,
3574        skip_serializing_if = "Option::is_none"
3575    )]
3576    pub attribute_value: Option<String>,
3577    #[serde(rename = "component")]
3578    pub component: Component,
3579    #[serde(rename = "variable")]
3580    pub variable: Variable,
3581    #[serde(
3582        rename = "customData",
3583        default,
3584        skip_serializing_if = "Option::is_none"
3585    )]
3586    pub custom_data: Option<CustomData>,
3587}
3588
3589impl Validate for GetVariableResult {
3590    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3591        if let Some(x) = &self.attribute_status_info {
3592            let p = path.field("attributeStatusInfo");
3593            x.validate(&p)?;
3594        }
3595        if let Some(x) = &self.attribute_value {
3596            let p = path.field("attributeValue");
3597            v::max_length(x, 2500, &p)?;
3598        }
3599        {
3600            let x = &self.component;
3601            let p = path.field("component");
3602            x.validate(&p)?;
3603        }
3604        {
3605            let x = &self.variable;
3606            let p = path.field("variable");
3607            x.validate(&p)?;
3608        }
3609        if let Some(x) = &self.custom_data {
3610            let p = path.field("customData");
3611            x.validate(&p)?;
3612        }
3613        Ok(())
3614    }
3615}
3616
3617#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3618#[serde(deny_unknown_fields)]
3619pub struct Gradient {
3620    /// Id of setting
3621    #[serde(rename = "priority")]
3622    pub priority: i64,
3623    /// Default ramp rate in seconds (0 if not applicable)
3624    #[serde(rename = "gradient")]
3625    pub gradient: f64,
3626    /// Soft-start ramp rate in seconds (0 if not applicable)
3627    #[serde(rename = "softGradient")]
3628    pub soft_gradient: f64,
3629    #[serde(
3630        rename = "customData",
3631        default,
3632        skip_serializing_if = "Option::is_none"
3633    )]
3634    pub custom_data: Option<CustomData>,
3635}
3636
3637impl Validate for Gradient {
3638    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3639        {
3640            let x = &self.priority;
3641            let p = path.field("priority");
3642            v::minimum(*x, 0i64, &p)?;
3643        }
3644        if let Some(x) = &self.custom_data {
3645            let p = path.field("customData");
3646            x.validate(&p)?;
3647        }
3648        Ok(())
3649    }
3650}
3651
3652#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3653#[serde(deny_unknown_fields)]
3654pub struct GradientGet {
3655    #[serde(rename = "gradient")]
3656    pub gradient: Gradient,
3657    /// Id of setting
3658    #[serde(rename = "id")]
3659    pub id: String,
3660    #[serde(
3661        rename = "customData",
3662        default,
3663        skip_serializing_if = "Option::is_none"
3664    )]
3665    pub custom_data: Option<CustomData>,
3666}
3667
3668impl Validate for GradientGet {
3669    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3670        {
3671            let x = &self.gradient;
3672            let p = path.field("gradient");
3673            x.validate(&p)?;
3674        }
3675        {
3676            let x = &self.id;
3677            let p = path.field("id");
3678            v::max_length(x, 36, &p)?;
3679        }
3680        if let Some(x) = &self.custom_data {
3681            let p = path.field("customData");
3682            x.validate(&p)?;
3683        }
3684        Ok(())
3685    }
3686}
3687
3688#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
3689#[serde(deny_unknown_fields)]
3690pub struct Hysteresis {
3691    /// High value for return to normal operation after a grid event, in absolute value. This value adopts the same unit as defined by yUnit
3692    #[serde(
3693        rename = "hysteresisHigh",
3694        default,
3695        skip_serializing_if = "Option::is_none"
3696    )]
3697    pub hysteresis_high: Option<f64>,
3698    /// Low value for return to normal operation after a grid event, in absolute value. This value adopts the same unit as defined by yUnit
3699    #[serde(
3700        rename = "hysteresisLow",
3701        default,
3702        skip_serializing_if = "Option::is_none"
3703    )]
3704    pub hysteresis_low: Option<f64>,
3705    /// Delay in seconds, once grid parameter within HysteresisLow and HysteresisHigh, for the EV to return to normal operation after a grid event.
3706    #[serde(
3707        rename = "hysteresisDelay",
3708        default,
3709        skip_serializing_if = "Option::is_none"
3710    )]
3711    pub hysteresis_delay: Option<f64>,
3712    /// Set default rate of change (ramp rate %/s) for the EV to return to normal operation after a grid event
3713    #[serde(
3714        rename = "hysteresisGradient",
3715        default,
3716        skip_serializing_if = "Option::is_none"
3717    )]
3718    pub hysteresis_gradient: Option<f64>,
3719    #[serde(
3720        rename = "customData",
3721        default,
3722        skip_serializing_if = "Option::is_none"
3723    )]
3724    pub custom_data: Option<CustomData>,
3725}
3726
3727impl Validate for Hysteresis {
3728    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3729        if let Some(x) = &self.custom_data {
3730            let p = path.field("customData");
3731            x.validate(&p)?;
3732        }
3733        Ok(())
3734    }
3735}
3736
3737/// Contains a case insensitive identifier to use for the authorization and the type of authorization to support multiple forms of identifiers.
3738#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3739#[serde(deny_unknown_fields)]
3740pub struct IdToken {
3741    #[serde(
3742        rename = "additionalInfo",
3743        default,
3744        skip_serializing_if = "Option::is_none"
3745    )]
3746    pub additional_info: Option<Vec<AdditionalInfo>>,
3747    /// *(2.1)* IdToken is case insensitive. Might hold the hidden id of an RFID tag, but can for example also contain a UUID.
3748    #[serde(rename = "idToken")]
3749    pub id_token: String,
3750    /// *(2.1)* Enumeration of possible idToken types. Values defined in Appendix as IdTokenEnumStringType.
3751    #[serde(rename = "type")]
3752    pub r#type: String,
3753    #[serde(
3754        rename = "customData",
3755        default,
3756        skip_serializing_if = "Option::is_none"
3757    )]
3758    pub custom_data: Option<CustomData>,
3759}
3760
3761impl Validate for IdToken {
3762    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3763        if let Some(x) = &self.additional_info {
3764            let p = path.field("additionalInfo");
3765            v::items(x, Some(1), None, &p)?;
3766            for (i0, it0) in x.iter().enumerate() {
3767                let p0 = p.index(i0);
3768                it0.validate(&p0)?;
3769            }
3770        }
3771        {
3772            let x = &self.id_token;
3773            let p = path.field("idToken");
3774            v::max_length(x, 255, &p)?;
3775        }
3776        {
3777            let x = &self.r#type;
3778            let p = path.field("type");
3779            v::max_length(x, 20, &p)?;
3780        }
3781        if let Some(x) = &self.custom_data {
3782            let p = path.field("customData");
3783            x.validate(&p)?;
3784        }
3785        Ok(())
3786    }
3787}
3788
3789/// Contains status information about an identifier.
3790/// 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.
3791#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3792#[serde(deny_unknown_fields)]
3793pub struct IdTokenInfo {
3794    #[serde(rename = "status")]
3795    pub status: AuthorizationStatusEnum,
3796    /// Date and Time after which the token must be considered invalid.
3797    #[serde(
3798        rename = "cacheExpiryDateTime",
3799        default,
3800        skip_serializing_if = "Option::is_none"
3801    )]
3802    pub cache_expiry_date_time: Option<DateTime>,
3803    /// 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.
3804    #[serde(
3805        rename = "chargingPriority",
3806        default,
3807        skip_serializing_if = "Option::is_none"
3808    )]
3809    pub charging_priority: Option<i64>,
3810    #[serde(
3811        rename = "groupIdToken",
3812        default,
3813        skip_serializing_if = "Option::is_none"
3814    )]
3815    pub group_id_token: Option<IdToken>,
3816    /// Preferred user interface language of identifier user. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
3817    #[serde(rename = "language1", default, skip_serializing_if = "Option::is_none")]
3818    pub language1: Option<String>,
3819    /// 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;.
3820    #[serde(rename = "language2", default, skip_serializing_if = "Option::is_none")]
3821    pub language2: Option<String>,
3822    /// Only used when the IdToken is only valid for one or more specific EVSEs, not for the entire Charging Station.
3823    #[serde(rename = "evseId", default, skip_serializing_if = "Option::is_none")]
3824    pub evse_id: Option<Vec<i64>>,
3825    #[serde(
3826        rename = "personalMessage",
3827        default,
3828        skip_serializing_if = "Option::is_none"
3829    )]
3830    pub personal_message: Option<MessageContent>,
3831    #[serde(
3832        rename = "customData",
3833        default,
3834        skip_serializing_if = "Option::is_none"
3835    )]
3836    pub custom_data: Option<CustomData>,
3837}
3838
3839impl Validate for IdTokenInfo {
3840    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3841        if let Some(x) = &self.group_id_token {
3842            let p = path.field("groupIdToken");
3843            x.validate(&p)?;
3844        }
3845        if let Some(x) = &self.language1 {
3846            let p = path.field("language1");
3847            v::max_length(x, 8, &p)?;
3848        }
3849        if let Some(x) = &self.language2 {
3850            let p = path.field("language2");
3851            v::max_length(x, 8, &p)?;
3852        }
3853        if let Some(x) = &self.evse_id {
3854            let p = path.field("evseId");
3855            v::items(x, Some(1), None, &p)?;
3856            for (i0, it0) in x.iter().enumerate() {
3857                let p0 = p.index(i0);
3858                v::minimum(*it0, 0i64, &p0)?;
3859            }
3860        }
3861        if let Some(x) = &self.personal_message {
3862            let p = path.field("personalMessage");
3863            x.validate(&p)?;
3864        }
3865        if let Some(x) = &self.custom_data {
3866            let p = path.field("customData");
3867            x.validate(&p)?;
3868        }
3869        Ok(())
3870    }
3871}
3872
3873#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3874#[serde(deny_unknown_fields)]
3875pub struct LimitAtSoC {
3876    /// The SoC value beyond which the charging rate limit should be applied.
3877    #[serde(rename = "soc")]
3878    pub soc: i64,
3879    /// Charging rate limit beyond the SoC value.
3880    /// The unit is defined by _chargingSchedule.chargingRateUnit_.
3881    #[serde(rename = "limit")]
3882    pub limit: f64,
3883    #[serde(
3884        rename = "customData",
3885        default,
3886        skip_serializing_if = "Option::is_none"
3887    )]
3888    pub custom_data: Option<CustomData>,
3889}
3890
3891impl Validate for LimitAtSoC {
3892    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3893        {
3894            let x = &self.soc;
3895            let p = path.field("soc");
3896            v::minimum(*x, 0i64, &p)?;
3897            v::maximum(*x, 100i64, &p)?;
3898        }
3899        if let Some(x) = &self.custom_data {
3900            let p = path.field("customData");
3901            x.validate(&p)?;
3902        }
3903        Ok(())
3904    }
3905}
3906
3907#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3908#[serde(deny_unknown_fields)]
3909pub struct LimitMaxDischarge {
3910    /// Priority of setting (0=highest)
3911    #[serde(rename = "priority")]
3912    pub priority: i64,
3913    /// Only for PowerMonitoring. +
3914    /// The value specifies a percentage (0 to 100) of the rated maximum discharge power of EV.
3915    /// The PowerMonitoring curve becomes active when power exceeds this percentage.
3916    #[serde(
3917        rename = "pctMaxDischargePower",
3918        default,
3919        skip_serializing_if = "Option::is_none"
3920    )]
3921    pub pct_max_discharge_power: Option<f64>,
3922    #[serde(
3923        rename = "powerMonitoringMustTrip",
3924        default,
3925        skip_serializing_if = "Option::is_none"
3926    )]
3927    pub power_monitoring_must_trip: Option<DERCurve>,
3928    /// Time when this setting becomes active
3929    #[serde(rename = "startTime", default, skip_serializing_if = "Option::is_none")]
3930    pub start_time: Option<DateTime>,
3931    /// Duration in seconds that this setting is active
3932    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
3933    pub duration: Option<f64>,
3934    #[serde(
3935        rename = "customData",
3936        default,
3937        skip_serializing_if = "Option::is_none"
3938    )]
3939    pub custom_data: Option<CustomData>,
3940}
3941
3942impl Validate for LimitMaxDischarge {
3943    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3944        {
3945            let x = &self.priority;
3946            let p = path.field("priority");
3947            v::minimum(*x, 0i64, &p)?;
3948        }
3949        if let Some(x) = &self.power_monitoring_must_trip {
3950            let p = path.field("powerMonitoringMustTrip");
3951            x.validate(&p)?;
3952        }
3953        if let Some(x) = &self.custom_data {
3954            let p = path.field("customData");
3955            x.validate(&p)?;
3956        }
3957        Ok(())
3958    }
3959}
3960
3961#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
3962#[serde(deny_unknown_fields)]
3963pub struct LimitMaxDischargeGet {
3964    /// Id of setting
3965    #[serde(rename = "id")]
3966    pub id: String,
3967    /// True if setting is a default control.
3968    #[serde(rename = "isDefault")]
3969    pub is_default: bool,
3970    /// True if this setting is superseded by a higher priority setting (i.e. lower value of _priority_)
3971    #[serde(rename = "isSuperseded")]
3972    pub is_superseded: bool,
3973    #[serde(rename = "limitMaxDischarge")]
3974    pub limit_max_discharge: LimitMaxDischarge,
3975    #[serde(
3976        rename = "customData",
3977        default,
3978        skip_serializing_if = "Option::is_none"
3979    )]
3980    pub custom_data: Option<CustomData>,
3981}
3982
3983impl Validate for LimitMaxDischargeGet {
3984    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
3985        {
3986            let x = &self.id;
3987            let p = path.field("id");
3988            v::max_length(x, 36, &p)?;
3989        }
3990        {
3991            let x = &self.limit_max_discharge;
3992            let p = path.field("limitMaxDischarge");
3993            x.validate(&p)?;
3994        }
3995        if let Some(x) = &self.custom_data {
3996            let p = path.field("customData");
3997            x.validate(&p)?;
3998        }
3999        Ok(())
4000    }
4001}
4002
4003/// Generic class for the configuration of logging entries.
4004#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4005#[serde(deny_unknown_fields)]
4006pub struct LogParameters {
4007    /// The URL of the location at the remote system where the log should be stored.
4008    #[serde(rename = "remoteLocation")]
4009    pub remote_location: String,
4010    /// This contains the date and time of the oldest logging information to include in the diagnostics.
4011    #[serde(
4012        rename = "oldestTimestamp",
4013        default,
4014        skip_serializing_if = "Option::is_none"
4015    )]
4016    pub oldest_timestamp: Option<DateTime>,
4017    /// This contains the date and time of the latest logging information to include in the diagnostics.
4018    #[serde(
4019        rename = "latestTimestamp",
4020        default,
4021        skip_serializing_if = "Option::is_none"
4022    )]
4023    pub latest_timestamp: Option<DateTime>,
4024    #[serde(
4025        rename = "customData",
4026        default,
4027        skip_serializing_if = "Option::is_none"
4028    )]
4029    pub custom_data: Option<CustomData>,
4030}
4031
4032impl Validate for LogParameters {
4033    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4034        {
4035            let x = &self.remote_location;
4036            let p = path.field("remoteLocation");
4037            v::max_length(x, 2000, &p)?;
4038        }
4039        if let Some(x) = &self.custom_data {
4040            let p = path.field("customData");
4041            x.validate(&p)?;
4042        }
4043        Ok(())
4044    }
4045}
4046
4047/// Contains message details, for a message to be displayed on a Charging Station.
4048#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4049#[serde(deny_unknown_fields)]
4050pub struct MessageContent {
4051    #[serde(rename = "format")]
4052    pub format: MessageFormatEnum,
4053    /// Message language identifier. Contains a language code as defined in &lt;&lt;ref-RFC5646,\[RFC5646\]&gt;&gt;.
4054    #[serde(rename = "language", default, skip_serializing_if = "Option::is_none")]
4055    pub language: Option<String>,
4056    /// *(2.1)* Required. Message contents. +
4057    /// Maximum length supported by Charging Station is given in OCPPCommCtrlr.FieldLength\["MessageContentType.content"\].
4058    /// Maximum length defaults to 1024.
4059    #[serde(rename = "content")]
4060    pub content: String,
4061    #[serde(
4062        rename = "customData",
4063        default,
4064        skip_serializing_if = "Option::is_none"
4065    )]
4066    pub custom_data: Option<CustomData>,
4067}
4068
4069impl Validate for MessageContent {
4070    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4071        if let Some(x) = &self.language {
4072            let p = path.field("language");
4073            v::max_length(x, 8, &p)?;
4074        }
4075        {
4076            let x = &self.content;
4077            let p = path.field("content");
4078            v::max_length(x, 1024, &p)?;
4079        }
4080        if let Some(x) = &self.custom_data {
4081            let p = path.field("customData");
4082            x.validate(&p)?;
4083        }
4084        Ok(())
4085    }
4086}
4087
4088/// Contains message details, for a message to be displayed on a Charging Station.
4089#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4090#[serde(deny_unknown_fields)]
4091pub struct MessageInfo {
4092    #[serde(rename = "display", default, skip_serializing_if = "Option::is_none")]
4093    pub display: Option<Component>,
4094    /// Unique id within an exchange context. It is defined within the OCPP context as a positive Integer value (greater or equal to zero).
4095    #[serde(rename = "id")]
4096    pub id: i64,
4097    #[serde(rename = "priority")]
4098    pub priority: MessagePriorityEnum,
4099    #[serde(rename = "state", default, skip_serializing_if = "Option::is_none")]
4100    pub state: Option<MessageStateEnum>,
4101    /// From what date-time should this message be shown. If omitted: directly.
4102    #[serde(
4103        rename = "startDateTime",
4104        default,
4105        skip_serializing_if = "Option::is_none"
4106    )]
4107    pub start_date_time: Option<DateTime>,
4108    /// Until what date-time should this message be shown, after this date/time this message SHALL be removed.
4109    #[serde(
4110        rename = "endDateTime",
4111        default,
4112        skip_serializing_if = "Option::is_none"
4113    )]
4114    pub end_date_time: Option<DateTime>,
4115    /// During which transaction shall this message be shown.
4116    /// Message SHALL be removed by the Charging Station after transaction has
4117    /// ended.
4118    #[serde(
4119        rename = "transactionId",
4120        default,
4121        skip_serializing_if = "Option::is_none"
4122    )]
4123    pub transaction_id: Option<String>,
4124    #[serde(rename = "message")]
4125    pub message: MessageContent,
4126    #[serde(
4127        rename = "messageExtra",
4128        default,
4129        skip_serializing_if = "Option::is_none"
4130    )]
4131    pub message_extra: Option<Vec<MessageContent>>,
4132    #[serde(
4133        rename = "customData",
4134        default,
4135        skip_serializing_if = "Option::is_none"
4136    )]
4137    pub custom_data: Option<CustomData>,
4138}
4139
4140impl Validate for MessageInfo {
4141    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4142        if let Some(x) = &self.display {
4143            let p = path.field("display");
4144            x.validate(&p)?;
4145        }
4146        {
4147            let x = &self.id;
4148            let p = path.field("id");
4149            v::minimum(*x, 0i64, &p)?;
4150        }
4151        if let Some(x) = &self.transaction_id {
4152            let p = path.field("transactionId");
4153            v::max_length(x, 36, &p)?;
4154        }
4155        {
4156            let x = &self.message;
4157            let p = path.field("message");
4158            x.validate(&p)?;
4159        }
4160        if let Some(x) = &self.message_extra {
4161            let p = path.field("messageExtra");
4162            v::items(x, Some(1), Some(4), &p)?;
4163            for (i0, it0) in x.iter().enumerate() {
4164                let p0 = p.index(i0);
4165                it0.validate(&p0)?;
4166            }
4167        }
4168        if let Some(x) = &self.custom_data {
4169            let p = path.field("customData");
4170            x.validate(&p)?;
4171        }
4172        Ok(())
4173    }
4174}
4175
4176/// 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.
4177#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4178#[serde(deny_unknown_fields)]
4179pub struct MeterValue {
4180    #[serde(rename = "sampledValue")]
4181    pub sampled_value: Vec<SampledValue>,
4182    /// Timestamp for measured value(s).
4183    #[serde(rename = "timestamp")]
4184    pub timestamp: DateTime,
4185    #[serde(
4186        rename = "customData",
4187        default,
4188        skip_serializing_if = "Option::is_none"
4189    )]
4190    pub custom_data: Option<CustomData>,
4191}
4192
4193impl Validate for MeterValue {
4194    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4195        {
4196            let x = &self.sampled_value;
4197            let p = path.field("sampledValue");
4198            v::items(x, Some(1), None, &p)?;
4199            for (i0, it0) in x.iter().enumerate() {
4200                let p0 = p.index(i0);
4201                it0.validate(&p0)?;
4202            }
4203        }
4204        if let Some(x) = &self.custom_data {
4205            let p = path.field("customData");
4206            x.validate(&p)?;
4207        }
4208        Ok(())
4209    }
4210}
4211
4212/// Defines parameters required for initiating and maintaining wireless communication with other devices.
4213#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
4214#[serde(deny_unknown_fields)]
4215pub struct Modem {
4216    /// This contains the ICCID of the modem’s SIM card.
4217    #[serde(rename = "iccid", default, skip_serializing_if = "Option::is_none")]
4218    pub iccid: Option<String>,
4219    /// This contains the IMSI of the modem’s SIM card.
4220    #[serde(rename = "imsi", default, skip_serializing_if = "Option::is_none")]
4221    pub imsi: Option<String>,
4222    #[serde(
4223        rename = "customData",
4224        default,
4225        skip_serializing_if = "Option::is_none"
4226    )]
4227    pub custom_data: Option<CustomData>,
4228}
4229
4230impl Validate for Modem {
4231    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4232        if let Some(x) = &self.iccid {
4233            let p = path.field("iccid");
4234            v::max_length(x, 20, &p)?;
4235        }
4236        if let Some(x) = &self.imsi {
4237            let p = path.field("imsi");
4238            v::max_length(x, 20, &p)?;
4239        }
4240        if let Some(x) = &self.custom_data {
4241            let p = path.field("customData");
4242            x.validate(&p)?;
4243        }
4244        Ok(())
4245    }
4246}
4247
4248/// Class to hold parameters of SetVariableMonitoring request.
4249#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4250#[serde(deny_unknown_fields)]
4251pub struct MonitoringData {
4252    #[serde(rename = "component")]
4253    pub component: Component,
4254    #[serde(rename = "variable")]
4255    pub variable: Variable,
4256    #[serde(rename = "variableMonitoring")]
4257    pub variable_monitoring: Vec<VariableMonitoring>,
4258    #[serde(
4259        rename = "customData",
4260        default,
4261        skip_serializing_if = "Option::is_none"
4262    )]
4263    pub custom_data: Option<CustomData>,
4264}
4265
4266impl Validate for MonitoringData {
4267    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4268        {
4269            let x = &self.component;
4270            let p = path.field("component");
4271            x.validate(&p)?;
4272        }
4273        {
4274            let x = &self.variable;
4275            let p = path.field("variable");
4276            x.validate(&p)?;
4277        }
4278        {
4279            let x = &self.variable_monitoring;
4280            let p = path.field("variableMonitoring");
4281            v::items(x, Some(1), None, &p)?;
4282            for (i0, it0) in x.iter().enumerate() {
4283                let p0 = p.index(i0);
4284                it0.validate(&p0)?;
4285            }
4286        }
4287        if let Some(x) = &self.custom_data {
4288            let p = path.field("customData");
4289            x.validate(&p)?;
4290        }
4291        Ok(())
4292    }
4293}
4294
4295/// The NetworkConnectionProfile defines the functional and technical parameters of a communication link.
4296#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4297#[serde(deny_unknown_fields)]
4298pub struct NetworkConnectionProfile {
4299    #[serde(rename = "apn", default, skip_serializing_if = "Option::is_none")]
4300    pub apn: Option<APN>,
4301    #[serde(
4302        rename = "ocppVersion",
4303        default,
4304        skip_serializing_if = "Option::is_none"
4305    )]
4306    pub ocpp_version: Option<OCPPVersionEnum>,
4307    #[serde(rename = "ocppInterface")]
4308    pub ocpp_interface: OCPPInterfaceEnum,
4309    #[serde(rename = "ocppTransport")]
4310    pub ocpp_transport: OCPPTransportEnum,
4311    /// Duration in seconds before a message send by the Charging Station via this network connection times-out.
4312    /// The best setting depends on the underlying network and response times of the CSMS.
4313    /// If you are looking for a some guideline: use 30 seconds as a starting point.
4314    #[serde(rename = "messageTimeout")]
4315    pub message_timeout: i64,
4316    /// URL of the CSMS(s) that this Charging Station communicates with, without the Charging Station identity part. +
4317    /// The SecurityCtrlr.Identity field is appended to _ocppCsmsUrl_ to provide the full websocket URL.
4318    #[serde(rename = "ocppCsmsUrl")]
4319    pub ocpp_csms_url: String,
4320    /// This field specifies the security profile used when connecting to the CSMS with this NetworkConnectionProfile.
4321    #[serde(rename = "securityProfile")]
4322    pub security_profile: i64,
4323    /// *(2.1)* Charging Station identity to be used as the basic authentication username.
4324    #[serde(rename = "identity", default, skip_serializing_if = "Option::is_none")]
4325    pub identity: Option<String>,
4326    /// *(2.1)* BasicAuthPassword to use for security profile 1 or 2.
4327    #[serde(
4328        rename = "basicAuthPassword",
4329        default,
4330        skip_serializing_if = "Option::is_none"
4331    )]
4332    pub basic_auth_password: Option<String>,
4333    #[serde(rename = "vpn", default, skip_serializing_if = "Option::is_none")]
4334    pub vpn: Option<VPN>,
4335    #[serde(
4336        rename = "customData",
4337        default,
4338        skip_serializing_if = "Option::is_none"
4339    )]
4340    pub custom_data: Option<CustomData>,
4341}
4342
4343impl Validate for NetworkConnectionProfile {
4344    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4345        if let Some(x) = &self.apn {
4346            let p = path.field("apn");
4347            x.validate(&p)?;
4348        }
4349        {
4350            let x = &self.ocpp_csms_url;
4351            let p = path.field("ocppCsmsUrl");
4352            v::max_length(x, 2000, &p)?;
4353        }
4354        {
4355            let x = &self.security_profile;
4356            let p = path.field("securityProfile");
4357            v::minimum(*x, 0i64, &p)?;
4358        }
4359        if let Some(x) = &self.identity {
4360            let p = path.field("identity");
4361            v::max_length(x, 48, &p)?;
4362        }
4363        if let Some(x) = &self.basic_auth_password {
4364            let p = path.field("basicAuthPassword");
4365            v::max_length(x, 64, &p)?;
4366        }
4367        if let Some(x) = &self.vpn {
4368            let p = path.field("vpn");
4369            x.validate(&p)?;
4370        }
4371        if let Some(x) = &self.custom_data {
4372            let p = path.field("customData");
4373            x.validate(&p)?;
4374        }
4375        Ok(())
4376    }
4377}
4378
4379/// Information about a certificate for an OCSP check.
4380#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4381#[serde(deny_unknown_fields)]
4382pub struct OCSPRequestData {
4383    #[serde(rename = "hashAlgorithm")]
4384    pub hash_algorithm: HashAlgorithmEnum,
4385    /// The hash of the issuer’s distinguished
4386    /// name (DN), that must be calculated over the DER
4387    /// encoding of the issuer’s name field in the certificate
4388    /// being checked.
4389    #[serde(rename = "issuerNameHash")]
4390    pub issuer_name_hash: String,
4391    /// The hash of the DER encoded public key:
4392    /// the value (excluding tag and length) of the subject
4393    /// public key field in the issuer’s certificate.
4394    #[serde(rename = "issuerKeyHash")]
4395    pub issuer_key_hash: String,
4396    /// The string representation of the
4397    /// hexadecimal value of the serial number without the
4398    /// prefix "0x" and without leading zeroes.
4399    #[serde(rename = "serialNumber")]
4400    pub serial_number: String,
4401    /// This contains the responder URL (Case insensitive).
4402    #[serde(rename = "responderURL")]
4403    pub responder_url: String,
4404    #[serde(
4405        rename = "customData",
4406        default,
4407        skip_serializing_if = "Option::is_none"
4408    )]
4409    pub custom_data: Option<CustomData>,
4410}
4411
4412impl Validate for OCSPRequestData {
4413    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4414        {
4415            let x = &self.issuer_name_hash;
4416            let p = path.field("issuerNameHash");
4417            v::max_length(x, 128, &p)?;
4418        }
4419        {
4420            let x = &self.issuer_key_hash;
4421            let p = path.field("issuerKeyHash");
4422            v::max_length(x, 128, &p)?;
4423        }
4424        {
4425            let x = &self.serial_number;
4426            let p = path.field("serialNumber");
4427            v::max_length(x, 40, &p)?;
4428        }
4429        {
4430            let x = &self.responder_url;
4431            let p = path.field("responderURL");
4432            v::max_length(x, 2000, &p)?;
4433        }
4434        if let Some(x) = &self.custom_data {
4435            let p = path.field("customData");
4436            x.validate(&p)?;
4437        }
4438        Ok(())
4439    }
4440}
4441
4442/// Part of ISO 15118-20 price schedule.
4443#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4444#[serde(deny_unknown_fields)]
4445pub struct OverstayRule {
4446    #[serde(rename = "overstayFee")]
4447    pub overstay_fee: RationalNumber,
4448    /// Human readable string to identify the overstay rule.
4449    #[serde(
4450        rename = "overstayRuleDescription",
4451        default,
4452        skip_serializing_if = "Option::is_none"
4453    )]
4454    pub overstay_rule_description: Option<String>,
4455    /// Time in seconds after trigger of the parent Overstay Rules for this particular fee to apply.
4456    #[serde(rename = "startTime")]
4457    pub start_time: i64,
4458    /// Time till overstay will be reapplied
4459    #[serde(rename = "overstayFeePeriod")]
4460    pub overstay_fee_period: i64,
4461    #[serde(
4462        rename = "customData",
4463        default,
4464        skip_serializing_if = "Option::is_none"
4465    )]
4466    pub custom_data: Option<CustomData>,
4467}
4468
4469impl Validate for OverstayRule {
4470    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4471        {
4472            let x = &self.overstay_fee;
4473            let p = path.field("overstayFee");
4474            x.validate(&p)?;
4475        }
4476        if let Some(x) = &self.overstay_rule_description {
4477            let p = path.field("overstayRuleDescription");
4478            v::max_length(x, 32, &p)?;
4479        }
4480        if let Some(x) = &self.custom_data {
4481            let p = path.field("customData");
4482            x.validate(&p)?;
4483        }
4484        Ok(())
4485    }
4486}
4487
4488/// Part of ISO 15118-20 price schedule.
4489#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4490#[serde(deny_unknown_fields)]
4491pub struct OverstayRuleList {
4492    #[serde(
4493        rename = "overstayPowerThreshold",
4494        default,
4495        skip_serializing_if = "Option::is_none"
4496    )]
4497    pub overstay_power_threshold: Option<RationalNumber>,
4498    #[serde(rename = "overstayRule")]
4499    pub overstay_rule: Vec<OverstayRule>,
4500    /// Time till overstay is applied in seconds.
4501    #[serde(
4502        rename = "overstayTimeThreshold",
4503        default,
4504        skip_serializing_if = "Option::is_none"
4505    )]
4506    pub overstay_time_threshold: Option<i64>,
4507    #[serde(
4508        rename = "customData",
4509        default,
4510        skip_serializing_if = "Option::is_none"
4511    )]
4512    pub custom_data: Option<CustomData>,
4513}
4514
4515impl Validate for OverstayRuleList {
4516    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4517        if let Some(x) = &self.overstay_power_threshold {
4518            let p = path.field("overstayPowerThreshold");
4519            x.validate(&p)?;
4520        }
4521        {
4522            let x = &self.overstay_rule;
4523            let p = path.field("overstayRule");
4524            v::items(x, Some(1), Some(5), &p)?;
4525            for (i0, it0) in x.iter().enumerate() {
4526                let p0 = p.index(i0);
4527                it0.validate(&p0)?;
4528            }
4529        }
4530        if let Some(x) = &self.custom_data {
4531            let p = path.field("customData");
4532            x.validate(&p)?;
4533        }
4534        Ok(())
4535    }
4536}
4537
4538#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
4539#[serde(deny_unknown_fields)]
4540pub struct PeriodicEventStreamParams {
4541    /// Time in seconds after which stream data is sent.
4542    #[serde(rename = "interval", default, skip_serializing_if = "Option::is_none")]
4543    pub interval: Option<i64>,
4544    /// Number of items to be sent together in stream.
4545    #[serde(rename = "values", default, skip_serializing_if = "Option::is_none")]
4546    pub values: Option<i64>,
4547    #[serde(
4548        rename = "customData",
4549        default,
4550        skip_serializing_if = "Option::is_none"
4551    )]
4552    pub custom_data: Option<CustomData>,
4553}
4554
4555impl Validate for PeriodicEventStreamParams {
4556    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4557        if let Some(x) = &self.interval {
4558            let p = path.field("interval");
4559            v::minimum(*x, 0i64, &p)?;
4560        }
4561        if let Some(x) = &self.values {
4562            let p = path.field("values");
4563            v::minimum(*x, 0i64, &p)?;
4564        }
4565        if let Some(x) = &self.custom_data {
4566            let p = path.field("customData");
4567            x.validate(&p)?;
4568        }
4569        Ok(())
4570    }
4571}
4572
4573/// Price with and without tax. At least one of _exclTax_, _inclTax_ must be present.
4574#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
4575#[serde(deny_unknown_fields)]
4576pub struct Price {
4577    /// Price/cost excluding tax. Can be absent if _inclTax_ is present.
4578    #[serde(rename = "exclTax", default, skip_serializing_if = "Option::is_none")]
4579    pub excl_tax: Option<f64>,
4580    /// Price/cost including tax. Can be absent if _exclTax_ is present.
4581    #[serde(rename = "inclTax", default, skip_serializing_if = "Option::is_none")]
4582    pub incl_tax: Option<f64>,
4583    #[serde(rename = "taxRates", default, skip_serializing_if = "Option::is_none")]
4584    pub tax_rates: Option<Vec<TaxRate>>,
4585    #[serde(
4586        rename = "customData",
4587        default,
4588        skip_serializing_if = "Option::is_none"
4589    )]
4590    pub custom_data: Option<CustomData>,
4591}
4592
4593impl Validate for Price {
4594    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4595        if let Some(x) = &self.tax_rates {
4596            let p = path.field("taxRates");
4597            v::items(x, Some(1), Some(5), &p)?;
4598            for (i0, it0) in x.iter().enumerate() {
4599                let p0 = p.index(i0);
4600                it0.validate(&p0)?;
4601            }
4602        }
4603        if let Some(x) = &self.custom_data {
4604            let p = path.field("customData");
4605            x.validate(&p)?;
4606        }
4607        Ok(())
4608    }
4609}
4610
4611/// 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.
4612#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4613#[serde(deny_unknown_fields)]
4614pub struct PriceLevelSchedule {
4615    #[serde(rename = "priceLevelScheduleEntries")]
4616    pub price_level_schedule_entries: Vec<PriceLevelScheduleEntry>,
4617    /// Starting point of this price schedule.
4618    #[serde(rename = "timeAnchor")]
4619    pub time_anchor: DateTime,
4620    /// Unique ID of this price schedule.
4621    #[serde(rename = "priceScheduleId")]
4622    pub price_schedule_id: i64,
4623    /// Description of the price schedule.
4624    #[serde(
4625        rename = "priceScheduleDescription",
4626        default,
4627        skip_serializing_if = "Option::is_none"
4628    )]
4629    pub price_schedule_description: Option<String>,
4630    /// Defines the overall number of distinct price level elements used across all PriceLevelSchedules.
4631    #[serde(rename = "numberOfPriceLevels")]
4632    pub number_of_price_levels: i64,
4633    #[serde(
4634        rename = "customData",
4635        default,
4636        skip_serializing_if = "Option::is_none"
4637    )]
4638    pub custom_data: Option<CustomData>,
4639}
4640
4641impl Validate for PriceLevelSchedule {
4642    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4643        {
4644            let x = &self.price_level_schedule_entries;
4645            let p = path.field("priceLevelScheduleEntries");
4646            v::items(x, Some(1), Some(100), &p)?;
4647            for (i0, it0) in x.iter().enumerate() {
4648                let p0 = p.index(i0);
4649                it0.validate(&p0)?;
4650            }
4651        }
4652        {
4653            let x = &self.price_schedule_id;
4654            let p = path.field("priceScheduleId");
4655            v::minimum(*x, 0i64, &p)?;
4656        }
4657        if let Some(x) = &self.price_schedule_description {
4658            let p = path.field("priceScheduleDescription");
4659            v::max_length(x, 32, &p)?;
4660        }
4661        {
4662            let x = &self.number_of_price_levels;
4663            let p = path.field("numberOfPriceLevels");
4664            v::minimum(*x, 0i64, &p)?;
4665        }
4666        if let Some(x) = &self.custom_data {
4667            let p = path.field("customData");
4668            x.validate(&p)?;
4669        }
4670        Ok(())
4671    }
4672}
4673
4674/// Part of ISO 15118-20 price schedule.
4675#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4676#[serde(deny_unknown_fields)]
4677pub struct PriceLevelScheduleEntry {
4678    /// The amount of seconds that define the duration of this given PriceLevelScheduleEntry.
4679    #[serde(rename = "duration")]
4680    pub duration: i64,
4681    /// 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.
4682    #[serde(rename = "priceLevel")]
4683    pub price_level: i64,
4684    #[serde(
4685        rename = "customData",
4686        default,
4687        skip_serializing_if = "Option::is_none"
4688    )]
4689    pub custom_data: Option<CustomData>,
4690}
4691
4692impl Validate for PriceLevelScheduleEntry {
4693    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4694        {
4695            let x = &self.price_level;
4696            let p = path.field("priceLevel");
4697            v::minimum(*x, 0i64, &p)?;
4698        }
4699        if let Some(x) = &self.custom_data {
4700            let p = path.field("customData");
4701            x.validate(&p)?;
4702        }
4703        Ok(())
4704    }
4705}
4706
4707/// Part of ISO 15118-20 price schedule.
4708#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4709#[serde(deny_unknown_fields)]
4710pub struct PriceRule {
4711    /// The duration of the parking fee period (in seconds).
4712    /// When the time enters into a ParkingFeePeriod, the ParkingFee will apply to the session. .
4713    #[serde(
4714        rename = "parkingFeePeriod",
4715        default,
4716        skip_serializing_if = "Option::is_none"
4717    )]
4718    pub parking_fee_period: Option<i64>,
4719    /// Number of grams of CO2 per kWh.
4720    #[serde(
4721        rename = "carbonDioxideEmission",
4722        default,
4723        skip_serializing_if = "Option::is_none"
4724    )]
4725    pub carbon_dioxide_emission: Option<i64>,
4726    /// Percentage of the power that is created by renewable resources.
4727    #[serde(
4728        rename = "renewableGenerationPercentage",
4729        default,
4730        skip_serializing_if = "Option::is_none"
4731    )]
4732    pub renewable_generation_percentage: Option<i64>,
4733    #[serde(rename = "energyFee")]
4734    pub energy_fee: RationalNumber,
4735    #[serde(
4736        rename = "parkingFee",
4737        default,
4738        skip_serializing_if = "Option::is_none"
4739    )]
4740    pub parking_fee: Option<RationalNumber>,
4741    #[serde(rename = "powerRangeStart")]
4742    pub power_range_start: RationalNumber,
4743    #[serde(
4744        rename = "customData",
4745        default,
4746        skip_serializing_if = "Option::is_none"
4747    )]
4748    pub custom_data: Option<CustomData>,
4749}
4750
4751impl Validate for PriceRule {
4752    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4753        if let Some(x) = &self.carbon_dioxide_emission {
4754            let p = path.field("carbonDioxideEmission");
4755            v::minimum(*x, 0i64, &p)?;
4756        }
4757        if let Some(x) = &self.renewable_generation_percentage {
4758            let p = path.field("renewableGenerationPercentage");
4759            v::minimum(*x, 0i64, &p)?;
4760            v::maximum(*x, 100i64, &p)?;
4761        }
4762        {
4763            let x = &self.energy_fee;
4764            let p = path.field("energyFee");
4765            x.validate(&p)?;
4766        }
4767        if let Some(x) = &self.parking_fee {
4768            let p = path.field("parkingFee");
4769            x.validate(&p)?;
4770        }
4771        {
4772            let x = &self.power_range_start;
4773            let p = path.field("powerRangeStart");
4774            x.validate(&p)?;
4775        }
4776        if let Some(x) = &self.custom_data {
4777            let p = path.field("customData");
4778            x.validate(&p)?;
4779        }
4780        Ok(())
4781    }
4782}
4783
4784/// Part of ISO 15118-20 price schedule.
4785#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4786#[serde(deny_unknown_fields)]
4787pub struct PriceRuleStack {
4788    /// Duration of the stack of price rules.  he amount of seconds that define the duration of the given PriceRule(s).
4789    #[serde(rename = "duration")]
4790    pub duration: i64,
4791    #[serde(rename = "priceRule")]
4792    pub price_rule: Vec<PriceRule>,
4793    #[serde(
4794        rename = "customData",
4795        default,
4796        skip_serializing_if = "Option::is_none"
4797    )]
4798    pub custom_data: Option<CustomData>,
4799}
4800
4801impl Validate for PriceRuleStack {
4802    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4803        {
4804            let x = &self.price_rule;
4805            let p = path.field("priceRule");
4806            v::items(x, Some(1), Some(8), &p)?;
4807            for (i0, it0) in x.iter().enumerate() {
4808                let p0 = p.index(i0);
4809                it0.validate(&p0)?;
4810            }
4811        }
4812        if let Some(x) = &self.custom_data {
4813            let p = path.field("customData");
4814            x.validate(&p)?;
4815        }
4816        Ok(())
4817    }
4818}
4819
4820/// Part of ISO 15118-20 price schedule.
4821#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4822#[serde(deny_unknown_fields)]
4823pub struct RationalNumber {
4824    /// The exponent to base 10 (dec)
4825    #[serde(rename = "exponent")]
4826    pub exponent: i64,
4827    /// Value which shall be multiplied.
4828    #[serde(rename = "value")]
4829    pub value: i64,
4830    #[serde(
4831        rename = "customData",
4832        default,
4833        skip_serializing_if = "Option::is_none"
4834    )]
4835    pub custom_data: Option<CustomData>,
4836}
4837
4838impl Validate for RationalNumber {
4839    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4840        if let Some(x) = &self.custom_data {
4841            let p = path.field("customData");
4842            x.validate(&p)?;
4843        }
4844        Ok(())
4845    }
4846}
4847
4848#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
4849#[serde(deny_unknown_fields)]
4850pub struct ReactivePowerParams {
4851    /// Only for VoltVar curve: The nominal ac voltage (rms) adjustment to the voltage curve points for Volt-Var curves (percentage).
4852    #[serde(rename = "vRef", default, skip_serializing_if = "Option::is_none")]
4853    pub v_ref: Option<f64>,
4854    /// Only for VoltVar: Enable/disable autonomous VRef adjustment
4855    #[serde(
4856        rename = "autonomousVRefEnable",
4857        default,
4858        skip_serializing_if = "Option::is_none"
4859    )]
4860    pub autonomous_v_ref_enable: Option<bool>,
4861    /// Only for VoltVar: Adjustment range for VRef time constant
4862    #[serde(
4863        rename = "autonomousVRefTimeConstant",
4864        default,
4865        skip_serializing_if = "Option::is_none"
4866    )]
4867    pub autonomous_v_ref_time_constant: Option<f64>,
4868    #[serde(
4869        rename = "customData",
4870        default,
4871        skip_serializing_if = "Option::is_none"
4872    )]
4873    pub custom_data: Option<CustomData>,
4874}
4875
4876impl Validate for ReactivePowerParams {
4877    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4878        if let Some(x) = &self.custom_data {
4879            let p = path.field("customData");
4880            x.validate(&p)?;
4881        }
4882        Ok(())
4883    }
4884}
4885
4886#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4887#[serde(deny_unknown_fields)]
4888pub struct RelativeTimeInterval {
4889    /// Start of the interval, in seconds from NOW.
4890    #[serde(rename = "start")]
4891    pub start: i64,
4892    /// Duration of the interval, in seconds.
4893    #[serde(rename = "duration", default, skip_serializing_if = "Option::is_none")]
4894    pub duration: Option<i64>,
4895    #[serde(
4896        rename = "customData",
4897        default,
4898        skip_serializing_if = "Option::is_none"
4899    )]
4900    pub custom_data: Option<CustomData>,
4901}
4902
4903impl Validate for RelativeTimeInterval {
4904    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4905        if let Some(x) = &self.custom_data {
4906            let p = path.field("customData");
4907            x.validate(&p)?;
4908        }
4909        Ok(())
4910    }
4911}
4912
4913/// Class to report components, variables and variable attributes and characteristics.
4914#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4915#[serde(deny_unknown_fields)]
4916pub struct ReportData {
4917    #[serde(rename = "component")]
4918    pub component: Component,
4919    #[serde(rename = "variable")]
4920    pub variable: Variable,
4921    #[serde(rename = "variableAttribute")]
4922    pub variable_attribute: Vec<VariableAttribute>,
4923    #[serde(
4924        rename = "variableCharacteristics",
4925        default,
4926        skip_serializing_if = "Option::is_none"
4927    )]
4928    pub variable_characteristics: Option<VariableCharacteristics>,
4929    #[serde(
4930        rename = "customData",
4931        default,
4932        skip_serializing_if = "Option::is_none"
4933    )]
4934    pub custom_data: Option<CustomData>,
4935}
4936
4937impl Validate for ReportData {
4938    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
4939        {
4940            let x = &self.component;
4941            let p = path.field("component");
4942            x.validate(&p)?;
4943        }
4944        {
4945            let x = &self.variable;
4946            let p = path.field("variable");
4947            x.validate(&p)?;
4948        }
4949        {
4950            let x = &self.variable_attribute;
4951            let p = path.field("variableAttribute");
4952            v::items(x, Some(1), Some(4), &p)?;
4953            for (i0, it0) in x.iter().enumerate() {
4954                let p0 = p.index(i0);
4955                it0.validate(&p0)?;
4956            }
4957        }
4958        if let Some(x) = &self.variable_characteristics {
4959            let p = path.field("variableCharacteristics");
4960            x.validate(&p)?;
4961        }
4962        if let Some(x) = &self.custom_data {
4963            let p = path.field("customData");
4964            x.validate(&p)?;
4965        }
4966        Ok(())
4967    }
4968}
4969
4970/// A SalesTariff provided by a Mobility Operator (EMSP) .
4971/// NOTE: This dataType is based on dataTypes from &lt;&lt;ref-ISOIEC15118-2,ISO 15118-2&gt;&gt;.
4972#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
4973#[serde(deny_unknown_fields)]
4974pub struct SalesTariff {
4975    /// SalesTariff identifier used to identify one sales tariff. An SAID remains a unique identifier for one schedule throughout a charging session.
4976    #[serde(rename = "id")]
4977    pub id: i64,
4978    /// A human readable title/short description of the sales tariff e.g. for HMI display purposes.
4979    #[serde(
4980        rename = "salesTariffDescription",
4981        default,
4982        skip_serializing_if = "Option::is_none"
4983    )]
4984    pub sales_tariff_description: Option<String>,
4985    /// Defines the overall number of distinct price levels used across all provided SalesTariff elements.
4986    #[serde(
4987        rename = "numEPriceLevels",
4988        default,
4989        skip_serializing_if = "Option::is_none"
4990    )]
4991    pub num_e_price_levels: Option<i64>,
4992    #[serde(rename = "salesTariffEntry")]
4993    pub sales_tariff_entry: Vec<SalesTariffEntry>,
4994    #[serde(
4995        rename = "customData",
4996        default,
4997        skip_serializing_if = "Option::is_none"
4998    )]
4999    pub custom_data: Option<CustomData>,
5000}
5001
5002impl Validate for SalesTariff {
5003    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5004        {
5005            let x = &self.id;
5006            let p = path.field("id");
5007            v::minimum(*x, 0i64, &p)?;
5008        }
5009        if let Some(x) = &self.sales_tariff_description {
5010            let p = path.field("salesTariffDescription");
5011            v::max_length(x, 32, &p)?;
5012        }
5013        if let Some(x) = &self.num_e_price_levels {
5014            let p = path.field("numEPriceLevels");
5015            v::minimum(*x, 0i64, &p)?;
5016        }
5017        {
5018            let x = &self.sales_tariff_entry;
5019            let p = path.field("salesTariffEntry");
5020            v::items(x, Some(1), Some(1024), &p)?;
5021            for (i0, it0) in x.iter().enumerate() {
5022                let p0 = p.index(i0);
5023                it0.validate(&p0)?;
5024            }
5025        }
5026        if let Some(x) = &self.custom_data {
5027            let p = path.field("customData");
5028            x.validate(&p)?;
5029        }
5030        Ok(())
5031    }
5032}
5033
5034#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5035#[serde(deny_unknown_fields)]
5036pub struct SalesTariffEntry {
5037    #[serde(rename = "relativeTimeInterval")]
5038    pub relative_time_interval: RelativeTimeInterval,
5039    /// 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.
5040    #[serde(
5041        rename = "ePriceLevel",
5042        default,
5043        skip_serializing_if = "Option::is_none"
5044    )]
5045    pub e_price_level: Option<i64>,
5046    #[serde(
5047        rename = "consumptionCost",
5048        default,
5049        skip_serializing_if = "Option::is_none"
5050    )]
5051    pub consumption_cost: Option<Vec<ConsumptionCost>>,
5052    #[serde(
5053        rename = "customData",
5054        default,
5055        skip_serializing_if = "Option::is_none"
5056    )]
5057    pub custom_data: Option<CustomData>,
5058}
5059
5060impl Validate for SalesTariffEntry {
5061    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5062        {
5063            let x = &self.relative_time_interval;
5064            let p = path.field("relativeTimeInterval");
5065            x.validate(&p)?;
5066        }
5067        if let Some(x) = &self.e_price_level {
5068            let p = path.field("ePriceLevel");
5069            v::minimum(*x, 0i64, &p)?;
5070        }
5071        if let Some(x) = &self.consumption_cost {
5072            let p = path.field("consumptionCost");
5073            v::items(x, Some(1), Some(3), &p)?;
5074            for (i0, it0) in x.iter().enumerate() {
5075                let p0 = p.index(i0);
5076                it0.validate(&p0)?;
5077            }
5078        }
5079        if let Some(x) = &self.custom_data {
5080            let p = path.field("customData");
5081            x.validate(&p)?;
5082        }
5083        Ok(())
5084    }
5085}
5086
5087/// Single sampled value in MeterValues. Each value can be accompanied by optional fields.
5088/// 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.
5089#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5090#[serde(deny_unknown_fields)]
5091pub struct SampledValue {
5092    /// Indicates the measured value.
5093    #[serde(rename = "value")]
5094    pub value: f64,
5095    #[serde(rename = "measurand", default, skip_serializing_if = "Option::is_none")]
5096    pub measurand: Option<MeasurandEnum>,
5097    #[serde(rename = "context", default, skip_serializing_if = "Option::is_none")]
5098    pub context: Option<ReadingContextEnum>,
5099    #[serde(rename = "phase", default, skip_serializing_if = "Option::is_none")]
5100    pub phase: Option<PhaseEnum>,
5101    #[serde(rename = "location", default, skip_serializing_if = "Option::is_none")]
5102    pub location: Option<LocationEnum>,
5103    #[serde(
5104        rename = "signedMeterValue",
5105        default,
5106        skip_serializing_if = "Option::is_none"
5107    )]
5108    pub signed_meter_value: Option<SignedMeterValue>,
5109    #[serde(
5110        rename = "unitOfMeasure",
5111        default,
5112        skip_serializing_if = "Option::is_none"
5113    )]
5114    pub unit_of_measure: Option<UnitOfMeasure>,
5115    #[serde(
5116        rename = "customData",
5117        default,
5118        skip_serializing_if = "Option::is_none"
5119    )]
5120    pub custom_data: Option<CustomData>,
5121}
5122
5123impl Validate for SampledValue {
5124    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5125        if let Some(x) = &self.signed_meter_value {
5126            let p = path.field("signedMeterValue");
5127            x.validate(&p)?;
5128        }
5129        if let Some(x) = &self.unit_of_measure {
5130            let p = path.field("unitOfMeasure");
5131            x.validate(&p)?;
5132        }
5133        if let Some(x) = &self.custom_data {
5134            let p = path.field("customData");
5135            x.validate(&p)?;
5136        }
5137        Ok(())
5138    }
5139}
5140
5141/// Class to hold parameters of SetVariableMonitoring request.
5142#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5143#[serde(deny_unknown_fields)]
5144pub struct SetMonitoringData {
5145    /// An id SHALL only be given to replace an existing monitor. The Charging Station handles the generation of id's for new monitors.
5146    #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
5147    pub id: Option<i64>,
5148    #[serde(
5149        rename = "periodicEventStream",
5150        default,
5151        skip_serializing_if = "Option::is_none"
5152    )]
5153    pub periodic_event_stream: Option<PeriodicEventStreamParams>,
5154    /// Monitor only active when a transaction is ongoing on a component relevant to this transaction. Default = false.
5155    #[serde(
5156        rename = "transaction",
5157        default,
5158        skip_serializing_if = "Option::is_none"
5159    )]
5160    pub transaction: Option<bool>,
5161    /// Value for threshold or delta monitoring.
5162    /// For Periodic or PeriodicClockAligned this is the interval in seconds.
5163    #[serde(rename = "value")]
5164    pub value: f64,
5165    #[serde(rename = "type")]
5166    pub r#type: MonitorEnum,
5167    /// 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.
5168    /// The severity levels have the following meaning: +
5169    /// *0-Danger* +
5170    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
5171    /// *1-Hardware Failure* +
5172    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
5173    /// *2-System Failure* +
5174    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
5175    /// *3-Critical* +
5176    /// Indicates a critical error. Action is required. +
5177    /// *4-Error* +
5178    /// Indicates a non-urgent error. Action is required. +
5179    /// *5-Alert* +
5180    /// Indicates an alert event. Default severity for any type of monitoring event.  +
5181    /// *6-Warning* +
5182    /// Indicates a warning event. Action may be required. +
5183    /// *7-Notice* +
5184    /// Indicates an unusual event. No immediate action is required. +
5185    /// *8-Informational* +
5186    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
5187    /// *9-Debug* +
5188    /// Indicates information useful to developers for debugging, not useful during operations.
5189    #[serde(rename = "severity")]
5190    pub severity: i64,
5191    #[serde(rename = "component")]
5192    pub component: Component,
5193    #[serde(rename = "variable")]
5194    pub variable: Variable,
5195    #[serde(
5196        rename = "customData",
5197        default,
5198        skip_serializing_if = "Option::is_none"
5199    )]
5200    pub custom_data: Option<CustomData>,
5201}
5202
5203impl Validate for SetMonitoringData {
5204    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5205        if let Some(x) = &self.id {
5206            let p = path.field("id");
5207            v::minimum(*x, 0i64, &p)?;
5208        }
5209        if let Some(x) = &self.periodic_event_stream {
5210            let p = path.field("periodicEventStream");
5211            x.validate(&p)?;
5212        }
5213        {
5214            let x = &self.severity;
5215            let p = path.field("severity");
5216            v::minimum(*x, 0i64, &p)?;
5217        }
5218        {
5219            let x = &self.component;
5220            let p = path.field("component");
5221            x.validate(&p)?;
5222        }
5223        {
5224            let x = &self.variable;
5225            let p = path.field("variable");
5226            x.validate(&p)?;
5227        }
5228        if let Some(x) = &self.custom_data {
5229            let p = path.field("customData");
5230            x.validate(&p)?;
5231        }
5232        Ok(())
5233    }
5234}
5235
5236/// Class to hold result of SetVariableMonitoring request.
5237#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5238#[serde(deny_unknown_fields)]
5239pub struct SetMonitoringResult {
5240    /// 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.
5241    #[serde(rename = "id", default, skip_serializing_if = "Option::is_none")]
5242    pub id: Option<i64>,
5243    #[serde(
5244        rename = "statusInfo",
5245        default,
5246        skip_serializing_if = "Option::is_none"
5247    )]
5248    pub status_info: Option<StatusInfo>,
5249    #[serde(rename = "status")]
5250    pub status: SetMonitoringStatusEnum,
5251    #[serde(rename = "type")]
5252    pub r#type: MonitorEnum,
5253    #[serde(rename = "component")]
5254    pub component: Component,
5255    #[serde(rename = "variable")]
5256    pub variable: Variable,
5257    /// 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.
5258    /// The severity levels have the following meaning: +
5259    /// *0-Danger* +
5260    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
5261    /// *1-Hardware Failure* +
5262    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
5263    /// *2-System Failure* +
5264    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
5265    /// *3-Critical* +
5266    /// Indicates a critical error. Action is required. +
5267    /// *4-Error* +
5268    /// Indicates a non-urgent error. Action is required. +
5269    /// *5-Alert* +
5270    /// Indicates an alert event. Default severity for any type of monitoring event.  +
5271    /// *6-Warning* +
5272    /// Indicates a warning event. Action may be required. +
5273    /// *7-Notice* +
5274    /// Indicates an unusual event. No immediate action is required. +
5275    /// *8-Informational* +
5276    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
5277    /// *9-Debug* +
5278    /// Indicates information useful to developers for debugging, not useful during operations.
5279    #[serde(rename = "severity")]
5280    pub severity: i64,
5281    #[serde(
5282        rename = "customData",
5283        default,
5284        skip_serializing_if = "Option::is_none"
5285    )]
5286    pub custom_data: Option<CustomData>,
5287}
5288
5289impl Validate for SetMonitoringResult {
5290    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5291        if let Some(x) = &self.id {
5292            let p = path.field("id");
5293            v::minimum(*x, 0i64, &p)?;
5294        }
5295        if let Some(x) = &self.status_info {
5296            let p = path.field("statusInfo");
5297            x.validate(&p)?;
5298        }
5299        {
5300            let x = &self.component;
5301            let p = path.field("component");
5302            x.validate(&p)?;
5303        }
5304        {
5305            let x = &self.variable;
5306            let p = path.field("variable");
5307            x.validate(&p)?;
5308        }
5309        {
5310            let x = &self.severity;
5311            let p = path.field("severity");
5312            v::minimum(*x, 0i64, &p)?;
5313        }
5314        if let Some(x) = &self.custom_data {
5315            let p = path.field("customData");
5316            x.validate(&p)?;
5317        }
5318        Ok(())
5319    }
5320}
5321
5322#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5323#[serde(deny_unknown_fields)]
5324pub struct SetVariableData {
5325    #[serde(
5326        rename = "attributeType",
5327        default,
5328        skip_serializing_if = "Option::is_none"
5329    )]
5330    pub attribute_type: Option<AttributeEnum>,
5331    /// Value to be assigned to attribute of variable.
5332    /// This value is allowed to be an empty string ("").
5333    /// 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.
5334    #[serde(rename = "attributeValue")]
5335    pub attribute_value: String,
5336    #[serde(rename = "component")]
5337    pub component: Component,
5338    #[serde(rename = "variable")]
5339    pub variable: Variable,
5340    #[serde(
5341        rename = "customData",
5342        default,
5343        skip_serializing_if = "Option::is_none"
5344    )]
5345    pub custom_data: Option<CustomData>,
5346}
5347
5348impl Validate for SetVariableData {
5349    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5350        {
5351            let x = &self.attribute_value;
5352            let p = path.field("attributeValue");
5353            v::max_length(x, 2500, &p)?;
5354        }
5355        {
5356            let x = &self.component;
5357            let p = path.field("component");
5358            x.validate(&p)?;
5359        }
5360        {
5361            let x = &self.variable;
5362            let p = path.field("variable");
5363            x.validate(&p)?;
5364        }
5365        if let Some(x) = &self.custom_data {
5366            let p = path.field("customData");
5367            x.validate(&p)?;
5368        }
5369        Ok(())
5370    }
5371}
5372
5373#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5374#[serde(deny_unknown_fields)]
5375pub struct SetVariableResult {
5376    #[serde(
5377        rename = "attributeType",
5378        default,
5379        skip_serializing_if = "Option::is_none"
5380    )]
5381    pub attribute_type: Option<AttributeEnum>,
5382    #[serde(rename = "attributeStatus")]
5383    pub attribute_status: SetVariableStatusEnum,
5384    #[serde(
5385        rename = "attributeStatusInfo",
5386        default,
5387        skip_serializing_if = "Option::is_none"
5388    )]
5389    pub attribute_status_info: Option<StatusInfo>,
5390    #[serde(rename = "component")]
5391    pub component: Component,
5392    #[serde(rename = "variable")]
5393    pub variable: Variable,
5394    #[serde(
5395        rename = "customData",
5396        default,
5397        skip_serializing_if = "Option::is_none"
5398    )]
5399    pub custom_data: Option<CustomData>,
5400}
5401
5402impl Validate for SetVariableResult {
5403    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5404        if let Some(x) = &self.attribute_status_info {
5405            let p = path.field("attributeStatusInfo");
5406            x.validate(&p)?;
5407        }
5408        {
5409            let x = &self.component;
5410            let p = path.field("component");
5411            x.validate(&p)?;
5412        }
5413        {
5414            let x = &self.variable;
5415            let p = path.field("variable");
5416            x.validate(&p)?;
5417        }
5418        if let Some(x) = &self.custom_data {
5419            let p = path.field("customData");
5420            x.validate(&p)?;
5421        }
5422        Ok(())
5423    }
5424}
5425
5426/// Represent a signed version of the meter value.
5427#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5428#[serde(deny_unknown_fields)]
5429pub struct SignedMeterValue {
5430    /// 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.
5431    #[serde(rename = "signedMeterData")]
5432    pub signed_meter_data: String,
5433    /// *(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.
5434    #[serde(
5435        rename = "signingMethod",
5436        default,
5437        skip_serializing_if = "Option::is_none"
5438    )]
5439    pub signing_method: Option<String>,
5440    /// Format used by the energy meter to encode the meter data. For example: OCMF or EDL.
5441    #[serde(rename = "encodingMethod")]
5442    pub encoding_method: String,
5443    /// *(2.1)* Base64 encoded, sending depends on configuration variable _PublicKeyWithSignedMeterValue_.
5444    #[serde(rename = "publicKey", default, skip_serializing_if = "Option::is_none")]
5445    pub public_key: Option<String>,
5446    #[serde(
5447        rename = "customData",
5448        default,
5449        skip_serializing_if = "Option::is_none"
5450    )]
5451    pub custom_data: Option<CustomData>,
5452}
5453
5454impl Validate for SignedMeterValue {
5455    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5456        {
5457            let x = &self.signed_meter_data;
5458            let p = path.field("signedMeterData");
5459            v::max_length(x, 32768, &p)?;
5460        }
5461        if let Some(x) = &self.signing_method {
5462            let p = path.field("signingMethod");
5463            v::max_length(x, 50, &p)?;
5464        }
5465        {
5466            let x = &self.encoding_method;
5467            let p = path.field("encodingMethod");
5468            v::max_length(x, 50, &p)?;
5469        }
5470        if let Some(x) = &self.public_key {
5471            let p = path.field("publicKey");
5472            v::max_length(x, 2500, &p)?;
5473        }
5474        if let Some(x) = &self.custom_data {
5475            let p = path.field("customData");
5476            x.validate(&p)?;
5477        }
5478        Ok(())
5479    }
5480}
5481
5482/// Element providing more information about the status.
5483#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5484#[serde(deny_unknown_fields)]
5485pub struct StatusInfo {
5486    /// A predefined code for the reason why the status is returned in this response. The string is case-insensitive.
5487    #[serde(rename = "reasonCode")]
5488    pub reason_code: String,
5489    /// Additional text to provide detailed information.
5490    #[serde(
5491        rename = "additionalInfo",
5492        default,
5493        skip_serializing_if = "Option::is_none"
5494    )]
5495    pub additional_info: Option<String>,
5496    #[serde(
5497        rename = "customData",
5498        default,
5499        skip_serializing_if = "Option::is_none"
5500    )]
5501    pub custom_data: Option<CustomData>,
5502}
5503
5504impl Validate for StatusInfo {
5505    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5506        {
5507            let x = &self.reason_code;
5508            let p = path.field("reasonCode");
5509            v::max_length(x, 20, &p)?;
5510        }
5511        if let Some(x) = &self.additional_info {
5512            let p = path.field("additionalInfo");
5513            v::max_length(x, 1024, &p)?;
5514        }
5515        if let Some(x) = &self.custom_data {
5516            let p = path.field("customData");
5517            x.validate(&p)?;
5518        }
5519        Ok(())
5520    }
5521}
5522
5523#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5524#[serde(deny_unknown_fields)]
5525pub struct StreamDataElement {
5526    /// Offset relative to _basetime_ of this message. _basetime_ + _t_ is timestamp of recorded value.
5527    #[serde(rename = "t")]
5528    pub t: f64,
5529    #[serde(rename = "v")]
5530    pub v: String,
5531    #[serde(
5532        rename = "customData",
5533        default,
5534        skip_serializing_if = "Option::is_none"
5535    )]
5536    pub custom_data: Option<CustomData>,
5537}
5538
5539impl Validate for StreamDataElement {
5540    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5541        {
5542            let x = &self.v;
5543            let p = path.field("v");
5544            v::max_length(x, 2500, &p)?;
5545        }
5546        if let Some(x) = &self.custom_data {
5547            let p = path.field("customData");
5548            x.validate(&p)?;
5549        }
5550        Ok(())
5551    }
5552}
5553
5554/// A tariff is described by fields with prices for:
5555/// energy,
5556/// charging time,
5557/// idle time,
5558/// fixed fee,
5559/// reservation time,
5560/// reservation fixed fee. +
5561/// Each of these fields may have (optional) conditions that specify when a price is applicable. +
5562/// The _description_ contains a human-readable explanation of the tariff to be shown to the user. +
5563/// The other fields are parameters that define the tariff. These are used by the charging station to calculate the price.
5564#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5565#[serde(deny_unknown_fields)]
5566pub struct Tariff {
5567    /// Unique id of tariff
5568    #[serde(rename = "tariffId")]
5569    pub tariff_id: String,
5570    #[serde(
5571        rename = "description",
5572        default,
5573        skip_serializing_if = "Option::is_none"
5574    )]
5575    pub description: Option<Vec<MessageContent>>,
5576    /// Currency code according to ISO 4217
5577    #[serde(rename = "currency")]
5578    pub currency: String,
5579    #[serde(rename = "energy", default, skip_serializing_if = "Option::is_none")]
5580    pub energy: Option<TariffEnergy>,
5581    /// Time when this tariff becomes active. When absent, it is immediately active.
5582    #[serde(rename = "validFrom", default, skip_serializing_if = "Option::is_none")]
5583    pub valid_from: Option<DateTime>,
5584    #[serde(
5585        rename = "chargingTime",
5586        default,
5587        skip_serializing_if = "Option::is_none"
5588    )]
5589    pub charging_time: Option<TariffTime>,
5590    #[serde(rename = "idleTime", default, skip_serializing_if = "Option::is_none")]
5591    pub idle_time: Option<TariffTime>,
5592    #[serde(rename = "fixedFee", default, skip_serializing_if = "Option::is_none")]
5593    pub fixed_fee: Option<TariffFixed>,
5594    #[serde(
5595        rename = "reservationTime",
5596        default,
5597        skip_serializing_if = "Option::is_none"
5598    )]
5599    pub reservation_time: Option<TariffTime>,
5600    #[serde(
5601        rename = "reservationFixed",
5602        default,
5603        skip_serializing_if = "Option::is_none"
5604    )]
5605    pub reservation_fixed: Option<TariffFixed>,
5606    #[serde(rename = "minCost", default, skip_serializing_if = "Option::is_none")]
5607    pub min_cost: Option<Price>,
5608    #[serde(rename = "maxCost", default, skip_serializing_if = "Option::is_none")]
5609    pub max_cost: Option<Price>,
5610    #[serde(
5611        rename = "customData",
5612        default,
5613        skip_serializing_if = "Option::is_none"
5614    )]
5615    pub custom_data: Option<CustomData>,
5616}
5617
5618impl Validate for Tariff {
5619    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5620        {
5621            let x = &self.tariff_id;
5622            let p = path.field("tariffId");
5623            v::max_length(x, 60, &p)?;
5624        }
5625        if let Some(x) = &self.description {
5626            let p = path.field("description");
5627            v::items(x, Some(1), Some(10), &p)?;
5628            for (i0, it0) in x.iter().enumerate() {
5629                let p0 = p.index(i0);
5630                it0.validate(&p0)?;
5631            }
5632        }
5633        {
5634            let x = &self.currency;
5635            let p = path.field("currency");
5636            v::max_length(x, 3, &p)?;
5637        }
5638        if let Some(x) = &self.energy {
5639            let p = path.field("energy");
5640            x.validate(&p)?;
5641        }
5642        if let Some(x) = &self.charging_time {
5643            let p = path.field("chargingTime");
5644            x.validate(&p)?;
5645        }
5646        if let Some(x) = &self.idle_time {
5647            let p = path.field("idleTime");
5648            x.validate(&p)?;
5649        }
5650        if let Some(x) = &self.fixed_fee {
5651            let p = path.field("fixedFee");
5652            x.validate(&p)?;
5653        }
5654        if let Some(x) = &self.reservation_time {
5655            let p = path.field("reservationTime");
5656            x.validate(&p)?;
5657        }
5658        if let Some(x) = &self.reservation_fixed {
5659            let p = path.field("reservationFixed");
5660            x.validate(&p)?;
5661        }
5662        if let Some(x) = &self.min_cost {
5663            let p = path.field("minCost");
5664            x.validate(&p)?;
5665        }
5666        if let Some(x) = &self.max_cost {
5667            let p = path.field("maxCost");
5668            x.validate(&p)?;
5669        }
5670        if let Some(x) = &self.custom_data {
5671            let p = path.field("customData");
5672            x.validate(&p)?;
5673        }
5674        Ok(())
5675    }
5676}
5677
5678/// Shows assignment of tariffs to EVSE or IdToken.
5679#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5680#[serde(deny_unknown_fields)]
5681pub struct TariffAssignment {
5682    /// Tariff id.
5683    #[serde(rename = "tariffId")]
5684    pub tariff_id: String,
5685    #[serde(rename = "tariffKind")]
5686    pub tariff_kind: TariffKindEnum,
5687    /// Date/time when this tariff become active.
5688    #[serde(rename = "validFrom", default, skip_serializing_if = "Option::is_none")]
5689    pub valid_from: Option<DateTime>,
5690    #[serde(rename = "evseIds", default, skip_serializing_if = "Option::is_none")]
5691    pub evse_ids: Option<Vec<i64>>,
5692    /// IdTokens related to tariff
5693    #[serde(rename = "idTokens", default, skip_serializing_if = "Option::is_none")]
5694    pub id_tokens: Option<Vec<String>>,
5695    #[serde(
5696        rename = "customData",
5697        default,
5698        skip_serializing_if = "Option::is_none"
5699    )]
5700    pub custom_data: Option<CustomData>,
5701}
5702
5703impl Validate for TariffAssignment {
5704    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5705        {
5706            let x = &self.tariff_id;
5707            let p = path.field("tariffId");
5708            v::max_length(x, 60, &p)?;
5709        }
5710        if let Some(x) = &self.evse_ids {
5711            let p = path.field("evseIds");
5712            v::items(x, Some(1), None, &p)?;
5713            for (i0, it0) in x.iter().enumerate() {
5714                let p0 = p.index(i0);
5715                v::minimum(*it0, 0i64, &p0)?;
5716            }
5717        }
5718        if let Some(x) = &self.id_tokens {
5719            let p = path.field("idTokens");
5720            v::items(x, Some(1), None, &p)?;
5721            for (i0, it0) in x.iter().enumerate() {
5722                let p0 = p.index(i0);
5723                v::max_length(it0, 255, &p0)?;
5724            }
5725        }
5726        if let Some(x) = &self.custom_data {
5727            let p = path.field("customData");
5728            x.validate(&p)?;
5729        }
5730        Ok(())
5731    }
5732}
5733
5734/// These conditions describe if and when a TariffEnergyType or TariffTimeType applies during a transaction.
5735/// 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.
5736/// For reverse energy flow (discharging) negative values of energy, power and current are used.
5737/// 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.
5738/// 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.
5739/// 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.
5740#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
5741#[serde(deny_unknown_fields)]
5742pub struct TariffConditions {
5743    /// Start time of day in local time. +
5744    /// Format as per RFC 3339: time-hour ":" time-minute  +
5745    /// Must be in 24h format with leading zeros. Hour/Minute separator: ":"
5746    /// Regex: (\[0-1\]\[0-9\]\|2\[0-3\]):\[0-5\]\[0-9\]
5747    #[serde(
5748        rename = "startTimeOfDay",
5749        default,
5750        skip_serializing_if = "Option::is_none"
5751    )]
5752    pub start_time_of_day: Option<String>,
5753    /// End time of day in local time. Same syntax as _startTimeOfDay_. +
5754    /// If end time &lt; start time then the period wraps around to the next day. +
5755    /// To stop at end of the day use: 00:00.
5756    #[serde(
5757        rename = "endTimeOfDay",
5758        default,
5759        skip_serializing_if = "Option::is_none"
5760    )]
5761    pub end_time_of_day: Option<String>,
5762    /// Day(s) of the week this is tariff applies.
5763    #[serde(rename = "dayOfWeek", default, skip_serializing_if = "Option::is_none")]
5764    pub day_of_week: Option<Vec<DayOfWeekEnum>>,
5765    /// Start date in local time, for example: 2015-12-24.
5766    /// Valid from this day (inclusive). +
5767    /// Format as per RFC 3339: full-date  +
5768    /// Regex: (\[12\]\[0-9\]{3})-(0\[1-9\]\|1\[0-2\])-(0\[1-9\]\|\[12\]\[0-9\]\|3\[01\])
5769    #[serde(
5770        rename = "validFromDate",
5771        default,
5772        skip_serializing_if = "Option::is_none"
5773    )]
5774    pub valid_from_date: Option<String>,
5775    /// End date in local time, for example: 2015-12-27.
5776    /// Valid until this day (exclusive). Same syntax as _validFromDate_.
5777    #[serde(
5778        rename = "validToDate",
5779        default,
5780        skip_serializing_if = "Option::is_none"
5781    )]
5782    pub valid_to_date: Option<String>,
5783    #[serde(rename = "evseKind", default, skip_serializing_if = "Option::is_none")]
5784    pub evse_kind: Option<EvseKindEnum>,
5785    /// Minimum consumed energy in Wh, for example 20000 Wh.
5786    /// Valid from this amount of energy (inclusive) being used.
5787    #[serde(rename = "minEnergy", default, skip_serializing_if = "Option::is_none")]
5788    pub min_energy: Option<f64>,
5789    /// Maximum consumed energy in Wh, for example 50000 Wh.
5790    /// Valid until this amount of energy (exclusive) being used.
5791    #[serde(rename = "maxEnergy", default, skip_serializing_if = "Option::is_none")]
5792    pub max_energy: Option<f64>,
5793    /// Sum of the minimum current (in Amperes) over all phases, for example 5 A.
5794    /// 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. +
5795    /// This is NOT about the minimum current over the entire transaction.
5796    #[serde(
5797        rename = "minCurrent",
5798        default,
5799        skip_serializing_if = "Option::is_none"
5800    )]
5801    pub min_current: Option<f64>,
5802    /// Sum of the maximum current (in Amperes) over all phases, for example 20 A.
5803    /// 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.
5804    /// This is NOT about the maximum current over the entire transaction.
5805    #[serde(
5806        rename = "maxCurrent",
5807        default,
5808        skip_serializing_if = "Option::is_none"
5809    )]
5810    pub max_current: Option<f64>,
5811    /// Minimum power in W, for example 5000 W.
5812    /// When the EV is charging with more than, or equal to, the defined amount of power, this price is/becomes active.
5813    /// If the charging power is or becomes lower, this price is not or no longer valid and becomes inactive.
5814    /// This is NOT about the minimum power over the entire transaction.
5815    #[serde(rename = "minPower", default, skip_serializing_if = "Option::is_none")]
5816    pub min_power: Option<f64>,
5817    /// Maximum power in W, for example 20000 W.
5818    /// When the EV is charging with less than the defined amount of power, this price becomes/is active.
5819    /// If the charging power is or becomes higher, this price is not or no longer valid and becomes inactive.
5820    /// This is NOT about the maximum power over the entire transaction.
5821    #[serde(rename = "maxPower", default, skip_serializing_if = "Option::is_none")]
5822    pub max_power: Option<f64>,
5823    /// Minimum duration in seconds the transaction (charging &amp; idle) MUST last (inclusive).
5824    /// When the duration of a transaction is longer than the defined value, this price is or becomes active.
5825    /// Before that moment, this price is not yet active.
5826    #[serde(rename = "minTime", default, skip_serializing_if = "Option::is_none")]
5827    pub min_time: Option<i64>,
5828    /// Maximum duration in seconds the transaction (charging &amp; idle) MUST last (exclusive).
5829    /// When the duration of a transaction is shorter than the defined value, this price is or becomes active.
5830    /// After that moment, this price is no longer active.
5831    #[serde(rename = "maxTime", default, skip_serializing_if = "Option::is_none")]
5832    pub max_time: Option<i64>,
5833    /// Minimum duration in seconds the charging MUST last (inclusive).
5834    /// When the duration of a charging is longer than the defined value, this price is or becomes active.
5835    /// Before that moment, this price is not yet active.
5836    #[serde(
5837        rename = "minChargingTime",
5838        default,
5839        skip_serializing_if = "Option::is_none"
5840    )]
5841    pub min_charging_time: Option<i64>,
5842    /// Maximum duration in seconds the charging MUST last (exclusive).
5843    /// When the duration of a charging is shorter than the defined value, this price is or becomes active.
5844    /// After that moment, this price is no longer active.
5845    #[serde(
5846        rename = "maxChargingTime",
5847        default,
5848        skip_serializing_if = "Option::is_none"
5849    )]
5850    pub max_charging_time: Option<i64>,
5851    /// Minimum duration in seconds the idle period (i.e. not charging) MUST last (inclusive).
5852    /// When the duration of the idle time is longer than the defined value, this price is or becomes active.
5853    /// Before that moment, this price is not yet active.
5854    #[serde(
5855        rename = "minIdleTime",
5856        default,
5857        skip_serializing_if = "Option::is_none"
5858    )]
5859    pub min_idle_time: Option<i64>,
5860    /// Maximum duration in seconds the idle period (i.e. not charging) MUST last (exclusive).
5861    /// When the duration of idle time is shorter than the defined value, this price is or becomes active.
5862    /// After that moment, this price is no longer active.
5863    #[serde(
5864        rename = "maxIdleTime",
5865        default,
5866        skip_serializing_if = "Option::is_none"
5867    )]
5868    pub max_idle_time: Option<i64>,
5869    #[serde(
5870        rename = "customData",
5871        default,
5872        skip_serializing_if = "Option::is_none"
5873    )]
5874    pub custom_data: Option<CustomData>,
5875}
5876
5877impl Validate for TariffConditions {
5878    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5879        if let Some(x) = &self.day_of_week {
5880            let p = path.field("dayOfWeek");
5881            v::items(x, Some(1), Some(7), &p)?;
5882        }
5883        if let Some(x) = &self.custom_data {
5884            let p = path.field("customData");
5885            x.validate(&p)?;
5886        }
5887        Ok(())
5888    }
5889}
5890
5891/// These conditions describe if a FixedPrice applies at start of the transaction.
5892/// 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.
5893/// 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.
5894/// 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.
5895#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
5896#[serde(deny_unknown_fields)]
5897pub struct TariffConditionsFixed {
5898    /// Start time of day in local time. +
5899    /// Format as per RFC 3339: time-hour ":" time-minute  +
5900    /// Must be in 24h format with leading zeros. Hour/Minute separator: ":"
5901    /// Regex: (\[0-1\]\[0-9\]\|2\[0-3\]):\[0-5\]\[0-9\]
5902    #[serde(
5903        rename = "startTimeOfDay",
5904        default,
5905        skip_serializing_if = "Option::is_none"
5906    )]
5907    pub start_time_of_day: Option<String>,
5908    /// End time of day in local time. Same syntax as _startTimeOfDay_. +
5909    /// If end time &lt; start time then the period wraps around to the next day. +
5910    /// To stop at end of the day use: 00:00.
5911    #[serde(
5912        rename = "endTimeOfDay",
5913        default,
5914        skip_serializing_if = "Option::is_none"
5915    )]
5916    pub end_time_of_day: Option<String>,
5917    /// Day(s) of the week this is tariff applies.
5918    #[serde(rename = "dayOfWeek", default, skip_serializing_if = "Option::is_none")]
5919    pub day_of_week: Option<Vec<DayOfWeekEnum>>,
5920    /// Start date in local time, for example: 2015-12-24.
5921    /// Valid from this day (inclusive). +
5922    /// Format as per RFC 3339: full-date  +
5923    /// Regex: (\[12\]\[0-9\]{3})-(0\[1-9\]\|1\[0-2\])-(0\[1-9\]\|\[12\]\[0-9\]\|3\[01\])
5924    #[serde(
5925        rename = "validFromDate",
5926        default,
5927        skip_serializing_if = "Option::is_none"
5928    )]
5929    pub valid_from_date: Option<String>,
5930    /// End date in local time, for example: 2015-12-27.
5931    /// Valid until this day (exclusive). Same syntax as _validFromDate_.
5932    #[serde(
5933        rename = "validToDate",
5934        default,
5935        skip_serializing_if = "Option::is_none"
5936    )]
5937    pub valid_to_date: Option<String>,
5938    #[serde(rename = "evseKind", default, skip_serializing_if = "Option::is_none")]
5939    pub evse_kind: Option<EvseKindEnum>,
5940    /// For which payment brand this (adhoc) tariff applies. Can be used to add a surcharge for certain payment brands.
5941    /// Based on value of _additionalIdToken_ from _idToken.additionalInfo.type_ = "PaymentBrand".
5942    #[serde(
5943        rename = "paymentBrand",
5944        default,
5945        skip_serializing_if = "Option::is_none"
5946    )]
5947    pub payment_brand: Option<String>,
5948    /// Type of adhoc payment, e.g. CC, Debit.
5949    /// Based on value of _additionalIdToken_ from _idToken.additionalInfo.type_ = "PaymentRecognition".
5950    #[serde(
5951        rename = "paymentRecognition",
5952        default,
5953        skip_serializing_if = "Option::is_none"
5954    )]
5955    pub payment_recognition: Option<String>,
5956    #[serde(
5957        rename = "customData",
5958        default,
5959        skip_serializing_if = "Option::is_none"
5960    )]
5961    pub custom_data: Option<CustomData>,
5962}
5963
5964impl Validate for TariffConditionsFixed {
5965    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
5966        if let Some(x) = &self.day_of_week {
5967            let p = path.field("dayOfWeek");
5968            v::items(x, Some(1), Some(7), &p)?;
5969        }
5970        if let Some(x) = &self.payment_brand {
5971            let p = path.field("paymentBrand");
5972            v::max_length(x, 20, &p)?;
5973        }
5974        if let Some(x) = &self.payment_recognition {
5975            let p = path.field("paymentRecognition");
5976            v::max_length(x, 20, &p)?;
5977        }
5978        if let Some(x) = &self.custom_data {
5979            let p = path.field("customData");
5980            x.validate(&p)?;
5981        }
5982        Ok(())
5983    }
5984}
5985
5986/// Price elements and tax for energy
5987#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
5988#[serde(deny_unknown_fields)]
5989pub struct TariffEnergy {
5990    #[serde(rename = "prices")]
5991    pub prices: Vec<TariffEnergyPrice>,
5992    #[serde(rename = "taxRates", default, skip_serializing_if = "Option::is_none")]
5993    pub tax_rates: Option<Vec<TaxRate>>,
5994    #[serde(
5995        rename = "customData",
5996        default,
5997        skip_serializing_if = "Option::is_none"
5998    )]
5999    pub custom_data: Option<CustomData>,
6000}
6001
6002impl Validate for TariffEnergy {
6003    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6004        {
6005            let x = &self.prices;
6006            let p = path.field("prices");
6007            v::items(x, Some(1), None, &p)?;
6008            for (i0, it0) in x.iter().enumerate() {
6009                let p0 = p.index(i0);
6010                it0.validate(&p0)?;
6011            }
6012        }
6013        if let Some(x) = &self.tax_rates {
6014            let p = path.field("taxRates");
6015            v::items(x, Some(1), Some(5), &p)?;
6016            for (i0, it0) in x.iter().enumerate() {
6017                let p0 = p.index(i0);
6018                it0.validate(&p0)?;
6019            }
6020        }
6021        if let Some(x) = &self.custom_data {
6022            let p = path.field("customData");
6023            x.validate(&p)?;
6024        }
6025        Ok(())
6026    }
6027}
6028
6029/// Tariff with optional conditions for an energy price.
6030#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6031#[serde(deny_unknown_fields)]
6032pub struct TariffEnergyPrice {
6033    /// Price per kWh (excl. tax) for this element.
6034    #[serde(rename = "priceKwh")]
6035    pub price_kwh: f64,
6036    #[serde(
6037        rename = "conditions",
6038        default,
6039        skip_serializing_if = "Option::is_none"
6040    )]
6041    pub conditions: Option<TariffConditions>,
6042    #[serde(
6043        rename = "customData",
6044        default,
6045        skip_serializing_if = "Option::is_none"
6046    )]
6047    pub custom_data: Option<CustomData>,
6048}
6049
6050impl Validate for TariffEnergyPrice {
6051    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6052        if let Some(x) = &self.conditions {
6053            let p = path.field("conditions");
6054            x.validate(&p)?;
6055        }
6056        if let Some(x) = &self.custom_data {
6057            let p = path.field("customData");
6058            x.validate(&p)?;
6059        }
6060        Ok(())
6061    }
6062}
6063
6064#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6065#[serde(deny_unknown_fields)]
6066pub struct TariffFixed {
6067    #[serde(rename = "prices")]
6068    pub prices: Vec<TariffFixedPrice>,
6069    #[serde(rename = "taxRates", default, skip_serializing_if = "Option::is_none")]
6070    pub tax_rates: Option<Vec<TaxRate>>,
6071    #[serde(
6072        rename = "customData",
6073        default,
6074        skip_serializing_if = "Option::is_none"
6075    )]
6076    pub custom_data: Option<CustomData>,
6077}
6078
6079impl Validate for TariffFixed {
6080    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6081        {
6082            let x = &self.prices;
6083            let p = path.field("prices");
6084            v::items(x, Some(1), None, &p)?;
6085            for (i0, it0) in x.iter().enumerate() {
6086                let p0 = p.index(i0);
6087                it0.validate(&p0)?;
6088            }
6089        }
6090        if let Some(x) = &self.tax_rates {
6091            let p = path.field("taxRates");
6092            v::items(x, Some(1), Some(5), &p)?;
6093            for (i0, it0) in x.iter().enumerate() {
6094                let p0 = p.index(i0);
6095                it0.validate(&p0)?;
6096            }
6097        }
6098        if let Some(x) = &self.custom_data {
6099            let p = path.field("customData");
6100            x.validate(&p)?;
6101        }
6102        Ok(())
6103    }
6104}
6105
6106/// Tariff with optional conditions for a fixed price.
6107#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6108#[serde(deny_unknown_fields)]
6109pub struct TariffFixedPrice {
6110    #[serde(
6111        rename = "conditions",
6112        default,
6113        skip_serializing_if = "Option::is_none"
6114    )]
6115    pub conditions: Option<TariffConditionsFixed>,
6116    /// Fixed price  for this element e.g. a start fee.
6117    #[serde(rename = "priceFixed")]
6118    pub price_fixed: f64,
6119    #[serde(
6120        rename = "customData",
6121        default,
6122        skip_serializing_if = "Option::is_none"
6123    )]
6124    pub custom_data: Option<CustomData>,
6125}
6126
6127impl Validate for TariffFixedPrice {
6128    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6129        if let Some(x) = &self.conditions {
6130            let p = path.field("conditions");
6131            x.validate(&p)?;
6132        }
6133        if let Some(x) = &self.custom_data {
6134            let p = path.field("customData");
6135            x.validate(&p)?;
6136        }
6137        Ok(())
6138    }
6139}
6140
6141/// Price elements and tax for time
6142#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6143#[serde(deny_unknown_fields)]
6144pub struct TariffTime {
6145    #[serde(rename = "prices")]
6146    pub prices: Vec<TariffTimePrice>,
6147    #[serde(rename = "taxRates", default, skip_serializing_if = "Option::is_none")]
6148    pub tax_rates: Option<Vec<TaxRate>>,
6149    #[serde(
6150        rename = "customData",
6151        default,
6152        skip_serializing_if = "Option::is_none"
6153    )]
6154    pub custom_data: Option<CustomData>,
6155}
6156
6157impl Validate for TariffTime {
6158    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6159        {
6160            let x = &self.prices;
6161            let p = path.field("prices");
6162            v::items(x, Some(1), None, &p)?;
6163            for (i0, it0) in x.iter().enumerate() {
6164                let p0 = p.index(i0);
6165                it0.validate(&p0)?;
6166            }
6167        }
6168        if let Some(x) = &self.tax_rates {
6169            let p = path.field("taxRates");
6170            v::items(x, Some(1), Some(5), &p)?;
6171            for (i0, it0) in x.iter().enumerate() {
6172                let p0 = p.index(i0);
6173                it0.validate(&p0)?;
6174            }
6175        }
6176        if let Some(x) = &self.custom_data {
6177            let p = path.field("customData");
6178            x.validate(&p)?;
6179        }
6180        Ok(())
6181    }
6182}
6183
6184/// Tariff with optional conditions for a time duration price.
6185#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6186#[serde(deny_unknown_fields)]
6187pub struct TariffTimePrice {
6188    /// Price per minute (excl. tax) for this element.
6189    #[serde(rename = "priceMinute")]
6190    pub price_minute: f64,
6191    #[serde(
6192        rename = "conditions",
6193        default,
6194        skip_serializing_if = "Option::is_none"
6195    )]
6196    pub conditions: Option<TariffConditions>,
6197    #[serde(
6198        rename = "customData",
6199        default,
6200        skip_serializing_if = "Option::is_none"
6201    )]
6202    pub custom_data: Option<CustomData>,
6203}
6204
6205impl Validate for TariffTimePrice {
6206    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6207        if let Some(x) = &self.conditions {
6208            let p = path.field("conditions");
6209            x.validate(&p)?;
6210        }
6211        if let Some(x) = &self.custom_data {
6212            let p = path.field("customData");
6213            x.validate(&p)?;
6214        }
6215        Ok(())
6216    }
6217}
6218
6219/// Tax percentage
6220#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6221#[serde(deny_unknown_fields)]
6222pub struct TaxRate {
6223    /// Type of this tax, e.g.  "Federal ",  "State", for information on receipt.
6224    #[serde(rename = "type")]
6225    pub r#type: String,
6226    /// Tax percentage
6227    #[serde(rename = "tax")]
6228    pub tax: f64,
6229    /// Stack level for this type of tax. Default value, when absent, is 0. +
6230    /// _stack_ = 0: tax on net price; +
6231    /// _stack_ = 1: tax added on top of _stack_ 0; +
6232    /// _stack_ = 2: tax added on top of _stack_ 1, etc.
6233    #[serde(rename = "stack", default, skip_serializing_if = "Option::is_none")]
6234    pub stack: Option<i64>,
6235    #[serde(
6236        rename = "customData",
6237        default,
6238        skip_serializing_if = "Option::is_none"
6239    )]
6240    pub custom_data: Option<CustomData>,
6241}
6242
6243impl Validate for TaxRate {
6244    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6245        {
6246            let x = &self.r#type;
6247            let p = path.field("type");
6248            v::max_length(x, 20, &p)?;
6249        }
6250        if let Some(x) = &self.stack {
6251            let p = path.field("stack");
6252            v::minimum(*x, 0i64, &p)?;
6253        }
6254        if let Some(x) = &self.custom_data {
6255            let p = path.field("customData");
6256            x.validate(&p)?;
6257        }
6258        Ok(())
6259    }
6260}
6261
6262/// Part of ISO 15118-20 price schedule.
6263#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6264#[serde(deny_unknown_fields)]
6265pub struct TaxRule {
6266    /// Id for the tax rule.
6267    #[serde(rename = "taxRuleID")]
6268    pub tax_rule_id: i64,
6269    /// Human readable string to identify the tax rule.
6270    #[serde(
6271        rename = "taxRuleName",
6272        default,
6273        skip_serializing_if = "Option::is_none"
6274    )]
6275    pub tax_rule_name: Option<String>,
6276    /// Indicates whether the tax is included in any price or not.
6277    #[serde(
6278        rename = "taxIncludedInPrice",
6279        default,
6280        skip_serializing_if = "Option::is_none"
6281    )]
6282    pub tax_included_in_price: Option<bool>,
6283    /// Indicates whether this tax applies to Energy Fees.
6284    #[serde(rename = "appliesToEnergyFee")]
6285    pub applies_to_energy_fee: bool,
6286    /// Indicates whether this tax applies to Parking Fees.
6287    #[serde(rename = "appliesToParkingFee")]
6288    pub applies_to_parking_fee: bool,
6289    /// Indicates whether this tax applies to Overstay Fees.
6290    #[serde(rename = "appliesToOverstayFee")]
6291    pub applies_to_overstay_fee: bool,
6292    /// Indicates whether this tax applies to Minimum/Maximum Cost.
6293    #[serde(rename = "appliesToMinimumMaximumCost")]
6294    pub applies_to_minimum_maximum_cost: bool,
6295    #[serde(rename = "taxRate")]
6296    pub tax_rate: RationalNumber,
6297    #[serde(
6298        rename = "customData",
6299        default,
6300        skip_serializing_if = "Option::is_none"
6301    )]
6302    pub custom_data: Option<CustomData>,
6303}
6304
6305impl Validate for TaxRule {
6306    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6307        {
6308            let x = &self.tax_rule_id;
6309            let p = path.field("taxRuleID");
6310            v::minimum(*x, 0i64, &p)?;
6311        }
6312        if let Some(x) = &self.tax_rule_name {
6313            let p = path.field("taxRuleName");
6314            v::max_length(x, 100, &p)?;
6315        }
6316        {
6317            let x = &self.tax_rate;
6318            let p = path.field("taxRate");
6319            x.validate(&p)?;
6320        }
6321        if let Some(x) = &self.custom_data {
6322            let p = path.field("customData");
6323            x.validate(&p)?;
6324        }
6325        Ok(())
6326    }
6327}
6328
6329/// This contains the cost calculated during a transaction. It is used both for running cost and final cost of the transaction.
6330#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6331#[serde(deny_unknown_fields)]
6332pub struct TotalCost {
6333    /// Currency of the costs in ISO 4217 Code.
6334    #[serde(rename = "currency")]
6335    pub currency: String,
6336    #[serde(rename = "typeOfCost")]
6337    pub type_of_cost: TariffCostEnum,
6338    #[serde(rename = "fixed", default, skip_serializing_if = "Option::is_none")]
6339    pub fixed: Option<Price>,
6340    #[serde(rename = "energy", default, skip_serializing_if = "Option::is_none")]
6341    pub energy: Option<Price>,
6342    #[serde(
6343        rename = "chargingTime",
6344        default,
6345        skip_serializing_if = "Option::is_none"
6346    )]
6347    pub charging_time: Option<Price>,
6348    #[serde(rename = "idleTime", default, skip_serializing_if = "Option::is_none")]
6349    pub idle_time: Option<Price>,
6350    #[serde(
6351        rename = "reservationTime",
6352        default,
6353        skip_serializing_if = "Option::is_none"
6354    )]
6355    pub reservation_time: Option<Price>,
6356    #[serde(
6357        rename = "reservationFixed",
6358        default,
6359        skip_serializing_if = "Option::is_none"
6360    )]
6361    pub reservation_fixed: Option<Price>,
6362    #[serde(rename = "total")]
6363    pub total: TotalPrice,
6364    #[serde(
6365        rename = "customData",
6366        default,
6367        skip_serializing_if = "Option::is_none"
6368    )]
6369    pub custom_data: Option<CustomData>,
6370}
6371
6372impl Validate for TotalCost {
6373    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6374        {
6375            let x = &self.currency;
6376            let p = path.field("currency");
6377            v::max_length(x, 3, &p)?;
6378        }
6379        if let Some(x) = &self.fixed {
6380            let p = path.field("fixed");
6381            x.validate(&p)?;
6382        }
6383        if let Some(x) = &self.energy {
6384            let p = path.field("energy");
6385            x.validate(&p)?;
6386        }
6387        if let Some(x) = &self.charging_time {
6388            let p = path.field("chargingTime");
6389            x.validate(&p)?;
6390        }
6391        if let Some(x) = &self.idle_time {
6392            let p = path.field("idleTime");
6393            x.validate(&p)?;
6394        }
6395        if let Some(x) = &self.reservation_time {
6396            let p = path.field("reservationTime");
6397            x.validate(&p)?;
6398        }
6399        if let Some(x) = &self.reservation_fixed {
6400            let p = path.field("reservationFixed");
6401            x.validate(&p)?;
6402        }
6403        {
6404            let x = &self.total;
6405            let p = path.field("total");
6406            x.validate(&p)?;
6407        }
6408        if let Some(x) = &self.custom_data {
6409            let p = path.field("customData");
6410            x.validate(&p)?;
6411        }
6412        Ok(())
6413    }
6414}
6415
6416/// Total cost with and without tax. Contains the total of energy, charging time, idle time, fixed and reservation costs including and/or excluding tax.
6417#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
6418#[serde(deny_unknown_fields)]
6419pub struct TotalPrice {
6420    /// Price/cost excluding tax. Can be absent if _inclTax_ is present.
6421    #[serde(rename = "exclTax", default, skip_serializing_if = "Option::is_none")]
6422    pub excl_tax: Option<f64>,
6423    /// Price/cost including tax. Can be absent if _exclTax_ is present.
6424    #[serde(rename = "inclTax", default, skip_serializing_if = "Option::is_none")]
6425    pub incl_tax: Option<f64>,
6426    #[serde(
6427        rename = "customData",
6428        default,
6429        skip_serializing_if = "Option::is_none"
6430    )]
6431    pub custom_data: Option<CustomData>,
6432}
6433
6434impl Validate for TotalPrice {
6435    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6436        if let Some(x) = &self.custom_data {
6437            let p = path.field("customData");
6438            x.validate(&p)?;
6439        }
6440        Ok(())
6441    }
6442}
6443
6444/// This contains the calculated usage of energy, charging time and idle time during a transaction.
6445#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6446#[serde(deny_unknown_fields)]
6447pub struct TotalUsage {
6448    #[serde(rename = "energy")]
6449    pub energy: f64,
6450    /// Total duration of the charging session (including the duration of charging and not charging), in seconds.
6451    #[serde(rename = "chargingTime")]
6452    pub charging_time: i64,
6453    /// Total duration of the charging session where the EV was not charging (no energy was transferred between EVSE and EV), in seconds.
6454    #[serde(rename = "idleTime")]
6455    pub idle_time: i64,
6456    /// Total time of reservation in seconds.
6457    #[serde(
6458        rename = "reservationTime",
6459        default,
6460        skip_serializing_if = "Option::is_none"
6461    )]
6462    pub reservation_time: Option<i64>,
6463    #[serde(
6464        rename = "customData",
6465        default,
6466        skip_serializing_if = "Option::is_none"
6467    )]
6468    pub custom_data: Option<CustomData>,
6469}
6470
6471impl Validate for TotalUsage {
6472    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6473        if let Some(x) = &self.custom_data {
6474            let p = path.field("customData");
6475            x.validate(&p)?;
6476        }
6477        Ok(())
6478    }
6479}
6480
6481#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6482#[serde(deny_unknown_fields)]
6483pub struct Transaction {
6484    /// This contains the Id of the transaction.
6485    #[serde(rename = "transactionId")]
6486    pub transaction_id: String,
6487    #[serde(
6488        rename = "chargingState",
6489        default,
6490        skip_serializing_if = "Option::is_none"
6491    )]
6492    pub charging_state: Option<ChargingStateEnum>,
6493    /// 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.
6494    #[serde(
6495        rename = "timeSpentCharging",
6496        default,
6497        skip_serializing_if = "Option::is_none"
6498    )]
6499    pub time_spent_charging: Option<i64>,
6500    #[serde(
6501        rename = "stoppedReason",
6502        default,
6503        skip_serializing_if = "Option::is_none"
6504    )]
6505    pub stopped_reason: Option<ReasonEnum>,
6506    /// 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.
6507    #[serde(
6508        rename = "remoteStartId",
6509        default,
6510        skip_serializing_if = "Option::is_none"
6511    )]
6512    pub remote_start_id: Option<i64>,
6513    #[serde(
6514        rename = "operationMode",
6515        default,
6516        skip_serializing_if = "Option::is_none"
6517    )]
6518    pub operation_mode: Option<OperationModeEnum>,
6519    /// *(2.1)* Id of tariff in use for transaction
6520    #[serde(rename = "tariffId", default, skip_serializing_if = "Option::is_none")]
6521    pub tariff_id: Option<String>,
6522    #[serde(
6523        rename = "transactionLimit",
6524        default,
6525        skip_serializing_if = "Option::is_none"
6526    )]
6527    pub transaction_limit: Option<TransactionLimit>,
6528    #[serde(
6529        rename = "customData",
6530        default,
6531        skip_serializing_if = "Option::is_none"
6532    )]
6533    pub custom_data: Option<CustomData>,
6534}
6535
6536impl Validate for Transaction {
6537    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6538        {
6539            let x = &self.transaction_id;
6540            let p = path.field("transactionId");
6541            v::max_length(x, 36, &p)?;
6542        }
6543        if let Some(x) = &self.tariff_id {
6544            let p = path.field("tariffId");
6545            v::max_length(x, 60, &p)?;
6546        }
6547        if let Some(x) = &self.transaction_limit {
6548            let p = path.field("transactionLimit");
6549            x.validate(&p)?;
6550        }
6551        if let Some(x) = &self.custom_data {
6552            let p = path.field("customData");
6553            x.validate(&p)?;
6554        }
6555        Ok(())
6556    }
6557}
6558
6559/// Cost, energy, time or SoC limit for a transaction.
6560#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
6561#[serde(deny_unknown_fields)]
6562pub struct TransactionLimit {
6563    /// Maximum allowed cost of transaction in currency of tariff.
6564    #[serde(rename = "maxCost", default, skip_serializing_if = "Option::is_none")]
6565    pub max_cost: Option<f64>,
6566    /// Maximum allowed energy in Wh to charge in transaction.
6567    #[serde(rename = "maxEnergy", default, skip_serializing_if = "Option::is_none")]
6568    pub max_energy: Option<f64>,
6569    /// Maximum duration of transaction in seconds from start to end.
6570    #[serde(rename = "maxTime", default, skip_serializing_if = "Option::is_none")]
6571    pub max_time: Option<i64>,
6572    /// Maximum State of Charge of EV in percentage.
6573    #[serde(rename = "maxSoC", default, skip_serializing_if = "Option::is_none")]
6574    pub max_so_c: Option<i64>,
6575    #[serde(
6576        rename = "customData",
6577        default,
6578        skip_serializing_if = "Option::is_none"
6579    )]
6580    pub custom_data: Option<CustomData>,
6581}
6582
6583impl Validate for TransactionLimit {
6584    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6585        if let Some(x) = &self.max_so_c {
6586            let p = path.field("maxSoC");
6587            v::minimum(*x, 0i64, &p)?;
6588            v::maximum(*x, 100i64, &p)?;
6589        }
6590        if let Some(x) = &self.custom_data {
6591            let p = path.field("customData");
6592            x.validate(&p)?;
6593        }
6594        Ok(())
6595    }
6596}
6597
6598/// Represents a UnitOfMeasure with a multiplier
6599#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
6600#[serde(deny_unknown_fields)]
6601pub struct UnitOfMeasure {
6602    /// Unit of the value. Default = "Wh" if the (default) measurand is an "Energy" type.
6603    /// This field SHALL use a value from the list Standardized Units of Measurements in Part 2 Appendices.
6604    /// If an applicable unit is available in that list, otherwise a "custom" unit might be used.
6605    #[serde(rename = "unit", default, skip_serializing_if = "Option::is_none")]
6606    pub unit: Option<String>,
6607    /// Multiplier, this value represents the exponent to base 10. I.e. multiplier 3 means 10 raised to the 3rd power. Default is 0. +
6608    /// The _multiplier_ only multiplies the value of the measurand. It does not specify a conversion between units, for example, kW and W.
6609    #[serde(
6610        rename = "multiplier",
6611        default,
6612        skip_serializing_if = "Option::is_none"
6613    )]
6614    pub multiplier: Option<i64>,
6615    #[serde(
6616        rename = "customData",
6617        default,
6618        skip_serializing_if = "Option::is_none"
6619    )]
6620    pub custom_data: Option<CustomData>,
6621}
6622
6623impl Validate for UnitOfMeasure {
6624    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6625        if let Some(x) = &self.unit {
6626            let p = path.field("unit");
6627            v::max_length(x, 20, &p)?;
6628        }
6629        if let Some(x) = &self.custom_data {
6630            let p = path.field("customData");
6631            x.validate(&p)?;
6632        }
6633        Ok(())
6634    }
6635}
6636
6637/// Charging parameters for ISO 15118-20, also supporting V2X charging/discharging.+
6638/// All values are greater or equal to zero, with the exception of EVMinEnergyRequest, EVMaxEnergyRequest, EVTargetEnergyRequest, EVMinV2XEnergyRequest and EVMaxV2XEnergyRequest.
6639#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
6640#[serde(deny_unknown_fields)]
6641pub struct V2XChargingParameters {
6642    /// Minimum charge power in W, defined by max(EV, EVSE).
6643    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6644    /// Relates to:
6645    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower
6646    #[serde(
6647        rename = "minChargePower",
6648        default,
6649        skip_serializing_if = "Option::is_none"
6650    )]
6651    pub min_charge_power: Option<f64>,
6652    /// Minimum charge power on phase L2 in W, defined by max(EV, EVSE).
6653    /// Relates to:
6654    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower_L2
6655    #[serde(
6656        rename = "minChargePower_L2",
6657        default,
6658        skip_serializing_if = "Option::is_none"
6659    )]
6660    pub min_charge_power_l2: Option<f64>,
6661    /// Minimum charge power on phase L3 in W, defined by max(EV, EVSE).
6662    /// Relates to:
6663    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumChargePower_L3
6664    #[serde(
6665        rename = "minChargePower_L3",
6666        default,
6667        skip_serializing_if = "Option::is_none"
6668    )]
6669    pub min_charge_power_l3: Option<f64>,
6670    /// Maximum charge (absorbed) power in W, defined by min(EV, EVSE) at unity power factor. +
6671    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6672    /// It corresponds to the ChaWMax attribute in the IEC 61850.
6673    /// It is usually equivalent to the rated apparent power of the EV when discharging (ChaVAMax) in IEC 61850. +
6674    /// Relates to:
6675    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower
6676    #[serde(
6677        rename = "maxChargePower",
6678        default,
6679        skip_serializing_if = "Option::is_none"
6680    )]
6681    pub max_charge_power: Option<f64>,
6682    /// Maximum charge power on phase L2 in W, defined by min(EV, EVSE)
6683    /// Relates to:
6684    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower_L2
6685    #[serde(
6686        rename = "maxChargePower_L2",
6687        default,
6688        skip_serializing_if = "Option::is_none"
6689    )]
6690    pub max_charge_power_l2: Option<f64>,
6691    /// Maximum charge power on phase L3 in W, defined by min(EV, EVSE)
6692    /// Relates to:
6693    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumChargePower_L3
6694    #[serde(
6695        rename = "maxChargePower_L3",
6696        default,
6697        skip_serializing_if = "Option::is_none"
6698    )]
6699    pub max_charge_power_l3: Option<f64>,
6700    /// Minimum discharge (injected) power in W, defined by max(EV, EVSE) at unity power factor. Value &gt;= 0. +
6701    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1. +
6702    /// It corresponds to the WMax attribute in the IEC 61850.
6703    /// It is usually equivalent to the rated apparent power of the EV when discharging (VAMax attribute in the IEC 61850).
6704    /// Relates to:
6705    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower
6706    #[serde(
6707        rename = "minDischargePower",
6708        default,
6709        skip_serializing_if = "Option::is_none"
6710    )]
6711    pub min_discharge_power: Option<f64>,
6712    /// Minimum discharge power on phase L2 in W, defined by max(EV, EVSE).  Value &gt;= 0.
6713    /// Relates to:
6714    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower_L2
6715    #[serde(
6716        rename = "minDischargePower_L2",
6717        default,
6718        skip_serializing_if = "Option::is_none"
6719    )]
6720    pub min_discharge_power_l2: Option<f64>,
6721    /// Minimum discharge power on phase L3 in W, defined by max(EV, EVSE).  Value &gt;= 0.
6722    /// Relates to:
6723    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMinimumDischargePower_L3
6724    #[serde(
6725        rename = "minDischargePower_L3",
6726        default,
6727        skip_serializing_if = "Option::is_none"
6728    )]
6729    pub min_discharge_power_l3: Option<f64>,
6730    /// Maximum discharge (injected) power in W, defined by min(EV, EVSE) at unity power factor.  Value &gt;= 0.
6731    /// This field represents the sum of all phases, unless values are provided for L2 and L3, in which case this field represents phase L1.
6732    /// Relates to:
6733    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePower
6734    #[serde(
6735        rename = "maxDischargePower",
6736        default,
6737        skip_serializing_if = "Option::is_none"
6738    )]
6739    pub max_discharge_power: Option<f64>,
6740    /// Maximum discharge power on phase L2 in W, defined by min(EV, EVSE).  Value &gt;= 0.
6741    /// Relates to:
6742    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePowe_L2
6743    #[serde(
6744        rename = "maxDischargePower_L2",
6745        default,
6746        skip_serializing_if = "Option::is_none"
6747    )]
6748    pub max_discharge_power_l2: Option<f64>,
6749    /// Maximum discharge power on phase L3 in W, defined by min(EV, EVSE).  Value &gt;= 0.
6750    /// Relates to:
6751    /// *ISO 15118-20*: BPT_AC/DC_CPDReqEnergyTransferModeType: EVMaximumDischargePower_L3
6752    #[serde(
6753        rename = "maxDischargePower_L3",
6754        default,
6755        skip_serializing_if = "Option::is_none"
6756    )]
6757    pub max_discharge_power_l3: Option<f64>,
6758    /// Minimum charge current in A, defined by max(EV, EVSE)
6759    /// Relates to:
6760    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumChargeCurrent
6761    #[serde(
6762        rename = "minChargeCurrent",
6763        default,
6764        skip_serializing_if = "Option::is_none"
6765    )]
6766    pub min_charge_current: Option<f64>,
6767    /// Maximum charge current in A, defined by min(EV, EVSE)
6768    /// Relates to:
6769    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumChargeCurrent
6770    #[serde(
6771        rename = "maxChargeCurrent",
6772        default,
6773        skip_serializing_if = "Option::is_none"
6774    )]
6775    pub max_charge_current: Option<f64>,
6776    /// Minimum discharge current in A, defined by max(EV, EVSE).  Value &gt;= 0.
6777    /// Relates to:
6778    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumDischargeCurrent
6779    #[serde(
6780        rename = "minDischargeCurrent",
6781        default,
6782        skip_serializing_if = "Option::is_none"
6783    )]
6784    pub min_discharge_current: Option<f64>,
6785    /// Maximum discharge current in A, defined by min(EV, EVSE).  Value &gt;= 0.
6786    /// Relates to:
6787    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumDischargeCurrent
6788    #[serde(
6789        rename = "maxDischargeCurrent",
6790        default,
6791        skip_serializing_if = "Option::is_none"
6792    )]
6793    pub max_discharge_current: Option<f64>,
6794    /// Minimum voltage in V, defined by max(EV, EVSE)
6795    /// Relates to:
6796    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMinimumVoltage
6797    #[serde(
6798        rename = "minVoltage",
6799        default,
6800        skip_serializing_if = "Option::is_none"
6801    )]
6802    pub min_voltage: Option<f64>,
6803    /// Maximum voltage in V, defined by min(EV, EVSE)
6804    /// Relates to:
6805    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: EVMaximumVoltage
6806    #[serde(
6807        rename = "maxVoltage",
6808        default,
6809        skip_serializing_if = "Option::is_none"
6810    )]
6811    pub max_voltage: Option<f64>,
6812    /// Energy to requested state of charge in Wh
6813    /// Relates to:
6814    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVTargetEnergyRequest
6815    #[serde(
6816        rename = "evTargetEnergyRequest",
6817        default,
6818        skip_serializing_if = "Option::is_none"
6819    )]
6820    pub ev_target_energy_request: Option<f64>,
6821    /// Energy to minimum allowed state of charge in Wh
6822    /// Relates to:
6823    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVMinimumEnergyRequest
6824    #[serde(
6825        rename = "evMinEnergyRequest",
6826        default,
6827        skip_serializing_if = "Option::is_none"
6828    )]
6829    pub ev_min_energy_request: Option<f64>,
6830    /// Energy to maximum state of charge in Wh
6831    /// Relates to:
6832    /// *ISO 15118-20*: Dynamic/Scheduled_SEReqControlModeType: EVMaximumEnergyRequest
6833    #[serde(
6834        rename = "evMaxEnergyRequest",
6835        default,
6836        skip_serializing_if = "Option::is_none"
6837    )]
6838    pub ev_max_energy_request: Option<f64>,
6839    /// Energy (in Wh) to minimum state of charge for cycling (V2X) activity.
6840    /// Positive value means that current state of charge is below V2X range.
6841    /// Relates to:
6842    /// *ISO 15118-20*: Dynamic_SEReqControlModeType: EVMinimumV2XEnergyRequest
6843    #[serde(
6844        rename = "evMinV2XEnergyRequest",
6845        default,
6846        skip_serializing_if = "Option::is_none"
6847    )]
6848    pub ev_min_v2_x_energy_request: Option<f64>,
6849    /// Energy (in Wh) to maximum state of charge for cycling (V2X) activity.
6850    /// Negative value indicates that current state of charge is above V2X range.
6851    /// Relates to:
6852    /// *ISO 15118-20*: Dynamic_SEReqControlModeType: EVMaximumV2XEnergyRequest
6853    #[serde(
6854        rename = "evMaxV2XEnergyRequest",
6855        default,
6856        skip_serializing_if = "Option::is_none"
6857    )]
6858    pub ev_max_v2_x_energy_request: Option<f64>,
6859    /// Target state of charge at departure as percentage.
6860    /// Relates to:
6861    /// *ISO 15118-20*: BPT_DC_CPDReqEnergyTransferModeType: TargetSOC
6862    #[serde(rename = "targetSoC", default, skip_serializing_if = "Option::is_none")]
6863    pub target_so_c: Option<i64>,
6864    #[serde(
6865        rename = "customData",
6866        default,
6867        skip_serializing_if = "Option::is_none"
6868    )]
6869    pub custom_data: Option<CustomData>,
6870}
6871
6872impl Validate for V2XChargingParameters {
6873    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6874        if let Some(x) = &self.target_so_c {
6875            let p = path.field("targetSoC");
6876            v::minimum(*x, 0i64, &p)?;
6877            v::maximum(*x, 100i64, &p)?;
6878        }
6879        if let Some(x) = &self.custom_data {
6880            let p = path.field("customData");
6881            x.validate(&p)?;
6882        }
6883        Ok(())
6884    }
6885}
6886
6887/// *(2.1)* A point of a frequency-watt curve.
6888#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6889#[serde(deny_unknown_fields)]
6890pub struct V2XFreqWattPoint {
6891    /// Net frequency in Hz.
6892    #[serde(rename = "frequency")]
6893    pub frequency: f64,
6894    /// Power in W to charge (positive) or discharge (negative) at specified frequency.
6895    #[serde(rename = "power")]
6896    pub power: f64,
6897    #[serde(
6898        rename = "customData",
6899        default,
6900        skip_serializing_if = "Option::is_none"
6901    )]
6902    pub custom_data: Option<CustomData>,
6903}
6904
6905impl Validate for V2XFreqWattPoint {
6906    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6907        if let Some(x) = &self.custom_data {
6908            let p = path.field("customData");
6909            x.validate(&p)?;
6910        }
6911        Ok(())
6912    }
6913}
6914
6915/// *(2.1)* A point of a signal-watt curve.
6916#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6917#[serde(deny_unknown_fields)]
6918pub struct V2XSignalWattPoint {
6919    /// Signal value from an AFRRSignalRequest.
6920    #[serde(rename = "signal")]
6921    pub signal: i64,
6922    /// Power in W to charge (positive) or discharge (negative) at specified frequency.
6923    #[serde(rename = "power")]
6924    pub power: f64,
6925    #[serde(
6926        rename = "customData",
6927        default,
6928        skip_serializing_if = "Option::is_none"
6929    )]
6930    pub custom_data: Option<CustomData>,
6931}
6932
6933impl Validate for V2XSignalWattPoint {
6934    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6935        if let Some(x) = &self.custom_data {
6936            let p = path.field("customData");
6937            x.validate(&p)?;
6938        }
6939        Ok(())
6940    }
6941}
6942
6943/// VPN Configuration settings
6944#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
6945#[serde(deny_unknown_fields)]
6946pub struct VPN {
6947    /// VPN Server Address
6948    #[serde(rename = "server")]
6949    pub server: String,
6950    /// VPN User
6951    #[serde(rename = "user")]
6952    pub user: String,
6953    /// VPN group.
6954    #[serde(rename = "group", default, skip_serializing_if = "Option::is_none")]
6955    pub group: Option<String>,
6956    /// *(2.1)* VPN Password.
6957    #[serde(rename = "password")]
6958    pub password: String,
6959    /// VPN shared secret.
6960    #[serde(rename = "key")]
6961    pub key: String,
6962    #[serde(rename = "type")]
6963    pub r#type: VPNEnum,
6964    #[serde(
6965        rename = "customData",
6966        default,
6967        skip_serializing_if = "Option::is_none"
6968    )]
6969    pub custom_data: Option<CustomData>,
6970}
6971
6972impl Validate for VPN {
6973    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
6974        {
6975            let x = &self.server;
6976            let p = path.field("server");
6977            v::max_length(x, 2000, &p)?;
6978        }
6979        {
6980            let x = &self.user;
6981            let p = path.field("user");
6982            v::max_length(x, 50, &p)?;
6983        }
6984        if let Some(x) = &self.group {
6985            let p = path.field("group");
6986            v::max_length(x, 50, &p)?;
6987        }
6988        {
6989            let x = &self.password;
6990            let p = path.field("password");
6991            v::max_length(x, 64, &p)?;
6992        }
6993        {
6994            let x = &self.key;
6995            let p = path.field("key");
6996            v::max_length(x, 255, &p)?;
6997        }
6998        if let Some(x) = &self.custom_data {
6999            let p = path.field("customData");
7000            x.validate(&p)?;
7001        }
7002        Ok(())
7003    }
7004}
7005
7006/// Reference key to a component-variable.
7007#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7008#[serde(deny_unknown_fields)]
7009pub struct Variable {
7010    /// 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.
7011    #[serde(rename = "name")]
7012    pub name: String,
7013    /// Name of instance in case the variable exists as multiple instances. Case Insensitive. strongly advised to use Camel Case.
7014    #[serde(rename = "instance", default, skip_serializing_if = "Option::is_none")]
7015    pub instance: Option<String>,
7016    #[serde(
7017        rename = "customData",
7018        default,
7019        skip_serializing_if = "Option::is_none"
7020    )]
7021    pub custom_data: Option<CustomData>,
7022}
7023
7024impl Validate for Variable {
7025    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
7026        {
7027            let x = &self.name;
7028            let p = path.field("name");
7029            v::max_length(x, 50, &p)?;
7030        }
7031        if let Some(x) = &self.instance {
7032            let p = path.field("instance");
7033            v::max_length(x, 50, &p)?;
7034        }
7035        if let Some(x) = &self.custom_data {
7036            let p = path.field("customData");
7037            x.validate(&p)?;
7038        }
7039        Ok(())
7040    }
7041}
7042
7043/// Attribute data of a variable.
7044#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
7045#[serde(deny_unknown_fields)]
7046pub struct VariableAttribute {
7047    #[serde(rename = "type", default, skip_serializing_if = "Option::is_none")]
7048    pub r#type: Option<AttributeEnum>,
7049    /// Value of the attribute. May only be omitted when mutability is set to 'WriteOnly'.
7050    /// 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.
7051    #[serde(rename = "value", default, skip_serializing_if = "Option::is_none")]
7052    pub value: Option<String>,
7053    #[serde(
7054        rename = "mutability",
7055        default,
7056        skip_serializing_if = "Option::is_none"
7057    )]
7058    pub mutability: Option<MutabilityEnum>,
7059    /// If true, value will be persistent across system reboots or power down. Default when omitted is false.
7060    #[serde(
7061        rename = "persistent",
7062        default,
7063        skip_serializing_if = "Option::is_none"
7064    )]
7065    pub persistent: Option<bool>,
7066    /// If true, value that will never be changed by the Charging Station at runtime. Default when omitted is false.
7067    #[serde(rename = "constant", default, skip_serializing_if = "Option::is_none")]
7068    pub constant: Option<bool>,
7069    #[serde(
7070        rename = "customData",
7071        default,
7072        skip_serializing_if = "Option::is_none"
7073    )]
7074    pub custom_data: Option<CustomData>,
7075}
7076
7077impl Validate for VariableAttribute {
7078    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
7079        if let Some(x) = &self.value {
7080            let p = path.field("value");
7081            v::max_length(x, 2500, &p)?;
7082        }
7083        if let Some(x) = &self.custom_data {
7084            let p = path.field("customData");
7085            x.validate(&p)?;
7086        }
7087        Ok(())
7088    }
7089}
7090
7091/// Fixed read-only parameters of a variable.
7092#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7093#[serde(deny_unknown_fields)]
7094pub struct VariableCharacteristics {
7095    /// Unit of the variable. When the transmitted value has a unit, this field SHALL be included.
7096    #[serde(rename = "unit", default, skip_serializing_if = "Option::is_none")]
7097    pub unit: Option<String>,
7098    #[serde(rename = "dataType")]
7099    pub data_type: DataEnum,
7100    /// Minimum possible value of this variable.
7101    #[serde(rename = "minLimit", default, skip_serializing_if = "Option::is_none")]
7102    pub min_limit: Option<f64>,
7103    /// 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.
7104    #[serde(rename = "maxLimit", default, skip_serializing_if = "Option::is_none")]
7105    pub max_limit: Option<f64>,
7106    /// *(2.1)* Maximum number of elements from _valuesList_ that are supported as _attributeValue_.
7107    #[serde(
7108        rename = "maxElements",
7109        default,
7110        skip_serializing_if = "Option::is_none"
7111    )]
7112    pub max_elements: Option<i64>,
7113    /// Mandatory when _dataType_ = OptionList, MemberList or SequenceList. In that case _valuesList_ specifies the allowed values for the type.
7114    /// The length of this field can be limited by DeviceDataCtrlr.ConfigurationValueSize.
7115    /// * OptionList: The (Actual) Variable value must be a single value from the reported (CSV) enumeration list.
7116    /// * MemberList: The (Actual) Variable value  may be an (unordered) (sub-)set of the reported (CSV) valid values list.
7117    /// * SequenceList: The (Actual) Variable value  may be an ordered (priority, etc)  (sub-)set of the reported (CSV) valid values.
7118    ///
7119    /// This is a comma separated list.
7120    /// 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.
7121    #[serde(
7122        rename = "valuesList",
7123        default,
7124        skip_serializing_if = "Option::is_none"
7125    )]
7126    pub values_list: Option<String>,
7127    /// Flag indicating if this variable supports monitoring.
7128    #[serde(rename = "supportsMonitoring")]
7129    pub supports_monitoring: bool,
7130    #[serde(
7131        rename = "customData",
7132        default,
7133        skip_serializing_if = "Option::is_none"
7134    )]
7135    pub custom_data: Option<CustomData>,
7136}
7137
7138impl Validate for VariableCharacteristics {
7139    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
7140        if let Some(x) = &self.unit {
7141            let p = path.field("unit");
7142            v::max_length(x, 16, &p)?;
7143        }
7144        if let Some(x) = &self.max_elements {
7145            let p = path.field("maxElements");
7146            v::minimum(*x, 1i64, &p)?;
7147        }
7148        if let Some(x) = &self.values_list {
7149            let p = path.field("valuesList");
7150            v::max_length(x, 1000, &p)?;
7151        }
7152        if let Some(x) = &self.custom_data {
7153            let p = path.field("customData");
7154            x.validate(&p)?;
7155        }
7156        Ok(())
7157    }
7158}
7159
7160/// A monitoring setting for a variable.
7161#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7162#[serde(deny_unknown_fields)]
7163pub struct VariableMonitoring {
7164    /// Identifies the monitor.
7165    #[serde(rename = "id")]
7166    pub id: i64,
7167    /// Monitor only active when a transaction is ongoing on a component relevant to this transaction.
7168    #[serde(rename = "transaction")]
7169    pub transaction: bool,
7170    /// Value for threshold or delta monitoring.
7171    /// For Periodic or PeriodicClockAligned this is the interval in seconds.
7172    #[serde(rename = "value")]
7173    pub value: f64,
7174    #[serde(rename = "type")]
7175    pub r#type: MonitorEnum,
7176    /// 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.
7177    /// The severity levels have the following meaning: +
7178    /// *0-Danger* +
7179    /// Indicates lives are potentially in danger. Urgent attention is needed and action should be taken immediately. +
7180    /// *1-Hardware Failure* +
7181    /// Indicates that the Charging Station is unable to continue regular operations due to Hardware issues. Action is required. +
7182    /// *2-System Failure* +
7183    /// Indicates that the Charging Station is unable to continue regular operations due to software or minor hardware issues. Action is required. +
7184    /// *3-Critical* +
7185    /// Indicates a critical error. Action is required. +
7186    /// *4-Error* +
7187    /// Indicates a non-urgent error. Action is required. +
7188    /// *5-Alert* +
7189    /// Indicates an alert event. Default severity for any type of monitoring event.  +
7190    /// *6-Warning* +
7191    /// Indicates a warning event. Action may be required. +
7192    /// *7-Notice* +
7193    /// Indicates an unusual event. No immediate action is required. +
7194    /// *8-Informational* +
7195    /// Indicates a regular operational event. May be used for reporting, measuring throughput, etc. No action is required. +
7196    /// *9-Debug* +
7197    /// Indicates information useful to developers for debugging, not useful during operations.
7198    #[serde(rename = "severity")]
7199    pub severity: i64,
7200    #[serde(rename = "eventNotificationType")]
7201    pub event_notification_type: EventNotificationEnum,
7202    #[serde(
7203        rename = "customData",
7204        default,
7205        skip_serializing_if = "Option::is_none"
7206    )]
7207    pub custom_data: Option<CustomData>,
7208}
7209
7210impl Validate for VariableMonitoring {
7211    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
7212        {
7213            let x = &self.id;
7214            let p = path.field("id");
7215            v::minimum(*x, 0i64, &p)?;
7216        }
7217        {
7218            let x = &self.severity;
7219            let p = path.field("severity");
7220            v::minimum(*x, 0i64, &p)?;
7221        }
7222        if let Some(x) = &self.custom_data {
7223            let p = path.field("customData");
7224            x.validate(&p)?;
7225        }
7226        Ok(())
7227    }
7228}
7229
7230#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)]
7231#[serde(deny_unknown_fields)]
7232pub struct VoltageParams {
7233    /// EN 50549-1 chapter 4.9.3.4
7234    /// Voltage threshold for the 10 min time window mean value monitoring.
7235    /// The 10 min mean is recalculated up to every 3 s.
7236    /// If the present voltage is above this threshold for more than the time defined by _hv10MinMeanValue_, the EV must trip.
7237    /// This value is mandatory if _hv10MinMeanTripDelay_ is set.
7238    #[serde(
7239        rename = "hv10MinMeanValue",
7240        default,
7241        skip_serializing_if = "Option::is_none"
7242    )]
7243    pub hv10_min_mean_value: Option<f64>,
7244    /// Time for which the voltage is allowed to stay above the 10 min mean value.
7245    /// After this time, the EV must trip.
7246    /// This value is mandatory if OverVoltageMeanValue10min is set.
7247    #[serde(
7248        rename = "hv10MinMeanTripDelay",
7249        default,
7250        skip_serializing_if = "Option::is_none"
7251    )]
7252    pub hv10_min_mean_trip_delay: Option<f64>,
7253    #[serde(
7254        rename = "powerDuringCessation",
7255        default,
7256        skip_serializing_if = "Option::is_none"
7257    )]
7258    pub power_during_cessation: Option<PowerDuringCessationEnum>,
7259    #[serde(
7260        rename = "customData",
7261        default,
7262        skip_serializing_if = "Option::is_none"
7263    )]
7264    pub custom_data: Option<CustomData>,
7265}
7266
7267impl Validate for VoltageParams {
7268    fn validate(&self, path: &Path<'_>) -> Result<(), Violation> {
7269        if let Some(x) = &self.custom_data {
7270            let p = path.field("customData");
7271            x.validate(&p)?;
7272        }
7273        Ok(())
7274    }
7275}