Extend modbus tcp class

This commit is contained in:
Simon Stürz 2021-05-27 10:32:04 +02:00 committed by Michael Zanetti
parent 8f281ed304
commit f8bc078437
2 changed files with 157 additions and 90 deletions

View File

@ -34,13 +34,15 @@
NYMEA_LOGGING_CATEGORY(dcModbusTCP, "ModbusTCP") NYMEA_LOGGING_CATEGORY(dcModbusTCP, "ModbusTCP")
ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent) : ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent) :
QObject(parent) QObject(parent),
m_hostAddress(hostAddress),
m_port(port)
{ {
m_modbusTcpClient = new QModbusTcpClient(this); m_modbusTcpClient = new QModbusTcpClient(this);
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, port); m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, m_port);
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, hostAddress.toString()); m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, m_hostAddress.toString());
m_modbusTcpClient->setTimeout(1000); m_modbusTcpClient->setTimeout(m_timeout);
m_modbusTcpClient->setNumberOfRetries(3); m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
connect(m_modbusTcpClient, &QModbusTcpClient::stateChanged, this, &ModbusTCPMaster::onModbusStateChanged); connect(m_modbusTcpClient, &QModbusTcpClient::stateChanged, this, &ModbusTCPMaster::onModbusStateChanged);
connect(m_modbusTcpClient, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusTCPMaster::onModbusErrorOccurred); connect(m_modbusTcpClient, &QModbusRtuSerialMaster::errorOccurred, this, &ModbusTCPMaster::onModbusErrorOccurred);
@ -52,38 +54,87 @@ ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QOb
ModbusTCPMaster::~ModbusTCPMaster() ModbusTCPMaster::~ModbusTCPMaster()
{ {
if (!m_modbusTcpClient) { if (m_reconnectTimer) {
m_modbusTcpClient->disconnectDevice();
m_modbusTcpClient->deleteLater();
}
if (!m_reconnectTimer) {
m_reconnectTimer->stop(); m_reconnectTimer->stop();
m_reconnectTimer->deleteLater(); delete m_reconnectTimer;
m_reconnectTimer = nullptr;
} }
if (m_modbusTcpClient) {
m_modbusTcpClient->disconnectDevice();
delete m_modbusTcpClient;
m_modbusTcpClient = nullptr;
}
}
QHostAddress ModbusTCPMaster::hostAddress() const
{
return m_hostAddress;
}
uint ModbusTCPMaster::port() const
{
return m_port;
}
bool ModbusTCPMaster::setPort(uint port)
{
m_port = port;
return connectDevice();
}
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
{
m_hostAddress = hostAddress;
return connectDevice();
} }
bool ModbusTCPMaster::connectDevice() { bool ModbusTCPMaster::connectDevice() {
// TCP connection to target device // TCP connection to target device
qCDebug(dcModbusTCP()) << "Setting up TCP connecion"; qCDebug(dcModbusTCP()) << "Setting up TCP connecion" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
if (!m_modbusTcpClient) if (!m_modbusTcpClient)
return false; return false;
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, m_port);
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, m_hostAddress.toString());
m_modbusTcpClient->setTimeout(m_timeout);
m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
return m_modbusTcpClient->connectDevice(); return m_modbusTcpClient->connectDevice();
} }
bool ModbusTCPMaster::connected() void ModbusTCPMaster::disconnectDevice()
{
if (!m_modbusTcpClient)
return;
m_modbusTcpClient->disconnectDevice();
}
bool ModbusTCPMaster::connected() const
{ {
return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState); return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState);
} }
int ModbusTCPMaster::numberOfRetries() const
{
return m_modbusTcpClient->numberOfRetries();
}
void ModbusTCPMaster::setNumberOfRetries(int number) void ModbusTCPMaster::setNumberOfRetries(int number)
{ {
m_numberOfRetries = number;
m_modbusTcpClient->setNumberOfRetries(number); m_modbusTcpClient->setNumberOfRetries(number);
} }
int ModbusTCPMaster::timeout() const
{
return m_modbusTcpClient->timeout();
}
void ModbusTCPMaster::setTimeout(int timeout) void ModbusTCPMaster::setTimeout(int timeout)
{ {
m_timeout = timeout;
m_modbusTcpClient->setTimeout(timeout); m_modbusTcpClient->setTimeout(timeout);
} }
@ -97,74 +148,51 @@ QModbusDevice::Error ModbusTCPMaster::error() const
return m_modbusTcpClient->error(); return m_modbusTcpClient->error();
} }
uint ModbusTCPMaster::port()
{
return m_modbusTcpClient->connectionParameter(QModbusDevice::NetworkPortParameter).toUInt();
}
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
{
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, hostAddress.toString());
return connectDevice();
}
bool ModbusTCPMaster::setPort(uint port)
{
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
return connectDevice();
}
void ModbusTCPMaster::onReconnectTimer() void ModbusTCPMaster::onReconnectTimer()
{ {
if(!m_modbusTcpClient->connectDevice()) { if (!m_modbusTcpClient->connectDevice()) {
m_reconnectTimer->start(10000); m_reconnectTimer->start(10000);
} }
} }
QHostAddress ModbusTCPMaster::hostAddress()
{
return QHostAddress(m_modbusTcpClient->connectionParameter(QModbusDevice::NetworkAddressParameter).toString());
}
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size) QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid();
QUuid requestId = QUuid::createUuid();
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size);
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) { if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
if (!reply->isFinished()) { if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] { connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
if (reply->error() == QModbusDevice::NoError) { if (reply->error() == QModbusDevice::NoError) {
emit readRequestExecuted(requestId, true); emit readRequestExecuted(requestId, true);
const QModbusDataUnit unit = reply->result(); const QModbusDataUnit unit = reply->result();
uint modbusAddress = unit.startAddress(); uint modbusAddress = unit.startAddress();
emit receivedCoil(reply->serverAddress(), modbusAddress, unit.values()); emit receivedCoil(reply->serverAddress(), modbusAddress, unit.values());
} else { } else {
emit readRequestExecuted(requestId, false); emit readRequestExecuted(requestId, false);
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error(); qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
} }
}); });
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error; qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
emit readRequestError(requestId, reply->errorString()); emit readRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(200, reply, &QModbusReply::deleteLater); QTimer::singleShot(200, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
@ -172,51 +200,70 @@ QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint si
QUuid ModbusTCPMaster::writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values) QUuid ModbusTCPMaster::writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid(); QUuid requestId = QUuid::createUuid();
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, values.length()); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, values.length());
request.setValues(values); request.setValues(values);
if (QModbusReply *reply = m_modbusTcpClient->sendWriteRequest(request, slaveAddress)) { if (QModbusReply *reply = m_modbusTcpClient->sendWriteRequest(request, slaveAddress)) {
if (!reply->isFinished()) { if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] { connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
if (reply->error() == QModbusDevice::NoError) { if (reply->error() == QModbusDevice::NoError) {
writeRequestExecuted(requestId, true); emit writeRequestExecuted(requestId, true);
const QModbusDataUnit unit = reply->result(); const QModbusDataUnit unit = reply->result();
uint modbusAddress = unit.startAddress(); uint modbusAddress = unit.startAddress();
emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.values()); emit receivedHoldingRegister(reply->serverAddress(), modbusAddress, unit.values());
} else { } else {
writeRequestExecuted(requestId, false); emit writeRequestExecuted(requestId, false);
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error(); qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
} }
reply->deleteLater(); reply->deleteLater();
}); });
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error; qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
emit writeRequestError(requestId, reply->errorString()); emit writeRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater); QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
QModbusReply *ModbusTCPMaster::sendRawRequest(const QModbusRequest &request, int serverAddress)
{
return m_modbusTcpClient->sendRawRequest(request, serverAddress);
}
QModbusReply *ModbusTCPMaster::sendReadRequest(const QModbusDataUnit &read, int serverAddress)
{
return m_modbusTcpClient->sendReadRequest(read, serverAddress);
}
QModbusReply *ModbusTCPMaster::sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress)
{
return m_modbusTcpClient->sendReadWriteRequest(read, write, serverAddress);
}
QModbusReply *ModbusTCPMaster::sendWriteRequest(const QModbusDataUnit &write, int serverAddress)
{
return m_modbusTcpClient->sendWriteRequest(write, serverAddress);
}
QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress, uint size) QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress, uint size)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid(); QUuid requestId = QUuid::createUuid();
@ -226,33 +273,32 @@ QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress
if (!reply->isFinished()) { if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
connect(reply, &QModbusReply::finished, this, [reply, requestId, this] { connect(reply, &QModbusReply::finished, this, [reply, requestId, this] {
if (reply->error() == QModbusDevice::NoError) { if (reply->error() == QModbusDevice::NoError) {
emit readRequestExecuted(requestId, true); emit readRequestExecuted(requestId, true);
const QModbusDataUnit unit = reply->result(); const QModbusDataUnit unit = reply->result();
uint modbusAddress = unit.startAddress(); uint modbusAddress = unit.startAddress();
emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.values()); emit receivedDiscreteInput(reply->serverAddress(), modbusAddress, unit.values());
} else { } else {
emit readRequestExecuted(requestId, false); emit readRequestExecuted(requestId, false);
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error(); qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
} }
}); });
connect(reply, &QModbusReply::errorOccurred, this, [requestId, this] (QModbusDevice::Error error){
connect(reply, &QModbusReply::errorOccurred, this, [requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus replay error:" << error; qCWarning(dcModbusTCP()) << "Modbus replay error:" << error;
QModbusReply *reply = qobject_cast<QModbusReply *>(sender()); QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
emit readRequestError(requestId, reply->errorString()); emit readRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater); QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
@ -260,10 +306,10 @@ QUuid ModbusTCPMaster::readDiscreteInput(uint slaveAddress, uint registerAddress
QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress, uint size) QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress, uint size)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid();
QUuid requestId = QUuid::createUuid();
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, size); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, size);
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) { if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
@ -276,26 +322,27 @@ QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress
const QModbusDataUnit unit = reply->result(); const QModbusDataUnit unit = reply->result();
uint modbusAddress = unit.startAddress(); uint modbusAddress = unit.startAddress();
emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.values()); emit receivedInputRegister(reply->serverAddress(), modbusAddress, unit.values());
} else { } else {
emit readRequestExecuted(requestId, false); emit readRequestExecuted(requestId, false);
qCWarning(dcModbusTCP()) << "Read response error:" << reply->error(); qCWarning(dcModbusTCP()) << "Read response error:" << reply->error();
} }
}); });
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error; qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
emit readRequestError(requestId, reply->errorString()); emit readRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater); QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
@ -303,10 +350,10 @@ QUuid ModbusTCPMaster::readInputRegister(uint slaveAddress, uint registerAddress
QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddress, uint size) QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddress, uint size)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid();
QUuid requestId = QUuid::createUuid();
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, size); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, size);
if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) { if (QModbusReply *reply = m_modbusTcpClient->sendReadRequest(request, slaveAddress)) {
@ -327,20 +374,22 @@ QUuid ModbusTCPMaster::readHoldingRegister(uint slaveAddress, uint registerAddre
} }
reply->deleteLater(); reply->deleteLater();
}); });
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){ connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error; qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
emit readRequestError(requestId, reply->errorString()); emit readRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater); QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
@ -353,10 +402,10 @@ QUuid ModbusTCPMaster::writeCoil(uint slaveAddress, uint registerAddress, bool v
QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const QVector<quint16> &values) QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const QVector<quint16> &values)
{ {
if (!m_modbusTcpClient) { if (!m_modbusTcpClient) {
return ""; return QUuid();
} }
QUuid requestId = QUuid::createUuid();
QUuid requestId = QUuid::createUuid();
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, values.length()); QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, values.length());
request.setValues(values); request.setValues(values);
@ -377,20 +426,21 @@ QUuid ModbusTCPMaster::writeCoils(uint slaveAddress, uint registerAddress, const
} }
reply->deleteLater(); reply->deleteLater();
}); });
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
connect(reply, &QModbusReply::errorOccurred, this, [reply, requestId, this] (QModbusDevice::Error error){
qCWarning(dcModbusTCP()) << "Modbus reply error:" << error; qCWarning(dcModbusTCP()) << "Modbus reply error:" << error;
emit writeRequestError(requestId, reply->errorString()); emit writeRequestError(requestId, reply->errorString());
reply->finished(); // To make sure it will be deleted emit reply->finished(); // To make sure it will be deleted
}); });
QTimer::singleShot(2000, reply, &QModbusReply::deleteLater); QTimer::singleShot(2000, reply, &QModbusReply::deleteLater);
} else { } else {
delete reply; // broadcast replies return immediately delete reply; // broadcast replies return immediately
return ""; return QUuid();
} }
} else { } else {
qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString(); qCWarning(dcModbusTCP()) << "Read error: " << m_modbusTcpClient->errorString();
return ""; return QUuid();
} }
return requestId; return requestId;
} }
@ -400,19 +450,20 @@ QUuid ModbusTCPMaster::writeHoldingRegister(uint slaveAddress, uint registerAddr
return writeHoldingRegisters(slaveAddress, registerAddress, QVector<quint16>() << value); return writeHoldingRegisters(slaveAddress, registerAddress, QVector<quint16>() << value);
} }
void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error) void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error)
{ {
qCWarning(dcModbusTCP()) << "An error occured" << error; qCWarning(dcModbusTCP()) << "An error occured" << error;
} }
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state) void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
{ {
qCDebug(dcModbusTCP()) << "Connection state changed for" << m_hostAddress << state;
bool connected = (state == QModbusDevice::ConnectedState); bool connected = (state == QModbusDevice::ConnectedState);
if (!connected) { if (!connected) {
//try to reconnect in 10 seconds //try to reconnect in 10 seconds
m_reconnectTimer->start(10000); m_reconnectTimer->start(10000);
} }
emit connectionStateChanged(connected); emit connectionStateChanged(connected);
} }

