Security and access control

The product has a configuration lock feature, which prevents unauthorized access to the module. When configuration lock has been enabled, a device-specific Product Access Key (PAK) will be needed to access the device. Keys are managed in a secure way using Elvaco’s OTC solution which includes the mobile application for configuration.


For more information about security and access control for the product, refer to the One-touch commissioning (OTC) documentation, available on the Elvaco website.

Scheduling readouts and transmissions

A Readout refers to a readout of meter data and storing the information locally in the device memory.

A Transmission refers to a sending a set of readouts from the device over NB-IoT network to a LWM2M or MQTT-SN server.

A combination of above is set to achieve the functionality specified by the project/customer.

Time handling

The module relies on the meter’s clock for keeping time. Time in the meter is assumed to be in standard local time (no DST). When synchronizing time in the meter using the OTC App, local standard time is always used, even if DST is in effect. The timestamped meter data sent from the module can be adjusted to be sent in UTC by specifying the “UTC offset” configuration parameter. The UTC offset will be subtracted from the timestamp prior to transmission. If the meter is in Sweden, which uses CET (Central European Time), it should have UTC offset set to +60 (+1h). In this case at time 12.00 a telegram is sent with timestamp 11.00 as this is the corresponding UTC time. A meter in New York (USA) should have a UTC offset of -300 (-5h) etc. A UTC offset of 0 means the meter time is used as-is.

If the meter is set to used DST this is ignored by the module and the standard time is used. Thus, the time on the meter’s display may not match the time in the telegram or in the OTC App.


All schedules are based on a synchronization with a clock. That means that if a readout schedule of 60 minutes is used, it is synchronized on top of the hour, so 11:00, 12:00, 13:00 etc. 120 minutes will give 12:00, 14:00, 16:00 etc.

When time in the module (or meter) is synchronized, a rescheduling takes place such that the next meter readout is made according to an updated time.

To handle the case where time synchronization “moves time” past a previously planned readout (like 23.58 → 00.02) the module will always make a readout and transmission of a new value when time is synchronized. The device will therefore send an additional readout which can be masked on the serverside.

Randomized transmissions

In order to prevent a large population of devices from transmitting data at exactly the same time the devices should have a random delay before transmitting data. The delay should be configurable via NFC/DM.

Readouts from the meter are always performed on top of the hour, 11.00, 13.00 etc. Transmissions can be carried out at other times but are planned at full ours given a set transmission interval (Ttransmit). The figure below illustrates this. The transmissions are planned at time T1. The actual Ttransmit is a random time between (T1 + Toffset) and (T1 + Toffset + Tdelay).

Ttransmit, Toffset and Tdelay are parameters in the product.


  • Toffset + Tdelay <= Ttransmit

This should be checked by the device and the OTC App.

  • If Ttransmit is reduced below Toffset + Tdelay , then Toffset should be set to 0 and Tdelay.= Ttransmit.

CMi61-serie_Transmission_ conditions

Meter data transmission

The module sends meter data messages according to it’s transmit interval settings. Meter read out is always related to meter’s clock at time 00:00:00. Transmission time is randomized between read outs.

The user can customize the data sent from the module by configuring message format and encoding of the telegram.

Transmitting and interpreting meter data from the module is flexible and the user can choose among three different encoding techniques, and two message formats. Chosen message format dictates what data is sent, while the encoding technique determines how that data in should be interpreted. In the following paragraphs, the available message formats and encoding techniques are described in detail.

Data retransmission

If data cannot be sent, due for instance to network issues, there will be a number of retries after which the device will give up and leave the readout as “unsent” in its storage. Next time a transmission is attempted unsent data will be resent (if possible). Retransmission can be done by FIFO or LIFO.

Rules for retransmissions include maximum age of data, order of data, number of retransmitted data / transmission interval.

Example 1. Example 1

A device is configured the following way:

  • Message encoding: M-Bus

  • Auto upload order: FIFO

  • Measurement interval: 60 minutes

  • Transmit interval: 60 minutes

  • Transmit offset: 15 minutes

  • Transmit delay: 30 minutes

  • Maximum uploads per transmission: 4

  • Upload maximum age 72h

