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.

  • 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).

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).