Open Charging Technology · Whitepapers

Metrological CBOR (Tag 44252)

Status: Stable. This document is the normative specification of CBOR tag 44252 and serves as the semantics reference of its IANA registration.

Version: 1.0 (2026-08-18)

The numeric identifications of Section 4 became permanent with the IANA registration of tag 44252, recorded on 2026-08-19. Changing one of them is from now on a change to a registered format rather than an editorial matter.

Point of contact: Achim Friedland <achim.friedland@graphdefined.com>, GraphDefined GmbH

Implementations:

Worked example: tag-44252-signed-example.md carries two metrological values through three signature layers of a charging transaction, byte by byte.

Text format and JSON: metrological-text.md specifies the one-string text form of a metrological value and the document-level conversion between CBOR and JSON built on it.

Test vectors: test-vectors/ is the machine-readable conformance annex — golden encodings, must-reject inputs, text renderings and the JSON conversion — exercised continuously against both reference implementations by the cross-implementation conformance suite.

1. Introduction

The Concise Binary Object Representation (CBOR, [RFC 8949]) has no standardized tag for readings of physical quantities. Encoding such readings as plain numbers loses three properties that matter in metrology, and especially in legal metrology (calibration law):

  1. The unit of measure. A bare 230 is meaningless without "volt".
  2. The exact decimal representation as displayed by the instrument. A reading of 1.10 kWh carries more information than 1.1 kWh: the trailing zero states the resolution of the measurement. Binary floating-point numbers can represent neither the value 0.1 exactly nor a decimal scale at all.
  3. The measurement uncertainty. A value without a statement of uncertainty is, strictly speaking, not a measurement result.

Tag 44252 addresses all three while remaining readable by generic CBOR decoders: without knowledge of the tag, a decoder still sees a well-formed array of standard CBOR numbers.

2. Notation

The data structure is described in CDDL ([RFC 8610]). Byte sequences are written as uppercase hexadecimal.

3. The tag

metrological-value = #6.44252([
    value         : number,          ; the reading
    unit          : unit-ref,        ; named unit or product of powers
    ? prefix      : int,             ; SI prefix as a power of ten
    ? uncertainty : number / uncertainty-map
])

number      = int / bignum / decfrac
bignum      = #6.2(bstr) / #6.3(bstr)                        ; RFC 8949, Section 3.4.3
decfrac     = #6.4([exponent: int, mantissa: int / bignum])  ; RFC 8949, Section 3.4.4

unit-ref    = named-unit / [+ unit-factor]
named-unit  = uint / tstr                                    ; registry id or unit symbol
unit-factor = [named-unit, exponent]
exponent    = int / [numerator: int, denominator: uint]      ; rational, e.g. [-1, 2] for √

uncertainty-map = {
    1 => number,      ; magnitude, as reported
  ? 2 => number,      ; coverage factor k (default 1)
  ? 3 => number,      ; coverage probability, ]0, 1]
  ? 4 => uint,        ; probability distribution
  ? 5 => number       ; effective degrees of freedom
}

The tag content MUST be an array of two, three or four data items. Any other length is an error.

3.1 value

The reading of the physical quantity, scaled by prefix and expressed in unit. It MUST be either

It MUST NOT be a binary floating-point number, and it MUST NOT be a bigfloat (tag 5). An integer that major type 0 or 1 can carry MUST NOT be written as a bignum — this is the preferred serialization of [RFC 8949], Section 3.4.3, and it keeps the encoding deterministic.

The exponent of a decimal fraction MUST be negative: a decimal fraction states decimal places, and an integral reading is written as an integer (or bignum). This gives every reading exactly one encoding — 500 has no second spelling as 4([0, 500]) or 4([2, 5]) — and text input in scientific notation whose exponent leaves no decimal places (5e2, 5.0e2) denotes the integer it equals. A resolution coarser than one is not something this format states; a producer that needs it states an uncertainty.

The decimal scale is significant: 4([-1, 50]) (= 5.0) and 5 denote the same numeric quantity but different measurement resolutions, and both MUST survive a decode/encode roundtrip unchanged.

3.2 unit

A named unit is either an unsigned integer identifying a unit of measure in the registry of Section 4, or a text string holding its symbol (or one of the aliases listed there). Encoders SHOULD use the numeric identification; decoders MUST accept both forms. A numeric identification greater than 65535, an unregistered identification and an unknown symbol are errors.

A product of powers is an array of [named-unit, exponent] factors, in the order they are to be displayed. It expresses every derived quantity that is not in the registry: m·s⁻² is [[15, 1], [8, -2]], and W·m⁻²·K⁻¹ is [[3, 1], [15, -2], [17, -1]].

