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#[serde(rename_all = "camelCase")]
27pub struct TimeOfUseRegister {
28    /// BO4E metadata
29    #[serde(flatten)]
30    pub meta: Bo4eMeta,
31
32    /// Register ID (Zaehlwerkskennung)
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub register_id: Option<String>,
35
36    /// OBIS code (OBIS-Kennzahl)
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub obis_code: Option<String>,
39
40    /// Tariff time period (Tarifzeit)
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub tariff_time: Option<TariffTime>,
43
44    /// Unit of measurement (Einheit)
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub unit: Option<Unit>,
47
48    /// Description of the register (Bezeichnung)
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub description: Option<String>,
51
52    /// Active start time in HH:MM format (Aktivzeitbeginn)
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub active_start_time: Option<String>,
55
56    /// Active end time in HH:MM format (Aktivzeitende)
57    #[serde(skip_serializing_if = "Option::is_none")]
58    pub active_end_time: Option<String>,
59}
60
61impl Bo4eObject for TimeOfUseRegister {
62    fn type_name_german() -> &'static str {
63        "Zaehlzeitregister"
64    }
65
66    fn type_name_english() -> &'static str {
67        "TimeOfUseRegister"
68    }
69
70    fn meta(&self) -> &Bo4eMeta {
71        &self.meta
72    }
73
74    fn meta_mut(&mut self) -> &mut Bo4eMeta {
75        &mut self.meta
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_high_tariff_register() {
85        let register = TimeOfUseRegister {
86            register_id: Some("HT".to_string()),
87            tariff_time: Some(TariffTime::HighTariff),
88            unit: Some(Unit::KilowattHour),
89            active_start_time: Some("06:00".to_string()),
90            active_end_time: Some("22:00".to_string()),
91            ..Default::default()
92        };
93
94        let json = serde_json::to_string(&register).unwrap();
95        assert!(json.contains("HT"));
96    }
97
98    #[test]
99    fn test_roundtrip() {
100        let register = TimeOfUseRegister {
101            register_id: Some("NT".to_string()),
102            tariff_time: Some(TariffTime::LowTariff),
103            ..Default::default()
104        };
105
106        let json = serde_json::to_string(&register).unwrap();
107        let parsed: TimeOfUseRegister = serde_json::from_str(&json).unwrap();
108        assert_eq!(register, parsed);
109    }
110
111    #[test]
112    fn test_bo4e_object_impl() {
113        assert_eq!(TimeOfUseRegister::type_name_german(), "Zaehlzeitregister");
114        assert_eq!(TimeOfUseRegister::type_name_english(), "TimeOfUseRegister");
115    }
116}