Skip to main content

Metering protocols: DLMS/COSEM, OBIS, Modbus, MQTT (and NFE CHINT register map)

Traceable explainer: how metering data actually moves, where DLMS/COSEM, OBIS, Modbus, MQTT and HTTP each sit, and how NFE's live CHINT registers map to the OBIS standard vocabulary. Compiled 2026-08-10. Companion to "NFE metering strategy + Glen Street-EMS".

The layer cake (mental model)

Networking is layers. Each solves one problem and talks only to the layer above and below.

Layer Job Examples
Link move bits over one physical medium RS485, Ethernet, WiFi
Network (IP) address and route between any machines IP
Transport (TCP) reliable, ordered byte-stream between two programs TCP, UDP
Application what the two programs actually say HTTP, MQTT, Modbus, DLMS

Key point: MQTT, HTTPS and DLMS/COSEM are all application-layer. MQTT and HTTPS run on top of TCP (transport) on top of IP (network). MQTT is NOT a transport or network protocol.

One clean way to hold it all: IP gets you to the right building. TCP is registered mail that guarantees the whole message. Modbus/DLMS is the local interview with one meter (DLMS adds a shared vocabulary and an ID badge). OBIS/COSEM/SunSpec is that shared vocabulary. MQTT is the courier network carrying notes across the village and orders back. HTTP is a different courier that only does "go fetch one thing and return".

  • MQTT: application, over TCP, port 1883 (8883 with TLS)
  • HTTPS: HTTP + TLS over TCP, port 443
  • DLMS/COSEM: application; rides serial (HDLC) OR TCP/IP directly
  • Modbus RTU (NFE's meter to Pi link): application, straight over RS485 serial, no IP at all (why it is the simplest thing on site)

Three separate jobs, often confused

  • Vocabulary (what a value means): OBIS / COSEM for meters, SunSpec for inverters.
  • Local interrogation (talk to one device): Modbus or DLMS.
  • Messaging (move data between many nodes, up and down): MQTT or HTTP.

You put COSEM-modelled data inside an MQTT message. They are not competitors: MQTT is the envelope, COSEM is the language on the page.

MQTT vs HTTPS

  • HTTPS is request/response, pull: client asks, server answers, one round trip. The server cannot easily push to a device.
  • MQTT is publish/subscribe through a broker, push: a device holds one persistent TCP socket to a broker and publishes to a topic; subscribers get pushed the message instantly. Tiny 2-byte header, QoS levels, retained last value, last-will (detect a dead node), pushes both ways (telemetry up, commands down), survives flaky low-bandwidth links.
  • The Street-EMS village dashboard uses MQTT: it pushes "TURN OFF SSR0" down to a specific cabinet on topic openami/StreetPoleEMS_<id>/cmd while readings stream up.

MQTT over the internet? Yes, it is just TCP. Devices make an outbound connection to a broker, so no inbound port-forwarding through the site modem, ideal for field gear on cellular.

Why not DLMS/COSEM over HTTPS? It buys nothing: DLMS already has its own TCP transport and its own message-level crypto (AES-128-GCM). And DLMS is a point-to-point session with one meter, not a fan-in/out telemetry bus. So the natural split is DLMS or Modbus to talk to the meter locally, MQTT to move the results around.

DLMS/COSEM, unpacked

  • COSEM (Companion Specification for Energy Metering) is the data model: every value is an object of an interface class (Register, Profile Generic for load profiles, Clock, Disconnect Control for the relay, etc.).
  • OBIS (OBject Identification System) names each object with a six-group code A-B:C.D.E.F. Example: 1-0:1.8.0 = total active energy imported (what you bill).
  • DLMS (Device Language Message Specification) is the protocol: GET an attribute, SET an attribute, ACTION a method, inside an authenticated, encrypted association.
  • Standardised as IEC 62056. Certified by the DLMS User Association.

The distinction: Modbus register vs COSEM "register"

A meter does NOT contain Modbus registers and COSEM registers side by side. They are two alternative languages for the same physical measurements. A given meter speaks one (or, on high-end dual-interface meters, both via separate ports).

  • Modbus register = a numbered 16-bit memory slot at an address (e.g. 0x2004). Dumb storage. It is meaningless without the vendor manual telling you "0x2004 is active power". The meaning lives in a PDF, not in the data.
  • COSEM Register (object) = a self-describing object that carries its own unit and scaler, addressed by a global OBIS code that means the same thing on every compliant meter. (COSEM has an interface class literally named "Register", class_id 3 - hence the word collision. It is an object, not a memory slot.)

NFE's CHINT DDSU666 / DTSU666 are Modbus-only meters: inside them there are only Modbus registers, no COSEM, no OBIS. The OBIS column below is a translation NFE applies in software (in the logger / EMS / OpenAMI layer); the meter itself never knows about OBIS. The value of doing it: the meaning stops living in the CHINT manual and becomes the industry-standard, self-describing vocabulary.

NFE CHINT register to OBIS map

Single-phase DDSU666 (tenant meters, one phase). Source: nfe-modbus-energy-logger/src/meter_reader.py and the OpenEMS Meter.Chint.DDSU666 driver.

Quantity Modbus register (float) OBIS code Meaning
Voltage 0x2000 1-0:32.7.0 Instantaneous voltage L1
Current 0x2002 1-0:31.7.0 Instantaneous current L1
Active power 0x2004 1-0:1.7.0 Instantaneous active power (import +)
Power factor 0x200A 1-0:13.7.0 Power factor
Frequency 0x200E 1-0:14.7.0 Frequency
Import energy 0x4000 1-0:1.8.0 Total active energy imported (billing)
Export energy (invert cfg) 0x4000 1-0:2.8.0 Total active energy exported

Three-phase DTSU666 (aggregate meter_100):

Quantity Modbus register(s) (float) OBIS code(s) Meaning
Voltage L1/L2/L3 0x2006 (x3) 32.7.0 / 52.7.0 / 72.7.0 Instantaneous phase voltages
Current L1/L2/L3 0x200C (x3) 31.7.0 / 51.7.0 / 71.7.0 Instantaneous phase currents
Active power total + L1/L2/L3 0x2012 (x4) 1.7.0 / 21.7.0 / 41.7.0 / 61.7.0 Instantaneous active power
Power factor 0x202A 13.7.0 Power factor total
Frequency 0x2044 14.7.0 Frequency
Import energy 0x4000 1-0:1.8.0 Total active energy imported

Note: the DDSU666 driver reads active power as already scaled kW; the DTSU666 needs per-manual scaling (Table 11: V/10, I x0.001, P x0.0001, PF x0.001, F x0.01). Minor code note: the logger's DTSU REGISTERS dict lists PF at 0x2020 but read() polls 0x202A; 0x202A is the one in use.

Why two OpenEMS drivers (meter and inverter)

Two physical devices with different proprietary Modbus maps means two drivers:

  • CHINT meter (MeterChintDdsu666Impl) reads 0x2000+; implements the ElectricityMeter Nature.
  • SRNE inverter (SrneEssImpl) reads a totally different map at 0x0100 (SoC), 0x0101 (voltage), 0x0102 (current); implements the SymmetricEss / HybridEss Natures.

OpenEMS "Natures" (ElectricityMeter, SymmetricEss) are abstract interfaces both drivers map into, so the rest of OpenEMS sees a uniform API regardless of vendor. That is the local equivalent of what OBIS/COSEM and SunSpec do industry-wide.

The real prize of the standards is not one driver for meter plus inverter. It is one driver per device TYPE that works across every compliant vendor: any DLMS meter uses the same meter driver, any SunSpec inverter the same inverter driver. That removes the per-vendor Modbus-map work NFE did for both the CHINT and the SRNE. OpenEMS Natures give that uniformity on the edge (after the driver); DLMS and SunSpec give it at the wire (removing the driver work).

OBIS vs profiles (IDIS / OpenAMI): naming is not interoperability

OBIS names things, it does not force a meter to implement or behave the same way. DLMS/COSEM is a large, flexible toolkit and leaves most choices to the manufacturer: which OBIS objects are actually present, which data types and scalers, which security suite, which communication profile, which optional events. So two meters can both be DLMS/COSEM compliant and both use OBIS and still not interoperate out of the box. Compliant is not the same as interoperable.

IDIS (Interoperable Device Interface Specifications) is an industry association profile that sits on top of DLMS/COSEM/OBIS and removes the optionality: it mandates exactly which OBIS objects must be present and how they behave, the data types, security and events, a fixed communication profile, and an interoperability certification (conformance plus multi-vendor testing). Packages by transport: Package 1 (basic, local/optical + core residential objects), Package 2 (power-line comms PRIME/G3 + data concentrators), Package 3 (cellular/IP). Any two IDIS-certified devices genuinely interchange.

Mental model: DLMS/COSEM is the grammar and a giant dictionary with optional dialects; OBIS gives every word one fixed meaning; IDIS is a mandated phrasebook plus accent everyone certifies to, so a whole conversation is portable, not just the words.

Why it matters here: even if two meters both spoke OBIS, if they exposed different object sets over different links you would still write per-vendor glue (the same thing that produced two OpenEMS drivers). A profile is what makes "buy any certified meter, one driver, plug and play" real. IDIS is the heavyweight, utility-grade version of exactly what OpenAMI aims to be for off-grid villages: a mandated, open, lightweight village-metering profile on top of the vocabulary. NFE does not need full IDIS, but it does need a profile, and that is OpenAMI's whole purpose.

How OpenAMI sits on top

OpenAMI (IEEE Smart Village) is the actionable, utility-facing telemetry layer above a village feeder. It does not reinvent meter semantics: it composes OBIS/DLMS/COSEM (meters), SunSpec (inverters/DER), MQTT (transport), IEEE 2030.5 and 1547 (DER control). Its value-add is two-way, village-edge, policy-driven control and a billing cache, run cloudlessly and cheaply.

Sources

Element room "Smart Village Energy Interest Group"; isv.wiki; nfe-modbus-energy-logger/src/meter_reader.py; OpenEMS drivers io.openems.edge.meter.chint.ddsu666 and io.openems.edge.ess.srne; IEC 62056 (DLMS/COSEM); DLMS User Association Blue Book (OBIS).