Improve reconnect behaviour
This commit is contained in:
parent
f8bc078437
commit
a62032ae45
@ -49,21 +49,18 @@ ModbusTCPMaster::ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QOb
|
||||
|
||||
m_reconnectTimer = new QTimer(this);
|
||||
m_reconnectTimer->setSingleShot(true);
|
||||
connect(m_reconnectTimer, &QTimer::timeout, this, &ModbusTCPMaster::onReconnectTimer);
|
||||
m_reconnectTimer->setInterval(4000);
|
||||
connect(m_reconnectTimer, &QTimer::timeout, this, &ModbusTCPMaster::connectDevice);
|
||||
}
|
||||
|
||||
ModbusTCPMaster::~ModbusTCPMaster()
|
||||
{
|
||||
if (m_reconnectTimer) {
|
||||
m_reconnectTimer->stop();
|
||||
delete m_reconnectTimer;
|
||||
m_reconnectTimer = nullptr;
|
||||
}
|
||||
|
||||
if (m_modbusTcpClient) {
|
||||
m_modbusTcpClient->disconnectDevice();
|
||||
delete m_modbusTcpClient;
|
||||
m_modbusTcpClient = nullptr;
|
||||
disconnectDevice();
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,30 +74,37 @@ uint ModbusTCPMaster::port() const
|
||||
return m_port;
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::setPort(uint port)
|
||||
void ModbusTCPMaster::setPort(uint port)
|
||||
{
|
||||
m_port = port;
|
||||
return connectDevice();
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
||||
void ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
||||
{
|
||||
m_hostAddress = hostAddress;
|
||||
return connectDevice();
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::connectDevice() {
|
||||
// TCP connection to target device
|
||||
qCDebug(dcModbusTCP()) << "Setting up TCP connecion" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
|
||||
if (!m_modbusTcpClient)
|
||||
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);
|
||||
// Only connect if we are in the unconnected state
|
||||
if (m_modbusTcpClient->state() == QModbusDevice::UnconnectedState) {
|
||||
qCDebug(dcModbusTCP()) << "Connecting modbus TCP client to" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
|
||||
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();
|
||||
} else if (m_modbusTcpClient->state() != QModbusDevice::ConnectedState) {
|
||||
// Restart the timer in case of connecting not finished yet or closing
|
||||
m_reconnectTimer->start();
|
||||
} else {
|
||||
qCWarning(dcModbusTCP()) << "Connect modbus TCP device" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port) << "called, but the socket is currently in the" << m_modbusTcpClient->state();
|
||||
}
|
||||
|
||||
return m_modbusTcpClient->connectDevice();
|
||||
return false;
|
||||
}
|
||||
|
||||
void ModbusTCPMaster::disconnectDevice()
|
||||
@ -108,12 +112,24 @@ void ModbusTCPMaster::disconnectDevice()
|
||||
if (!m_modbusTcpClient)
|
||||
return;
|
||||
|
||||
// Stop the reconnect timer since disconnect was explicitly called
|
||||
m_reconnectTimer->stop();
|
||||
m_modbusTcpClient->disconnectDevice();
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::reconnectDevice()
|
||||
{
|
||||
qCWarning(dcModbusTCP()) << "Reconnecting modbus TCP device" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
|
||||
if (!m_modbusTcpClient)
|
||||
return false;
|
||||
|
||||
disconnectDevice();
|
||||
return connectDevice();
|
||||
}
|
||||
|
||||
bool ModbusTCPMaster::connected() const
|
||||
{
|
||||
return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState);
|
||||
return m_connected;
|
||||
}
|
||||
|
||||
int ModbusTCPMaster::numberOfRetries() const
|
||||
@ -148,13 +164,6 @@ QModbusDevice::Error ModbusTCPMaster::error() const
|
||||
return m_modbusTcpClient->error();
|
||||
}
|
||||
|
||||
void ModbusTCPMaster::onReconnectTimer()
|
||||
{
|
||||
if (!m_modbusTcpClient->connectDevice()) {
|
||||
m_reconnectTimer->start(10000);
|
||||
}
|
||||
}
|
||||
|
||||
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
|
||||
{
|
||||
if (!m_modbusTcpClient) {
|
||||
@ -458,12 +467,17 @@ void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error)
|
||||
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
|
||||
{
|
||||
qCDebug(dcModbusTCP()) << "Connection state changed for" << m_hostAddress << state;
|
||||
|
||||
bool connected = (state == QModbusDevice::ConnectedState);
|
||||
if (!connected) {
|
||||
//try to reconnect in 10 seconds
|
||||
m_reconnectTimer->start(10000);
|
||||
if (m_connected != connected) {
|
||||
m_connected = connected;
|
||||
emit connectionStateChanged(m_connected);
|
||||
}
|
||||
|
||||
emit connectionStateChanged(connected);
|
||||
// If the socket is connected, stop the reconnect timer...
|
||||
// If the socket is unconnected (not connecting and not closing), start the reconnect timer
|
||||
if (m_connected) {
|
||||
m_reconnectTimer->stop();
|
||||
} else if (state == QModbusDevice::UnconnectedState) {
|
||||
m_reconnectTimer->start();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,14 +44,13 @@ public:
|
||||
explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr);
|
||||
~ModbusTCPMaster();
|
||||
|
||||
// If you change the hostaddress, make sure to reconnectDevice afterwards
|
||||
QHostAddress hostAddress() const;
|
||||
bool setHostAddress(const QHostAddress &hostAddress);
|
||||
void setHostAddress(const QHostAddress &hostAddress);
|
||||
|
||||
// If you change the port, make sure to reconnectDevice afterwards
|
||||
uint port() const;
|
||||
bool setPort(uint port);
|
||||
|
||||
bool connectDevice();
|
||||
void disconnectDevice();
|
||||
void setPort(uint port);
|
||||
|
||||
bool connected() const;
|
||||
|
||||
@ -81,6 +80,11 @@ public:
|
||||
QModbusReply *sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress);
|
||||
QModbusReply *sendWriteRequest(const QModbusDataUnit &write, int serverAddress);
|
||||
|
||||
public slots:
|
||||
bool connectDevice();
|
||||
void disconnectDevice();
|
||||
bool reconnectDevice();
|
||||
|
||||
private:
|
||||
QTimer *m_reconnectTimer = nullptr;
|
||||
QModbusTcpClient *m_modbusTcpClient = nullptr;
|
||||
@ -89,10 +93,9 @@ private:
|
||||
uint m_port;
|
||||
int m_timeout = 1000;
|
||||
int m_numberOfRetries = 3;
|
||||
bool m_connected = false;
|
||||
|
||||
private slots:
|
||||
void onReconnectTimer();
|
||||
|
||||
void onModbusErrorOccurred(QModbusDevice::Error error);
|
||||
void onModbusStateChanged(QModbusDevice::State state);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user