#sml #meter #message #smart #parser #peg-parser #messages

hackdose-sml-parser

a parser for the smart message language spoken by smart meters

15 releases (8 breaking)

0.10.0 Feb 10, 2023
0.7.0 Dec 23, 2022
0.1.0 Nov 12, 2022

#1258 in Parser implementations


Used in hackdose-server

MIT/Apache

72KB
1K SLoC

Hackdose SML-parser

A parser for SML messages as emitted by ISKRA(tm) smart meters for instance. It currently uses the peg-crate to express SML as a parser expression grammar. It also contains a mapping for OBIS numbers.

Usage

This crate comes in three different flavors

Message-Stream

This is propably the most frequent application: Convert an async byte stream into a stream of SML messages. See examples/serial-stream.rs for an example.

Transport

This layer deals with streaming of SML messages from raw bytes.

Application

The application module consumes readly-parsed bodies of SML messages.

Once you have obtained the data for your SML-speaking appliance (e.g. a smart meter), you can use the library as follows:

use hackdose_sml_parser::application::{
    domain::AnyValue, domain::SmlMessageEnvelope, obis::Obis, parser::parse_body,
};

pub fn find_total_power(body: &[u8]) -> Option<i32> {
    let result = parse_body(body);
    let result = result.ok()?;
    for list in result.messages {
        match list {
            SmlMessageEnvelope::GetOpenResponse(_) => continue,
            SmlMessageEnvelope::GetListResponse(body) => {
                let values = &body.value_list;
                let usage = values.iter().find(|value| {
                    value.object_name == Obis::SumActiveInstantaneousPower.obis_number()
                });

                if let Some(usage) = usage {
                    if let AnyValue::Signed(value) = usage.value {
                        return Some(value as i32);
                    }
                }
            }
            SmlMessageEnvelope::GetCloseResponse => continue,
        }
    }
    return None;
}

Acknowledgements

Most of the work inside the library is actually performed by Kevin Mehall's peg crate. I am also indebted to Stefan Weigert's great blog post about the SML protocol which enabled me to develop the grammar incrementally rather than reading the whole 80 page specification in the first place.

Contributions

Any contributions are highly appreciated. I published this library (which is part of the hackdose) to save everyone the work to implement yet another parser for this hard-to-read binary protocol and to focus on more interesting tasks.

License

This crate is dual-licensed under MIT and Apache 2 license at your choice.

Dependencies

~3–5MB
~83K SLoC