View File

@ -37,8 +37,6 @@
#include <QTimer> #include <QTimer>
#include <QUuid> #include <QUuid>
Q_DECLARE_LOGGING_CATEGORY(dcModbusTcp)
class ModbusTCPMaster : public QObject class ModbusTCPMaster : public QObject
{ {
Q_OBJECT Q_OBJECT
@ -46,9 +44,21 @@ public:
explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr); explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr);
~ModbusTCPMaster(); ~ModbusTCPMaster();
QHostAddress hostAddress() const;
bool setHostAddress(const QHostAddress &hostAddress);
uint port() const;
bool setPort(uint port);
bool connectDevice(); bool connectDevice();
bool connected(); void disconnectDevice();
bool connected() const;
int numberOfRetries() const;
void setNumberOfRetries(int number); void setNumberOfRetries(int number);
int timeout() const;
void setTimeout(int timeout); void setTimeout(int timeout);
QString errorString() const; QString errorString() const;
@ -65,14 +75,20 @@ public:
QUuid writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value); QUuid writeHoldingRegister(uint slaveAddress, uint registerAddress, quint16 value);
QUuid writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values); QUuid writeHoldingRegisters(uint slaveAddress, uint registerAddress, const QVector<quint16> &values);
QHostAddress hostAddress(); // Generic requests
uint port(); QModbusReply *sendRawRequest(const QModbusRequest &request, int serverAddress);
bool setHostAddress(const QHostAddress &hostAddress); QModbusReply *sendReadRequest(const QModbusDataUnit &read, int serverAddress);
bool setPort(uint port); QModbusReply *sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress);
QModbusReply *sendWriteRequest(const QModbusDataUnit &write, int serverAddress);
private: private:
QTimer *m_reconnectTimer = nullptr; QTimer *m_reconnectTimer = nullptr;
QModbusTcpClient *m_modbusTcpClient; QModbusTcpClient *m_modbusTcpClient = nullptr;
QHostAddress m_hostAddress;
uint m_port;
int m_timeout = 1000;
int m_numberOfRetries = 3;
private slots: private slots:
void onReconnectTimer(); void onReconnectTimer();