· OMS· EN 13757· wM-Bus· telegram· protokol· HCA· fabrikant-ID· DIB· VIB· parsing
OMS standard EN 13757 — wM-Bus telegram-format fra bund til top
OMS (Open Metering System) og EN 13757: Layer-model, telegram-header, DIB/VIB datastruktur, fabrikant-ID, medietypes og praktisk byte-for-byte parsing.
Af M-Bus Gateway
OMS (Open Metering System) er den åbne standard bag alle interoperable wM-Bus-målere. Her er telegram-formatet fra bund til top.
OMS og EN 13757: Relationen
EN 13757 (CENELEC standard):
EN 13757-2: Fysisk lag og datalink-lag (M-Bus wired)
EN 13757-3: Applikationslag (data-struktur, DIB/VIB)
EN 13757-4: Trådløs M-Bus (wM-Bus) — radio-lag
EN 13757-5: Kryptografi (AES-128)
EN 13757-7: Transport og nætværkslag
OMS (Open Metering System):
→ Industriens profildokument oven på EN 13757
→ Specificerer hvilke EN-13757-3 VIF/VIFE der bruges pr. måletype
→ Definerer krypteringskrav pr. mode (Mode 5 = AES-128 CTR)
→ OMS-Volume 2: Profiler for HCA, varmemåler, vandmåler, gasmåler
→ Overholdelse = interoperabilitet (enhver OMS-gateway kan læse enhver OMS-måler)
Telegram-struktur: Byte-for-byte
Komplet wM-Bus C1/T1 telegram (hex):
27 44 93 15 78 56 34 12 03 07 8C 20 77 AB 1C 3E 22 ...
Offset Bytes Felt Forklaring
────── ───── ──────────────── ──────────────────────────────────────
0 01 L (Length) 27h = 39 bytes total telegram-længde
1 01 C (C-field) 44h = SND-NR (Send No Reply, T1/C1)
2 02 M (Manufacturer) 9315h = "ELS" (Engelmann)
4 04 A (Address) 78563412h = Serienummer (LSB first) = 12345678
8 01 Ver (Version) 03h = firmwareversion
9 01 Type (Media) 07h = vandmåler (07=vand, 04=varme, 08=HCA)
10 02 CI (Control Info) 8C20h = Long Transport Layer header
12 rest Payload Krypteret eller klar tekst data
Medietypes (EN 13757-4, tabel 5):
01 = Elektricitet
03 = Gas
04 = Varmemåler
06 = Vandvarmer
07 = Vand (koldtvandsmåler)
08 = HCA (Heat Cost Allocator)
0A = Køling
0B = Kombination: køle + varme
0C = Varmt brugsvand
16 = El (alternativ)
Fabrikant-ID: M-felt dekodning
def decode_manufacturer_id(m_bytes: bytes) -> str:
"""
Dekod 2-byte fabrikant-ID til 3-bogstavers kode.
EN 13757-4 § 6.4.3
Encoding: 5-bit per bogstav, packed i 16 bit (little-endian)
A=1, B=2, ..., Z=26 (kun store bogstaver)
Eksempler:
ELS = Engelmann: 9315h
KAM = Kamstrup: 2C2Dh
TCH = Techem: 6850h
DIE = Diehl: A324h
ZRI = Zenner: F732h
"""
m_val = int.from_bytes(m_bytes, "little")
# Bit 15-11: bogstav 1, 10-6: bogstav 2, 5-1: bogstav 3
c1 = chr(((m_val >> 10) & 0x1F) + 64)
c2 = chr(((m_val >> 5) & 0x1F) + 64)
c3 = chr((m_val & 0x1F) + 64)
return f"{c1}{c2}{c3}"
# Test:
assert decode_manufacturer_id(bytes.fromhex("9315")) == "ELS"
assert decode_manufacturer_id(bytes.fromhex("2C2D")) == "KAM"
assert decode_manufacturer_id(bytes.fromhex("6850")) == "TCH"
DIB/VIB: Applikationslag-datastruktur
DIB (Data Information Block) + VIB (Value Information Block):
→ Hvert datapunkt i payload er en DIB+VIB+data tripel
→ Kan gentages N gange (mange datapunkter pr. telegram)
DIB-byte (Data Information Block):
Bit 7-6: DIF Extension (00=normal, 01=special)
Bit 5-4: Function Field (00=Instantaneous, 01=Maximum, 10=Minimum, 11=Error)
Bit 3-0: Data Field (0000=None, 0001=8bit, 0010=16bit, 0100=32bit, 0110=48bit, 1100=date, 1101=string)
VIB-byte (Value Information Block):
Bit 7: VIF Extension (0=tabel A, 1=tabel B eller VIFE)
Bit 6-0: VIF-kode
Vigtige VIF-koder (EN 13757-3, tabel A):
00h-07h: Energi (kWh, MWh)
10h-17h: Volumen (m³, l)
40h-43h: Temperatur (°C)
20h-27h: On Time / Operating Time
6Dh: Dato + tid (6-byte)
78h: Fabrikantspecifik
79h: OBIS-kode reference
Eksempel: Energidata (32-bit, kWh):
04 → DIB: 32-bit integer, instantaneous
04 → VIB: Energi, enhed: 1 × 10^(0-3) Wh = 0.001 kWh
B0 36 00 00 → Data: 0x000036B0 = 14.000 = 14.000 × 0.001 kWh = 14 kWh
Kryptografi: OMS Mode 5
# OMS kryptering Mode 5 = AES-128 CTR (Counter Mode)
# Nøgle: 16 bytes AES-nøgle (leveret af fabrikant ved installation)
# IV: Bygget fra telegram-header-felter
from Crypto.Cipher import AES
def decrypt_oms_mode5(
ciphertext: bytes,
aes_key: bytes,
manufacturer_id: bytes, # 2 bytes M-felt
address: bytes, # 4 bytes A-felt (serienummer)
version: int, # 1 byte Ver
media_type: int, # 1 byte Type
) -> bytes:
"""
Dekryptér OMS Mode 5 (AES-128 CTR).
IV = M(2) + A(4) + Ver(1) + Type(1) + 08*(8)
"""
iv = manufacturer_id + address + bytes([version, media_type]) + b"\x08" * 8
cipher = AES.new(aes_key, AES.MODE_CTR, nonce=b"", initial_value=iv)
return cipher.decrypt(ciphertext)
# wmbusmeters håndterer dette automatisk ved key-konfiguration:
# key = AES-nøgle i hex pr. meter (fra fabrikant)
OMS-profil: HCA (Heat Cost Allocator)
OMS Volume 2, Profil HCA:
Krævet data:
- Aktuelt HCA-tal (DIB=04, VIB=6E) — units
- Forrige HCA-tal (DIB=44, VIB=6E, Function=01) — units
- Forrige periode start (dato)
- Aktuelt dato/tid
- Serienummer radiator (fabrikantspecifik)
Valgfrit:
- RSSI (modtagefeltsvurdering)
- Batteriniveau
- Fejlkoder (defekt, fjernet, sabotage-alarm)
Typisk OMS HCA telegram (wmbusmeters JSON output):
{
"media": "heat_cost_allocator",
"meter": "sensostar",
"name": "Lej1Radiator",
"id": "66073591",
"current_hca": 312, ← Aktuelt tal (DIB=04, VIB=6E)
"previous_hca": 285, ← 1. jan foregående år
"set_date": "2025-01-01", ← Periodestart
"rssi_dbm": -72,
"battery_ok": true,
}
Konklusion
OMS/EN 13757 definerer en åben, interoperabel standard for forbrugsmålere. Telegram-strukturen er hierarkisk: fysisk lag (868MHz) → datalink (CRC) → transport (header med M/A/Ver/Type) → applikation (DIB/VIB datapar). Fabrikant-ID dekodes fra 2 bytes til 3-bogstavers kode. AES-128 CTR Mode 5 krypterer payload med IV bygget fra header-felter.
Se wM-Bus telegram parsing guide eller AES-128 CTR dekryptering guide.