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

wirenboard / wb-mqtt-serial / 2

29 Dec 2025 12:28PM UTC coverage: 76.817% (+4.0%) from 72.836%
2

Pull #1045

github

54aa0c
pgasheev
up changelog
Pull Request #1045: Fix firmware version in WB-M1W2 template

6873 of 9161 branches covered (75.02%)

12966 of 16879 relevant lines covered (76.82%)

1651.61 hits per line

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

90.48
/src/devices/modbus_io_device.cpp
1
#include "modbus_io_device.h"
2

3
namespace
4
{
5
    const TRegisterTypes ModbusIORegisterTypes({{Modbus::REG_HOLDING, "holding", "value", U16},
6
                                                {Modbus::REG_COIL, "coil", "switch", U8},
7
                                                {Modbus::REG_DISCRETE, "discrete", "switch", U8, true},
8
                                                {Modbus::REG_INPUT, "input", "value", U16, true}});
9

10
    int GetSecondaryId(const std::string& fullId)
42✔
11
    {
12
        try {
13
            auto delimiter_it = fullId.find(':');
42✔
14
            return std::stoi(fullId.substr(delimiter_it + 1), 0, 0);
42✔
15
        } catch (const std::logic_error& e) {
×
16
            throw TSerialDeviceException("slave ID \"" + fullId + "\" is not convertible to modbus_io id");
×
17
        }
18
    }
19

20
    class TModbusIOProtocol: public IProtocol
21
    {
22
        std::unique_ptr<Modbus::IModbusTraitsFactory> ModbusTraitsFactory;
23

24
    public:
25
        TModbusIOProtocol(const char* name): IProtocol(name, ModbusIORegisterTypes)
576✔
26
        {}
576✔
27

28
        bool IsSameSlaveId(const std::string& id1, const std::string& id2) const override
10✔
29
        {
30
            if (TUInt32SlaveId(id1) == TUInt32SlaveId(id2)) {
10✔
31
                return GetSecondaryId(id1) == GetSecondaryId(id2);
10✔
32
            }
33
            return false;
×
34
        }
35

36
        bool IsModbus() const override
×
37
        {
38
            return true;
×
39
        }
40
    };
41
}
42

43
void TModbusIODevice::Register(TSerialDeviceFactory& factory)
288✔
44
{
45
    factory.RegisterProtocol(
288✔
46
        new TModbusIOProtocol("modbus_io"),
288✔
47
        new TModbusDeviceFactory<TModbusIODevice>(std::make_unique<Modbus::TModbusRTUTraitsFactory>()));
576✔
48
    factory.RegisterProtocol(
288✔
49
        new TModbusIOProtocol("modbus_io-tcp"),
288✔
50
        new TModbusDeviceFactory<TModbusIODevice>(std::make_unique<Modbus::TModbusTCPTraitsFactory>()));
576✔
51
}
288✔
52

53
TModbusIODevice::TModbusIODevice(std::unique_ptr<Modbus::IModbusTraits> modbusTraits,
22✔
54
                                 const TModbusDeviceConfig& config,
55
                                 PProtocol protocol)
22✔
56
    : TSerialDevice(config.CommonConfig, protocol),
22✔
57
      TUInt32SlaveId(config.CommonConfig->SlaveId),
44✔
58
      ModbusTraits(std::move(modbusTraits)),
22✔
59
      ResponseTime(std::chrono::milliseconds::zero())
22✔
60
{
61
    auto SecondaryId = GetSecondaryId(config.CommonConfig->SlaveId);
22✔
62
    Shift = (((SecondaryId - 1) % 4) + 1) * DeviceConfig()->Stride + DeviceConfig()->Shift;
22✔
63
}
22✔
64

65
PRegisterRange TModbusIODevice::CreateRegisterRange() const
24✔
66
{
67
    return Modbus::CreateRegisterRange(ResponseTime.GetValue());
24✔
68
}
69

70
void TModbusIODevice::PrepareImpl(TPort& port)
28✔
71
{
72
    TSerialDevice::PrepareImpl(port);
28✔
73
    if (GetConnectionState() != TDeviceConnectionState::CONNECTED) {
28✔
74
        Modbus::EnableWbContinuousRead(shared_from_this(), *ModbusTraits, port, SlaveId, ModbusCache);
14✔
75
    }
76
}
28✔
77

78
void TModbusIODevice::WriteRegisterImpl(TPort& port, const TRegisterConfig& reg, const TRegisterValue& value)
4✔
79
{
80
    Modbus::WriteRegister(*ModbusTraits,
8✔
81
                          port,
82
                          SlaveId,
4✔
83
                          reg,
84
                          value,
85
                          ModbusCache,
4✔
86
                          DeviceConfig()->RequestDelay,
8✔
87
                          GetResponseTimeout(port),
4✔
88
                          GetFrameTimeout(port),
4✔
89
                          Shift);
90
}
4✔
91

92
void TModbusIODevice::ReadRegisterRange(TPort& port, PRegisterRange range, bool breakOnError)
22✔
93
{
94
    auto modbus_range = std::dynamic_pointer_cast<Modbus::TModbusRegisterRange>(range);
22✔
95
    if (!modbus_range) {
22✔
96
        throw std::runtime_error("modbus range expected");
×
97
    }
98
    Modbus::ReadRegisterRange(*ModbusTraits, port, SlaveId, *modbus_range, ModbusCache, breakOnError, Shift);
22✔
99
    ResponseTime.AddValue(modbus_range->GetResponseTime());
22✔
100
}
22✔
101

102
void TModbusIODevice::WriteSetupRegisters(TPort& port, const TDeviceSetupItems& setupItems, bool breakOnError)
14✔
103
{
104
    Modbus::WriteSetupRegisters(*ModbusTraits,
28✔
105
                                port,
106
                                SlaveId,
14✔
107
                                setupItems,
108
                                ModbusCache,
14✔
109
                                DeviceConfig()->RequestDelay,
28✔
110
                                GetResponseTimeout(port),
14✔
111
                                GetFrameTimeout(port),
14✔
112
                                breakOnError,
113
                                Shift);
114
}
12✔
115

116
std::chrono::milliseconds TModbusIODevice::GetFrameTimeout(TPort& port) const
82✔
117
{
118
    return std::max(
119
        DeviceConfig()->FrameTimeout,
164✔
120
        std::chrono::ceil<std::chrono::milliseconds>(port.GetSendTimeBytes(Modbus::STANDARD_FRAME_TIMEOUT_BYTES)));
164✔
121
}
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