Merge PR #513: Add a timeout to ModbusRtuReplies

pull/510/head
jenkins 2022-05-03 23:27:10 +02:00
commit 2b32bca5cf
3 changed files with 29 additions and 72 deletions

View File

@ -238,9 +238,10 @@ ModbusRtuReply *ModbusRtuMasterImpl::readCoil(int slaveAddress, int registerAddr
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, size);
QModbusReply *modbusReply = m_modbus->sendReadRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -260,15 +261,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::readCoil(int slaveAddress, int registerAddr
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read coil request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)
@ -291,9 +283,10 @@ ModbusRtuReply *ModbusRtuMasterImpl::readDiscreteInput(int slaveAddress, int reg
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::DiscreteInputs, registerAddress, size);
QModbusReply *modbusReply = m_modbus->sendReadRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -313,15 +306,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::readDiscreteInput(int slaveAddress, int reg
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read descrete inputs request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)
@ -344,9 +328,10 @@ ModbusRtuReply *ModbusRtuMasterImpl::readInputRegister(int slaveAddress, int reg
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::InputRegisters, registerAddress, size);
QModbusReply *modbusReply = m_modbus->sendReadRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -366,15 +351,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::readInputRegister(int slaveAddress, int reg
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read input registers request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)
@ -397,9 +373,10 @@ ModbusRtuReply *ModbusRtuMasterImpl::readHoldingRegister(int slaveAddress, int r
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, size);
QModbusReply *modbusReply = m_modbus->sendReadRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -419,15 +396,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::readHoldingRegister(int slaveAddress, int r
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read holding registers request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)
@ -449,12 +417,12 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeCoils(int slaveAddress, int registerAd
// Create the actual modbus lib reply
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::Coils, registerAddress, values.length());
request.setValues(values);
QModbusReply *modbusReply = m_modbus->sendWriteRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -462,7 +430,7 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeCoils(int slaveAddress, int registerAd
// Check if the reply finished with an error
if (modbusReply->error() != QModbusDevice::NoError) {
qCWarning(dcModbusRtu()) << "Read coil request finished with error" << modbusReply->error() << modbusReply->errorString();
qCWarning(dcModbusRtu()) << "Write coil request finished with error" << modbusReply->error() << modbusReply->errorString();
emit reply->errorOccurred(reply->error());
emit reply->finished();
return;
@ -474,15 +442,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeCoils(int slaveAddress, int registerAd
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read coil request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)
@ -505,12 +464,12 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeHoldingRegisters(int slaveAddress, int
// Create the actual modbus lib reply
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, registerAddress, values.length());
request.setValues(values);
QModbusReply *modbusReply = m_modbus->sendWriteRequest(request, slaveAddress);
connect(modbusReply, &QModbusReply::finished, modbusReply, [=](){
modbusReply->deleteLater();
// Cleaning up modbusReply when our reply finishes, regardless if that happened because modbusReply finished or reply timeouted
connect(reply, &ModbusRtuReply::finished, modbusReply, &QModbusReply::deleteLater);
connect(modbusReply, &QModbusReply::finished, reply, [=](){
// Fill common reply data
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
@ -518,7 +477,7 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeHoldingRegisters(int slaveAddress, int
// Check if the reply finished with an error
if (modbusReply->error() != QModbusDevice::NoError) {
qCWarning(dcModbusRtu()) << "Read coil request finished with error" << modbusReply->error() << modbusReply->errorString();
qCWarning(dcModbusRtu()) << "Write holding register request finished with error" << modbusReply->error() << modbusReply->errorString();
emit reply->errorOccurred(reply->error());
emit reply->finished();
return;
@ -530,15 +489,6 @@ ModbusRtuReply *ModbusRtuMasterImpl::writeHoldingRegisters(int slaveAddress, int
emit reply->finished();
});
connect(modbusReply, &QModbusReply::errorOccurred, modbusReply, [=](QModbusDevice::Error error){
qCWarning(dcModbusRtu()) << "Read coil request finished with error" << error << modbusReply->errorString();
reply->setFinished(true);
reply->setError(static_cast<ModbusRtuReply::Error>(modbusReply->error()));
reply->setErrorString(modbusReply->errorString());
emit reply->errorOccurred(reply->error());
emit reply->finished();
});
return qobject_cast<ModbusRtuReply *>(reply);
#else
Q_UNUSED(slaveAddress)

View File

@ -37,7 +37,13 @@ ModbusRtuReplyImpl::ModbusRtuReplyImpl(int slaveAddress, int registerAddress, QO
m_slaveAddress(slaveAddress),
m_registerAddress(registerAddress)
{
m_timeoutTimer.start(10000);
connect(&m_timeoutTimer, &QTimer::timeout, this, [=](){
if (!m_finished) {
m_error = TimeoutError;
emit errorOccurred(TimeoutError);
}
});
}
bool ModbusRtuReplyImpl::isFinished() const

View File

@ -32,6 +32,7 @@
#define MODBUSRTUREPLYIMPL_H
#include <QObject>
#include <QTimer>
#include "hardware/modbus/modbusrtureply.h"
@ -65,7 +66,7 @@ private:
Error m_error = UnknownError;
QString m_errorString;
QVector<quint16> m_result;
QTimer m_timeoutTimer;
};
}