diff --git a/README.md b/README.md index 5b62258..1a13f9f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ -Arduino Dutch Smart meter (DSMR) parser -======================================= -This is an Arduino library for interfacing with Dutch smart meters, through +Arduino Dutch and Belgium Smart meter (DSMR) parser +=================================================== +This library is a fork from the original Arduino Dutch Smart Meter parser, made by Matthijs Kooijman. It is made so it can be a full replacement for the original library, if you use the switch #define DSMR_IN_BELIGUM in your code, then the definition of the fields is switched to the Belgium specification. + +This is an Arduino library for interfacing with Dutch and Belgium smart meters, through their P1 port. This library can take care of controlling the "request" pin, reading messages and parsing them. diff --git a/library.properties b/library.properties index 5c272df..2e93f8b 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ -name=Dsmr -author=Matthijs Kooijman -email=matthijs@stdin.nl -sentence=Parser and utilities for Dutch Smart Meters (Implementing DSMR) +name=Dsmr-be-nl +author=Robert van den Breemen +email=robert@vandenbreemen.net +sentence=Parser and utilities for Dutch and Belgium Smart Meters (Implementing DSMR) paragraph= category=Data Processing -url=https://github.com/matthijskooijman/arduino-dsmr +url=https://github.com/rvdbreemen/arduino-dsmr-nl-be architectures=* version=0.1 dependencies= diff --git a/specs/Belgium Fluvius extention specification/1901-fluvius-technical-specification-user-ports-digital-meter.pdf b/specs/Belgium Fluvius extention specification/1901-fluvius-technical-specification-user-ports-digital-meter.pdf new file mode 100644 index 0000000..9606063 Binary files /dev/null and b/specs/Belgium Fluvius extention specification/1901-fluvius-technical-specification-user-ports-digital-meter.pdf differ diff --git a/specs/Belgium Fluvius extention specification/e-MUCS_H_Ed_1_3.docx b/specs/Belgium Fluvius extention specification/e-MUCS_H_Ed_1_3.docx new file mode 100644 index 0000000..6ca3cb8 Binary files /dev/null and b/specs/Belgium Fluvius extention specification/e-MUCS_H_Ed_1_3.docx differ diff --git a/specs/Belgium Fluvius extention specification/voorbeelden.txt b/specs/Belgium Fluvius extention specification/voorbeelden.txt new file mode 100644 index 0000000..0bc013e --- /dev/null +++ b/specs/Belgium Fluvius extention specification/voorbeelden.txt @@ -0,0 +1,200 @@ +/FLU5\253770234_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414731313030303331373636) +0-0:1.0.0(200104202329W) +1-0:1.8.1(000180.802*kWh) +1-0:1.8.2(000161.920*kWh) +1-0:2.8.1(000000.001*kWh) +1-0:2.8.2(000000.025*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.364*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(240.9*V) +1-0:31.7.0(001*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +0-1:24.1.0(003) +0-1:96.1.1(37464C4F32313139303935333131) +0-1:24.4.0(1) +0-1:24.2.3(200104202004W)(00385.264*m3) +!XXXX + +--------- + + + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200225180427W) +1-0:1.8.1(000750.826*kWh) +1-0:1.8.2(000830.366*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0001) +1-0:1.7.0(00.921*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(227.3*V) +1-0:52.7.0(233.1*V) +1-0:72.7.0(229.5*V) +1-0:31.7.0(000*A) +1-0:51.7.0(003*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +0-1:24.1.0(003) +0-1:96.1.1(37464C4F32313139303835363835) +0-1:24.4.0(1) +0-1:24.2.3(200225180258W)(00000.255*m3) +!09EF + + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200207211650W) +1-0:1.8.1(000604.154*kWh) +1-0:1.8.2(000640.405*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0001) +1-0:1.7.0(00.643*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(223.0*V) +1-0:52.7.0(233.0*V) +1-0:72.7.0(229.5*V) +1-0:31.7.0(000*A) +1-0:51.7.0(001*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!BCCF + +p/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200209122751W) +1-0:1.8.1(000604.603*kWh) +1-0:1.8.2(000675.909*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.701*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(228.7*V) +1-0:52.7.0(235.2*V) +1-0:72.7.0(232.9*V) +1-0:31.7.0(000*A) +1-0:51.7.0(002*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!E9F6 + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200209122752W) +1-0:1.8.1(000604.603*kWh) +1-0:1.8.2(000675.909*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.693*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(228.7*V) +1-0:52.7.0(235.2*V) +1-0:72.7.0(232.9*V) +1-0:31.7.0(000*A) +1-0:51.7.0(002*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!0FD9 + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200209122753W) +1-0:1.8.1(000604.603*kWh) +1-0:1.8.2(000675.909*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.696*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(228.5*V) +1-0:52.7.0(235.1*V) +1-0:72.7.0(233.1*V) +1-0:31.7.0(000*A) +1-0:51.7.0(002*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!AD77 + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200209122754W) +1-0:1.8.1(000604.603*kWh) +1-0:1.8.2(000675.910*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.698*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(228.8*V) +1-0:52.7.0(235.1*V) +1-0:72.7.0(233.0*V) +1-0:31.7.0(000*A) +1-0:51.7.0(002*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!16EC + +/FLU5\253769484_A + +0-0:96.1.4(50213) +0-0:96.1.1(3153414733313030303130383431) +0-0:1.0.0(200209122755W) +1-0:1.8.1(000604.603*kWh) +1-0:1.8.2(000675.910*kWh) +1-0:2.8.1(000000.005*kWh) +1-0:2.8.2(000000.204*kWh) +0-0:96.14.0(0002) +1-0:1.7.0(00.692*kW) +1-0:2.7.0(00.000*kW) +1-0:32.7.0(229.0*V) +1-0:52.7.0(234.9*V) +1-0:72.7.0(233.2*V) +1-0:31.7.0(000*A) +1-0:51.7.0(002*A) +1-0:71.7.0(000*A) +0-0:96.3.10(1) +0-0:17.0.0(999.9*kW) +1-0:31.4.0(999*A) +0-0:96.13.0() +!0A72 diff --git a/src/dsmr.h b/src/dsmr.h index ced73ec..d81d71b 100644 --- a/src/dsmr.h +++ b/src/dsmr.h @@ -32,6 +32,9 @@ #ifndef DSMR_INCLUDE_DSMR_H #define DSMR_INCLUDE_DSMR_H +// If in belgium, make sure the next line is uncommented +// #define DSRM_IN_BELGIUM + #include "dsmr/parser.h" #include "dsmr/reader.h" #include "dsmr/fields.h" diff --git a/src/dsmr/fields.h b/src/dsmr/fields.h index a6a10f5..a10ed9e 100644 --- a/src/dsmr/fields.h +++ b/src/dsmr/fields.h @@ -146,7 +146,10 @@ struct RawField : ParsedField { } }; -namespace fields { + +#ifndef DSRM_IN_BELGIUM +//Default is the Dutch DSMR specification +namespace fields { // Dutch DSMR specification struct units { // These variables are inside a struct, since that allows us to make @@ -347,6 +350,217 @@ DEFINE_FIELD(slave_delivered, TimestampedFixedValue, ObisId(0, SLAVE_MBUS_ID, 24 } // namespace fields +#else // Belgium definition starts here +namespace fields { + //This is the DSMR specification for the Belgium DSMR - specification 5.0.2 - with Belgium extentention + //Link: Fluvius Specification document: https://www.fluvius.be/sites/fluvius/files/2019-07/1901-fluvius-technical-specification-user-ports-digital-meter.pdf + //Link: Specification document Belgium https://onedrive.live.com/view.aspx?resid=EAEC8CA1B66CDF7B!245341&ithint=file%2Cdocx&authkey=!ABXM6pDlhjeOr7A + +struct units { + // These variables are inside a struct, since that allows us to make + // them constexpr and define their values here, but define the storage + // in a cpp file. Global const(expr) variables have implicitly + // internal linkage, meaning each cpp file that includes us will have + // its own copy of the variable. Since we take the address of these + // variables (passing it as a template argument), this would cause a + // compiler warning. By putting these in a struct, this is prevented. + static constexpr char none[] = ""; + static constexpr char kWh[] = "kWh"; + static constexpr char Wh[] = "Wh"; + static constexpr char kW[] = "kW"; + static constexpr char W[] = "W"; + static constexpr char V[] = "V"; + static constexpr char mV[] = "mV"; + static constexpr char A[] = "A"; + static constexpr char mA[] = "mA"; + static constexpr char m3[] = "m3"; + static constexpr char dm3[] = "dm3"; + static constexpr char GJ[] = "GJ"; + static constexpr char MJ[] = "MJ"; +}; + +const uint8_t GAS_MBUS_ID = 1; +const uint8_t WATER_MBUS_ID = 2; +const uint8_t THERMAL_MBUS_ID = 3; +const uint8_t SLAVE_MBUS_ID = 4; + +#define DEFINE_FIELD(fieldname, value_t, obis, field_t, field_args...) \ + struct fieldname : field_t { \ + value_t fieldname; \ + bool fieldname ## _present = false; \ + static constexpr ObisId id = obis; \ + static constexpr char name_progmem[] DSMR_PROGMEM = #fieldname; \ + static constexpr const __FlashStringHelper *name = reinterpret_cast(&name_progmem); \ + value_t& val() { return fieldname; } \ + bool& present() { return fieldname ## _present; } \ + } + +/* Meter identification. This is not a normal field, but a + * specially-formatted first line of the message */ +DEFINE_FIELD(identification, String, ObisId(255, 255, 255, 255, 255, 255), RawField); + +/* Version information for P1 output */ +//DEFINE_FIELD(p1_version, String, ObisId(1, 3, 0, 2, 8), StringField, 2, 2); +DEFINE_FIELD(p1_version, String, ObisId(0, 0, 96, 1, 4), StringField, 0, 5); + +/* Date-time stamp of the P1 message */ +DEFINE_FIELD(timestamp, String, ObisId(0, 0, 1, 0, 0), TimestampField); + +/* Equipment identifier */ +DEFINE_FIELD(equipment_id, String, ObisId(0, 0, 96, 1, 1), StringField, 0, 96); + +/* Meter Reading electricity delivered to client (Tariff 1) in 0,001 kWh */ +DEFINE_FIELD(energy_delivered_tariff1, FixedValue, ObisId(1, 0, 1, 8, 1), FixedField, units::kWh, units::Wh); +/* Meter Reading electricity delivered to client (Tariff 2) in 0,001 kWh */ +DEFINE_FIELD(energy_delivered_tariff2, FixedValue, ObisId(1, 0, 1, 8, 2), FixedField, units::kWh, units::Wh); +/* Meter Reading electricity delivered by client (Tariff 1) in 0,001 kWh */ +DEFINE_FIELD(energy_returned_tariff1, FixedValue, ObisId(1, 0, 2, 8, 1), FixedField, units::kWh, units::Wh); +/* Meter Reading electricity delivered by client (Tariff 2) in 0,001 kWh */ +DEFINE_FIELD(energy_returned_tariff2, FixedValue, ObisId(1, 0, 2, 8, 2), FixedField, units::kWh, units::Wh); + +/* Tariff indicator electricity. The tariff indicator can also be used + * to switch tariff dependent loads e.g boilers. This is the + * responsibility of the P1 user */ +DEFINE_FIELD(electricity_tariff, String, ObisId(0, 0, 96, 14, 0), StringField, 4, 4); + +/* Actual electricity power delivered (+P) in 1 Watt resolution */ +DEFINE_FIELD(power_delivered, FixedValue, ObisId(1, 0, 1, 7, 0), FixedField, units::kW, units::W); +/* Actual electricity power received (-P) in 1 Watt resolution */ +DEFINE_FIELD(power_returned, FixedValue, ObisId(1, 0, 2, 7, 0), FixedField, units::kW, units::W); + +/* The actual threshold Electricity in kW. Removed in 4.0.7 / 4.2.2 / 5.0 */ +DEFINE_FIELD(electricity_threshold, FixedValue, ObisId(0, 0, 17, 0, 0), FixedField, units::kW, units::W); + +/* Switch position Electricity (in/out/enabled). Removed in 4.0.7 / 4.2.2 / 5.0 */ +DEFINE_FIELD(electricity_switch_position, uint8_t, ObisId(0, 0, 96, 3, 10), IntField, units::none); + +/* Number of power failures in any phase */ +DEFINE_FIELD(electricity_failures, uint32_t, ObisId(0, 0, 96, 7, 21), IntField, units::none); +/* Number of long power failures in any phase */ +DEFINE_FIELD(electricity_long_failures, uint32_t, ObisId(0, 0, 96, 7, 9), IntField, units::none); + +/* Power Failure Event Log (long power failures) */ +DEFINE_FIELD(electricity_failure_log, String, ObisId(1, 0, 99, 97, 0), RawField); + +/* Number of voltage sags in phase L1 */ +DEFINE_FIELD(electricity_sags_l1, uint32_t, ObisId(1, 0, 32, 32, 0), IntField, units::none); +/* Number of voltage sags in phase L2 (polyphase meters only) */ +DEFINE_FIELD(electricity_sags_l2, uint32_t, ObisId(1, 0, 52, 32, 0), IntField, units::none); +/* Number of voltage sags in phase L3 (polyphase meters only) */ +DEFINE_FIELD(electricity_sags_l3, uint32_t, ObisId(1, 0, 72, 32, 0), IntField, units::none); + +/* Number of voltage swells in phase L1 */ +DEFINE_FIELD(electricity_swells_l1, uint32_t, ObisId(1, 0, 32, 36, 0), IntField, units::none); +/* Number of voltage swells in phase L2 (polyphase meters only) */ +DEFINE_FIELD(electricity_swells_l2, uint32_t, ObisId(1, 0, 52, 36, 0), IntField, units::none); +/* Number of voltage swells in phase L3 (polyphase meters only) */ +DEFINE_FIELD(electricity_swells_l3, uint32_t, ObisId(1, 0, 72, 36, 0), IntField, units::none); + +/* Text message codes: numeric 8 digits (Note: Missing from 5.0 spec) + * */ +DEFINE_FIELD(message_short, String, ObisId(0, 0, 96, 13, 1), StringField, 0, 16); +/* Text message max 2048 characters (Note: Spec says 1024 in comment and + * 2048 in format spec, so we stick to 2048). */ +DEFINE_FIELD(message_long, String, ObisId(0, 0, 96, 13, 0), StringField, 0, 2048); + +/* Instantaneous voltage L1 in 0.1V resolution (Note: Spec says V + * resolution in comment, but 0.1V resolution in format spec. Added in + * 5.0) */ +DEFINE_FIELD(voltage_l1, FixedValue, ObisId(1, 0, 32, 7, 0), FixedField, units::V, units::mV); +/* Instantaneous voltage L2 in 0.1V resolution (Note: Spec says V + * resolution in comment, but 0.1V resolution in format spec. Added in + * 5.0) */ +DEFINE_FIELD(voltage_l2, FixedValue, ObisId(1, 0, 52, 7, 0), FixedField, units::V, units::mV); +/* Instantaneous voltage L3 in 0.1V resolution (Note: Spec says V + * resolution in comment, but 0.1V resolution in format spec. Added in + * 5.0) */ +DEFINE_FIELD(voltage_l3, FixedValue, ObisId(1, 0, 72, 7, 0), FixedField, units::V, units::mV); + +/* Instantaneous current L1 in A resolution */ +DEFINE_FIELD(current_l1, uint16_t, ObisId(1, 0, 31, 7, 0), IntField, units::A); +/* Instantaneous current L2 in A resolution */ +DEFINE_FIELD(current_l2, uint16_t, ObisId(1, 0, 51, 7, 0), IntField, units::A); +/* Instantaneous current L3 in A resolution */ +DEFINE_FIELD(current_l3, uint16_t, ObisId(1, 0, 71, 7, 0), IntField, units::A); + +/* Instantaneous active power L1 (+P) in W resolution */ +DEFINE_FIELD(power_delivered_l1, FixedValue, ObisId(1, 0, 21, 7, 0), FixedField, units::kW, units::W); +/* Instantaneous active power L2 (+P) in W resolution */ +DEFINE_FIELD(power_delivered_l2, FixedValue, ObisId(1, 0, 41, 7, 0), FixedField, units::kW, units::W); +/* Instantaneous active power L3 (+P) in W resolution */ +DEFINE_FIELD(power_delivered_l3, FixedValue, ObisId(1, 0, 61, 7, 0), FixedField, units::kW, units::W); + +/* Instantaneous active power L1 (-P) in W resolution */ +DEFINE_FIELD(power_returned_l1, FixedValue, ObisId(1, 0, 22, 7, 0), FixedField, units::kW, units::W); +/* Instantaneous active power L2 (-P) in W resolution */ +DEFINE_FIELD(power_returned_l2, FixedValue, ObisId(1, 0, 42, 7, 0), FixedField, units::kW, units::W); +/* Instantaneous active power L3 (-P) in W resolution */ +DEFINE_FIELD(power_returned_l3, FixedValue, ObisId(1, 0, 62, 7, 0), FixedField, units::kW, units::W); + + +/* Device-Type */ +DEFINE_FIELD(gas_device_type, uint16_t, ObisId(0, GAS_MBUS_ID, 24, 1, 0), IntField, units::none); + +/* Equipment identifier (Gas) */ +// DEFINE_FIELD(gas_equipment_id, String, ObisId(0, GAS_MBUS_ID, 96, 1, 0), StringField, 0, 96); +// Beligum gas equipment id OBIS +DEFINE_FIELD(gas_equipment_id, String, ObisId(0, GAS_MBUS_ID, 96, 1, 1), StringField, 0, 96); + +/* Valve position Gas (on/off/released) (Note: Removed in 4.0.7 / 4.2.2 / 5.0). */ +// Beligum gas valve position OBIS in extention on 5.0.2 +DEFINE_FIELD(gas_valve_position, uint8_t, ObisId(0, GAS_MBUS_ID, 24, 4, 0), IntField, units::none); + +/* Last 5-minute value (temperature converted), gas delivered to client + * in m3, including decimal values and capture time (Note: 4.x spec has + * "hourly value") */ +// Beligum gas_delivered OBIS: Last value of ‘not temperature corrected’ gas volume in m³, including decimal values and capture time +DEFINE_FIELD(gas_delivered, TimestampedFixedValue, ObisId(0, GAS_MBUS_ID, 24, 2, 3), TimestampedFixedField, units::m3, units::dm3); + +/* Device-Type */ +DEFINE_FIELD(thermal_device_type, uint16_t, ObisId(0, THERMAL_MBUS_ID, 24, 1, 0), IntField, units::none); + +/* Equipment identifier (Thermal: heat or cold) */ +DEFINE_FIELD(thermal_equipment_id, String, ObisId(0, THERMAL_MBUS_ID, 96, 1, 0), StringField, 0, 96); + +/* Valve position (on/off/released) (Note: Removed in 4.0.7 / 4.2.2 / 5.0). */ +DEFINE_FIELD(thermal_valve_position, uint8_t, ObisId(0, THERMAL_MBUS_ID, 24, 4, 0), IntField, units::none); + +/* Last 5-minute Meter reading Heat or Cold in 0,01 GJ and capture time + * (Note: 4.x spec has "hourly meter reading") */ +DEFINE_FIELD(thermal_delivered, TimestampedFixedValue, ObisId(0, THERMAL_MBUS_ID, 24, 2, 1), TimestampedFixedField, units::GJ, units::MJ); + + +/* Device-Type */ +DEFINE_FIELD(water_device_type, uint16_t, ObisId(0, WATER_MBUS_ID, 24, 1, 0), IntField, units::none); + +/* Equipment identifier (Thermal: heat or cold) */ +DEFINE_FIELD(water_equipment_id, String, ObisId(0, WATER_MBUS_ID, 96, 1, 0), StringField, 0, 96); + +/* Valve position (on/off/released) (Note: Removed in 4.0.7 / 4.2.2 / 5.0). */ +DEFINE_FIELD(water_valve_position, uint8_t, ObisId(0, WATER_MBUS_ID, 24, 4, 0), IntField, units::none); + +/* Last 5-minute Meter reading in 0,001 m3 and capture time + * (Note: 4.x spec has "hourly meter reading") */ +DEFINE_FIELD(water_delivered, TimestampedFixedValue, ObisId(0, WATER_MBUS_ID, 24, 2, 1), TimestampedFixedField, units::m3, units::dm3); + + +/* Device-Type */ +DEFINE_FIELD(slave_device_type, uint16_t, ObisId(0, SLAVE_MBUS_ID, 24, 1, 0), IntField, units::none); + +/* Equipment identifier (Thermal: heat or cold) */ +DEFINE_FIELD(slave_equipment_id, String, ObisId(0, SLAVE_MBUS_ID, 96, 1, 0), StringField, 0, 96); + +/* Valve position (on/off/released) (Note: Removed in 4.0.7 / 4.2.2 / 5.0). */ +DEFINE_FIELD(slave_valve_position, uint8_t, ObisId(0, SLAVE_MBUS_ID, 24, 4, 0), IntField, units::none); + +/* Last 5-minute Meter reading Heat or Cold and capture time (e.g. slave + * E meter) (Note: 4.x spec has "hourly meter reading") */ +DEFINE_FIELD(slave_delivered, TimestampedFixedValue, ObisId(0, SLAVE_MBUS_ID, 24, 2, 1), TimestampedFixedField, units::m3, units::dm3); + +} // namespace fields_belgium + +#endif + } // namespace dsmr #endif // DSMR_INCLUDE_FIELDS_H