#![allow(clippy::result_large_err)]
use edi_energy::{AnyMessage, EdiEnergyMessage, Platform};
const MSCONS_BYTES: &[u8] = b"\
UNB+UNOC:3+4012345000023:14+9900357000004:14+240115:0800+INTER-MS-001'\
UNH+MSG-002+MSCONS:D:04B:UN:2.4c'\
BGM+7+13002+9'\
DTM+137:20240115:102'\
NAD+MS+4012345000023::293'\
NAD+MR+9900357000004::293'\
UNS+D'\
NAD+DP+DE0001234567890123456789012345::293'\
LOC+172+DE0001234567890123456789012345::293'\
DTM+163:20240101:102'\
DTM+164:20240131:102'\
LIN+1'\
PIA+5+1-1:1.29.0:SRW'\
QTY+220:1234.567:KWH'\
DTM+163:20240101000000:203'\
DTM+164:20240131235959:203'\
STS+7::293'\
UNT+17+MSG-002'\
UNZ+1+INTER-MS-001'";
fn main() -> Result<(), edi_energy::Error> {
let msg = Platform::with_all_profiles().parse(MSCONS_BYTES)?;
println!(
"Message type : {}",
msg.try_message_type()
.map(|t| t.as_str().to_owned())
.unwrap_or_else(|| "Unknown".to_owned())
);
println!("Release : {}", msg.detect_release()?.as_str());
println!(
"PID : {}",
msg.detect_pruefidentifikator()?.as_u32()
);
if let AnyMessage::Mscons(mscons) = &msg {
if let Some(bgm) = &mscons.bgm() {
println!("Doc code : {}", bgm.document_code);
}
for dtm in mscons.dtm() {
if dtm.is_document_date() {
println!("Message date : {}", dtm.value_str().unwrap_or("-"));
}
}
println!("\nDelivery points: {}", mscons.delivery_points().len());
for (dp_i, dp) in mscons.delivery_points().iter().enumerate() {
println!(
"\n[DP {}] Location: {}",
dp_i,
dp.nad.party_id.as_deref().unwrap_or("-")
);
for (ts_i, ts) in dp.time_series.iter().enumerate() {
println!(
" [TS {}] LOC {} (qualifier: {})",
ts_i,
ts.loc.location_id.as_deref().unwrap_or("-"),
ts.loc.qualifier
);
let period_start = ts.dtm.iter().find(|d| d.is_period_start());
let period_end = ts.dtm.iter().find(|d| d.is_period_end());
if let (Some(s), Some(e)) = (period_start, period_end) {
println!(
" Period: {} – {}",
s.value_str().unwrap_or("-"),
e.value_str().unwrap_or("-")
);
}
for (li_i, item) in ts.items.iter().enumerate() {
let obis = item
.pia
.as_ref()
.and_then(|p| p.item_number.as_deref())
.unwrap_or("-");
println!(" [LI {li_i}] OBIS: {obis}");
for qty_entry in &item.quantities {
let value_f64 = qty_entry.qty.value_f64().unwrap_or(f64::NAN);
let unit = qty_entry.qty.unit.as_deref().unwrap_or("-");
let metered = qty_entry.qty.is_metered();
println!(
" QTY: {:.3} {} {}",
value_f64,
unit,
if metered { "(metered)" } else { "" }
);
for dtm in &qty_entry.dtm {
if dtm.is_period_start() {
println!(" Start : {}", dtm.value_str().unwrap_or("-"));
} else if dtm.is_period_end() {
println!(" End : {}", dtm.value_str().unwrap_or("-"));
}
}
}
}
}
}
}
let bytes = msg.serialize()?;
let reparsed = Platform::with_all_profiles().parse(&bytes)?;
assert_eq!(reparsed.try_message_type(), msg.try_message_type());
println!("\nRound-trip : OK ({} bytes)", bytes.len());
Ok(())
}