A network issue caused the module to be offline for 5 days, while still reading and storing measurement data. When the device manages to go online the following scenario takes place.

  • The device will start by transmitting measurement data that is 3 days old (FIFO order)

  • The device will send 4 measurement telegrams per hour, at a randomly chosen time between minute 15 and 45

  • Each telegram contains a single readout, totaling 4 readouts per transmission

  • The device will take approximately 1 day to “catch up” and start sending one measurement per hour

Example 2. Example 2

A device is configured the following way:

  • Message encoding: SenML/CBOR/M-Bus

  • Auto upload order: FIFO

  • Measurement interval: 60 minutes

  • Transmit interval: 60 minutes

  • Transmit offset: 15 minutes

  • Transmit delay: 30 minutes

  • Maximum uploads per transmission: 4

  • Upload maximum age 72h

  • Device max payload size: 12 (readouts per telegram)

A network issue caused the module to be offline for 5 days, while still reading and storing measurement data. When the device manages to go online the following scenario takes place.

  • The device will start by transmitting measurement data that is 3 days old (FIFO order)

  • The device will send 4 measurement telegrams per hour, at a randomly chosen time between minute 15 and 45

  • Each telegram contains 12 meter readouts, totaling 4 x 12 = 48 readouts per transmission

  • The device will take approximately 2 hours to “catch up” and start sending one measurement per hour

Message encoding

The product has three options when it comes to message encoding:

  • M-Bus

  • JSON

  • SenML/CBOR


If using M-Bus as message encoding technique, data will be divided into Data Information Blocks (DIB) that include Data information field (DIF code), Value information field (VIF code) and a data field (DATA) where the actual payload is stored (illustrated in the following image).


DIB structure

Table 2, “Payload, M-Bus encoded message” provides a detailed description of how data is encoded when using either message format Standard or Extended.

Table 2. Payload, M-Bus encoded message




Data type




6 bytes


Meter date and time (YY-MM-DD HH:MM)

Mapped to OBIS 9.36


Bit 31-28 = Year-high*

Bit 27-24 = Month

Bit 23-21 = Year-low*

Bit 20-16 = Day

Bit 15 = Summer time flag**

Bit 14-13 = Century

Bit 12-8 = Hour

Bit 7 = Error flag

Bit 6 = Reserved for future use***

Bit 5-0 = Minute

*The year is read by combining the yearhigh and year-low field. For example, year-high = 0010 and year-low = 010 =&gt; year = 0010010

**0 = standard time, 1= daylight-saving time

***0 = timestamp is valid, 1 = timestamp is not valid


Meter ID

6 bytes

According to M-Bus EN13757- 3 identification field

Meter ID




6-7 bytes


Energy consumption (Wh, J)

0406xxxxxxxx = xxxxxxxx * 0.001 MWh (kWh)

0407xxxxxxxx = xxxxxxxx * 0.01 MWh

04FB00xxxxxxxx = xxxxxxxx * 0.1 MWh

04FB01xxxxxxxx = xxxxxxxx MWh

040Exxxxxxxx = xxxxxxxx * 0.001 GJ (MJ)

040Fxxxxxxxx = xxxxxxxx * 0.01 GJ

04FB08xxxxxxxx = xxxxxxxx * 0.1 GJ

04FB09xxxxxxxx = xxxxxxxx GJ



6 bytes


Volume (m3)

0413xxxxxxxx = xxxxxxxx * 0.001 m3

0414xxxxxxxx = xxxxxxxx * 0.01 m3

0415xxxxxxxx = xxxxxxxx * 0.1 m3

0416xxxxxxxx = xxxxxxxx m3



4 bytes


Power (W)

022Bxxxxxx = xxxxxx * 0.001 kW (W)

022Cxxxxxx = xxxxxx * 0.01 kW

022Dxxxxxx = xxxxxx * 0.1 kW

022Exxxxxx = xxxxxx kW



4 bytes


Flow (m3/h)

023Bxxxxxx = xxxxxx * 0.001 m3/h

023Cxxxxxx = xxxxxx * 0.01 m3/h

023Dxxxxxx = xxxxxx * 0.1 m3/h

023Exxxxxx = xxxxxx m3/h


Fw temp

4 bytes


Forward temperature (°C)

025Axxxx = xxxx * 0.1 °C

