Improved error handling logic to connect

master
Hermann Detz 2021-05-20 09:49:17 +02:00 committed by Michael Zanetti
parent a71b86f82e
commit 82dc46cd3b
6 changed files with 77 additions and 31 deletions

View File

@ -153,7 +153,7 @@ void IntegrationPluginMTec::update(Thing *thing)
}
}
void IntegrationPluginMTec::onConnectedChanged(bool connected)
void IntegrationPluginMTec::onConnectedChanged(MTecHelpers::ConnectionState state)
{
MTec *mtec = qobject_cast<MTec *>(sender());
Thing *thing = m_mtecConnections.key(mtec);
@ -163,7 +163,11 @@ void IntegrationPluginMTec::onConnectedChanged(bool connected)
if (!thing)
return;
thing->setStateValue(mtecConnectedStateTypeId, connected);
if (state == MTecHelpers::ConnectionState::Online) {
thing->setStateValue(mtecConnectedStateTypeId, true);
}
thing->setStateValue(mtecStatusStateTypeId, MTecHelpers::connectionStateToString(state));
}
void IntegrationPluginMTec::onStatusUpdated(const MTecInfo &info)

View File

@ -34,6 +34,7 @@
#include "plugintimer.h"
#include "mtec.h"
#include "mtechelpers.h"
#include <QUuid>
@ -62,7 +63,7 @@ private:
QHash<QUuid, ThingActionInfo *> m_asyncActions;
private slots:
void onConnectedChanged(bool connected);
void onConnectedChanged(MTecHelpers::ConnectionState state);
void onRefreshTimer();
void onStatusUpdated(const MTecInfo &info);

View File

@ -41,7 +41,10 @@ MTec::MTec(const QHostAddress &address, QObject *parent) :
m_modbusMaster = new ModbusTCPMaster(address, 502, this);
qCDebug(dcMTec()) << "created ModbusTCPMaster";
m_connected = m_modbusMaster->connectDevice();
if (m_modbusMaster->connectDevice()) {
emit connectedChanged(MTecHelpers::ConnectionState::Connecting);
}
connect(m_modbusMaster, &ModbusTCPMaster::receivedHoldingRegister, this, &MTec::onReceivedHoldingRegister);
connect(m_modbusMaster, &ModbusTCPMaster::readRequestError, this, &MTec::onModbusError);
@ -56,19 +59,22 @@ void MTec::onModbusError()
{
qCWarning(dcMTec()) << "MTec: Received modbus error";
emit connectedChanged(false);
/* Only emit connected changed signal, if a soft connection
* had already been established.
* This avoids a series of possibly fake connection state changes,
* while the modbus server in the heatpump is starting up. */
if (m_softConnection) {
m_softConnection = false;
emit connectedChanged(MTecHelpers::ConnectionState::Offline);
}
}
void MTec::onRequestStatus()
{
if ((m_connected) && (!m_firstTimeout.isValid())) {
/* No timestamp for timeout of first telegram defined,
* -> first request has not yet been sent
* -> do it now */
if ((m_softConnection) ||
((m_connected) && (m_requestsSent < MTec::ConnectionRetries))) {
/* Note: m_firstRequest is set to false in
* the onReceivedHoldingRegister function */
if (m_firstRequest == true) {
if (m_requestsSent < MTec::ConnectionRetries) {
m_firstTimeout = QDateTime::currentDateTime();
m_firstTimeout = m_firstTimeout.addSecs(MTec::FirstConnectionTimeout);
@ -83,17 +89,14 @@ void MTec::onRequestStatus()
/* Set back original modbus timeout */
m_modbusMaster->setTimeout(m_modbusTimeout);
}
} else {
QDateTime now = QDateTime::currentDateTime();
if (m_firstTimeout.msecsTo(now) < MTec::FirstConnectionTimeout) {
/* Timeout of first request not yet reached
* -> return without sending another request */
return;
}
qCDebug(dcMTec()) << "Max number of modbus connects reached, giving up";
return;
}
m_modbusMaster->readHoldingRegister(MTec::ModbusUnitID, MTec::ActualPowerConsumption, 1);
m_requestsSent ++;
}
void MTec::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const QVector<quint16> &value)
@ -102,7 +105,8 @@ void MTec::onReceivedHoldingRegister(int slaveAddress, int modbusRegister, const
/* Some response was received, so the modbus communication is
* established. */
m_firstRequest = false;
m_softConnection = true;
emit connectedChanged(MTecHelpers::ConnectionState::Online);
switch (modbusRegister) {
case ActualPowerConsumption:

View File

@ -37,6 +37,7 @@
#include "../modbus/modbustcpmaster.h"
#include "mtecinfo.h"
#include "mtechelpers.h"
class MTec : public QObject
{
@ -62,6 +63,9 @@ private:
/** Modbus Unit ID (undocumented, guessing 1 for now) */
static const quint16 ModbusUnitID = 1;
/** Number of retries to establish a modbus connection with the heat pump */
static const int ConnectionRetries = 3;
/** The following modbus addresses can be read: */
enum RegisterList {
/**
@ -108,15 +112,16 @@ private:
/** This structure is filled by the receivedStatus... functions */
MTecInfo m_info ;
bool m_firstRequest = true;
int m_requestsSent = 0;
bool m_connected = false;
bool m_softConnection = false;
QDateTime m_firstTimeout;
int m_modbusTimeout;
signals:
void connectedChanged(bool connected);
void connectedChanged(MTecHelpers::ConnectionState state);
void statusUpdated(const MTecInfo &info);
public slots:

View File

@ -44,19 +44,41 @@ void MTecHelpers::convertFloatToRegister(quint16 &reg, float value)
reg = qRound(value * 100.0);
}
QString MTecHelpers::externalHeatSourceRequestToString(quint16 value)
QString MTecHelpers::connectionStateToString(ConnectionState state)
{
QString str{};
switch (value) {
case 0:
str = "No request, external heat source must be turned off";
switch (state) {
case Offline:
str = QT_TR_NOOP("Off");
break;
case 1:
str = "External heat source is released and can be switched on";
case Connecting:
str = QT_TR_NOOP("Connecting");
break;
case 2:
str = "External heat source is required and must be turned on";
case Online:
str = QT_TR_NOOP("Connected");
break;
case Error:
str = QT_TR_NOOP("Error");
break;
}
return str;
}
QString MTecHelpers::externalHeatSourceRequestToString(quint16 value)
{
QString str{};
switch (value) {
case 0:
str = QT_TR_NOOP("No request, external heat source must be turned off");
break;
case 1:
str = QT_TR_NOOP("External heat source is released and can be switched on");
break;
case 2:
str = QT_TR_NOOP("External heat source is required and must be turned on");
break;
}

View File

@ -32,13 +32,23 @@
#define MTECHELPERS_H
#include <QtGlobal>
#include <QObject>
#include <QString>
class MTecHelpers {
class MTecHelpers : public QObject {
public:
enum ConnectionState {
Offline,
Connecting,
Online,
Error
};
Q_ENUM(ConnectionState);
static float convertRegisterToFloat(quint16 reg);
static void convertFloatToRegister(quint16 &reg, float value);
static QString connectionStateToString(ConnectionState state);
static QString externalHeatSourceRequestToString(quint16 value);
};