Skip to main content

bo4e_core/com/
time_of_use_register.rs

1//! Time-of-use register (Zaehlzeitregister) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::{TariffTime, Unit};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// A time-of-use register on a meter for different tariff periods.
9///
10/// German: Zaehlzeitregister
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::TimeOfUseRegister;
16/// use bo4e_core::enums::{TariffTime, Unit};
17///
18/// let register = TimeOfUseRegister {
19///     register_id: Some("HT".to_string()),
20///     tariff_time: Some(TariffTime::HighTariff),
21///     unit: Some(Unit::KilowattHour),
22///     ..Default::default()
23/// };
24/// ```
25#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
27#[cfg_attr(feature = "json-schema", schemars(rename = "Zaehlzeitregister"))]
28#[serde(rename_all = "camelCase")]
29pub struct TimeOfUseRegister {
30    /// BO4E metadata
31    #[serde(flatten)]
32    pub meta: Bo4eMeta,
33
34    /// Register ID (Zaehlwerkskennung)
35    #[serde(skip_serializing_if = "Option::is_none")]
36    #[cfg_attr(feature = "json-schema", schemars(rename = "zaehlwerkskennung"))]
37    pub register_id: Option<String>,
38
39    /// OBIS code (OBIS-Kennzahl)
40    #[serde(skip_serializing_if = "Option::is_none")]
41    #[cfg_attr(feature = "json-schema", schemars(rename = "obisKennzahl"))]
42    pub obis_code: Option<String>,
43
44    /// Tariff time period (Tarifzeit)
45    #[serde(skip_serializing_if = "Option::is_none")]
46    #[cfg_attr(feature = "json-schema", schemars(rename = "tarifzeit"))]
47    pub tariff_time: Option<TariffTime>,
48
49    /// Unit of measurement (Einheit)
50    #[serde(skip_serializing_if = "Option::is_none")]
51    #[cfg_attr(feature = "json-schema", schemars(rename = "einheit"))]
52    pub unit: Option<Unit>,
53
54    /// Description of the register (Bezeichnung)
55    #[serde(skip_serializing_if = "Option::is_none")]
56    #[cfg_attr(feature = "json-schema", schemars(rename = "bezeichnung"))]
57    pub description: Option<String>,
58
59    /// Active start time in HH:MM format (Aktivzeitbeginn)
60    #[serde(skip_serializing_if = "Option::is_none")]
61    #[cfg_attr(feature = "json-schema", schemars(rename = "aktivzeitbeginn"))]
62    pub active_start_time: Option<String>,
63
64    /// Active end time in HH:MM format (Aktivzeitende)
65    #[serde(skip_serializing_if = "Option::is_none")]
66    #[cfg_attr(feature = "json-schema", schemars(rename = "aktivzeitende"))]
67    pub active_end_time: Option<String>,
68}
69
70impl Bo4eObject for TimeOfUseRegister {
71    fn type_name_german() -> &'static str {
72        "Zaehlzeitregister"
73    }
74
75    fn type_name_english() -> &'static str {
76        "TimeOfUseRegister"
77    }
78
79    fn meta(&self) -> &Bo4eMeta {
80        &self.meta
81    }
82
83    fn meta_mut(&mut self) -> &mut Bo4eMeta {
84        &mut self.meta
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn test_high_tariff_register() {
94        let register = TimeOfUseRegister {
95            register_id: Some("HT".to_string()),
96            tariff_time: Some(TariffTime::HighTariff),
97            unit: Some(Unit::KilowattHour),
98            active_start_time: Some("06:00".to_string()),
99            active_end_time: Some("22:00".to_string()),
100            ..Default::default()
101        };
102
103        let json = serde_json::to_string(&register).unwrap();
104        assert!(json.contains("HT"));
105    }
106
107    #[test]
108    fn test_roundtrip() {
109        let register = TimeOfUseRegister {
110            register_id: Some("NT".to_string()),
111            tariff_time: Some(TariffTime::LowTariff),
112            ..Default::default()
113        };
114
115        let json = serde_json::to_string(&register).unwrap();
116        let parsed: TimeOfUseRegister = serde_json::from_str(&json).unwrap();
117        assert_eq!(register, parsed);
118    }
119
120    #[test]
121    fn test_bo4e_object_impl() {
122        assert_eq!(TimeOfUseRegister::type_name_german(), "Zaehlzeitregister");
123        assert_eq!(TimeOfUseRegister::type_name_english(), "TimeOfUseRegister");
124    }
125}