@@ -71,23 +71,13 @@ struct FixedValue {
7171template <typename T, const char * _unit, const char * _int_unit>
7272struct FixedField : ParsedField<T> {
7373 ParseResult<void > parse (const char * str, const char * end) {
74- // Check if the value is a float value, plus its expected unit type.
75- ParseResult<uint32_t > res_float = NumParser::parse (3 , _unit, str, end);
76- if (!res_float.err ) {
77- static_cast <T*>(this )->val ()._value = res_float.result ;
78- return res_float;
79- }
80- // If not, then check for an int value, plus its expected unit type.
81- // This accomodates for some smart meters that publish int values instead
82- // of floats. E.g. most meters would publish "1-0:1.8.0(000441.879*kWh)",
74+ // Some smart meters publish int values instead of a float.
75+ // E.g. most meters would publish "1-0:1.8.0(000441.879*kWh)",
8376 // but some use "1-0:1.8.0(000441879*Wh)" instead.
84- ParseResult<uint32_t > res_int = NumParser::parse (0 , _int_unit, str, end);
85- if (!res_int.err ) {
86- static_cast <T*>(this )->val ()._value = res_int.result ;
87- return res_int;
88- }
89- // If not, then return the initial error result for the float parsing step.
90- return res_float;
77+ auto res = NumParser::parse_float_or_int (3 , _unit, _int_unit, str, end);
78+ if (!res.err )
79+ static_cast <T*>(this )->val ()._value = res.result ;
80+ return res;
9181 }
9282
9383 static const char * unit () noexcept { return _unit; }
@@ -199,12 +189,9 @@ struct AveragedFixedField : public FixedField<T, _unit, _int_unit> {
199189 return res;
200190
201191 // parse value (04.329*kW) or (04329*W)
202- auto monthValue = NumParser::parse (3 , _unit, res.next , end);
203- if (monthValue.err ) {
204- monthValue = NumParser::parse (0 , _int_unit, res.next , end);
205- if (monthValue.err )
206- return monthValue;
207- }
192+ auto monthValue = NumParser::parse_float_or_int (3 , _unit, _int_unit, res.next , end);
193+ if (monthValue.err )
194+ return monthValue;
208195
209196 average.next = monthValue.next ;
210197 average.result += monthValue.result ;
@@ -260,14 +247,14 @@ const uint8_t WATER_MBUS_ID = DSMR_WATER_MBUS_ID;
260247const uint8_t THERMAL_MBUS_ID = DSMR_THERMAL_MBUS_ID;
261248const uint8_t SUB_MBUS_ID = DSMR_SUB_MBUS_ID;
262249
263- #define DEFINE_FIELD (fieldname, value_t , obis, field_t , ...) \
264- struct fieldname : field_t <fieldname __VA_OPT__ (, __VA_ARGS__)> { \
265- value_t fieldname; \
266- bool fieldname##_present = false ; \
267- static inline constexpr ObisId id = obis; \
268- static inline constexpr char name[] = #fieldname; \
269- value_t & val () { return fieldname; } \
270- bool & present () { return fieldname##_present; } \
250+ #define DEFINE_FIELD (fieldname, value_t , obis, field_t , ...) \
251+ struct fieldname : field_t <fieldname __VA_OPT__ (, __VA_ARGS__)> { \
252+ value_t fieldname; \
253+ bool fieldname##_present = false ; \
254+ static inline constexpr ObisId id = obis; \
255+ static inline constexpr char name[] = #fieldname; \
256+ value_t & val () { return fieldname; } \
257+ bool & present () { return fieldname##_present; } \
271258 }
272259
273260// Meter identification. This is not a normal field, but a specially-formatted first line of the message
@@ -514,6 +501,8 @@ DEFINE_FIELD(gas_valve_position, uint8_t, ObisId(0, GAS_MBUS_ID, 24, 4, 0), IntF
514501// Last 5-minute value (temperature converted), gas delivered to client
515502// in m3, including decimal values and capture time (Note: 4.x spec has "hourly value")
516503DEFINE_FIELD (gas_delivered, TimestampedFixedValue, ObisId(0 , GAS_MBUS_ID, 24 , 2 , 1 ), TimestampedFixedField, units::m3, units::dm3);
504+ // Eneco in the Netherlands has smart meters for their district heating network, which uses the gas_delivered in GJ rather than m3
505+ DEFINE_FIELD (gas_delivered_gj, TimestampedFixedValue, ObisId(0 , GAS_MBUS_ID, 24 , 2 , 1 ), TimestampedFixedField, units::GJ, units::MJ);
517506// _BE
518507DEFINE_FIELD (gas_delivered_be, TimestampedFixedValue, ObisId(0 , GAS_MBUS_ID, 24 , 2 , 3 ), TimestampedFixedField, units::m3, units::dm3);
519508DEFINE_FIELD (gas_delivered_text, std::string, ObisId(0 , GAS_MBUS_ID, 24 , 3 , 0 ), RawField);
0 commit comments