{"id":26012426,"url":"https://github.com/tudborg/exmbus","last_synced_at":"2026-03-04T20:31:55.834Z","repository":{"id":279840337,"uuid":"470564016","full_name":"tudborg/exmbus","owner":"tudborg","description":"Elixir M-Bus \u0026 Wireless M-Bus (wM-bus) parser library","archived":false,"fork":false,"pushed_at":"2025-11-11T09:02:46.000Z","size":542,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-11-11T10:21:13.729Z","etag":null,"topics":["elixir","mbus","oms","wmbus"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/exmbus","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tudborg.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-16T12:00:20.000Z","updated_at":"2025-11-11T09:02:49.000Z","dependencies_parsed_at":"2025-02-28T02:14:15.921Z","dependency_job_id":"4cb66a9f-abef-4cc5-b24f-ce0268a1041e","html_url":"https://github.com/tudborg/exmbus","commit_stats":null,"previous_names":["tudborg/exmbus"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/tudborg/exmbus","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tudborg%2Fexmbus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tudborg%2Fexmbus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tudborg%2Fexmbus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tudborg%2Fexmbus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tudborg","download_url":"https://codeload.github.com/tudborg/exmbus/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tudborg%2Fexmbus/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30091771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T19:41:02.502Z","status":"ssl_error","status_checked_at":"2026-03-04T19:40:05.550Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","mbus","oms","wmbus"],"created_at":"2025-03-06T00:30:53.925Z","updated_at":"2026-03-04T20:31:54.781Z","avatar_url":"https://github.com/tudborg.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Exmbus\n\n---\n\n[![Build Status](https://github.com/tudborg/exmbus/actions/workflows/elixir.yml/badge.svg?branch=main)](https://github.com/tudborg/exmbus/actions/workflows/elixir.yml)\n[![Hex.pm](https://img.shields.io/hexpm/v/exmbus.svg)](https://hex.pm/packages/exmbus)\n[![Documentation](https://img.shields.io/badge/documentation-gray)](https://hexdocs.pm/exmbus/)\n\n\nElixir M-Bus \u0026 Wireless M-Bus (wM-bus) parser library.\n\n## Installation\n\nThe package can be installed by adding `exmbus` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:exmbus, \"~\u003e 0.2.0\"}\n  ]\nend\n```\n\n## Features\n\n- M-bus\n- wM-bus\n- TPL Encryption modes: 0, 5\n- (partly) supports ELL (supports encryption modes: 0 (none), 1 (aes_128_ctr)\n- Compact Frames and Format Frames\n- Compact Profiles\n- VIF extension tables 0xFD and 0xFB (with a few exceptions)\n\n### Feature Requests\n\nIf you'd like a specific device supported, open an issue and attach or link to the datasheet for the device.  \nIf you can provide data from a real test device even better.\n\nNo effort will be made towards supporting a device without an example of a payload from the device (either from the datasheet or real world capture)\n\n\u003e [!IMPORTANT]  \n\u003e Under no circumstances should you publish data to the issue tracker or repository from a device that is actually deployed, as those might contain PII or other sensitive information.\n\u003e The same is true encryption keys where the key might potentially be used in more than once device.\n\n\n### Planned\n\n- [ ] Transition the parser fully to handler + context based, and avoid raising on error but instead attach an error to the context. The APL layer in particular needs a lot of work here.\n- [ ] Better API for encryption key storage.\n- [ ] DLL CRC support.\n- [ ] Split parsing and decoding into two steps. Currently the code parses the binary and decodes it in the same walk, but this causes errors when we can't decode an unsupported feature.\n\n### Not Planned\n\n- [ ] Authentication and Fragmentation layer CI=90\n\n\n## Performance\n\nIt's fine.\n\nYou can run the benchmarks under `benchmarks/` to get an idea of the performance on the relevant hardware.\n\nYou should test on frames that matches your deployment scenario, but if you just want a rough estimate,\nthere is a benchmark using an example frame from OMS Vol2 Annex N:\n\n```\nmix run benchmarks/oms_vol2_annex_n.exs\n```\n\nHere are the results we've gathered so far for the \"With input N.2.1. wM-Bus Meter with Security profile A\" bench\n\n\n| Hardware                  |        ips |       average | deviation |        median |        99th % |\n|---------------------------|------------|---------------|-----------|---------------|---------------|\n| Apple 12 core M3 Pro 36GB |   289.61 K |       3.45 μs |   ±63.73% |       3.13 μs |       7.21 μs |\n\n\n## Examples\n\n### Parse wM-Bus\n\nThis is an example from the OMS Vol2 Annex N - N.2.1. wM-Bus Meter with Security profile A\n\n`Exmbus.parse!` will return an `Exmbus.Parser.Context` struct as the result.\n\n```elixir\niex\u003e \"2E4493157856341233037A2A0020255923C95AAA26D1B2E7493B013EC4A6F6D3529B520EDFF0EA6DEFC99D6D69EBF3\"\n...\u003e |\u003e Base.decode16!()\n...\u003e |\u003e Exmbus.parse!(key: Base.decode16!(\"0102030405060708090A0B0C0D0E0F11\"))\n%Exmbus.Parser.Context{\n  bin: \"\",\n  opts: %{\n    length: false,\n    key: \u003c\u003c1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17\u003e\u003e,\n    crc: false\n  },\n  handlers: [],\n  handler: \u0026Exmbus.Parser.Apl.FullFrame.maybe_expand_compact_profiles/1,\n  dll: %Exmbus.Parser.Dll.Wmbus{\n    control: :snd_nr,\n    manufacturer: \"ELS\",\n    identification_no: 12345678,\n    version: 51,\n    device: :gas\n  },\n  ell: %Exmbus.Parser.Ell.None{},\n  tpl: %Exmbus.Parser.Tpl{\n    frame_type: :full_frame,\n    header: %Exmbus.Parser.Tpl.Header.Short{\n      access_no: 42,\n      status: %Exmbus.Parser.Tpl.Status{\n        manufacturer_status: 0,\n        temporary_error: false,\n        permanent_error: false,\n        low_power: false,\n        application_status: :no_error\n      },\n      configuration_field: %Exmbus.Parser.Tpl.ConfigurationField{\n        hop_count: 0,\n        repeater_access: 0,\n        content_of_message: 0,\n        mode: 5,\n        syncrony: true,\n        accessibility: false,\n        bidirectional: false,\n        blocks: 2\n      }\n    }\n  },\n  apl: %Exmbus.Parser.Apl.FullFrame{\n    records: [\n      %Exmbus.Parser.Apl.DataRecord{\n        header: %Exmbus.Parser.Apl.DataRecord.Header{\n          dib_bytes: \"\\f\",\n          vib_bytes: \u003c\u003c20\u003e\u003e,\n          dib: %Exmbus.Parser.Apl.DataRecord.DataInformationBlock{\n            device: 0,\n            tariff: 0,\n            storage: 0,\n            function_field: :instantaneous,\n            data_type: :bcd,\n            size: 32\n          },\n          vib: %Exmbus.Parser.Apl.DataRecord.ValueInformationBlock{\n            description: :volume,\n            multiplier: 0.01,\n            unit: \"m^3\",\n            extensions: [],\n            coding: nil,\n            table: :main\n          },\n          coding: :type_a\n        },\n        data: 2850427\n      },\n      %Exmbus.Parser.Apl.DataRecord{\n        header: %Exmbus.Parser.Apl.DataRecord.Header{\n          dib_bytes: \u003c\u003c4\u003e\u003e,\n          vib_bytes: \"m\",\n          dib: %Exmbus.Parser.Apl.DataRecord.DataInformationBlock{\n            device: 0,\n            tariff: 0,\n            storage: 0,\n            function_field: :instantaneous,\n            data_type: :int_or_bin,\n            size: 32\n          },\n          vib: %Exmbus.Parser.Apl.DataRecord.ValueInformationBlock{\n            description: :naive_datetime,\n            multiplier: nil,\n            unit: nil,\n            extensions: [],\n            coding: :type_f,\n            table: :main\n          },\n          coding: :type_f\n        },\n        data: ~N[2008-05-31 23:50:00]\n      },\n      %Exmbus.Parser.Apl.DataRecord{\n        header: %Exmbus.Parser.Apl.DataRecord.Header{\n          dib_bytes: \u003c\u003c2\u003e\u003e,\n          vib_bytes: \u003c\u003c253, 23\u003e\u003e,\n          dib: %Exmbus.Parser.Apl.DataRecord.DataInformationBlock{\n            device: 0,\n            tariff: 0,\n            storage: 0,\n            function_field: :instantaneous,\n            data_type: :int_or_bin,\n            size: 16\n          },\n          vib: %Exmbus.Parser.Apl.DataRecord.ValueInformationBlock{\n            description: :error_flags,\n            multiplier: nil,\n            unit: nil,\n            extensions: [],\n            coding: :type_d,\n            table: :fd\n          },\n          coding: :type_d\n        },\n        data: [false, false, false, false, false, false, false, false, false,\n         false, false, false, false, false, false, false]\n      }\n    ],\n    manufacturer_bytes: \"\"\n  },\n  dib: nil,\n  vib: nil,\n  errors: [],\n  warnings: []\n}\n```\n\n\n## Testing\n\n`mix test`\n\n## Profiling\n\nSome profiling scripts are available under `profiling/`.\n\nYou can run then with e.g. eprof:\n\n```sh\n mix profile.eprof profiling/oms_vol2_annex_n.exs\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftudborg%2Fexmbus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftudborg%2Fexmbus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftudborg%2Fexmbus/lists"}