Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.2.0]

Breaking changes for JSON/YAML consumers:

- Changed `summary.records[].value` from a table-style string (e.g.
`"(2850427)e-2[m³](Volume)"`) to structured fields: `value` (number),
`exponent`, `unit` and `quantity`, derived from the processed data record
header. The human-readable string is still available as
`summary.records[].display`. Table and CSV outputs are unchanged.
- Removed the top-level `manufacturer_info` key from JSON and YAML output.
Migration: use `summary.manufacturer`, which carries `code`, `name`,
`website` and `description`.
- Changed raw byte payloads (`frame.data` of wireless frames,
`data_records[].raw_bytes` and manufacturer-specific record data) to
serialize as compact uppercase hex strings instead of decimal byte arrays.
Migration: decode the hex string instead of reading a JSON/YAML array
(e.g. `"2F2F"` instead of `[47, 47]`). Serialize-only: parsing APIs and
`Deserialize` implementations are unchanged.

## [0.1.4] - 2026-07-17

- Added direct application-layer parsing APIs, record accessors, and a crate-local data-record example.
Expand Down
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "m-bus-parser"
version = "0.1.4"
version = "0.2.0"
edition = "2021"
description = "A library for parsing M-Bus frames"
license = "MIT"
Expand Down Expand Up @@ -47,10 +47,10 @@ serde = { version = "1.0", features = ["derive"], optional = true }
bitflags = "2.8.0"
arrayvec = { version = "0.7.4", default-features = false }
defmt = { version = "1.0.1", optional = true }
wired-mbus-link-layer = { version = "0.1.4", path = "crates/wired-mbus-link-layer" }
wireless-mbus-link-layer = { version = "0.1.4", path = "crates/wireless-mbus-link-layer" }
m-bus-core = { version = "0.1.4", path = "crates/m-bus-core" }
m-bus-application-layer = { version = "0.1.4", path = "crates/m-bus-application-layer" }
wired-mbus-link-layer = { version = "0.2.0", path = "crates/wired-mbus-link-layer" }
wireless-mbus-link-layer = { version = "0.2.0", path = "crates/wireless-mbus-link-layer" }
m-bus-core = { version = "0.2.0", path = "crates/m-bus-core" }
m-bus-application-layer = { version = "0.2.0", path = "crates/m-bus-application-layer" }
aes = { version = "0.9", optional = true, default-features = false }
cbc = { version = "0.2", optional = true, default-features = false }
cipher = { version = "0.5", optional = true, default-features = false, features = ["block-padding"] }
Expand Down
4 changes: 2 additions & 2 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "m-bus-parser-cli"
version = "0.1.4"
version = "0.2.0"
edition = "2021"
description = "A cli to use the library for parsing M-Bus frames"
license = "MIT"
Expand All @@ -22,6 +22,6 @@ default = ["decryption"]
decryption = ["m-bus-parser/decryption"]

[dependencies]
m-bus-parser = { path = "..", version = "0.1.4", features = ["std", "serde"] }
m-bus-parser = { path = "..", version = "0.2.0", features = ["std", "serde"] }
hex = "0.4"
clap = { version = "4.5.4", features = ["derive"] }
4 changes: 2 additions & 2 deletions crates/m-bus-application-layer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "m-bus-application-layer"
version = "0.1.4"
version = "0.2.0"
edition = "2021"
description = "M-Bus application layer parser (DIF/VIF, data records)"
license = "MIT"
Expand All @@ -20,4 +20,4 @@ serde = { version = "1.0", features = ["derive"], optional = true }
defmt = { version = "1.0.1", optional = true }
bitflags = "2.8.0"
arrayvec = { version = "0.7.4", default-features = false }
m-bus-core = { version = "0.1.4", path = "../m-bus-core" }
m-bus-core = { version = "0.2.0", path = "../m-bus-core" }
8 changes: 7 additions & 1 deletion crates/m-bus-application-layer/src/data_information.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,13 @@ pub enum DataType<'a> {
SingleEveryOrInvalid<Minute>,
SingleEveryOrInvalid<Second>,
),
ManufacturerSpecific(&'a [u8]),
ManufacturerSpecific(
#[cfg_attr(
feature = "serde",
serde(serialize_with = "m_bus_core::serde_hex::serialize")
)]
&'a [u8],
),
}
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[derive(PartialEq, Debug, Clone)]
Expand Down
4 changes: 4 additions & 0 deletions crates/m-bus-application-layer/src/data_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ pub struct DataRecord<'a> {
pub data_record_header: DataRecordHeader<'a>,
pub data: Data<'a>,
/// Raw bytes encompassing this data record
#[cfg_attr(
feature = "serde",
serde(serialize_with = "m_bus_core::serde_hex::serialize")
)]
pub raw_bytes: &'a [u8],
}

