• 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

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)
21✔
11
    {
12
        try {
13
            auto delimiter_it = fullId.find(':');
21✔
14
            return std::stoi(fullId.substr(delimiter_it + 1), 0, 0);
21✔
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)
286✔
26
        {}
286✔
27

28
        bool IsSameSlaveId(const std::string& id1, const std::string& id2) const override
5✔
29
        {
30
            if (TUInt32SlaveId(id1) == TUInt32SlaveId(id2)) {
5✔
31
                return GetSecondaryId(id1) == GetSecondaryId(id2);
5✔
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)
143✔
44
{
45
    factory.RegisterProtocol(
143✔
46
        new TModbusIOProtocol("modbus_io"),
143✔
47
        new TModbusDeviceFactory<TModbusIODevice>(std::make_unique<Modbus::TModbusRTUTraitsFactory>()));
286✔
48
    factory.RegisterProtocol(
143✔
49
        new TModbusIOProtocol("modbus_io-tcp"),
143✔
50
        new TModbusDeviceFactory<TModbusIODevice>(std::make_unique<Modbus::TModbusTCPTraitsFactory>()));
286✔
51
}
143✔
52

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

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

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

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

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

102
void TModbusIODevice::WriteSetupRegisters(TPort& port)
7✔
103
{
104
    Modbus::WriteSetupRegisters(*ModbusTraits,
14✔
105
                                port,
106
                                SlaveId,
7✔
107
                                GetSetupItems(),
108
                                ModbusCache,
7✔
109
                                DeviceConfig()->RequestDelay,
14✔
110
                                GetResponseTimeout(port),
7✔
111
                                GetFrameTimeout(port),
7✔
112
                                Shift);
113
}
6✔
114

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