• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wirenboard / wb-mqtt-serial / 1

08 Jul 2025 01:20PM UTC coverage: 73.854% (+1.0%) from 72.836%
1

Pull #963

github

39d9bc
KraPete
Bump version
Pull Request #963: Bump version

6444 of 9057 branches covered (71.15%)

12341 of 16710 relevant lines covered (73.85%)

305.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.3
/test/mercury230_test.cpp
1
#include "devices/mercury230_device.h"
2
#include "fake_serial_port.h"
3
#include "mercury230_expectations.h"
4
#include <string>
5

6
class TMercury230Test: public TSerialDeviceTest, public TMercury230Expectations
7
{
8
protected:
9
    void SetUp();
10
    void VerifyEnergyQuery();
11
    void VerifyParamQuery();
12

13
    virtual PDeviceConfig GetDeviceConfig() const;
14

15
    PMercury230Device Mercury230Dev;
16

17
    PRegister Mercury230TotalReactiveEnergyReg;
18
    PRegister Mercury230TotalConsumptionReg;
19
    PRegister Mercury230PReg;
20
    PRegister Mercury230P1Reg;
21
    PRegister Mercury230P2Reg;
22
    PRegister Mercury230P3Reg;
23
    PRegister Mercury230QReg;
24
    PRegister Mercury230Q1Reg;
25
    PRegister Mercury230Q2Reg;
26
    PRegister Mercury230Q3Reg;
27
    PRegister Mercury230U1Reg;
28
    PRegister Mercury230U2Reg;
29
    PRegister Mercury230U3Reg;
30
    PRegister Mercury230I1Reg;
31
    PRegister Mercury230I2Reg;
32
    PRegister Mercury230I3Reg;
33
    PRegister Mercury230FrequencyReg;
34
    PRegister Mercury230PFReg;
35
    PRegister Mercury230PF1Reg;
36
    PRegister Mercury230PF2Reg;
37
    PRegister Mercury230PF3Reg;
38
    PRegister Mercury230KU1Reg;
39
    PRegister Mercury230KU2Reg;
40
    PRegister Mercury230KU3Reg;
41
    PRegister Mercury230TempReg;
42
};
43

44
PDeviceConfig TMercury230Test::GetDeviceConfig() const
5✔
45
{
46
    return std::make_shared<TDeviceConfig>("mercury230", std::to_string(0x00), "mercury230");
10✔
47
}
48

49
void TMercury230Test::SetUp()
5✔
50
{
51
    TSerialDeviceTest::SetUp();
5✔
52

53
    Mercury230Dev = std::make_shared<TMercury230Device>(GetDeviceConfig(), DeviceFactory.GetProtocol("mercury230"));
5✔
54
    Mercury230TotalConsumptionReg =
55
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_VALUE_ARRAY, 0x00, U32));
5✔
56
    TRegisterDesc regAddress;
5✔
57
    regAddress.Address = std::make_shared<TUint32RegisterAddress>(0x00);
5✔
58
    regAddress.DataOffset = 2;
5✔
59
    Mercury230TotalReactiveEnergyReg =
60
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_VALUE_ARRAY, regAddress, U32));
5✔
61

62
    Mercury230PReg =
63
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1100, S24));
5✔
64
    Mercury230P1Reg =
65
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1101, S24));
5✔
66
    Mercury230P2Reg =
67
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1102, S24));
5✔
68
    Mercury230P3Reg =
69
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1103, S24));
5✔
70

71
    Mercury230QReg =
72
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_REACT, 0x1104, S24));
5✔
73
    Mercury230Q1Reg =
74
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_REACT, 0x1105, S24));
5✔
75
    Mercury230Q2Reg =
76
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_REACT, 0x1106, S24));
5✔
77
    Mercury230Q3Reg =
78
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_REACT, 0x1107, S24));
5✔
79

80
    Mercury230U1Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1111, U24));
5✔
81
    Mercury230U2Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1112, U24));
5✔
82
    Mercury230U3Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1113, U24));
5✔
83

84
    Mercury230I1Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1121, U24));
5✔
85
    Mercury230I2Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1122, U24));
5✔
86
    Mercury230I3Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1123, U24));
5✔
87

88
    Mercury230FrequencyReg =
89
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1140, U24));
5✔
90

91
    Mercury230PFReg =
92
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1130, S24));
5✔
93
    Mercury230PF1Reg =
94
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1131, S24));
5✔
95
    Mercury230PF2Reg =
96
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1132, S24));
5✔
97
    Mercury230PF3Reg =
98
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_SIGN_ACT, 0x1133, S24));
5✔
99

100
    Mercury230KU1Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1161, U16));
5✔
101
    Mercury230KU2Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1162, U16));
5✔
102
    Mercury230KU3Reg = Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM, 0x1163, U16));