Expand Down
2 changes: 1 addition & 1 deletion crates/m-bus-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "m-bus-core"
version = "0.1.4"
version = "0.2.0"
edition = "2024"
description = "Core types for the m-bus-parser M-Bus protocol library"
license = "MIT"
Expand Down
23 changes: 23 additions & 0 deletions crates/m-bus-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
pub mod decryption;

/// Serializes raw byte payloads as compact uppercase hex strings so that
/// human-facing dumps (JSON/YAML) don't render them as decimal byte arrays.
/// Serialize-only: deserialization of these fields is unaffected.
#[cfg(feature = "serde")]
pub mod serde_hex {
use core::fmt;

struct HexSlice<'a>(&'a [u8]);

impl fmt::Display for HexSlice<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for byte in self.0 {
write!(f, "{:02X}", byte)?;
}
Ok(())
}
}

pub fn serialize<S: serde::Serializer>(data: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
serializer.collect_str(&HexSlice(data))
}
}

#[cfg(feature = "std")]
use std::fmt::{self, Display};

Expand Down
4 changes: 2 additions & 2 deletions crates/wired-mbus-link-layer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wired-mbus-link-layer"
version = "0.1.4"
version = "0.2.0"
edition = "2024"
description = "Wired M-Bus link layer parser (EN 13757-2)"
license = "MIT"
Expand All @@ -15,4 +15,4 @@ defmt = ["dep:defmt"]
[dependencies]
serde = { version = "1.0", features = ["derive"], optional = true }
defmt = { version = "1.0.1", optional = true }
m-bus-core = { version = "0.1.4", path = "../m-bus-core" }
m-bus-core = { version = "0.2.0", path = "../m-bus-core" }
4 changes: 2 additions & 2 deletions crates/wireless-mbus-link-layer/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "wireless-mbus-link-layer"
version = "0.1.4"
version = "0.2.0"
edition = "2024"
description = "Wireless M-Bus link layer parser (wMBus)"
license = "MIT"
Expand All @@ -14,6 +14,6 @@ defmt = ["dep:defmt"]

[dependencies]
crc16 = "0.4.0"
m-bus-core = { version = "0.1.4", path = "../m-bus-core" }
m-bus-core = { version = "0.2.0", path = "../m-bus-core" }
serde = { version = "1.0", features = ["derive"], optional = true }
defmt = { version = "1.0.1", optional = true }
4 changes: 4 additions & 0 deletions crates/wireless-mbus-link-layer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ pub fn strip_format_a_crcs<'a>(data: &[u8], output: &'a mut [u8]) -> Option<&'a
pub struct WirelessFrame<'a> {
pub function: Function,
pub manufacturer_id: ManufacturerId,
#[cfg_attr(
feature = "serde",
serde(serialize_with = "m_bus_core::serde_hex::serialize")
)]
pub data: &'a [u8],
}

Expand Down
4 changes: 2 additions & 2 deletions python/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "pymbusparser"
version = "0.1.4"
version = "0.2.0"
edition = "2021"
homepage = "https://maebli.github.io/"
repository = "https://github.com/maebli/m-bus-parser"
description = "A Python binding for the M-Bus parser"
license = "MIT"

[dependencies]
m-bus-parser = { path = "..", version = "0.1.4", features = ["std", "serde", "decryption"] }
m-bus-parser = { path = "..", version = "0.2.0", features = ["std", "serde", "decryption"] }
serde_json = "1.0"
pyo3 = { version = "0.29.0", features = ["extension-module", "generate-import-lib"] }
hex = "0.4"
Expand Down
Loading
Loading