The exponent is an integer, or a [numerator, denominator] pair for a rational power, and it MUST NOT be zero. A rational exponent MUST be in lowest terms and its denominator MUST be greater than one: [-2, 4] and [2, 1] are not valid spellings of [-1, 2] and 2, and decoders MUST reject them rather than reduce them — a reading has one encoding, and a signed document must not change its bytes on the way through a decoder. Rational powers are not decoration: an amplitude spectral density is stated per √Hz (V·Hz^-1/2), fracture toughness in Pa·m^1/2 and the Warburg impedance in Ω·s^-1/2.

A single named unit MUST be written in the named form, never as a one-element array with exponent one — the compact form is the one that stays cheap on the wire, and a canonical encoding must not have two spellings for the same unit. Decoders MUST reject [[unit, 1]].

Why not an existing unit vocabulary? SenML ([RFC 8428], with an IANA registry of its own), UCUM, QUDT and UN/CEFACT Recommendation 20 all define unit identifiers, and Section 4 lists the SenML symbol next to every entry so that a translation is mechanical. They are not used directly because this tag needs three properties at once that none of them provides together: a short integer identifier (a byte or two, not a string, because measurement data is transmitted in bulk), a prefix kept separate from the unit (Section 3.3), and stable numbering under our own control so that a value written today decodes identically in twenty years, which is the horizon calibration law works on.

3.3 prefix

The decimal power of the SI prefix by which value (and uncertainty) are scaled: 3 for kilo, -3 for milli, -6 for micro. When absent, the prefix is 0.

Only the 25 canonical SI prefix exponents are valid:

-30 -27 -24 -21 -18 -15 -12 -9 -6 -3 -2 -1 0 1 2 3 6 9 12 15 18 21 24 27 30

Any other exponent is an error; in particular, prefix is not a general scaling factor.

The prefix applies to the quantity as a whole, not to an individual factor of a compound unit: [3, [[15,1],[8,-2]]] with prefix 3 is km·s⁻², i.e. the whole reading scaled by 10³, and not m·(ks)⁻².

Affine units. The degree Celsius is an interval scale: converting it to the kelvin needs an offset, not a factor. A prefix on such a unit therefore scales a temperature difference, never a thermodynamic temperature — a "m°C" reading is a difference of a thousandth of a degree, and nothing about it can be turned into kelvin by multiplication alone. Encoders SHOULD write absolute temperatures with prefix 0, and consumers MUST NOT convert a prefixed affine reading by scaling alone. The registry marks the affected units.

The prefix is deliberately kept separate from the value instead of being folded into it: 5.00 mA is the reading of the instrument, 0.005 A is a computation on it. Both denote the same quantity, but only the former reproduces what was displayed and certified.

When uncertainty is present, prefix MUST be written explicitly, even when it is 0, because the array is positional and uncertainty is trailing. When no uncertainty follows, a prefix of 0 MUST be omitted — writing it would give the same reading two encodings — and decoders MUST reject the redundant form.

3.4 uncertainty

The symmetric measurement uncertainty associated with value, as defined by the Guide to the Expression of Uncertainty in Measurement ([GUM], JCGM 100:2008, BIPM). It is expressed in the same unit and the same prefix as value and MUST NOT be negative.

A bare number is the standard uncertainty u, i.e. a coverage factor of 1, encoded per Section 3.1. This is the compact and by far the most common form.

A map states more. Its keys are:

Key Meaning
1 the magnitude, as reported (required)
2 the coverage factor k the magnitude belongs to (default 1)
3 the coverage probability, a fraction in ]0, 1]
4 the probability distribution (see below)
5 the effective degrees of freedom (positive)

The standard uncertainty is always u = magnitude / k, and the coverage factor MUST therefore be positive. A calibration certificate stating U = 0.12 V with k = 2 is written as {1: 4([-2, 12]), 2: 2} and keeps saying exactly that, instead of being normalised to u = 0.06 and losing the statement the certificate was issued with. Consumers that only need u divide by k.

A map that states only the magnitude MUST NOT be written: with the coverage factor at its default of 1 it says exactly what the bare number says, which would give the same uncertainty two encodings — and decoders MUST reject the redundant form.

Distributions (key 4): 1 = normal, 2 = rectangular, 3 = triangular, 4 = U-shaped, 5 = Student's t. 0 means "not stated" and MUST be omitted rather than written. The degrees of freedom are what a consumer needs to derive a coverage factor from a coverage probability ([GUM] Annex G).

A map key other than 1..5 MUST be rejected: an unknown key could state anything — an asymmetry, a correlation, a second magnitude — and dropping it would silently change what the uncertainty says.

