Skip to main content

bo4e_core/com/
metering_point_status.rs

1//! Metering point status (Messstellenstatus) component.
2
3use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// Status information for a metering point.
9///
10/// German: Messstellenstatus
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::MeteringPointStatus;
16/// use chrono::Utc;
17///
18/// let status = MeteringPointStatus {
19///     status_timestamp: Some(Utc::now()),
20///     is_active: Some(true),
21///     ..Default::default()
22/// };
23/// ```
24#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
25#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
26#[cfg_attr(feature = "json-schema", schemars(rename = "Messstellenstatus"))]
27#[serde(rename_all = "camelCase")]
28pub struct MeteringPointStatus {
29    /// BO4E metadata
30    #[serde(flatten)]
31    pub meta: Bo4eMeta,
32
33    /// Timestamp of the status (Statuszeitpunkt)
34    #[serde(skip_serializing_if = "Option::is_none")]
35    #[cfg_attr(feature = "json-schema", schemars(rename = "statuszeitpunkt"))]
36    pub status_timestamp: Option<DateTime<Utc>>,
37
38    /// Whether the metering point is active (Aktiv)
39    #[serde(skip_serializing_if = "Option::is_none")]
40    #[cfg_attr(feature = "json-schema", schemars(rename = "aktiv"))]
41    pub is_active: Option<bool>,
42
43    /// Status code (Statuscode)
44    #[serde(skip_serializing_if = "Option::is_none")]
45    #[cfg_attr(feature = "json-schema", schemars(rename = "statuscode"))]
46    pub status_code: Option<String>,
47
48    /// Status description (Statusbeschreibung)
49    #[serde(skip_serializing_if = "Option::is_none")]
50    #[cfg_attr(feature = "json-schema", schemars(rename = "statusbeschreibung"))]
51    pub status_description: Option<String>,
52
53    /// Whether data is being transmitted (Datenübertragung)
54    #[serde(skip_serializing_if = "Option::is_none")]
55    #[cfg_attr(feature = "json-schema", schemars(rename = "datenuebertragung"))]
56    pub data_transmission_active: Option<bool>,
57
58    /// Installation status (Installationsstatus)
59    #[serde(skip_serializing_if = "Option::is_none")]
60    #[cfg_attr(feature = "json-schema", schemars(rename = "installationsstatus"))]
61    pub installation_status: Option<String>,
62}
63
64impl Bo4eObject for MeteringPointStatus {
65    fn type_name_german() -> &'static str {
66        "Messstellenstatus"
67    }
68
69    fn type_name_english() -> &'static str {
70        "MeteringPointStatus"
71    }
72
73    fn meta(&self) -> &Bo4eMeta {
74        &self.meta
75    }
76
77    fn meta_mut(&mut self) -> &mut Bo4eMeta {
78        &mut self.meta
79    }
80}
81
82#[cfg(test)]
83mod tests {
84    use super::*;
85    use chrono::TimeZone;
86
87    #[test]
88    fn test_metering_point_status() {
89        let status = MeteringPointStatus {
90            status_timestamp: Some(Utc.with_ymd_and_hms(2024, 1, 15, 12, 0, 0).unwrap()),
91            is_active: Some(true),
92            status_code: Some("ACTIVE".to_string()),
93            data_transmission_active: Some(true),
94            ..Default::default()
95        };
96
97        let json = serde_json::to_string(&status).unwrap();
98        assert!(json.contains("true"));
99        assert!(json.contains("ACTIVE"));
100    }
101
102    #[test]
103    fn test_roundtrip() {
104        let status = MeteringPointStatus {
105            status_timestamp: Some(Utc::now()),
106            is_active: Some(false),
107            status_description: Some("Meter removed".to_string()),
108            ..Default::default()
109        };
110
111        let json = serde_json::to_string(&status).unwrap();
112        let parsed: MeteringPointStatus = serde_json::from_str(&json).unwrap();
113        assert_eq!(status.is_active, parsed.is_active);
114        assert_eq!(status.status_description, parsed.status_description);
115    }
116
117    #[test]
118    fn test_bo4e_object_impl() {
119        assert_eq!(MeteringPointStatus::type_name_german(), "Messstellenstatus");
120        assert_eq!(
121            MeteringPointStatus::type_name_english(),
122            "MeteringPointStatus"
123        );
124    }
125}