modbus-tool: Improve reachability check error handling
parent
28f280b15c
commit
586f50a2dc
|
|
@ -270,3 +270,45 @@ QVector<quint16> ModbusDataUtils::convertFromFloat64(double value, ByteOrder byt
|
|||
memcpy(&rawValue, &value, sizeof(double));
|
||||
return ModbusDataUtils::convertFromUInt64(rawValue, byteOrder);
|
||||
}
|
||||
|
||||
QString ModbusDataUtils::exceptionCodeToString(QModbusPdu::ExceptionCode exception)
|
||||
{
|
||||
QString exceptionString;
|
||||
switch (exception) {
|
||||
case QModbusPdu::IllegalFunction:
|
||||
exceptionString = "Illegal function";
|
||||
break;
|
||||
case QModbusPdu::IllegalDataAddress:
|
||||
exceptionString = "Illegal data address";
|
||||
break;
|
||||
case QModbusPdu::IllegalDataValue:
|
||||
exceptionString = "Illegal data value";
|
||||
break;
|
||||
case QModbusPdu::ServerDeviceFailure:
|
||||
exceptionString = "Server device failure";
|
||||
break;
|
||||
case QModbusPdu::Acknowledge:
|
||||
exceptionString = "Acknowledge";
|
||||
break;
|
||||
case QModbusPdu::ServerDeviceBusy:
|
||||
exceptionString = "Server device busy";
|
||||
break;
|
||||
case QModbusPdu::NegativeAcknowledge:
|
||||
exceptionString = "Negative acknowledge";
|
||||
break;
|
||||
case QModbusPdu::MemoryParityError:
|
||||
exceptionString = "Memory parity error";
|
||||
break;
|
||||
case QModbusPdu::GatewayPathUnavailable:
|
||||
exceptionString = "Gateway path unavailable";
|
||||
break;
|
||||
case QModbusPdu::GatewayTargetDeviceFailedToRespond:
|
||||
exceptionString = "Gateway target device failed to respond";
|
||||
break;
|
||||
case QModbusPdu::ExtendedException:
|
||||
exceptionString = "Extended exception";
|
||||
break;
|
||||
}
|
||||
|
||||
return exceptionString;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <QVector>
|
||||
#include <QObject>
|
||||
#include <QModbusPdu>
|
||||
|
||||
class ModbusDataUtils
|
||||
{
|
||||
|
|
@ -102,6 +103,8 @@ public:
|
|||
static QVector<quint16> convertFromString(const QString &value, quint16 stringLength, ByteOrder characterByteOrder = ByteOrderLittleEndian);
|
||||
static QVector<quint16> convertFromFloat32(float value, ByteOrder byteOrder = ByteOrderLittleEndian);
|
||||
static QVector<quint16> convertFromFloat64(double value, ByteOrder byteOrder = ByteOrderLittleEndian);
|
||||
|
||||
static QString exceptionCodeToString(QModbusPdu::ExceptionCode exception);
|
||||
};
|
||||
|
||||
#endif // MODBUSDATAUTILS_H
|
||||
|
|
|
|||
|
|
@ -100,9 +100,9 @@ bool ModbusTcpMaster::connectDevice()
|
|||
m_modbusTcpClient->setTimeout(m_timeout);
|
||||
m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
|
||||
return m_modbusTcpClient->connectDevice();
|
||||
} else if (m_modbusTcpClient->state() != QModbusDevice::ConnectedState) {
|
||||
} else if (m_modbusTcpClient->state() != QModbusDevice::ConnectedState && m_modbusTcpClient->state() != QModbusDevice::ConnectingState) {
|
||||
// Restart the timer in case of connecting not finished yet or closing
|
||||
qCDebug(dcModbusTcpMaster()) << "Starting the reconnect mechanism timer";
|
||||
qCDebug(dcModbusTcpMaster()) << "Starting the re-connect mechanism timer";
|
||||
m_reconnectTimer->start();
|
||||
} else {
|
||||
qCWarning(dcModbusTcpMaster()) << "Connect modbus TCP device" << connectionUrl() << "called, but the socket is currently in the" << m_modbusTcpClient->state();
|
||||
|
|
|
|||
|
|
@ -114,7 +114,12 @@ def writePropertyUpdateMethodImplementationsTcp(fileDescriptor, className, regis
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString();' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor, '}')
|
||||
writeLine(fileDescriptor)
|
||||
|
|
@ -177,7 +182,12 @@ def writeBlockUpdateMethodImplementationsTcp(fileDescriptor, className, blockDef
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, this, [reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString();' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor, '}')
|
||||
writeLine(fileDescriptor)
|
||||
|
|
@ -317,7 +327,15 @@ def writeTestReachabilityImplementationsTcp(fileDescriptor, className, registerD
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(m_checkRechableReply, &QModbusReply::errorOccurred, this, [this] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = m_checkRechableReply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (m_checkRechableReply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_checkRechableReply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' // Note: if we get an exception on the reachability register, the modbus server is probably not ready')
|
||||
writeLine(fileDescriptor, ' // For some reasons on some devices the reply will never be finished on exception response. A reconnect might fix it.')
|
||||
writeLine(fileDescriptor, ' QTimer::singleShot(2000, m_modbusTcpMaster, &ModbusTcpMaster::reconnectDevice);')
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCDebug(dc%s()) << "Modbus reply error occurred while verifying reachability by reading \\"%s\\" register" << error << m_checkRechableReply->errorString();' % (className, checkReachableRegister['description']))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor, '}')
|
||||
writeLine(fileDescriptor)
|
||||
|
|
@ -398,7 +416,12 @@ def writeInitMethodImplementationTcp(fileDescriptor, className, registerDefiniti
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, m_initObject, [this, reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while reading \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while reading \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString();' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
|
||||
# Read init blocks
|
||||
|
|
@ -465,7 +488,12 @@ def writeInitMethodImplementationTcp(fileDescriptor, className, registerDefiniti
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, m_initObject, [reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString();' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
|
||||
|
|
@ -546,7 +574,12 @@ def writeUpdateMethodTcp(fileDescriptor, className, registerDefinitions, blockDe
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while reading \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while reading \\"%s\\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString();' % (className, registerDefinition['description']))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
|
||||
# Read init blocks
|
||||
|
|
@ -613,7 +646,12 @@ def writeUpdateMethodTcp(fileDescriptor, className, registerDefinitions, blockDe
|
|||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
writeLine(fileDescriptor, ' connect(reply, &QModbusReply::errorOccurred, this, [reply] (QModbusDevice::Error error){')
|
||||
writeLine(fileDescriptor, ' QModbusResponse response = reply->rawResult();')
|
||||
writeLine(fileDescriptor, ' if (reply->error() == QModbusDevice::ProtocolError && response.isException()) {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode());' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' } else {')
|
||||
writeLine(fileDescriptor, ' qCWarning(dc%s()) << "Modbus reply error occurred while updating block \\"%s\\" registers" << error << reply->errorString();' % (className, blockName))
|
||||
writeLine(fileDescriptor, ' }')
|
||||
writeLine(fileDescriptor, ' });')
|
||||
writeLine(fileDescriptor)
|
||||
|
||||
|
|
|
|||
|
|
@ -208,6 +208,8 @@ def writeTcpSourceFile():
|
|||
writeLine(sourceFile, '#include <loggingcategories.h>')
|
||||
writeLine(sourceFile, '#include <math.h>')
|
||||
writeLine(sourceFile, '#include <QTimer>')
|
||||
writeLine(sourceFile, '#include <QModbusDevice>')
|
||||
writeLine(sourceFile, '#include <QModbusResponse>')
|
||||
writeLine(sourceFile)
|
||||
writeLine(sourceFile, 'NYMEA_LOGGING_CATEGORY(dc%s, "%s")' % (className, className))
|
||||
writeLine(sourceFile)
|
||||
|
|
@ -366,7 +368,7 @@ def writeTcpSourceFile():
|
|||
writeLine(sourceFile, ' m_communicationFailedCounter++;')
|
||||
writeLine(sourceFile, ' if (m_communicationWorking && m_communicationFailedCounter >= m_communicationFailedMax) {')
|
||||
writeLine(sourceFile, ' m_communicationWorking = false;')
|
||||
writeLine(sourceFile, ' qCWarning(dc%s()) << "Received" << m_communicationFailedCounter << "errors while communicating with the RTU master. Mark as not reachable until the communication works again.";' % (className))
|
||||
writeLine(sourceFile, ' qCWarning(dc%s()) << "Received" << m_communicationFailedCounter << "errors while communicating with the TCP master. Mark as not reachable until the communication works again.";' % (className))
|
||||
writeLine(sourceFile, ' evaluateReachableState();')
|
||||
writeLine(sourceFile, ' }')
|
||||
writeLine(sourceFile, ' }')
|
||||
|
|
|
|||
Loading…
Reference in New Issue