From b52d1e99c15d3f644dab1241dcdb0d01f1698ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20St=C3=BCrz?= Date: Thu, 8 Aug 2024 15:53:51 +0200 Subject: [PATCH] Update 1.2 verion handling and update states and debug information MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Simon Stürz --- inro/integrationplugininro.cpp | 14 +++++- inro/pantabox-registers.json | 3 +- inro/pantabox.cpp | 90 ++++++++++++++++++++-------------- inro/pantabox.h | 6 ++- inro/pantaboxdiscovery.cpp | 17 ++----- inro/pantaboxdiscovery.h | 2 - 6 files changed, 75 insertions(+), 57 deletions(-) diff --git a/inro/integrationplugininro.cpp b/inro/integrationplugininro.cpp index de06d88..7dc2d11 100644 --- a/inro/integrationplugininro.cpp +++ b/inro/integrationplugininro.cpp @@ -321,7 +321,13 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info) // Reset energy live values on disconnected thing->setStateValue(pantaboxCurrentPowerStateTypeId, 0); } else { - thing->setStateValue(pantaboxModbusTcpVersionStateTypeId, PantaboxDiscovery::modbusVersionToString(connection->modbusTcpVersion())); + connection->initialize(); + } + }); + + connect(connection, &Pantabox::initializationFinished, thing, [thing, connection](bool success){ + if (success) { + thing->setStateValue(pantaboxModbusTcpVersionStateTypeId, Pantabox::modbusVersionToString(connection->modbusTcpVersion())); } }); @@ -360,7 +366,7 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info) thing->setStateValue(pantaboxPluggedInStateTypeId, connection->chargingState() >= Pantabox::ChargingStateB); thing->setStateValue(pantaboxChargingStateTypeId, connection->chargingState() >= Pantabox::ChargingStateC); thing->setStateValue(pantaboxCurrentPowerStateTypeId, connection->currentPower()); // W - thing->setStateValue(pantaboxTotalEnergyConsumedStateTypeId, connection->chargedEnergy() / 1000.0); // Wh + thing->setStateValue(pantaboxSessionEnergyStateTypeId, connection->chargedEnergy() / 1000.0); // Wh thing->setStateMaxValue(pantaboxMaxChargingCurrentActionTypeId, connection->maxPossibleChargingCurrent()); // Phase count is a setting, since we don't get the information from the device. @@ -371,6 +377,10 @@ void IntegrationPluginInro::setupConnection(ThingSetupInfo *info) thing->setStateValue(pantaboxPhaseCountStateTypeId, Electricity::getPhaseCount(phases)); thing->setStateValue(pantaboxUsedPhasesStateTypeId, thing->setting(pantaboxSettingsPhasesParamTypeId).toString()); + // Following states depend on the modbus TCP version, default they will be reset. + thing->setStateValue(pantaboxFirmwareVersionStateTypeId, connection->firmwareVersion()); + thing->setStateValue(pantaboxTotalEnergyConsumedStateTypeId, connection->absoluteEnergy() / 1000.0); // Wh + }); m_connections.insert(thing, connection); diff --git a/inro/pantabox-registers.json b/inro/pantabox-registers.json index edb4d13..6e59fb9 100644 --- a/inro/pantabox-registers.json +++ b/inro/pantabox-registers.json @@ -2,6 +2,7 @@ "className": "Pantabox", "protocol": "TCP", "endianness": "LittleEndian", + "stringEndianness": "LittleEndian", "errorLimitUntilNotReachable": 2, "checkReachableRegister": "chargingState", "blocks": [ ], @@ -81,7 +82,7 @@ "id": "firmwareVersion", "address": 266, "size": 16, - "type": "uint32", + "type": "string", "registerType": "inputRegister", "description": "Firmware version", "readSchedule": "update", diff --git a/inro/pantabox.cpp b/inro/pantabox.cpp index 452c09f..9195c00 100644 --- a/inro/pantabox.cpp +++ b/inro/pantabox.cpp @@ -29,7 +29,6 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "pantabox.h" -#include "loggingcategories.h" #include "pantaboxmodbustcpconnection.cpp" Pantabox::Pantabox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent) : @@ -38,6 +37,13 @@ Pantabox::Pantabox(const QHostAddress &hostAddress, uint port, quint16 slaveId, } +QString Pantabox::modbusVersionToString(quint32 value) +{ + quint16 modbusVersionMinor = (value >> 16) & 0xffff; + quint16 modbusVersionMajor = value & 0xffff; + return QString("%1.%2").arg(modbusVersionMajor).arg(modbusVersionMinor); +} + bool Pantabox::update() { if (!m_modbusTcpMaster->connected()) return false; @@ -308,45 +314,11 @@ bool Pantabox::update() { } }); - // The Modbus register for absolute charged energy is available since Modbusversion 1.1 - if (m_modbusTcpVersion > 65536) { - // Read Absolute charged energy - qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Absolute charged energy\" register:" << 519 << "size:" << 2; - reply = readAbsoluteEnergy(); - if (!reply) { - qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); - return false; - } + // Following Modbus registers depend on the modbus TCP protocol version and require compatibility checks - if (reply->isFinished()) { - reply->deleteLater(); // Broadcast reply returns immediatly - return false; - } - - m_pendingUpdateReplies.append(reply); - connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); - connect(reply, &QModbusReply::finished, this, [this, reply](){ - m_pendingUpdateReplies.removeAll(reply); - handleModbusError(reply->error()); - if (reply->error() != QModbusDevice::NoError) { - verifyUpdateFinished(); - return; - } - - const QModbusDataUnit unit = reply->result(); - processAbsoluteEnergyRegisterValues(unit.values()); - verifyUpdateFinished(); - }); - - connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ - QModbusResponse response = reply->rawResult(); - if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { - qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); - } else { - qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); - } - }); + // Firmware version registers are available since modbus TCP version 1.1 (0x0001 0x0001) 0x10001 = 65537 + if (m_modbusTcpVersion >= 65537) { // Read Firmware version qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Firmware version\" register:" << 266 << "size:" << 16; @@ -385,5 +357,47 @@ bool Pantabox::update() { } }); } + + // Absolute charged energy is available since modbus TCP version 1.2 (0x0001 0x0002) 0x10002 = 65538 + if (m_modbusTcpVersion >= 65538) { + + // Read Absolute charged energy + qCDebug(dcPantaboxModbusTcpConnection()) << "--> Read \"Absolute charged energy\" register:" << 519 << "size:" << 2; + reply = readAbsoluteEnergy(); + if (!reply) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + return false; + } + + if (reply->isFinished()) { + reply->deleteLater(); // Broadcast reply returns immediatly + return false; + } + + m_pendingUpdateReplies.append(reply); + connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater); + connect(reply, &QModbusReply::finished, this, [this, reply](){ + m_pendingUpdateReplies.removeAll(reply); + handleModbusError(reply->error()); + if (reply->error() != QModbusDevice::NoError) { + verifyUpdateFinished(); + return; + } + + const QModbusDataUnit unit = reply->result(); + processAbsoluteEnergyRegisterValues(unit.values()); + verifyUpdateFinished(); + }); + + connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){ + QModbusResponse response = reply->rawResult(); + if (reply->error() == QModbusDevice::ProtocolError && response.isException()) { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString() << ModbusDataUtils::exceptionCodeToString(response.exceptionCode()); + } else { + qCWarning(dcPantaboxModbusTcpConnection()) << "Modbus reply error occurred while reading \"Absolute charged energy\" registers from" << m_modbusTcpMaster->hostAddress().toString() << error << reply->errorString(); + } + }); + } + return true; } diff --git a/inro/pantabox.h b/inro/pantabox.h index 1e88d92..a9fe6ee 100644 --- a/inro/pantabox.h +++ b/inro/pantabox.h @@ -39,9 +39,11 @@ class Pantabox : public PantaboxModbusTcpConnection public: explicit Pantabox(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent = nullptr); explicit Pantabox(ModbusTcpMaster *modbusTcpMaster, quint16 slaveId, QObject *parent = nullptr); - ~Pantabox() = default; + ~Pantabox() override = default ; - virtual bool update() override; + static QString modbusVersionToString(quint32 value); + + bool update() override; }; #endif // PANTABOX_H diff --git a/inro/pantaboxdiscovery.cpp b/inro/pantaboxdiscovery.cpp index 0ccf067..66ec346 100644 --- a/inro/pantaboxdiscovery.cpp +++ b/inro/pantaboxdiscovery.cpp @@ -43,13 +43,6 @@ QList PantaboxDiscovery::results() const return m_results; } -QString PantaboxDiscovery::modbusVersionToString(quint32 value) -{ - quint16 modbusVersionMinor = (value >> 8) & 0xffff; - quint16 modbusVersionMajor = value & 0xffff; - return QString("%1.%2").arg(modbusVersionMajor).arg(modbusVersionMinor); -} - void PantaboxDiscovery::startDiscovery() { qCInfo(dcInro()) << "Discovery: Start searching for PANTABOX wallboxes in the network..."; @@ -87,8 +80,8 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic return; } - // Modbus registers for vendor and product name are available since Modbus version 1.1 - if (connection->modbusTcpVersion() > 65536) { + // Vendor and product name registers are available since modbus TCP version 1.1 (0x0001 0x0001) 0x10001 = 65537 + if (connection->modbusTcpVersion() >= 65537) { QModbusReply *reply = connection->readProductName(); if (!reply) { @@ -111,7 +104,6 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic } const QModbusDataUnit unit = reply->result(); - qCDebug(dcInro()) << "<-- Response from \"Name of product\" register" << 262 << "size:" << 4 << unit.values(); if (unit.values().size() == 4) { QString receivedProductName = ModbusDataUtils::convertToString(unit.values(), connection->stringEndianness()); if (receivedProductName.toUpper().contains("PANTABOX")) { @@ -127,7 +119,8 @@ void PantaboxDiscovery::checkNetworkDevice(const NetworkDeviceInfo &networkDevic } }); } else { - qCDebug(dcInro()) << "Discovery: Device not added to result because of wrong ModbusTcpVersion" << modbusVersionToString(connection->modbusTcpVersion()); + qCDebug(dcInro()) << "Discovery: Adding connection to results even tough the result is not precise due to modbus TCP protocol version:" + << connection->modbusTcpVersion() << Pantabox::modbusVersionToString(connection->modbusTcpVersion()); addResult(connection, networkDeviceInfo); } }); @@ -183,7 +176,7 @@ void PantaboxDiscovery::addResult(Pantabox *connection, const NetworkDeviceInfo Result result; result.serialNumber = QString::number(connection->serialNumber(), 16).toUpper(); - result.modbusTcpVersion = modbusVersionToString(connection->modbusTcpVersion()); + result.modbusTcpVersion = Pantabox::modbusVersionToString(connection->modbusTcpVersion()); result.networkDeviceInfo = networkDeviceInfo; m_results.append(result); diff --git a/inro/pantaboxdiscovery.h b/inro/pantaboxdiscovery.h index 7732601..6030c0a 100644 --- a/inro/pantaboxdiscovery.h +++ b/inro/pantaboxdiscovery.h @@ -50,8 +50,6 @@ public: QList results() const; - static QString modbusVersionToString(quint32 value); - public slots: void startDiscovery();