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 = new QTimer(this);
|
||||||
m_reconnectTimer->setSingleShot(true);
|
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()
|
ModbusTCPMaster::~ModbusTCPMaster()
|
||||||
{
|
{
|
||||||
if (m_reconnectTimer) {
|
if (m_reconnectTimer) {
|
||||||
m_reconnectTimer->stop();
|
m_reconnectTimer->stop();
|
||||||
delete m_reconnectTimer;
|
|
||||||
m_reconnectTimer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_modbusTcpClient) {
|
if (m_modbusTcpClient) {
|
||||||
m_modbusTcpClient->disconnectDevice();
|
disconnectDevice();
|
||||||
delete m_modbusTcpClient;
|
|
||||||
m_modbusTcpClient = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,30 +74,37 @@ uint ModbusTCPMaster::port() const
|
|||||||
return m_port;
|
return m_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusTCPMaster::setPort(uint port)
|
void ModbusTCPMaster::setPort(uint port)
|
||||||
{
|
{
|
||||||
m_port = port;
|
m_port = port;
|
||||||
return connectDevice();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
void ModbusTCPMaster::setHostAddress(const QHostAddress &hostAddress)
|
||||||
{
|
{
|
||||||
m_hostAddress = 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" << 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);
|
// Only connect if we are in the unconnected state
|
||||||
m_modbusTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, m_hostAddress.toString());
|
if (m_modbusTcpClient->state() == QModbusDevice::UnconnectedState) {
|
||||||
m_modbusTcpClient->setTimeout(m_timeout);
|
qCDebug(dcModbusTCP()) << "Connecting modbus TCP client to" << QString("%1:%2").arg(m_hostAddress.toString()).arg(m_port);
|
||||||
m_modbusTcpClient->setNumberOfRetries(m_numberOfRetries);
|
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()
|
void ModbusTCPMaster::disconnectDevice()
|
||||||
@ -108,12 +112,24 @@ void ModbusTCPMaster::disconnectDevice()
|
|||||||
if (!m_modbusTcpClient)
|
if (!m_modbusTcpClient)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Stop the reconnect timer since disconnect was explicitly called
|
||||||
|
m_reconnectTimer->stop();
|
||||||
m_modbusTcpClient->disconnectDevice();
|
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
|
bool ModbusTCPMaster::connected() const
|
||||||
{
|
{
|
||||||
return (m_modbusTcpClient->state() == QModbusDevice::State::ConnectedState);
|
return m_connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModbusTCPMaster::numberOfRetries() const
|
int ModbusTCPMaster::numberOfRetries() const
|
||||||
@ -148,13 +164,6 @@ QModbusDevice::Error ModbusTCPMaster::error() const
|
|||||||
return m_modbusTcpClient->error();
|
return m_modbusTcpClient->error();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModbusTCPMaster::onReconnectTimer()
|
|
||||||
{
|
|
||||||
if (!m_modbusTcpClient->connectDevice()) {
|
|
||||||
m_reconnectTimer->start(10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
|
QUuid ModbusTCPMaster::readCoil(uint slaveAddress, uint registerAddress, uint size)
|
||||||
{
|
{
|
||||||
if (!m_modbusTcpClient) {
|
if (!m_modbusTcpClient) {
|
||||||
@ -458,12 +467,17 @@ void ModbusTCPMaster::onModbusErrorOccurred(QModbusDevice::Error error)
|
|||||||
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
|
void ModbusTCPMaster::onModbusStateChanged(QModbusDevice::State state)
|
||||||
{
|
{
|
||||||
qCDebug(dcModbusTCP()) << "Connection state changed for" << m_hostAddress << state;
|
qCDebug(dcModbusTCP()) << "Connection state changed for" << m_hostAddress << state;
|
||||||
|
|
||||||
bool connected = (state == QModbusDevice::ConnectedState);
|
bool connected = (state == QModbusDevice::ConnectedState);
|
||||||
if (!connected) {
|
if (m_connected != connected) {
|
||||||
//try to reconnect in 10 seconds
|
m_connected = connected;
|
||||||
m_reconnectTimer->start(10000);
|
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);
|
explicit ModbusTCPMaster(const QHostAddress &hostAddress, uint port, QObject *parent = nullptr);
|
||||||
~ModbusTCPMaster();
|
~ModbusTCPMaster();
|
||||||
|
|
||||||
|
// If you change the hostaddress, make sure to reconnectDevice afterwards
|
||||||
QHostAddress hostAddress() const;
|
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;
|
uint port() const;
|
||||||
bool setPort(uint port);
|
void setPort(uint port);
|
||||||
|
|
||||||
bool connectDevice();
|
|
||||||
void disconnectDevice();
|
|
||||||
|
|
||||||
bool connected() const;
|
bool connected() const;
|
||||||
|
|
||||||
@ -81,6 +80,11 @@ public:
|
|||||||
QModbusReply *sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress);
|
QModbusReply *sendReadWriteRequest(const QModbusDataUnit &read, const QModbusDataUnit &write, int serverAddress);
|
||||||
QModbusReply *sendWriteRequest(const QModbusDataUnit &write, int serverAddress);
|
QModbusReply *sendWriteRequest(const QModbusDataUnit &write, int serverAddress);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
bool connectDevice();
|
||||||
|
void disconnectDevice();
|
||||||
|
bool reconnectDevice();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimer *m_reconnectTimer = nullptr;
|
QTimer *m_reconnectTimer = nullptr;
|
||||||
QModbusTcpClient *m_modbusTcpClient = nullptr;
|
QModbusTcpClient *m_modbusTcpClient = nullptr;
|
||||||
@ -89,10 +93,9 @@ private:
|
|||||||
uint m_port;
|
uint m_port;
|
||||||
int m_timeout = 1000;
|
int m_timeout = 1000;
|
||||||
int m_numberOfRetries = 3;
|
int m_numberOfRetries = 3;
|
||||||
|
bool m_connected = false;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onReconnectTimer();
|
|
||||||
|
|
||||||
void onModbusErrorOccurred(QModbusDevice::Error error);
|
void onModbusErrorOccurred(QModbusDevice::Error error);
|
||||||
void onModbusStateChanged(QModbusDevice::State state);
|
void onModbusStateChanged(QModbusDevice::State state);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user