025Bxxxx = xxxx * °C


Rt temp

4 bytes


Return temperature (°C)

025Exxxx = xxxx * 0.1 °C

025Fxxxx = xxxx °C


Error flags

5 bytes


Error and warning flags


For further information about Error flags, refer to the latest meter’s manual


Tariff 1


7 bytes


Tariff 1 Energy consumption (Wh, J)

841003xxxxxxxx = xxxxxxxx Wh

841003xxxxxxxx = xxxxxxxx * 10 Wh

841003xxxxxxxx = xxxxxxxx * 100 Wh

841003xxxxxxxx = xxxxxxxx kWh

841003xxxxxxxx = xxxxxxxx *10 kWh

841003xxxxxxxx = xxxxxxxx MJ

841003xxxxxxxx = xxxxxxxx * 10 MJ


Tariff 2


7 bytes


Tariff 2 Energy consumption (Wh, J)

842003xxxxxxxx = xxxxxxxx Wh

842003xxxxxxxx = xxxxxxxx * 10 Wh

842003xxxxxxxx = xxxxxxxx * 100 Wh

842003xxxxxxxx = xxxxxxxx kWh

842003xxxxxxxx = xxxxxxxx *10 kWh

842003xxxxxxxx = xxxxxxxx MJ

842003xxxxxxxx = xxxxxxxx * 10 MJ


Tariff 3


7 bytes


Tariff 3 Energy consumption (Wh, J)

843003xxxxxxxx = xxxxxxxx Wh

843003xxxxxxxx = xxxxxxxx * 10 Wh

843003xxxxxxxx = xxxxxxxx * 100 Wh

843003xxxxxxxx = xxxxxxxx kWh

843003xxxxxxxx = xxxxxxxx *10 kWh

843003xxxxxxxx = xxxxxxxx MJ

843003xxxxxxxx = xxxxxxxx * 10 MJ


Missing time

6 bytes


3C22xxxxxxxx = xxxxxxxx hours

3C23xxxxxxxx = xxxxxxxx days

*Only included in the extended message


The payload of message format JSON consists of one object with a list of key – value pairs. The names of each value type and unit is presented in Table 3, “Payload, JSON encoded message”. The values are encoded as numbers or strings and the units are encoded as strings.

Table 3. Payload, JSON encoded message


JSON key

Meter ID


Meter date / time




Energy unit




Volume unit




Power unit




Flow unit


Forward temperature


Forward temperature unit


9eturn temperature


Return temperature unit


Error flags


Tariff 1 Energy*


Tariff 1 Energy unit*


Tariff 2 Energy*


Tariff 2 Energy unit*


Tariff 3 Energy*


Tariff 3 Energy unit*


Missing time*


Missing time unit*


*Only included in the extended message.

Example payload, JSON:



















For battery-powered devices it might be necessary to send several measurements in the same UDP frame to save energy. In order to achieve this SenML RFC 8428 - Sensor Measurement Lists (SenML) + CBOR RFC 8949: Concise Binary Object Representation (CBOR) is used to define a measurement list.

The idea is to send a list of measurements, where the first entry contains the base time for all the readouts (which only need to specify an offset) and the meter id shared by all readouts. The other records in the list may contain fewer readout fields to save space. The format allows sending all the data for every readout, in which case the save (in terms of bytes) is smaller and lies in that fewer telegrams are sent, some data needs not be transferred for every reading (like meter-id) and timestamps can be handled more efficiently. SenML/CBOR also provides one way to structure lists of readings in an efficient manner.

The first implementation will use M-Bus for encoding the data transferred, but other formats could be implemented in the future.

Note that SenML, CBOR and M-Bus are separate standards, this page describes how products can use these three in conjunction for representing multiple measurement values in a compact format suitable for radio transmission over for instance NB-IoT. Also, other means of encoding the data than M-Bus can be used in the future.

Elvaco uses SenML/CBOR/M-Bus data representation for transferring meter data in a compact and selfdescribing manner. The data being transferred is referred to as a pack, containing one record per readout.

Structure of SenML pack

Meter readout data is sent as SenML, i.e., a list (aka array) of readout values (records), encoded using CBOR. Each record is a map of key/value pairs using SenML.

