Merge PR #216: Wattsonic: Improve inverter generation detection and provide fallback mechanism

pull/219/head
jenkins 2025-09-11 14:25:45 +02:00
commit c8eeeac911
5 changed files with 71 additions and 26 deletions

View File

@ -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

View File

@ -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": [

View File

@ -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";

View File

@ -29,12 +29,14 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "wattsonicinverter.h"
#include "extern-plugininfo.h"
#include <QLoggingCategory>
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;
}

View File

@ -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;
};