5✔
103

104
    Mercury230TempReg =
105
        Mercury230Dev->AddRegister(TRegisterConfig::Create(TMercury230Device::REG_PARAM_BE, 0x1170, U16));
5✔
106

107
    SerialPort->Open();
5✔
108
}
5✔
109

110
TEST_F(TMercury230Test, ReadEnergy)
8✔
111
{
112
    EnqueueMercury230SessionSetupResponse();
2✔
113
    EnqueueMercury230EnergyResponse1();
2✔
114

115
    // Register address for energy arrays:
116
    // 0000 0000 CCCC CCCC TTTT AAAA MMMM IIII
117
    // C = command (0x05)
118
    // A = array number
119
    // M = month
120
    // T = tariff (FIXME!!! 5 values)
121
    // I = index
122
    // Note: for A=6, 12-byte and not 16-byte value is returned.
123
    // This is not supported at the moment.
124

125
    // Here we make sure that consecutive requests querying the same array
126
    // don't cause redundant requests during the single poll cycle.
127
    ASSERT_EQ(TRegisterValue{3196200},
4✔
128
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalConsumptionReg->GetConfig()));
129
    ASSERT_EQ(TRegisterValue{300444},
4✔
130
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalReactiveEnergyReg->GetConfig()));
131
    ASSERT_EQ(TRegisterValue{3196200},
4✔
132
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalConsumptionReg->GetConfig()));
133
    Mercury230Dev->InvalidateReadCache();
2✔
134

135
    EnqueueMercury230EnergyResponse2();
2✔
136
    ASSERT_EQ(TRegisterValue{3196201},
4✔
137
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalConsumptionReg->GetConfig()));
138
    ASSERT_EQ(TRegisterValue{300445},
4✔
139
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalReactiveEnergyReg->GetConfig()));
140
    ASSERT_EQ(TRegisterValue{3196201},
4✔
141
              Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TotalConsumptionReg->GetConfig()));
142
    Mercury230Dev->InvalidateReadCache();
2✔
143
    SerialPort->Close();
2✔
144
}
145

146
void TMercury230Test::VerifyParamQuery()
3✔
147
{
148
    EnqueueMercury230U1Response();
3✔
149
    // Register address for params:
150
    // 0000 0000 CCCC CCCC NNNN NNNN BBBB BBBB
151
    // C = command (0x08)
152
    // N = param number (0x11)
153
    // B = subparam spec (BWRI), 0x11 = voltage, phase 1
154
    ASSERT_EQ(TRegisterValue{24128}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230U1Reg->GetConfig()));
6✔
155

156
    EnqueueMercury230I1Response();
3✔
157
    // subparam 0x21 = current (phase 1)
158
    ASSERT_EQ(TRegisterValue{69}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230I1Reg->GetConfig()));
6✔
159

160
    EnqueueMercury230I2Response();
3✔
161
    // subparam 0x22 = current (phase 2)
162
    ASSERT_EQ(TRegisterValue{96}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230I2Reg->GetConfig()));
6✔
163

164
    EnqueueMercury230U2Response();
3✔
165
    // subparam 0x12 = voltage (phase 2)
166
    ASSERT_EQ(TRegisterValue{24043}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230U2Reg->GetConfig()));
6✔
167

168
    EnqueueMercury230U3Response();
3✔
169
    // subparam 0x12 = voltage (phase 3)
170
    ASSERT_EQ(TRegisterValue{50405}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230U3Reg->GetConfig()));
6✔
171

172
    EnqueueMercury230PResponse();
3✔
173
    // Total power (P)
174
    ASSERT_EQ(TRegisterValue{553095}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230PReg->GetConfig()));
6✔
175

176
    EnqueueMercury230TempResponse();
3✔
177
    ASSERT_EQ(TRegisterValue{24}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230TempReg->GetConfig()));
6✔
178
}
179

180
TEST_F(TMercury230Test, ReadParams)
8✔
181
{
182
    EnqueueMercury230SessionSetupResponse();
2✔
183
    VerifyParamQuery();
2✔
184
    Mercury230Dev->InvalidateReadCache();
2✔
185
    VerifyParamQuery();
2✔
186
    Mercury230Dev->InvalidateReadCache();
2✔
187
    SerialPort->Close();
2✔
188
}
2✔
189

190
TEST_F(TMercury230Test, Reconnect)
8✔
191
{
192
    EnqueueMercury230SessionSetupResponse();
2✔
193
    EnqueueMercury230NoSessionResponse();
2✔
194
    // re-setup happens here
195
    EnqueueMercury230SessionSetupResponse();
2✔
196
    EnqueueMercury230U2Response();
2✔
197

198
    // subparam 0x12 = voltage (phase 2)
199
    ASSERT_EQ(TRegisterValue{24043}, Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230U2Reg->GetConfig()));