Each product that uses the SenML/CBOR format shall follow the requirements below. In addition, it shall specify the exact contents of the data values included, meter id format etc. This specification alone is not sufficient for building a parser for a specific product.

Base Time

Base time is used to set a reference time.

  • Timestamps are always encoded according to SenML (i.e., UNIX time). SenML label -1 “Base time”, SenML definition of Time field o

  • This value must be included in the first record of the pack

  • All other values have a time value that is added to the base time to define the exact time of the readout

Base Name

Base name is used to represent the MeterID (Meter identification in M-Bus)

  • This value must be included in the first record of the pack

  • This is represented as a string array (CBOR Major Type 3 - SenML label -2 “Base name”). The product shall specify the exact format for this field, as it may vary depending on what type of “meter” is used. For an M-Bus format it is typically the M-Bus data without DIF/VIF.

  • No name is set for remaining meter readout values, only values belonging to a single meter can be represented in one pack.

Data values
  • The actual values from the meter can be encoded using multiple methods, such as M-Bus.

  • The first record can also contain a data value field containing more information than the remaining records in the pack. This is to include more information for the first reading and then only a subset of values for the remaining records to save space. (SenML label 8 - “Data value”)

Other values
  • (Base) Unit is not used, since the unit is specified by the M-Bus data

  • An “Encoder Version field” is used in a separate record to define the type and version of the encoded payload data.

Additional records

All records in the SenML pack are expected to contain measurement values. If there is a need for transmitting additional information in the same pack additional records can be added. For such records the name field shall be used by defining a name of at least a single character. In SenML the base name and the name fields are appended to result in the final record name.

The name shall contain at least one character outside [A-Fa-f0-9] which signifies non-hexadecimal representation, since meter-id is typically decimal/hexadecimal, and this makes it easier to check the record name for validity.

If a parser finds a record with a name field like described above that it does not recognize it shall ignore the record.

The following additional records are currently used:


Name field


Encoder Type & Version


This field allows defining versions for the contents of the measurement field.

Encoder Type & Versioning

The following table defines allowed encoder types and versions. The information is sent in a special record “Encoder Version field”.

  • This field encapsulates both the encoding of the data and versioning

  • It contains no timestamp

  • It is encoded as a SenML Value

  • It has a Name field with the single letter “V”

  • If, when parsing, an invalid version is encountered the parsing shall stop with an error

  • The value shall be interpreted as an UINT16

    • The first byte is the encoder type and the second is the encoder version, both interpreted as UINT8.

      Example: value 0x0102 means Encoder type 0x01 and Encoder version 0x02.

    • Defined valid encoder types and versions are found in a table below on this page o

    • Size of whole record is maximum 7 bytes

    • If we ever need to extend this beyond 256 encoder types or versions, we could use an UINT32 and let the least significant byte overlap with the definition above and thus simply extend encoder type and version to use UINT16 instead of UINT8

  • If record is excluded, encoder type is 0 and encoder version is 0


Name field



0 (M-Bus)



M-Bus encoding of payload data. Each data record contains all DIF/VIF/Values according to M-Bus.

Note that M-Bus uses LSB first byte order for the data and it shall be preserved here as well.

Example and Data Size

Below is a break-down of the number of bytes used for the different parts described.

