For contributing see CONTRIBUTING.md, for change history see CHANGELOG.md.
An open-source parser (decoder/deserializer) for the wired and wireless M-Bus protocol, written in Rust.
M-Bus (Meter-Bus) is a European standard (EN 13757-2 physical and link layer, EN 13757-3 application layer) for remote reading of water, gas, electricity, and heat meters. β Wikipedia
- Try it live: maebli.github.io/m-bus-parser
- Spec: m-bus.com/documentation Β· OMS specification
- Parses wired M-Bus (EN 13757-2/-3) and wireless M-Bus (wMBus) frames
- Five output formats:
table,json,yaml,csv,mermaid - AES-128 decryption for encrypted wMBus frames (mode 5 / mode 7)
no_stdcompatible β runs on embedded targets (manufacturer lookup and output formats requirestd)- Available as a Rust library, CLI, WebAssembly (npm) and Python bindings
Paste a hex frame at maebli.github.io/m-bus-parser and get instant output in any format, including a rendered Mermaid diagram. Frames can be shared via URL.
Source: wasm/
cargo install m-bus-parser-cliSource: cli/
pip install pymbusparserSource: python/
m-bus-parser-cli parse [OPTIONS]
Options:
-d, --data <DATA> Raw M-Bus frame as a hex string
-f, --file <FILE> File containing a hex frame
-t, --format <FORMAT> Output format: table (default), json, yaml, csv, mermaid
-k, --key <KEY> AES-128 decryption key (32 hex characters)
Input hex can be in any of these forms:
68 3D 3D 68 ... (space-separated)
683D3D68... (plain hex)
0x68,0x3D,0x3D,... (0x-prefixed, comma-separated)
m-bus-parser-cli parse -d "68 3D 3D 68 08 01 72 00 51 20 02 82 4D 02 04 00 88 00 00 \
04 07 00 00 00 00 0C 15 03 00 00 00 0B 2E 00 00 00 0B 3B 00 00 00 0A 5A 88 12 \
0A 5E 16 05 0B 61 23 77 00 02 6C 8C 11 02 27 37 0D 0F 60 00 67 16"Long Frame
ββββββββββββββββββββββββββββββββββ¬ββββββββββββββ
β Function β Address β
ββββββββββββββββββββββββββββββββββΌββββββββββββββ€
β RspUd (ACD: false, DFC: false) β Primary (1) β
ββββββββββββββββββββββββββββββββββ΄ββββββββββββββ
βββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββββ
β Field β Value β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Identification Number β 02205100 β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Manufacturer β SLB β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Manufacturer Name β Schlumberger Industries β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Website β slb.com β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Description β Energy and water metering β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Access Number β 0 β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Status β Permanent error, Manufacturer specific 3 β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Security Mode β No encryption used β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β Version β 2 β
βββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββ€
β DeviceType β Heat Meter (Return) β
βββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββ¬βββββββββββββ¬ββββββββββββββ
β Value β Data Information β Header Hex β Data Hex β
βββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β (0)e4[Wh] β 0,Inst,32-bit Integer β 04 07 β 00 00 00 00 β
βββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β (3)e-1[mΒ³](Volume) β 0,Inst,BCD 8-digit β 0C 15 β 03 00 00 00 β
βββββββββββββββββββββββββββββββββββββββββββΌββββββββββββββββββββββββΌβββββββββββββΌββββββββββββββ€
β (1288)e-1[Β°C] β 0,Inst,BCD 4-digit β 0A 5A β 88 12 β
βββββββββββββββββββββββββββββββββββββββββββ΄ββββββββββββββββββββββββ΄βββββββββββββ΄ββββββββββββββ
# JSON
m-bus-parser-cli parse -d "..." -t json
# YAML
m-bus-parser-cli parse -d "..." -t yaml
# CSV
m-bus-parser-cli parse -d "..." -t csv
# Mermaid diagram source (renders in the web app)
m-bus-parser-cli parse -d "..." -t mermaid
# With AES-128 decryption key
m-bus-parser-cli parse -d "..." -k "000102030405060708090A0B0C0D0E0F"Add to Cargo.toml:
[dependencies]
m-bus-parser = "0.1"use m_bus_parser::{Address, WiredFrame, Function};
use m_bus_parser::mbus_data::MbusData;
use m_bus_parser::user_data::{DataRecords, UserDataBlock};
let frame_bytes: Vec<u8> = vec![
0x68, 0x4D, 0x4D, 0x68, 0x08, 0x01, 0x72, 0x01,
// ... rest of frame
];
let frame = WiredFrame::try_from(frame_bytes.as_slice())?;
if let WiredFrame::LongFrame { function, address, data } = frame {
if let Ok(user_data) = UserDataBlock::try_from(data) {
if let UserDataBlock::VariableDataStructureWithLongTplHeader {
long_tpl_header,
variable_data_block,
..
} = user_data {
let records = DataRecords::from((variable_data_block, &long_tpl_header));
for record in records.flatten() {
println!("{}", record.data);
}
}
}
}use m_bus_parser::serialize_mbus_data;
let hex = "68 3D 3D 68 08 01 72 ...";
let table = serialize_mbus_data(hex, "table", None);
let json = serialize_mbus_data(hex, "json", None);
let yaml = serialize_mbus_data(hex, "yaml", None);
let csv = serialize_mbus_data(hex, "csv", None);
let mermaid = serialize_mbus_data(hex, "mermaid", None);
// With decryption key
let key: [u8; 16] = [0x00, 0x01, ..., 0x0F];
let decrypted = serialize_mbus_data(hex, "table", Some(&key));The core parsing types are no_std compatible. Disable default features:
[dependencies]
m-bus-parser = { version = "0.1", default-features = false }An embedded example (Cortex-M) is in examples/cortex-m/.
| Format | Flag | Description |
|---|---|---|
table |
default | Human-readable ASCII table |
json |
-t json |
JSON |
yaml |
-t yaml |
YAML |
csv |
-t csv |
Comma-separated values |
mermaid |
-t mermaid |
Mermaid flowchart source (renders in web app) |
| Type | CI bytes | Status |
|---|---|---|
| Long frame | 0x72, 0x76, 0x7A | Supported |
| Short frame | β | Supported |
| Control frame | β | Supported |
| Single character | β | Supported |
| Wireless frame | wMBus link layer | Supported |
ResponseWithVariableDataStructure(CI: 0x72, 0x76, 0x7A)ResponseWithFixedDataStructure(CI: 0x73)ApplicationLayerShortTransport(CI: 0x7D)ApplicationLayerLongTransport(CI: 0x7E)ExtendedLinkLayerI(CI: 0x8A)ResetAtApplicationLevel
Returns ApplicationLayerError::Unimplemented for: SendData, SelectSlave, SynchronizeSlave, baud-rate commands, ExtendedLinkLayerII/III, COSEM/OBIS data, and various transport/network layer types.
Most common value information unit codes are supported. Contributions for additional CI types and VIF codes are welcome.
| Language | Project |
|---|---|
| C | libmbus by rscada |
| Java | jMbus |
| C# | Valley.Net.Protocols.MeterBus |
| JS | tmbus |
| Python | pyMeterBus |




