diff --git a/mtec/integrationpluginmtec.cpp b/mtec/integrationpluginmtec.cpp index 1c94e2e..0dffcc0 100644 --- a/mtec/integrationpluginmtec.cpp +++ b/mtec/integrationpluginmtec.cpp @@ -153,7 +153,7 @@ void IntegrationPluginMTec::update(Thing *thing) } } -void IntegrationPluginMTec::onConnectedChanged(bool connected) +void IntegrationPluginMTec::onConnectedChanged(MTecHelpers::ConnectionState state) { MTec *mtec = qobject_cast(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) diff --git a/mtec/integrationpluginmtec.h b/mtec/integrationpluginmtec.h index f7fe9ea..a2ecedb 100644 --- a/mtec/integrationpluginmtec.h +++ b/mtec/integrationpluginmtec.h @@ -34,6 +34,7 @@ #include "plugintimer.h" #include "mtec.h" +#include "mtechelpers.h" #include @@ -62,7 +63,7 @@ private: QHash m_asyncActions; private slots: - void onConnectedChanged(bool connected); + void onConnectedChanged(MTecHelpers::ConnectionState state); void onRefreshTimer(); void onStatusUpdated(const MTecInfo &info); diff --git a/mtec/mtec.cpp b/mtec/mtec.cpp index 7a027fd..21d25bf 100644 --- a/mtec/mtec.cpp +++ b/mtec/mtec.cpp @@ -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 &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: diff --git a/mtec/mtec.h b/mtec/mtec.h index d725b8a..1fbe047 100644 --- a/mtec/mtec.h +++ b/mtec/mtec.h @@ -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: diff --git a/mtec/mtechelpers.cpp b/mtec/mtechelpers.cpp index 27cb7a0..b57547b 100644 --- a/mtec/mtechelpers.cpp +++ b/mtec/mtechelpers.cpp @@ -44,19 +44,41 @@ void MTecHelpers::convertFloatToRegister(quint16 ®, 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; } diff --git a/mtec/mtechelpers.h b/mtec/mtechelpers.h index 452ba51..c95ae28 100644 --- a/mtec/mtechelpers.h +++ b/mtec/mtechelpers.h @@ -32,13 +32,23 @@ #define MTECHELPERS_H #include +#include #include -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 ®, float value); + static QString connectionStateToString(ConnectionState state); static QString externalHeatSourceRequestToString(quint16 value); };