1                                                             : size (bytes)
2 98 18                    # 24 item array                    : 2 (fixed)
3   A3                     # Map with length 3                : 1 (fixed)
4     21                   # Key 1 = -2 = Base name           : 1 (fixed)
5     68                   # Value 1 = String array, length 8 : 1 (fixed)
6        3132333435363738  # meter specific encoding          : 8 (fixed, dep. on m.)
7     22                   # Key 2 = -3 = Base time           : 1 (fixed)
8     1A 5DE02740          # Value 2 = 1574971200 =           : 5 (fixed)
9                          # Time "2019-11-28T20:00Z"
10     08                  # Key 3 = 8 = Data value           : 1 (fixed)
11     58 21               # Value 3 = Byte array, length 33  : 2 (payload1 < 256 bytes)
12                         #                                                or
13                         #                                    3 (payload1 > 255)
14        04064E61BC000415
15        07870000022B9413
16        023BD400025A2303
17        025E1A0202FD1712
18        40                                                  : variable
19                                                        Sum : 22+(1)+payload1 bytes
21                 ** Record for defining encoder and version **            
23   A2                    # Map with length 2                 : 1 (fixed)
24     00                  # Key 1 = "0" name                  : 1 (fixed)
25       61 56             # Value 1 = string => "V" = version : 2 (fixed)
26     02                  # Key 2 = integer value             : 1 (fixed)
27       00                # Value 2 UINT16
28                         # 0x0000 => enc=0, ver=0            : 3 (max)
29                                                         Sum : 8 bytes (max)
30                 ** Follows X items of same size **
32   A2                    # Map with length 2                 : 1 (fixed)
33     06                  # Key 1 = 6 = Time                  : 1 (fixed)
34     39 0E0F             # Value 1 = -3600 =                 : 3 (fixed)
35                         # Time "2019-11-28T19:00Z"
36     08                  # Key 2 = 8 = Data value            : 1 (fixed)
37     46                  # Value 2 = Byte array, length 6    : 1 (payload < 24)
38        0406F24FBC00     # M-bus record with one DIB:        : variable
39                         # Energy = 12341,234 MWh
40                                                         Sum : X*(7+(1)+payload2 size)
42                 Total: 22 + (1) + payload 1 + 8 + X * (7 + (1) + payload2 size)

Given the fixed sizes above using M-Bus and assuming payload is < 256 bytes for the first record and < 24 for the subsequent records, the total size is:

29 + payload1 + 6 + X * (7 + payload2)

Some example sizes:



Total #records

Total size














https://cbor.me/- Validator for CBOR, does not understand SenML or M-Bus


A small bug has been identified in the hex interpretation of negative numbers in the validator. Please have this in mind if using the validator.


SenML/CBOR is to be considered a message encoding. It defines how the messages are encoded, but not the actual contents of the messages (which fields from the meter are included). SenML/CBOR/M-Bus is one such encoding, but there could be several based on this SenML/CBOR specification and the encoder version field above defines exactly which type and version is used.

The contents of the message are defined by the message format. The message format sets which fields are to be included in both the first and the subsequent records of the SenML pack.

The number of records included in a pack is set by the readout and transmit intervals. See Scheduling Readouts for more details. If the readout interval is 120 minutes and the transmit interval is 1440 minutes 12 readouts in total will be included.

Message size restrictions

Each product may have different maximum payload sizes in a single telegram. Also depending on configuration (DTLS or not for instance) the net payload size may vary. Therefore, the device shall “fill up” as many telegrams as required to send the data. It is for the user to define a configuration that gives a reasonable tradeoff between power consumption (send fewer telegrams) and functional requirements (much data is sent).

If a device is configured using a Message Format and many readouts the data may not fit in a single telegram. In such cases multiple telegrams shall be sent and each telegram shall be fully self-described, i.e., contain Meter ID, timestamps etc.

Example 1



Readout interval


Transmit interval

1440 (daily)

Message encoding

SenML/CBOR/M-Bus version 0

Message format


Max transmissions per day


This example results in the transmission of one message per day, containing 24 readings, all with the contents defined in the Standard message format. Data is encoded using SenML/CBOR/M-Bus. Maximum 3 unsent such messages are sent each time (if for some reason the messages were not sent “last time”). So maximum transmitted messages per day is 3 (containing 3x24=72 readings, covering 3 days)

Example 2



Readout interval


Transmit interval


Message encoding

SenML/CBOR/M-Bus version 0

Message format


Max transmissions per day


This example results in the transmission of one message every 12h, containing 6 readings, all with the content defined in the Tariff message format. Data is encoded using SenML/CBOR/M-Bus. Maximum 2 unsent such messages are sent each time (if for some reason the messages were not sent “last time”), so maximum transmitted messages per day is 4 (containing 4x6=24 readings, covering 2 days).

Reset procedures

Rebooting the module

  1. Press and hold the push button for 5-15 seconds.

  2. Release the button when the green LED is lit.


Switching off the module

  1. Press and hold the push button for 15-20 seconds.

  2. Release the button when the red LED is lit.


Was this article helpful?

0 out of 0 found this helpful
Have more questions? Submit a request

Comments (0 comments)

Article is closed for comments.