Out of scope, deliberately: asymmetric uncertainties and correlations between quantities. A correlation is a property of a set of values, not of a single one, and belongs in the structure that carries them.

Rounding. [GUM] Section 7.2.6 recommends reporting a value with the number of digits its uncertainty justifies. This format performs no such rounding: it reproduces what the instrument reported, digit for digit (Section 3.1). Rounding is a presentation decision and stays with the producer.

4. Unit registry

The numeric identifications are stable and MUST NOT be renumbered. 0 is reserved and never valid on the wire. Identifications 1..32767 are managed by this specification; 32768 and above are available for private use and are not interoperable outside the agreement of the communicating parties.

The single-byte range is allocated by frequency, not by taxonomy. CBOR encodes the identifications 1..23 in a single byte and everything from 24 onwards in two, so those 23 places are the scarcest thing this registry has to give away. They go to the units that dominate the traffic this format was built for — electric vehicle charging, metering and grid telemetry — which is why the watt-hour is identification 2 while the candela is 25. A taxonomic allocation, SI base units first and the named derived ones in textbook order, would have inverted exactly that.

The consequence is that the table below does not read in textbook order. That is the price, and it is paid once per value transmitted, forever.

Identification 1 is the dimensionless one, because it is the neutral element of unit multiplication and because its symbol is literally "1".

Taxonomy resumes above the byte boundary: 24..39 hold the remaining SI base and named derived units, 60..65 the remaining accepted non-SI units, 120..122 the data units and 140..141 the geometric ones. The ranges 40..59, 66..99, 100..119 and 123..139 are reserved for future registrations, so that a later addition never has to break the grouping.

Id CBOR Symbol Unit
1 01 1 one (dimensionless)
2 02 Wh watt-hour
3 03 W watt
4 04 A ampere
5 05 V volt
6 06 % percent
7 07 °C degree Celsius
8 08 s second
9 09 Hz hertz
10 0A var volt-ampere reactive
11 0B VA volt-ampere
12 0C Ah ampere-hour
13 0D varh volt-ampere-reactive hour
14 0E Ω ohm
15 0F m meter
16 10 g gram
17 11 K kelvin
18 12 h hour
19 13 min minute
20 14 J joule
21 15 Pa pascal
22 16 bit/s bit per second
23 17 S siemens
— from here on an identification costs two bytes instead of one —
24 1818 mol mole
25 1819 cd candela
26 181A N newton
27 181B C coulomb
28 181C F farad
29 181D Wb weber
30 181E T tesla
31 181F H henry
32 1820 lm lumen
33 1821 lx lux
34 1822 Bq becquerel
35 1823 Gy gray
36 1824 Sv sievert
37 1825 kat katal
38 1826 rad radian
39 1827 sr steradian
60 183C d day
61 183D ° degree
62 183E l litre
63 183F t tonne
64 1840 permille
65 1841 ppm parts per million
120 1878 bit bit
121 1879 B byte
122 187A B/s byte per second
140 188C square meter
141 188D cubic meter

Accepted symbol aliases: Metre (15), Ohm (14), Cel (7), deg (61), L/Liter (62), one and / (1), bps (22), m2 (140), m3 (141). Decoders MUST accept them; encoders SHOULD emit the symbol of the table above.

Dimensionless quantities use one (1): ratios, efficiencies, counts, refractive indices. It is the coherent SI unit of a quantity of dimension one, and a reading without a unit is not the same thing as a reading whose unit is one.

Affine units (Section 3.3): °C (7). Prefixes on it denote temperature differences.

SenML. Where a unit also exists in the IANA "SenML Units" registry ([RFC 8428]), the symbol is either identical (m, A, W, V, Hz, Wh, VA, var, bit, ppm) or an accepted alias of ours (Cel → 7, / → 1). The mapping is therefore mechanical in both directions for the overlapping subset; SenML's %RH and its /100 convention for percent have no counterpart here, and this format's percent (6) is the plain dimensionless ratio.

Note on mass. The SI base unit of mass is the kilogram, but SI prefixes attach to the gram. The registry therefore contains the gram (16), and a mass of five kilograms is encoded as (5, 16, 3) — five, gram, kilo.

Note on implementations. This registry is the wire vocabulary, not a list of types an implementation has to provide. A decoder needs the identifier and the symbol; whether it also offers a dedicated class per unit is its own business. The reference implementation, for instance, has purpose-built types for the eighteen units its applications work with and carries every other registered unit through its generic metrological value. Nothing about a unit having no dedicated type restricts what may be sent.

5. Examples