4✔
200
    SerialPort->Close();
2✔
201
}
202

203
TEST_F(TMercury230Test, Exception)
8✔
204
{
205
    EnqueueMercury230SessionSetupResponse();
2✔
206
    EnqueueMercury230InternalMeterErrorResponse();
2✔
207
    try {
208
        Mercury230Dev->ReadRegisterImpl(*SerialPort, *Mercury230U2Reg->GetConfig());
4✔
209
        FAIL() << "No exception thrown";
×
210
    } catch (const TSerialDeviceException& e) {
4✔
211
        ASSERT_STREQ("Serial protocol error: Internal meter error", e.what());
2✔
212
        SerialPort->Close();
2✔
213
    }
214
}
215

216
class TMercury230CustomPasswordTest: public TMercury230Test
217
{
218
public:
219
    PDeviceConfig GetDeviceConfig() const override;
220
};
221

222
PDeviceConfig TMercury230CustomPasswordTest::GetDeviceConfig() const
1✔
223
{
224
    PDeviceConfig device_config = TMercury230Test::GetDeviceConfig();
1✔
225
    device_config->Password = {0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
1✔
226
    device_config->AccessLevel = 2;
1✔
227
    return device_config;
1✔
228
}
229

230
TEST_F(TMercury230CustomPasswordTest, Test)
8✔
231
{
232
    EnqueueMercury230AccessLevel2SessionSetupResponse();
2✔
233
    VerifyParamQuery();
2✔
234
    SerialPort->Close();
2✔
235
}
2✔
236

237
class TMercury230IntegrationTest: public TSerialDeviceIntegrationTest, public TMercury230Expectations
238
{
239
protected:
240
    void SetUp() override;
241
    void TearDown() override;
242
    const char* ConfigPath() const override
1✔
243
    {
244
        return "configs/config-mercury230-test.json";
1✔
245
    }
246
    std::string GetTemplatePath() const override
1✔
247
    {
248
        return "device-templates";
2✔
249
    }
250
    void ExpectQueries(bool firstPoll);
251
};
252

253
void TMercury230IntegrationTest::SetUp()
1✔
254
{
255
    TSerialDeviceIntegrationTest::SetUp();
1✔
256
    SerialPort->SetExpectedFrameTimeout(std::chrono::milliseconds(7));
1✔
257
    ASSERT_TRUE(!!SerialPort);
1✔
258
}
259

260
void TMercury230IntegrationTest::TearDown()
1✔
261
{
262
    SerialPort->Close();
1✔
263
    TSerialDeviceIntegrationTest::TearDown();
1✔
264
}
1✔
265

266
void TMercury230IntegrationTest::ExpectQueries(bool firstPoll)
1✔
267
{
268
    if (firstPoll) {
1✔
269
        EnqueueMercury230SessionSetupResponse();
1✔
270
    }
271

272
    EnqueueMercury230EnergyResponse1();
1✔
273

274
    EnqueueMercury230U1Response();
1✔
275
    EnqueueMercury230U2Response();
1✔
276
    EnqueueMercury230U3Response();
1✔
277

278
    EnqueueMercury230I1Response();
1✔
279
    EnqueueMercury230I2Response();
1✔
280
    EnqueueMercury230I3Response();
1✔
281

282
    EnqueueMercury230FrequencyResponse();
1✔
283

284
    EnqueueMercury230KU1Response();
1✔
285
    EnqueueMercury230KU2Response();
1✔
286
    EnqueueMercury230KU3Response();
1✔
287

288
    EnqueueMercury230PResponse();
1✔
289
    EnqueueMercury230P1Response();
1✔
290
    EnqueueMercury230P2Response();
1✔
291
    EnqueueMercury230P3Response();
1✔
292

293
    EnqueueMercury230PFResponse();
1✔
294
    EnqueueMercury230PF1Response();
1✔
295
    EnqueueMercury230PF2Response();
1✔
296
    EnqueueMercury230PF3Response();
1✔
297

298
    EnqueueMercury230QResponse();
1✔
299
    EnqueueMercury230Q1Response();
1✔
300
    EnqueueMercury230Q2Response();
1✔
301
    EnqueueMercury230Q3Response();
1✔
302

303
    EnqueueMercury230TempResponse();
1✔
304
    EnqueueMercury230PerPhaseEnergyResponse();
1✔
305
}
1✔
306

307
TEST_F(TMercury230IntegrationTest, Poll)
8✔
308
{
309
    ExpectQueries(true);
2✔
310
    Note() << "LoopOnce()";
2✔
311
    for (auto i = 0; i < 25; ++i) {
52✔
312
        SerialDriver->LoopOnce();
50✔
313
    }
314
}
2✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc