Skip to content

Commit a599bce

Browse files
geduxasPolarGoose
authored andcommitted
Fix Test for active_demand_net
Add PF obis fields Add negative value support, add active_demand_net
1 parent 62481cf commit a599bce

File tree

5 files changed

+49
-17
lines changed

5 files changed

+49
-17
lines changed
572 KB
Binary file not shown.

src/dsmr_parser/fields.h

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ struct TimestampField : StringField<T, 13, 13> {};
5656
struct FixedValue {
5757
operator float() const noexcept { return val(); }
5858
float val() const noexcept { return static_cast<float>(_value) / 1000.0f; }
59-
uint32_t int_val() const noexcept { return _value; }
59+
int32_t int_val() const noexcept { return _value; }
6060

61-
uint32_t _value;
61+
int32_t _value;
6262
};
6363

6464
// Floating point numbers in the message never have more than 3 decimal
@@ -132,7 +132,7 @@ struct LastFixedField : public FixedField<T, _unit, _int_unit> {
132132
template <typename T, const char* _unit>
133133
struct IntField : ParsedField<T> {
134134
ParseResult<void> parse(const char* str, const char* end) {
135-
ParseResult<uint32_t> res = NumParser::parse(0, _unit, str, end);
135+
ParseResult<int32_t> res = NumParser::parse(0, _unit, str, end);
136136
if (!res.err) {
137137
auto& dst = static_cast<T*>(this)->val();
138138
using Dst = std::remove_reference_t<decltype(dst)>;
@@ -174,10 +174,10 @@ struct AveragedFixedField : public FixedField<T, _unit, _int_unit> {
174174
if (res.err)
175175
return res;
176176

177-
ParseResult<uint32_t> average;
178-
average.succeed(0u);
177+
ParseResult<int32_t> average;
178+
average.succeed(0);
179179
average.next = res.next;
180-
for (uint32_t i = 0; i < numberOfValues.result; i++) {
180+
for (int32_t i = 0; i < numberOfValues.result; i++) {
181181
// skip date (230201000000W)
182182
res = StringParser::parse_string(1, 20, average.next, end);
183183
if (res.err)
@@ -482,8 +482,7 @@ DEFINE_FIELD(apparent_return_power_l3, FixedValue, ObisId(1, 0, 70, 7, 0), Fixed
482482
// Active Demand Avg3 Plus in W resolution
483483
DEFINE_FIELD(active_demand_power, FixedValue, ObisId(1, 0, 1, 24, 0), FixedField, units::kW, units::W);
484484
// Active Demand Avg3 Net in W resolution
485-
// TODO: 1-0.16.24.0.255 can have negative value, this library is not ready for negative numbers.
486-
// DEFINE_FIELD(active_demand_net, int32_t, ObisId(1, 0, 16, 24, 0), IntField, units::kW);
485+
DEFINE_FIELD(active_demand_net, FixedValue, ObisId(1, 0, 16, 24, 0), FixedField, units::kW, units::W);
487486
// Active Demand Avg3 Absolute in W resolution
488487
DEFINE_FIELD(active_demand_abs, FixedValue, ObisId(1, 0, 15, 24, 0), FixedField, units::kW, units::W);
489488

@@ -572,5 +571,12 @@ DEFINE_FIELD(fw_core_checksum, std::string, ObisId(1, 0, 0, 2, 8), StringField,
572571
DEFINE_FIELD(fw_module_version, std::string, ObisId(1, 1, 0, 2, 0), StringField, 0, 96);
573572
DEFINE_FIELD(fw_module_checksum, std::string, ObisId(1, 1, 0, 2, 8), StringField, 0, 96);
574573

574+
/* Power Factor*/
575+
DEFINE_FIELD(power_factor, FixedValue, ObisId(1, 0, 13, 7, 0),FixedField, units::none, units::none);
576+
DEFINE_FIELD(power_factor_l1, FixedValue, ObisId(1, 0, 33, 7, 0),FixedField, units::none, units::none);
577+
DEFINE_FIELD(power_factor_l2, FixedValue, ObisId(1, 0, 53, 7, 0),FixedField, units::none, units::none);
578+
DEFINE_FIELD(power_factor_l3, FixedValue, ObisId(1, 0, 73, 7, 0),FixedField, units::none, units::none);
579+
DEFINE_FIELD(min_power_factor, FixedValue, ObisId(1, 0, 13, 3, 0),FixedField, units::none, units::none);
580+
575581
}
576582
}

src/dsmr_parser/parser.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ static constexpr char INVALID_NUMBER[] = "Invalid number";
105105
static constexpr char INVALID_UNIT[] = "Invalid unit";
106106

107107
struct NumParser final {
108-
static ParseResult<uint32_t> parse_float_or_int(const size_t max_decimals, const char* float_unit, const char* int_unit, const char* str, const char* end) {
108+
static ParseResult<int32_t> parse_float_or_int(const size_t max_decimals, const char* float_unit, const char* int_unit, const char* str, const char* end) {
109109
auto float_res = NumParser::parse(max_decimals, float_unit, str, end);
110110
if (!float_res.err)
111111
return float_res;
@@ -117,22 +117,28 @@ struct NumParser final {
117117
return float_res;
118118
}
119119

120-
static ParseResult<uint32_t> parse(size_t max_decimals, const char* unit, const char* str, const char* end) {
121-
ParseResult<uint32_t> res;
120+
static ParseResult<int32_t> parse(size_t max_decimals, const char* unit, const char* str, const char* end) {
121+
ParseResult<int32_t> res;
122122
if (str >= end || *str != '(')
123123
return res.fail("Missing (", str);
124124

125125
const char* num_start = str + 1; // Skip (
126126
const char* num_end = num_start;
127127

128-
uint32_t value = 0;
128+
bool negative = false;
129+
if (num_end < end && *num_end == '-') {
130+
negative = true;
131+
++num_end;
132+
}
133+
134+
int32_t value = 0;
129135

130136
// Parse integer part
131137
while (num_end < end && !strchr("*.)", *num_end)) {
132138
if (*num_end < '0' || *num_end > '9')
133139
return res.fail(INVALID_NUMBER, num_end);
134140
value *= 10;
135-
value += static_cast<uint32_t>(*num_end - '0');
141+
value += (*num_end - '0');
136142
++num_end;
137143
}
138144

@@ -145,7 +151,7 @@ struct NumParser final {
145151
if (*num_end < '0' || *num_end > '9')
146152
return res.fail(INVALID_NUMBER, num_end);
147153
value *= 10;
148-
value += static_cast<uint32_t>(*num_end - '0');
154+
value += (*num_end - '0');
149155
++num_end;
150156
}
151157
}
@@ -179,6 +185,8 @@ struct NumParser final {
179185
if (num_end >= end || *num_end != ')')
180186
return res.fail("Extra data", num_end);
181187

188+
if (negative) value = -value;
189+
182190
return res.succeed(value).until(num_end + 1); // Skip )
183191
}
184192
};

src/dsmr_parser/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct _ParseResult {
6868

6969
template <class U>
7070
P& succeed(U&& value) {
71-
result = std::forward<U>(value);
71+
result = static_cast<T>(std::forward<U>(value));
7272
return *static_cast<P*>(this);
7373
}
7474
};

tests/parser_test.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ TEST_CASE("Should parse all fields in the DSMR message correctly") {
4949
"1-1:0.2.0((ER12)\r\n"
5050
"1-1:0.2.8(ER13))\r\n"
5151
"0-1:24.4.0(1)\r\n"
52-
"!96c9\r\n";
52+
"1-0:16.24.0(-03.618*kW)\r\n"
53+
"1-0:13.7.0(0.998)\r\n"
54+
"1-0:33.7.0(0.975)\r\n"
55+
"1-0:53.7.0(0.963)\r\n"
56+
"1-0:73.7.0(0.987)\r\n"
57+
"1-0:13.3.0(0.000)\r\n"
58+
"!6f8f\r\n";
5359

5460
ParsedData<
5561
/* String */ identification,
@@ -104,7 +110,13 @@ TEST_CASE("Should parse all fields in the DSMR message correctly") {
104110
/* String */ fw_core_version,
105111
/* String */ fw_core_checksum,
106112
/* String */ fw_module_version,
107-
/* String */ fw_module_checksum>
113+
/* String */ fw_module_checksum,
114+
/* FixedValue */ active_demand_net,
115+
/* FixedValue */ power_factor,
116+
/* FixedValue */ power_factor_l1,
117+
/* FixedValue */ power_factor_l2,
118+
/* FixedValue */ power_factor_l3,
119+
/* FixedValue */ min_power_factor>
108120
data;
109121

110122
auto res = P1Parser::parse(data, msg, std::size(msg), true);
@@ -146,6 +158,12 @@ TEST_CASE("Should parse all fields in the DSMR message correctly") {
146158
REQUIRE(data.fw_core_checksum == "1.0.smth smth-123");
147159
REQUIRE(data.fw_module_version == "(ER12");
148160
REQUIRE(data.fw_module_checksum == "ER13)");
161+
REQUIRE(data.active_demand_net == -3.618f);
162+
REQUIRE(data.power_factor == 0.998f);
163+
REQUIRE(data.power_factor_l1 == 0.975f);
164+
REQUIRE(data.power_factor_l2 == 0.963f);
165+
REQUIRE(data.power_factor_l3 == 0.987f);
166+
REQUIRE(data.min_power_factor == 0.0f);
149167
}
150168

151169
TEST_CASE("Should report an error if the crc has incorrect format") {

0 commit comments

Comments
 (0)