Reading Encoding
5 A D9ACDC 82 05 04
230 V D9ACDC 82 18E6 05
5.0 mA D9ACDC 83 C482201832 04 22
1.10 kWh D9ACDC 83 C48221186E 02 03
(5.00 ±0.02) mA D9ACDC 84 C482211901F4 04 22 C4822102
(5 ±0.5) A D9ACDC 84 05 04 00 C4822005
5.0 mA, symbolic unit D9ACDC 83 C482201832 6141 22
9.81 m·s⁻² D9ACDC 82 C482211903D5 82 820F01 820821
(230.00 ±0.12) V, k=2 D9ACDC 84 C482211959D8 05 00 A201C482210C0202
4.5 nV·Hz^-1/2 D9ACDC 83 C48220182D 82 820501 820982200228

Byte-level breakdown of 5.0 mA:

D9 ACDC        tag(44252)
   83          array(3)
      C4       tag(4), decimal fraction
         82    array(2)
            20 -1                          exponent
            18 32                          mantissa 50   -> 50 * 10^-1 = 5.0
      04       4                           unit: ampere
      22       -3                          prefix: milli

In diagnostic notation ([RFC 8949], Section 8) this reads as 44252([4([-1, 50]), 4, -3]).

Note the (5 ±0.5) A row: the prefix 00 is present although it is zero, because the uncertainty follows it.

6. Deterministic encoding

Tag 44252 imposes no requirements of its own beyond the Core Deterministic Encoding Requirements of [RFC 8949], Section 4.2.1, which it fully supports: the encoding of a given metrological value is a function of its value, scale, unit, prefix and uncertainty alone. This keeps measurement data suitable for signing, e.g. with COSE ([RFC 9052]).

That suitability grows rather than fades as signatures do. A signature travels as a byte string, which costs its own length and a head of one to three bytes; a textual encoding has to spell the same bytes out, typically in base64, at a third again their size — and by then the signature, not the measurement, is the largest field in the message. A reading is tens of bytes and a signature may be thousands, so the ratio only points one way.

The value-level uniqueness rules — one spelling per reading (Section 3.1), per exponent and per unit (Section 3.2), per prefix (Section 3.3), per uncertainty (Section 3.4) — are decoder MUSTs of their sections. For the byte level beneath them (shortest integer heads, definite lengths, sorted map keys, preferred bignums) two decoder profiles exist: a strict decoder verifies deterministic encoding and rejects what violates it, which is the profile this specification RECOMMENDS; a lenient decoder MAY accept non-deterministic bytes where it has to read documents from producers beyond its control. A lenient decoder MUST NOT reproduce non-deterministic bytes when re-encoding.

The same reasoning reaches past this tag, to the structure that carries it. A signature covers bytes rather than meaning, so a document that will be signed SHOULD be written in the deterministic encoding of [RFC 8949], Section 4.2.1 throughout — not merely in the readings it holds. A consumer that receives such a document, decodes it and encodes it again produces that encoding; where the signer wrote a different spelling of the same data, the re-encoded document no longer verifies, and the failure is indistinguishable from tampering. This is a property of the carrier rather than of the tag, which is why it is a SHOULD here and not a MUST: this specification cannot bind a format it does not define. The worked example of this specification (tag-44252-signed-example.md) is written that way.

Two readings that denote the same physical quantity in different representations (5.0 mA and 0.005 A) intentionally do not produce the same bytes. Implementations that need to compare quantities rather than representations should compare mantissa and total exponent, which is exact and unbounded, rather than converting to a common prefix, which can overflow.

6a. What this tag does not carry

A tag annotates one data item, so this one describes a quantity value with its unit and its uncertainty — and nothing else. The following belong to the structure that carries the value, typically a CBOR map holding it alongside its siblings:

This is a deliberate division of labour, not an omission: a value tag that also carried provenance would be unusable as the leaf of somebody else's schema.

7. Security considerations

The security considerations of [RFC 8949] apply. In addition:

8. IANA considerations

Tag 44252 (0xACDC) is registered in the "Concise Binary Object Representation (CBOR) Tags" registry ([RFC 8949], Section 9.2), assigned on 2026-08-19 under that registry's First Come First Served policy. This document is the "Description of semantics" the entry points at.

The entry as published, quoted from the registry rather than from the request:

Tag:         44252
Data item:   array
Semantics:   Metrological value (quantity value with unit of measure, SI prefix
             and GUM measurement uncertainty)
Reference:   https://github.com/OpenChargingTechnology/Whitepapers/blob/master/MetrologicalCBOR/README.md
             Achim Friedland
Template:    template/44252

https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml

9. References

Both are XML-based and considerably broader in scope than this tag: they describe whole documents, this describes one number. The intent here is to be the compact binary leaf such a model can carry — which is why Section 6a keeps provenance out and Section 3.4 keeps the coverage factor in.