Operation
Table 2. Essential settings to control meter data readouts and transmissions
|
LwM2M resource |
Setting |
Description |
|---|---|---|
|
33906/./17 |
Meter Report Interval |
Interval in minutes. Specifies how often the module reads and stores values from the meter. A short report interval means the meter is read often, meaning a higher data granularity can be achieved. The meter data are persistently stored in non-volatile memory and can be deleted by doing a factory reset. In case the memory is full, the oldest data will be replaced by the newest. |
|
33906/./18 |
Meter Transmit Interval |
Interval in minutes. Specifies how often the module sends data to the receiving system. A short transmit interval means the module will send data more frequently, allowing the system to get data from more recent meter readouts. |
|
33906/./1 |
Report data encoding |
Specifies how the data is encoded before transmission. Select the option that best suits the receiving system and other requirements |
Tip
Transmitting data is a far more energy consuming operation than reading the meter. For battery operated devices, it is therefore wise to set a larger transmit interval than the report interval to achieve a decent data granularity.
Meter data can be transmitted using either MQTT-SN or LwM2M Send. The protocols cannot be used simultaneously, but it's possible to configure via LwM2M or the Elvaco OTC App. Regardless of the chosen transport protocol, the content of the transmitted data remains the same. When a meter data transmission is scheduled, the data being sent is defined by the chosen message format. If there are any unsent meter data available in the module, they will be transmitted according to the chosen recovery strategy (First in First out (FiFO) or Last in First out (LiFo)).
When using MQTT-SN, meter data messages are published to a MQTT-SN topic. The topic can be configured remotely using LwM2M resource 33905/./11, or via the Elvaco OTC App.
The module relies on the meter’s clock to keep time. The meter time is assumed to be standard local time (no DST). When synchronizing time in the meter using the Elvaco 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 use 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 Elvaco OTC App.
All schedules are based on a synchronization with a clock. This 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. Synchronization of the meter clock can be done in various ways, either periodically (automatically) or manually. It is recommended using a periodic approach to avoid the risk of letting the clock drift too much.
Manual synchronization options
-
Over NFC using Elvaco OTC App
-
Over LwM2M using resource
3/./13 -
Setting the meter clock in the meter
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 server side.
In order to prevent a large population of devices from transmitting data at exactly the same time the devices have a random delay before transmitting data. The delay is configurable via either the Elvaco OTC App and the NFC interface, or remotely via a device management system.
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 hours 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.
If data cannot be sent, for instance due 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
Meter alarms are transmitted using the chosen transport protocol, which can be either MQTT-SN or LwM2M Send. Regardless of the chosen transport protocol, the content of the transmitted data remains the same. When an alarm is triggered, the message follows the selected format, with Extended Error Codes appended to it. If there are any unsent meter data available in the module, they will be transmitted simultaneously with the alarm.
When using MQTT-SN, alarm messages are published on a separate topic, apart from the ordinary meter data delivery. The alarm topic is configurable via LwM2M resource 33906/./67.
Each bit in the alarm mask is directly mapped to a meter error. The different alarm masks used for controlling the alarm monitor have the same mapping. The sections below describe how each bitmask should be managed and interpreted.
Monitoring an alarm is enabled by setting the bit to high (1), while keeping the alarm silent (i.e., preventing alarm messages from being triggered) is done by setting the bit to low (0). Below table gives some examples on how the bitmask can be set to achieve different behaviour.
Table 4. Examples of Alarm functionality enable bitmasks
|
Binary |
Hex |
Interpretation |
|---|---|---|
|
0b1111 1111 1111 1111 |
0xFFFF |
All alarms are monitored |
|
0b0 |
0x0 |
No alarms are monitored. |
|
0b0001 1100 0001 |
0x1C1 |
Alarm bits 0, 6, 7, and 8 are monitored. |
In practical means, the Alarm auto reset mask makes it possible to re-trigger on a meter alarm that has been reset (e.g. due to natural reset, i.e. the meter has healed or been repaired, or thanks to a manual reset). If not enabling any alarms in the Alarm auto reset mask, a specific alarm will only be sent maximum twice during the lifetime of the module (once while set, and once while possibly reset). Choosing what alarms that automatically should be reset is handled in the same way as the alarm functionality enable bitmask.
Table 5. Examples of Alarm auto reset mask and Alarm reset bitmasks
|
Binary |
Hex |
Interpretation |
|---|---|---|
|
0b1111 1111 1111 1111 |
0xFFFF |
All alarms in the alarm mask are reset. |
|
0b0 |
0x0 |
No alarms in the alarm mask are reset (not interesting wanting to manually resetting the alarm mask). |
|
0b0001 1100 0001 |
0x1C1 |
Alarm bits 0, 6, 7, and 8 are reset once the hysteresis criteria is fulfilled. |
A manual reset can take place any point in time, allowing the module to trigger on meter alarms again. Choosing what alarms that should be manually reset is handled in the same way as the alarm functionality enable bitmask.
Table 6. Alarm reset bitmasks
|
Binary |
Hex |
Interpretation |
|---|---|---|
|
0b1111 1111 1111 1111 |
0xFFFF |
All alarms in the alarm mask are reset. |
|
0b0 |
0x0 |
No alarms in the alarm mask are reset (not interesting wanting to manually resetting the alarm mask). |
|
0b0001 1100 0001 |
0x1C1 |
Alarm bits 0, 6, 7, and 8 are reset. |
The table below specifies available meter errors and how they are mapped to the bitmask.
Using message format Standard, a typical payload can look like:
046D002A323B0C7837266966040637570A000414EF472000022B0000023BFCFF025B0000025F000002FD170400
0x02FD17 is the M-Bus DIF/VIF indicator for error flags, and the following two bytes 0x0400 indicates there's an error. Given that M-Bus encoding using LSB, the corresponding bit map is read as 0x00 04, giving the resulting bits 0b0000 0000 0000 0100. This means that bit 2 is set, meaning there is an issue with the return temperature sensor (see Meter error interpretation table above).
If a payload instead is sent as an alarm message, it will look similar, but the extended error codes will also be appended to the message:
046D0F2A323B0C7837266966040637570A000414EF472000022B0000023BFCFF025B0000025F000002FD17040002FD180400
0x02FD17 again indicates the error flags, and the following two bytes 0x04 00 are identical to the example above. Since this message has been triggered as an alarm, the extended error codes are appended to the payload, see 02FD180400. The FD18 indicates it's an M-Bus error mask. The bytes in the error mask are decoded in the same way as the error flags, following the information given the Meter error interpretation table above.
Throughout the module's lifetime, various events may need to be logged, for example, to analyze its behavior and overall health status. The built-in system log can be configured to store and report such events based on their criticality.
There are two settings available to control the behavior of the system log: Syslog storage level and Syslog auto-upload level. The storage level determines which events should be logged and stored in the module, while the auto-upload level defines which events should automatically be sent from the module, depending on their criticality. This allows storing critical events without necessarily sending them, reducing data traffic and power consumption. New system log entries, with appropriate logging level, will be sent together with the subsequent meter data delivery.
Note
For a complete reference to LwM2M resources related to the module system log, see LwM2M Object 'Elvaco Syslog Config' (Object ID: 33918).
Below tables list what logging levels there are, and the implemented events that can be logged.
Table 8. Supported logging levels
|
Log level |
Log level name |
Description |
Remark |
|---|---|---|---|
|
0 |
DEBUG |
Used for debugging unexpected device or server behavior. |
During normal operation, it's recommended not storing nor sending debug events. |
|
1 |
INFO |
Informational, normal events |
|
|
2 |
NOTICE |
Normal operation notifications |
|
|
3 |
WARNING |
Warning logs |
|
|
4 |
ERROR |
Error logs |
|
|
5 |
CRITICAL |
Critical error logs |
|
|
Varies |
Varies |
Log level determined based on the content of the log entry. |
Varying log level used e.g. for configuration changes. Some changes might be more or less sensitive. More sensitive log entries will get a higher logging level. |
The table below lists all entries that can be logged in the device. The column to the right declares whether the system log entry origins from a configuration change or not. Apart from the log level, this categorization can be helpful when interpreting the logs on the receiving server.
Table 9. Supported log elements and corresponding log level
|
Entry |
Log data |
Log level |
Is configuration change |
|---|---|---|---|
|
Product activation |
Reason for activation (button (if applicable), NFC, Activation at flow etc) |
NOTICE |
NO |
|
Successful timesync |
INFO |
NO |
|
|
Unsuccessful time sync |
Failed time synchronizations |
WARNING |
NO |
|
Modem restarts |
INFO |
NO |
|
|
Successful connections to Bootstrap, DM, MDM |
INFO |
NO |
|
|
Failed connections to Network, Bootstrap, DM, MDM |
Network rejects, failed DTLS handshakes etc |
WARNING |
NO |
|
Startup cause |
Reason/cause for startup, for example watchdog, brownout, soft-reset (e.g. button, NFC, LwM2M, console). Level may depend on cause. |
NOTICE |
NO |
|
Changed SIM |
Change in ICCID |
WARNING |
NO |
|
Successful FW Upgrade |
|
WARNING |
NO |
|
Unsuccessful FW Upgrade |
|
WARNING |
NO |
|
Config reset with result |
|
CRITICAL |
NO |
|
Unsuccessful NFC writes |
Reason for failure
|
WARNING |
NO |
|
Failed staged settings |
|
WARNING |
NO |
|
DeviceEnable |
Source of activation |
WARNING |
YES |
|
DevEUI |
New and old |
WARNING |
YES |
|
NfcCfgOpen |
WARNING |
YES |
|
|
NfcAutoLockEnable |
WARNING |
YES |
|
|
NfcAutoLockTimeout |
WARNING |
YES |
|
|
MessageEncoding |
INFO |
YES |
|
|
MessageType |
INFO |
YES |
|
|
NfcEnabled |
WARNING |
YES |
|
|
NdefUserText1 |
INFO |
YES |
|
|
NdefUserText2 |
INFO |
YES |
|
|
HwModel |
WARNING |
YES |
|
|
ConsoleEnable |
Log in order to know the current state of the console. |
WARNING |
YES |
|
HwRevision |
WARNING |
YES |
|
|
MeterMaxRetries |
INFO |
YES |
|
|
MeterCustomerNo |
WARNING |
YES |
|
|
MeterIdentificationSource |
INFO |
YES |
|
|
TraceLogLevels |
WARNING |
YES |
|
|
ApnMode |
WARNING |
YES |
|
|
ManualApn |
WARNING |
YES |
|
|
BootstrapIp |
WARNING |
YES |
|
|
BootstrapHostName |
WARNING |
YES |
|
|
BootstrapPort |
WARNING |
YES |
|
|
BootstrapSecurityMode |
WARNING |
YES |
|
|
NbIotTimer3412 |
WARNING |
YES |
|
|
NbIotTimer3324 |
WARNING |
YES |
|
|
NbIotEdrx |
WARNING |
YES |
|
|
NbIotEdrxMode |
WARNING |
YES |
|
|
NbIotUsePSM |
WARNING |
YES |
|
|
NbIotRadioBand |
WARNING |
YES |
|
|
MqttSnConnectionMode |
WARNING |
YES |
|
|
MqttSnTopic |
WARNING |
YES |
|
|
LwM2MQueueMode |
WARNING |
YES |
|
|
NbIotTxOffset |
WARNING |
YES |
|
|
NbIotTxDelay |
WARNING |
YES |
|
|
NbIotUploadsPerTx |
WARNING |
YES |
|
|
ManualPlmn |
WARNING |
YES |
|
|
NbIotDtlsMaxRewinds |
WARNING |
YES |
|
|
NbIotDtlsMinTimeout |
WARNING |
YES |
|
|
NbIotDtlsMaxTimeout |
WARNING |
YES |
|
|
NbIotMqttsnCommTimeout |
WARNING |
YES |
|
|
NbIotMqttsnCommAttempts |
WARNING |
YES |
|
|
NbIotMdmCommFailures |
WARNING |
YES |
|
|
NbIotCoapAckTimeout |
WARNING |
YES |
|
|
NbIotCoapMaxRetransmit |
WARNING |
YES |
|
|
NbIotIowaDtlsMinTimeout |
INFO |
YES |
|
|
NbIotIowaDtlsMaxTimeout |
INFO |
YES |
|
|
NbIotIowaCommRetryCount |
WARNING |
YES |
|
|
NbIotIowaCommRetryDelay |
WARNING |
YES |
|
|
NbIotIowaCommSeqRetryCount |
WARNING |
YES |
|
|
NbIotIowaCommSeqRetryDelay |
WARNING |
YES |
|
|
NbIotNwkConnMaxHoldoff |
WARNING |
YES |
|
|
NbIotNwkSearchPeriod |
WARNING |
YES |
|
|
NbIotModemRestartBackoff |
WARNING |
YES |
|
|
NbIotMdmReconnectBackoff |
WARNING |
YES |
|
|
NbIotLwM2MResumeBackoff |
WARNING |
YES |
|
|
NbIotAutoUploadAgeLimit |
WARNING |
YES |
|
|
NbIotAutoUploadOrder |
WARNING |
YES |
|
|
Lwm2mBsUri |
WARNING |
YES |
|
|
Lwm2mBsSecurityMode |
WARNING |
YES |
|
|
Lwm2mUri |
WARNING |
YES |
|
|
Lwm2mSecurityMode |
WARNING |
YES |
|
|
Lwm2mLifetime |
WARNING |
YES |
|
|
MqttsnUri |
WARNING |
YES |
|
|
MqttsnSecurityMode |
WARNING |
YES |
|
|
TimeSyncSource |
Log the new value. Relevant for determining the quality of the timestamps used in the log |
WARNING |
YES |
|
NbIotUploadProtocol |
WARNING |
YES |
|
|
NbIotEnableRai |
WARNING |
YES |
|
|
PowerSource |
WARNING |
YES |
|
|
NbIotAllowedRadioBands |
WARNING |
YES |
|
|
MqttKeepaliveTimeout |
WARNING |
YES |
|
|
LwM2MForcedQueueMode |
WARNING |
YES |
|
|
NbIotRoamHomePlmnSearch |
WARNING |
YES |
|
|
NbIotSyslogLevel |
WARNING |
YES |
|
|
NbIotSyslogMqttSnTopic |
WARNING |
YES |
|
|
NbIotSyslogAutoUploadLevel |
WARNING |
YES |
|
|
NbIotSyslogAutoUploadAgeLimit |
WARNING |
YES |
|
|
NbIotAlarmFuncEnableBitmask |
WARNING |
YES |
|
|
NbIotAlarmMaskResetPeriod |
WARNING |
YES |
|
|
NbIotAlarmHysteresis |
WARNING |
YES |
|
|
NbIotAlarmAutoResetBitmask |
WARNING |
YES |
|
|
NbIotAlarmTxDelayMax |
WARNING |
YES |
|
|
NbIotEmcTestMode |
WARNING |
YES |
|
|
NbIotAlarmMqttSnTopic |
WARNING |
YES |
|
|
MeasurementMode |
WARNING |
YES |
|
|
TxInterval |
INFO |
YES |
|
|
MeterId |
Log both from and to values. Relevant for tracking meter changes or issues in meter communication. |
WARNING |
YES |
|
UTCOffset |
INFO |
YES |
|
|
TimestampRounding |
INFO |
YES |
|
|
ModemConfigured |
INFO |
YES |
|
|
ReadoutInterval |
INFO |
YES |
|
|
ReportInterval |
INFO |
YES |
|
|
Meter data readout |
DEBUG |
NO |
|
|
Meter data transmission |
DEBUG |
NO |
|
|
Found long payload |
WARNING |
NO |
|
|
Meter data readout error |
Status code |
WARNING |
NO |
|
No valid timestamp from meter |
NOTICE |
NO |
|
|
Readout skipped on time change |
Old and new time |
NOTICE |
NO |
|
Performing readout on time change |
Old and new time |
INFO |
NO |
|
Stored [type] credentials for [address] |
[type] BS, DM etc. [address] server URI |
NOTICE |
NO |
|
Unsupported encrypted meter communication |
ERROR |
NO |
The module system log can be transmitted using either MQTT-SN or LwM2M Send. Which one is used depends on the chosen transport protocol for the meter data. Regardless of the choice, the content of the transmitted data remains the same. When a system log entry, having a system log level that is configured to be sent, is stored in the module, it will be sent together with the subsequent meter data transmission. All unsent log entries that are supposed to be sent will be included.
When using MQTT-SN, system log entries are sent on a separate topic, apart from the ordinary meter data. The system log topic is configurable via LwM2M resource 33918/./0.
Regardless if the system log is sent using MQTT-SN or LwM2M Send, the payload is structured according to the SenML data model and encoded using CBOR. The system log message itself is stored as an ASCII text string inside the SenML record.
To get a complete description on how the SenML/CBOR packages are encoded, see section SenML/CBOR. Below example shows a simplified way to decode a system log message, from the raw payload to a human readable system log message.
-
Raw payload (reference):
82A200615602190200A322C11A699337A002020858335B636F6E6669675D204D65746572206964206368616E6765642066726F6D20383537323731363020746F203835373435303430 -
Decode raw payload (e.g. using https://cbor.me/):
[{0: "V", 2: 512}, {-3: 1(1771255712), 2: 2, 8: h'5B636F6E6669675D204D65746572206964206368616E6765642066726F6D20383537323731363020746F203835373435303430'}] -
Identify the data record in the package:
5B636F6E6669675D204D65746572206964206368616E6765642066726F6D20383537323731363020746F2038353734353034305B636F6E6E48646C725D204D444D55706C6F61646564 -
Decode data record as ASCII string:
[config] Meter id changed from 85727160 to 85745040
The product supports three message encoding options:
-
M-Bus
-
JSON
-
SenML/CBOR
If using M-Bus as message encoding technique, data is 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
The table below provides detailed examples of how data is encoded when using message encoding M-Bus.
Table 10. Payload, M-Bus encoded message
|
DIB |
Field |
Size |
Data type |
Description |
|---|---|---|---|---|
|
1 |
Date/time |
6 bytes |
INT32 |
Meter date and time (YY-MM-DD HH:MM) Mapped to OBIS 9.36 046Dxxxxxxxx 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 => year = 0010010 **0 = standard time, 1= daylight-saving time ***0 = timestamp is valid, 1 = timestamp is not valid |
|
2 |
Meter ID |
6 bytes |
According to M-Bus EN13757- 3 identification field |
Meter ID 0C78xxxxxxxx |
|
3 |
Energy |
6-7 bytes |
INT32 |
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 |
|
4 |
Volume |
6 bytes |
INT32 |
Volume (m3) 0413xxxxxxxx = xxxxxxxx * 0.001 m3 0414xxxxxxxx = xxxxxxxx * 0.01 m3 0415xxxxxxxx = xxxxxxxx * 0.1 m3 0416xxxxxxxx = xxxxxxxx m3 |
|
5 |
Power |
4 bytes |
INT16 |
Power (W) 022Bxxxxxx = xxxxxx * 0.001 kW (W) 022Cxxxxxx = xxxxxx * 0.01 kW 022Dxxxxxx = xxxxxx * 0.1 kW 022Exxxxxx = xxxxxx kW |
|
6 |
Flow |
4 bytes |
INT16 |
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 |
|
7 |
Fw temp |
4 bytes |
INT16 |
Forward temperature (°C) 025Axxxx = xxxx * 0.1 °C 025Bxxxx = xxxx * °C |
|
8 |
Rt temp |
4 bytes |
INT16 |
Return temperature (°C) 025Exxxx = xxxx * 0.1 °C 025Fxxxx = xxxx °C |
|
9 |
Error flags |
5 bytes |
INT16 |
Error and warning flags 02FD17xxxx For further information about Error flags, refer to the latest meter’s manual |
|
10 |
Tariff 1 Energy |
7 bytes |
INT32 |
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 |
|
11 |
Tariff 2 Energy |
7 bytes |
INT32 |
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 |
|
12 |
Tariff 3 Energy |
7 bytes |
INT32 |
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 |
|
13 |
Missing time |
6 bytes |
INT32 |
3C22xxxxxxxx = xxxxxxxx hours 3C23xxxxxxxx = xxxxxxxx days |
When using JSON message encoding, messages sent consist of an object with a list of key – value pairs. Example of the names for each value type and unit are presented in the table below. The values are encoded as numbers or strings and the units are encoded as strings. JSON provides human-readable encoding, at the expense of not being equally compact as e.g. SenML/CBOR.
Table 11. Payload, JSON encoded message
|
Field |
JSON key |
|---|---|
|
Meter ID |
ID |
|
Meter date / time |
TS |
|
Energy |
E |
|
Energy unit |
U |
|
Volume |
V |
|
Volume unit |
VU |
|
Power |
P |
|
Power unit |
PU |
|
Flow |
F |
|
Flow unit |
FU |
|
Forward temperature |
FT |
|
Forward temperature unit |
TU |
|
Return temperature |
RT |
|
Return temperature unit |
RU |
|
Error flags |
EF |
|
Tariff 1 Energy |
T1 |
|
Tariff 1 Energy unit |
U1 |
|
Tariff 2 Energy |
T2 |
|
Tariff 2 Energy unit |
U2 |
|
Tariff 3 Energy |
T3 |
|
Tariff 3 Energy unit |
U3 |
|
Missing time |
MT |
|
Missing time unit |
MU |
Example payload, JSON:
{
"TS":"2025-11-28T20:39Z",
"ID":87654321,
"E":12345.678,
"U":"MWh",
"V":3456.7,
"VU":"m3",
"P":5012,
"PU":"W",
"F":212,
"FU":"l/h",
"FT":80.3,
"TU":"C",
"RT":53.8,
"RU":"C",
"EF":"0x4012"
}
For battery-powered devices it is recommended to send several measurements in the same UDP frame to save energy. In order to achieve this, SenML (Sensor Measurement Lists) + CBOR (Concise Binary Object Representation) 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 savings (in 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.
Elvaco uses SenML/CBOR/M-Bus data representation for transferring meter data in a compact and self-describing manner. The data being transferred is referred to as a pack, containing one record per measurement.
Note
SenML, CBOR and M-Bus are separate standards, this section 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.
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.
Note
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. Thus, this specification alone is not sufficient for building a parser for a specific product.
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)
-
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 is used to represent the MeterID (Meter identification in M-Bus) for products that deliver measurement data for one meter.
-
If base name is used
-
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.
-
-
If readouts to be sent contain different MeterIDs (module moved between meters for instance) they must NOT be sent in the same SenML pack
-
All values within a SenML pack MUST be for the same MeterID
-
The data values SHALL NOT have a name value further specifying the name for each value.
-
-
Base name SHALL NOT be used for SenML packs that have data for multiple meters. In such cases each record shall contain the MeterID of the meter.
-
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”)
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-F, a-f, 0-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:
|
Record |
Name field |
Comment |
|---|---|---|
|
Encoder Type & Version |
”V” |
This field allows defining versions for the contents of the measurement field. |
|
Extended Error Information |
"I" |
This record allows for sending extended information on a measurement, such as error information. |
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 the table below
-
Size of whole record is maximum 7 bytes
-
-
If record is excluded, encoder type is 0 and encoder version is 0
|
Encoder Type |
Encoder Version |
Data |
Comment |
|---|---|---|---|
|
0 (M-Bus) |
0 |
0x0000 |
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. |
|
1 (Gateway) |
0 |
0x0100 |
Gateway for meter data, i.e., data for multiple meters are contained in a single pack. Payload can be of various types depending on the interface used. Example of payload format is unencrypted or encrypted M-Bus data, with additional meta data. This encoder type is currently not relevant for Elvaco meter connectivity products. |
|
2 (Syslog) |
0 |
0x0200 |
Syslog data message encoded as an ASCII hex string. Key 2 indicates Log level. See section covering Module system log for details on the values for each level. |
|
3 (Transparent M-Bus) |
0 |
0x0300 |
Transparent M-Bus data. The payload contains a full (wired) M-Bus telegram, including both header and CRC. This encoder type is relevant when using the measurement mode meter-controlled Transparent. |
This record is used to send extended information that cannot be sent as part of the normal meter readout data. Typical use case is additional error codes from the meter/device.
-
The format of the extended information is specific for the selected encoder. See table below.
-
The detailed interpretation of the information is product specific. For instance error codes for a meter is specific for a particular meter, even though they are encoded using M-Bus.
-
It is encoded as a SenML data Value
-
It has a Name field “I”
-
It shall contain a timestamp
-
The timestamp can be the same as another meter data record and then these two records shall be considered having been taken at the same time.
-
-
The extended information is an optional record
|
Encoder type |
Encoder version |
Format of extended error information |
|---|---|---|
|
0 (M-Bus) |
0 |
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. |
|
1 (Gateway) |
0 |
Not relevant for Elvaco meter connectivity modules. |
|
2 (Syslog) |
0 |
Not defined yet |
|
3 (Transparent M-Bus) |
0 |
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. |
Below shows an example payload and how it can be decoded. The payload consists of three records; first the Encoder Type and Version, second an ordinary meter reading including Base Name (Meter ID) and Base Time, and third, extended information, which in this case corresponds to the extended error codes.
Raw CBOR encoded payload (hex):
83A20061560200A32168363636393236333722C11A691C43A0085821040637570A000414EF472000022B0000023BFDFF025B0000025F000002FD170400A3006149084502FD1804000600
Decoding this payload using e.g. https://cbor.me/, the CBOR-structure unfolds:
01 83 # array(3) 02 A2 # map(2) 03 00 # unsigned(0) 04 61 # text(1) 05 56 # "V" 06 02 # unsigned(2) 07 00 # unsigned(0) 08 A3 # map(3) 09 21 # negative(1) 10 68 # text(8) 11 3636363932363337 # "66692637" 12 22 # negative(2) 13 C1 # tag(1) 14 1A 691C43A0 # unsigned(1763460000) 15 08 # unsigned(8) 16 58 21 # bytes(33) 17 040637570A000414EF472000022B0000023BFDFF025B0000025F000002FD170400 # "\u0004\u00067W\n\u0000\u0004\u0014\xEFG \u0000\u0002+\u0000\u0000\u0002;\xFD\xFF\u0002[\u0000\u0000\u0002_\u0000\u0000\u0002\xFD\u0017\u0004\u0000" 18 A3 # map(3) 19 00 # unsigned(0) 20 61 # text(1) 21 49 # "I" 22 08 # unsigned(8) 23 45 # bytes(5) 24 02FD180400 # "\u0002\xFD\u0018\u0004\u0000" 25 06 # unsigned(6) 26 00 # unsigned(0)
Written on a more compact form, this gives:
[{0: "V", 2: 0}, {-2: "66692637", -3: 1(1763460000), 8: h'040637570A000414EF472000022B0000023BFDFF025B0000025F000002FD170400'}, {0: "I", 8: h'02FD180400', 6: 0}]
Note
Since this pack includes the extended error information (in the third record), this pack has been sent as an alarm. This means that it has been published to a separate topic (if using MQTT-SN) or as an instance of the Meter data object 33911 (if using LwM2M Send).
Below is some real-life sample payload. Note that several (5) meter readings are included in this one package. One meter reading fits in one record. In the first record of the pack, the Base Time and Base Name (MeterID) are given. In the last record, the Encoder Type and Version are given, allowing correct interpretation and parsing of the data.
Raw payload (Base64):
hqMhaDcxOTUxMzE4IsEaZtB0VAhYIQQGAHcDAAQUYdgKAAItEwACO1QBAlogAgJe8AEC/RcAAKIGOQODCFghBAYAdwMABBRY2AoAAi0TAAI7VAECWh8CAl7wAQL9FwAAogY5BwcIWCEEBv92AwAEFFDYCgACLRgAAjteAQJaHwICXuMBAv0XAACiBjkKiwhYIQQG/3YDAAQUR9gKAAItEwACO1QBAloeAgJe7wEC/RcAAKIGOQ4PCFghBAb+dgMABBQ/2AoAAi0UAAI7SgECWiACAl7sAQL9FwAAogBhVgIA
Decoding this, using e.g.CBOR decoder, the CBOR-structure unfolds:
1 86 # array(6) 2 A3 # map(3) 3 21 # negative(1) 4 68 # text(8) 5 3731393531333138 # "71951318" 6 22 # negative(2) 7 C1 # tag(1) 8 1A 66D07454 # unsigned(1724937300) # "2024-08-29T13:15:00Z" 9 08 # unsigned(8) 10 58 21 # bytes(33) 11 040600770300041461D80A00022D1300023B5401025A2002025EF00102FD170000 12 A2 # map(2) 13 06 # unsigned(6) 14 39 0383 # negative(899) # "2024-08-29T13:00:00Z" 15 08 # unsigned(8) 16 58 21 # bytes(33) 17 040600770300041458D80A00022D1300023B5401025A1F02025EF00102FD170000 18 A2 # map(2) 19 06 # unsigned(6) 20 39 0707 # negative(1799) # "2024-08-29T12:45:00Z" 21 08 # unsigned(8) 22 58 21 # bytes(33) 23 0406FF760300041450D80A00022D1800023B5E01025A1F02025EE30102FD170000 24 A2 # map(2) 25 06 # unsigned(6) 26 39 0A8B # negative(2699) # "2024-08-29T12:30:00Z" 27 08 # unsigned(8) 28 58 21 # bytes(33) 29 0406FF760300041447D80A00022D1300023B5401025A1E02025EEF0102FD170000 30 A2 # map(2) 31 06 # unsigned(6) 32 39 0E0F # negative(3599) # "2024-08-29T12:15:00Z" 33 08 # unsigned(8) 34 58 21 # bytes(33) 35 0406FE76030004143FD80A00022D1400023B4A01025A2002025EEC0102FD170000 36 A2 # map(2) 37 00 # unsigned(0) 38 61 # text(1) 39 56 # "V" 40 02 # unsigned(2) 41 00 # unsigned(0)
At https://cbor.me/, there's a Validator available for CBOR. Note that it does not understand SenML or M-Bus.
Note
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.
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.
|
Parameter |
Value |
|---|---|
|
Readout interval |
60 |
|
Transmit interval |
1440 (daily) |
|
Message encoding |
SenML/CBOR/M-Bus version 0 |
|
Message format |
Standard |
|
Max transmissions per day |
3 |
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)
|
Parameter |
Value |
|---|---|
|
Readout interval |
120 |
|
Transmit interval |
720 |
|
Message encoding |
SenML/CBOR/M-Bus version 0 |
|
Message format |
Tariff |
|
Max transmissions per day |
2 |
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).
Table 12. Settings for controlling the local access to the device
|
LwM2M resource |
Setting |
Description |
|---|---|---|
|
33906/./4 |
NFC Enabled |
Boolean. Turns on or off the NFC interface of the device. If disabled, it's not possible to do any local configuration to the device. |
|
33906/./5 |
NFC Config-locked |
Boolean. Turn the NFC configuration lock on or off. If enabled, it will not be possible to do any local configuration to the device, unless having the PAK at hand. |
Table 13. Settings for controlling the automatic NFC configuration lock
|
LwM2M resource |
Setting |
Description |
|---|---|---|
|
33906/./71 |
Enable NFC automatic configuration Lock |
Boolean. Turn the automatic NFC configuration lock On or Off. If turned on, the configuration lock will be enabled after the Automatic lock timeout has elapsed. The timer is started once the device has been activated. |
|
33906/./72 |
Automatic NFC configuration lock timeout |
Time in minutes. Sets the time in minutes before the configuration lock will be enabled upon activation (requires the NFC automatic configuration lock to be enabled). |
Comments (0 comments)