diff --git a/wattsonic/integrationpluginwattsonic.cpp b/wattsonic/integrationpluginwattsonic.cpp index 258ad38..5c5a8a4 100644 --- a/wattsonic/integrationpluginwattsonic.cpp +++ b/wattsonic/integrationpluginwattsonic.cpp @@ -157,7 +157,17 @@ void IntegrationPluginWattsonic::setupWattsonicConnection(ThingSetupInfo *info) return; } - WattsonicInverter *connection = new WattsonicInverter(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), slaveId, this); + QString inverterGenerationModeString = thing->paramValue(inverterThingInverterGenerationParamTypeId).toString(); + WattsonicInverter::InverterGenerationMode inverterGenerationMode; + if (inverterGenerationModeString == "Gen2") { + inverterGenerationMode = WattsonicInverter::InverterGenerationModeGen2; + } else if (inverterGenerationModeString == "Gen3") { + inverterGenerationMode = WattsonicInverter::InverterGenerationModeGen3; + } else { + inverterGenerationMode = WattsonicInverter::InverterGenerationModeAuto; + } + + WattsonicInverter *connection = new WattsonicInverter(hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid), slaveId, inverterGenerationMode, this); m_connections.insert(thing, connection); // Only for setup diff --git a/wattsonic/integrationpluginwattsonic.json b/wattsonic/integrationpluginwattsonic.json index b7ce3b8..6078322 100644 --- a/wattsonic/integrationpluginwattsonic.json +++ b/wattsonic/integrationpluginwattsonic.json @@ -44,6 +44,14 @@ "displayName": "Serial number", "type": "QString", "defaultValue": "" + }, + { + "id": "388032f7-80c6-4410-8f7b-367cd06cb40a", + "name": "inverterGeneration", + "displayName": "Inverter generation", + "type": "QString", + "allowedValues": ["Auto", "Gen2", "Gen3"], + "defaultValue": "Auto" } ], "stateTypes": [ diff --git a/wattsonic/wattsonicdiscovery.cpp b/wattsonic/wattsonicdiscovery.cpp index e80eb9a..e7a0c03 100644 --- a/wattsonic/wattsonicdiscovery.cpp +++ b/wattsonic/wattsonicdiscovery.cpp @@ -77,7 +77,7 @@ void WattsonicDiscovery::tryConnect(ModbusRtuMaster *master, quint16 slaveId) qCDebug(dcWattsonic()) << "Discovery: Scanning modbus RTU master" << master->modbusUuid() << "Slave ID:" << slaveId; m_verifiedMasters.append(master); - WattsonicInverter *connection = new WattsonicInverter(master, slaveId, this); + WattsonicInverter *connection = new WattsonicInverter(master, slaveId, WattsonicInverter::InverterGenerationModeAuto, this); connect(connection, &WattsonicInverter::reachableChanged, this, [connection](bool reachable){ if (reachable) { qCDebug(dcWattsonic()) << "Discovery: The connection is now reachable. Starting the initialization"; diff --git a/wattsonic/wattsonicinverter.cpp b/wattsonic/wattsonicinverter.cpp index 47fb94c..879107f 100644 --- a/wattsonic/wattsonicinverter.cpp +++ b/wattsonic/wattsonicinverter.cpp @@ -29,12 +29,14 @@ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "wattsonicinverter.h" +#include "extern-plugininfo.h" #include Q_DECLARE_LOGGING_CATEGORY(dcWattsonicModbusRtuConnection) -WattsonicInverter::WattsonicInverter(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, QObject *parent) - : WattsonicModbusRtuConnection{modbusRtuMaster, slaveId, parent} +WattsonicInverter::WattsonicInverter(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, InverterGenerationMode generationMode, QObject *parent) + : WattsonicModbusRtuConnection{modbusRtuMaster, slaveId, parent}, + m_generationMode{generationMode} { connect(this, &WattsonicInverter::initializationFinished, this, [this](bool success){ @@ -58,26 +60,43 @@ WattsonicInverter::WattsonicInverter(ModbusRtuMaster *modbusRtuMaster, quint16 s qCDebug(dcWattsonicModbusRtuConnection()) << "Internal init finished successfully" << serialNumber() << inverterInfo.type << inverterInfo.model; m_inverterInfo = inverterInfo; - // Verify which generation this is by testing one generation dependent register. - ModbusRtuReply *reply = readBatteryVoltageDcGen2(); - if (!reply) { - qCWarning(dcWattsonicModbusRtuConnection()) << "Unable to test the generation request on the modbus master. Something might be wrong with the connection."; - emit customInitializationFinished(false); - return; + if (m_generationMode == InverterGenerationModeAuto) { + + // Verify which generation this is by testing one generation dependent register. + // On Gen3 this request returns with an exception response + + // Note: The DC voltage returns in both generations valid data, don't use that one + qCDebug(dcWattsonic()) << "Inverter generation autodetection active. Checking the inverter generation..."; + ModbusRtuReply *reply = readSOCGen2(); + if (!reply) { + qCWarning(dcWattsonicModbusRtuConnection()) << "Unable to test the generation request on the modbus master. Something might be wrong with the connection."; + emit customInitializationFinished(false); + return; + } + + connect(reply, &ModbusRtuReply::finished, this, [this, reply](){ + if (reply->error() != ModbusRtuReply::NoError) { + qCWarning(dcWattsonicModbusRtuConnection()) << "Reply finished with error after reading a Gen2 register. Assuming this is a Gen3 inverter."; + m_generation = Generation3; + emit customInitializationFinished(true); + return; + } else { + qCDebug(dcWattsonicModbusRtuConnection()) << "Successfully read gen2 register. Assuming this is a Gen2 inverter."; + m_generation = Generation2; + emit customInitializationFinished(true); + } + }); + } else { + if (m_generationMode == InverterGenerationModeGen2) { + m_generation = Generation2; + } else { + m_generation = Generation3; + } + + emit customInitializationFinished(true); + qCDebug(dcWattsonic()) << "Inverter generation forced to" << m_generation; } - connect(reply, &ModbusRtuReply::finished, this, [this, reply](){ - if (reply->error() != ModbusRtuReply::NoError) { - qCWarning(dcWattsonicModbusRtuConnection()) << "Reply finished with error after reading gen 2 register. Assuming this is a gen 3 device."; - m_generation = Generation3; - emit customInitializationFinished(true); - return; - } else { - qCDebug(dcWattsonicModbusRtuConnection()) << "Successfully read gen2 register. Assuming this is a gen 2 device."; - m_generation = Generation2; - emit customInitializationFinished(true); - } - }); }); } @@ -163,7 +182,7 @@ float WattsonicInverter::SOH() const bool WattsonicInverter::update() { - if (m_generation == GenerationUnknwon) { + if (m_generation == GenerationUnknown) { qCDebug(dcWattsonicModbusRtuConnection()) << "Tried to update but we don't know yet if this is a gen2 or gen3 inverter. Waiting for the information."; return false; } diff --git a/wattsonic/wattsonicinverter.h b/wattsonic/wattsonicinverter.h index 1d146e1..dbaf774 100644 --- a/wattsonic/wattsonicinverter.h +++ b/wattsonic/wattsonicinverter.h @@ -44,14 +44,21 @@ public: QString model; }; + enum InverterGenerationMode { + InverterGenerationModeAuto, + InverterGenerationModeGen2, + InverterGenerationModeGen3 + }; + Q_ENUM(InverterGenerationMode) + enum Generation { - GenerationUnknwon, + GenerationUnknown, Generation2, Generation3 }; Q_ENUM(Generation) - explicit WattsonicInverter(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, QObject *parent = nullptr); + explicit WattsonicInverter(ModbusRtuMaster *modbusRtuMaster, quint16 slaveId, InverterGenerationMode generationMode = InverterGenerationModeAuto, QObject *parent = nullptr); Generation generation() const; WattsonicInverter::Info inverterInfo() const; @@ -75,7 +82,8 @@ signals: private: WattsonicInverter::Info m_inverterInfo; - Generation m_generation = GenerationUnknwon; + InverterGenerationMode m_generationMode = InverterGenerationModeAuto; + Generation m_generation = GenerationUnknown; };