wMbus Parser

The Lobaro wMbus Parser is used from device Parsers and available as web API at https://platform.lobaro.com/#/wmbus/parser

wMbus API

Response (Lobaro wMbus JSON)

The following is an example of the parsing result of an encrypted example telegram from the OMS specification:

  "Raw": "0x2e4493157856341233037a2a0020055923c95aaa26d1b2e7493b013ec4a6f6d3529b520edff0ea6defc99d6d69ebf3",
  "RawWithCrc": "0x2e44931578563412330333637a2a0020055923c95aaa26d1b2e7493b2a8b013ec4a6f6d3529b520edff0ea6defc955b29d6d69ebf3ec8a",
  "FrameFormat": "A",
  "Length": 46,
  "CField": "0x44",
  "CFieldString": "0x44 (SND_NR)",
  "MField": "0x9315",
  "MFieldCodeString": "ELS",
  "MFieldLongString": "Elster GmbH, Germany, Europe",
  "Id": 305419896,
  "IdString": "12345678",
  "Version": 51,
  "Device": "0x03",
  "DeviceString": "Gas",
  "CiField": "0x7a",
  "HeaderKnown": true,
  "PayloadKnown": true,
  "Header": {
    "Serial": 0,
    "IdString": "",
    "ManufacturerCode": 0,
    "MFieldCodeString": "",
    "MFieldLongString": "",
    "Version": 0,
    "DeviceType": 0,
    "DeviceString": "",
    "EncryptionMode": 5,
    "EncryptionModeString": "AES with CBC",
    "EncryptedBlocks": 2,
    "HopCount": 0,
    "IsAccessible": true,
    "IsBidirectionalMode": false,
    "IsSynchronous": false,
    "ReservedBit": false,
    "TelegramType": 0,
    "AccessNumber": 42,
    "StatusByte": 0,
    "ConfigField": [
  "Body": {
    "Raw": "0x2f2f0c1427048502046d32371f1502fd1700002f2f2f2f2f2f2f2f2f2f2f2f2f",
    "DataRecords": [
        "DifDataLength": 4,
        "DifFunctionString": "Current Value",
        "DifDataFormat": "BCD (8 digits)",
        "VifUnit": "m^3",
        "VifQuantity": "Volume",
        "VifExponent": 0.01,
        "VifEDescription": "",
        "Value": 2850427,
        "ValueScaled": 28504.27,
        "ValueString": "28504.27",
        "Tariff": 0,
        "StorageNo": 0,
        "DifVif": "0x0c14",
        "Data": "0x27048502",
        "Dif": {
          "Value": 12,
          "DifE": []
        "Vif": {
          "IsPresent": true,
          "Value": 20,
          "VifE": []
        "DifDataLength": 4,
        "DifFunctionString": "Current Value",
        "DifDataFormat": "signed binary (32 bits), or date/time in F format",
        "VifUnit": "",
        "VifQuantity": "Time & Date",
        "VifExponent": 1,
        "VifEDescription": "",
        "Value": 354367282,
        "ValueScaled": 354367282,
        "ValueString": "2008-05-31T23:50:00Z",
        "Tariff": 0,
        "StorageNo": 0,
        "DifVif": "0x046d",
        "Data": "0x32371f15",
        "Dif": {
          "Value": 4,
          "DifE": []
        "Vif": {
          "IsPresent": true,
          "Value": 109,
          "VifE": []
        "DifDataLength": 2,
        "DifFunctionString": "Current Value",
        "DifDataFormat": "signed binary (16 bits), or date in G format",
        "VifUnit": "",
        "VifQuantity": "Error flags",
        "VifExponent": 1,
        "VifEDescription": "",
        "Value": 0,
        "ValueScaled": 0,
        "ValueString": "0",
        "Tariff": 0,
        "StorageNo": 0,
        "DifVif": "0x02fd17",
        "Data": "0x0000",
        "Dif": {
          "Value": 2,
          "DifE": []
        "Vif": {
          "IsPresent": true,
          "Value": 253,
          "VifE": [
    "PayloadKnown": true,
    "IsEncrypted": false,
    "DecryptionFailed": false,
    "BlockCiField": 0
  "AField": {
    "Id": 305419896,
    "Version": 51,
    "Device": 3
  "Ell": null,
  "Afl": null,
  "BodyParseError": "",
  "CrcValid": true,
  "HasCrc": true,
  "SourceType": "",
  "IsCompactFrame": false,
  "FormatSignature": 61330,
  "FormatFrame": "DBQEbQL9Fw=="

Important fields



true if the parsed telegram is still encrypted

true if the parser tied to decrypt the telegram without success.

Can be used in conjunction with IsEncrypted to detect if the telegram was encrypted (see below).

PayloadKnownIf the payload of the telegram (related to the CI field) is known to the parser and can be parsed
BodyParseErrorError while parsing the payload body
FormatSignatureUnique signature of the DifVif structure of all DataRecords. If any DifVif changes, the FormatSignature does change as well.

Encryption state

truetrueNo valid key
falsefalseTelegram not encrypted
truefalseTelegram is encrypted but parser can not decrypt it (e.g. unknown algorithm)
falsetruePlain telegram where decryption failed - should not happen

VifUnit & VifQuantity

There are a many valid combinations of VifUnit & VifQuantity. All possible values are listed below.

Lines without VifUnit have an empty string as Unit.

VifQuantity: (Enhanced) Identification
VifQuantity: Access Code Developer
VifQuantity: Access Code Operator
VifQuantity: Access Code System Operator
VifQuantity: Access Code User
VifQuantity: Access Number
VifQuantity: Any VIF
VifQuantity: Bus Address
VifQuantity: Control signal
VifQuantity: Cumulation counter
VifQuantity: Customer
VifQuantity: Customer location
VifQuantity: Data container for wMBus
VifQuantity: Datacontainer for manufactuerer specific protocol
VifQuantity: Date
VifQuantity: Date and time of battery change
VifQuantity: Day of week
VifQuantity: Device type
VifQuantity: Digital Input
VifQuantity: Digital Output
VifQuantity: Dimensionless
VifQuantity: Error flags
VifQuantity: Error mask
VifQuantity: Fabrication No
VifQuantity: Firmware version
VifQuantity: First storage # for cyclic storage
VifQuantity: Hardware version
VifQuantity: Last storage # for cyclic storage
VifQuantity: Manufacturer
VifQuantity: Manufacturer specific
VifQuantity: Manufacturer specific data
VifQuantity: Number of counter stops
VifQuantity: Parameter set identification
VifQuantity: Password
VifQuantity: Receive window management
VifQuantity: Remote control
VifQuantity: Reset counter
VifQuantity: Retry
VifQuantity: Security key
VifQuantity: Size of storage block
VifQuantity: Software version
VifQuantity: Special supplier information
VifQuantity: State of parameter activation
VifQuantity: Summertime (begin, end, deviation
VifQuantity: Time & Date
VifQuantity: Time point of day change
VifQuantity: Week number
VifUnit: A, VifQuantity: Current
VifUnit: American gallon, VifQuantity: Volume
VifUnit: American gallon/h, VifQuantity: Volume flow
VifUnit: American gallon/min, VifQuantity: Volume flow
VifUnit: Baud, VifQuantity: Baudrate
VifUnit: Bittimes, VifQuantity: Response delay time
VifUnit: Currency units, VifQuantity: Credit
VifUnit: Currency units, VifQuantity: Debit
VifUnit: GJ, VifQuantity: Energy
VifUnit: Hz, VifQuantity: Frequency
VifUnit: J, VifQuantity: Energy
VifUnit: J, VifQuantity: Power
VifUnit: J/h, VifQuantity: Power
VifUnit: K, VifQuantity: Temperature difference
VifUnit: MCal, VifQuantity: Energy
VifUnit: Relative humidity, VifQuantity: %
VifUnit: Reserved, VifQuantity: Reserved
VifUnit: Units for H.C.A., VifQuantity: H.C.A.
VifUnit: V, VifQuantity: Voltage
VifUnit: W, VifQuantity: Cumul count max power
VifUnit: W, VifQuantity: Power
VifUnit: Wh, VifQuantity: Energy
VifUnit: bar, VifQuantity: Pressure
VifUnit: d, VifQuantity: Remaining battery
VifUnit: dBm, VifQuantity: Receiver sensitivity
VifUnit: feet^3, VifQuantity: Volume
VifUnit: kVA, VifQuantity: Apparent power
VifUnit: kVA/h, VifQuantity: Apparent energy
VifUnit: kVAR, VifQuantity: Reactive power
VifUnit: kVAR/h, VifQuantity: Reactive energy
VifUnit: kg, VifQuantity: Mass
VifUnit: kg/h, VifQuantity: Mass flow
VifUnit: m^3, VifQuantity: Volume
VifUnit: m^3/h, VifQuantity: Volume flow
VifUnit: m^3/min, VifQuantity: Volume flow
VifUnit: m^3/s, VifQuantity: Volume flow
VifUnit: s, VifQuantity: Averaging Duration
VifUnit: s, VifQuantity: Duration since last cumulation
VifUnit: s, VifQuantity: Duration since last readout
VifUnit: s, VifQuantity: Interval of data transmission
VifUnit: s, VifQuantity: On time
VifUnit: s, VifQuantity: Operating time
VifUnit: s, VifQuantity: Operating time battery
VifUnit: s, VifQuantity: Period of tariff
VifUnit: s, VifQuantity: Point in Time
VifUnit: s, VifQuantity: Storage interval
VifUnit: °, VifQuantity: Phase U-U
VifUnit: °, VifQuantity: Phase U-l
VifUnit: °C, VifQuantity: Cold / Warm Temperature Limit
VifUnit: °C, VifQuantity: External temperature
VifUnit: °C, VifQuantity: Flow temperature
VifUnit: °C, VifQuantity: Return temperature
VifUnit: °F, VifQuantity: Cold / Warm Temperature Limit
VifUnit: °F, VifQuantity: External temperature
VifUnit: °F, VifQuantity: Flow temperature
VifUnit: °F, VifQuantity: Return temperature
VifUnit: °F, VifQuantity: Temperature difference

Domain Model Mapping Extention

When Using wMbus/OMS Telegrams there is a Problem: The Telegrams are self describing in a way that they describe values as "this is a Volume in m³" "this is a Date with Time" but they dont include the information about the businesses meaning if the value.

For example in the following "heat cost" device we got several H.C.A Values and 3 Date informations:

When we want to create a heating bill for tenants we need to know the meaning because we want to use a Due Date and the Value for that due Date or we want to use the actual H.C.A Value with the it is from.
The problem here is: The order and meaning of these Values differ widely. Sometimes the actual Value is the first one, sometimes the last one, Sometimes Due Date values of the last 12 months are presented in  descending order sometimes in ascending order. Sometimes the date information regarding due dates are grouped next to the duedate values some times values and date information are kept in 2 blocks. So we want to archive a a way to configure the logical meaning for different devices so we can produce a general usable format containing the meter data usable by billing software.

Mapping Configuration

Configures how telegrams are mapped to the Domain Model.

Example Configuration for Kampstrup MC603, a Diehl Heat Meters and a Engelman Water Meter

		"comment":"Kampstrup MC603",
			"flowTemperatureIdx": 5,
			"returnTemperatureIdx": 6,
			"volumeIdx": 3
		"comment":"Diehl Heat Meter",
		"comment":"Engelmann Water Meter",

The Mapping contains 3 Parts:

  • A comment so humans can identify the mappings.
  • A filter part to select telegrams that the mapping shall be applied to. The mapping is applied if all filters match true.
  • A object "heat" or "water" defining which values of the telegram shall be mapped in to which Field of a Domain Model output.

API Endpoint

  • curl Example: (With mapping from: domainMappings.json File)
  • Method: POST
  • Path: /api/meterData
  • URL Params:
    • raw: Raw OMS/WMBUS Telegram in Hex: e.g. 44442d2c0198508035048d20aac070c420dd3d967a564c53dfe4dedfbc45e8d41912db6c0973921bef3c2d5dc8d3b6fe01cc272258cd728f825a2d2e76b256fd722680
    • key: decryption key as Hex String e.g. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  • Body: Type: application/json with a Mapping Configuration as described on this Page.
  • Response: With Domain Data described under "Metering Domain Model" on this Page.
  • Headers

Endpoint: POST https://platform.lobaro.com/api/meterData

curl -X 'POST' \  'https://platform.lobaro.com/api/meterData?raw=44442d2c0198508035048d20aac070c420dd3d967a564c53dfe4dedfbc45e8d41912db6c0973921bef3c2d5dc8d3b6fe01cc272258cd728f825a2d2e76b256fd722680&key=7ADA08C8C89C7D21EAEE6F662BF0A6ED' \
-H 'accept: \ application/json' -H 'Authorization: Bearer eyJh[...]' -H "Content-Type: application/json" -d @domainMappings.json 

Metering Domain Model

Example output of a Kampstrup MC603 with the example Configuration from Mapping Configuration

  "id": "KAM80509801532022-01-24T14:55:50+01:00",
  "type": "HeatMeterReading",
  "meterId": "80509801",
  "linkLayerId": "80509801",
  "meterType": 4,
  "manufacturer": "KAM",
  "manufacturerLinkLayer": "KAM",
  "version": 53,
  "versionLinkLayer": 0,
  "currentValue": {
    "date": "2022-01-24T14:55:50.171063+01:00",
    "value": 0,
    "unit": "Wh"
  "flowTemperature": {
    "date": "2022-01-24T14:55:50.171063+01:00",
    "value": 24.08,
    "unit": "°C"
  "returnTemperature": {
    "date": "2022-01-24T14:55:50.171063+01:00",
    "value": 23.96,
    "unit": "°C"
  "volume": {
    "date": "2022-01-24T14:55:50.171063+01:00",
    "value": 0,
    "unit": "m^3"