diff --git a/sungrow/integrationpluginsungrow.cpp b/sungrow/integrationpluginsungrow.cpp index c508b3c..5161a8c 100644 --- a/sungrow/integrationpluginsungrow.cpp +++ b/sungrow/integrationpluginsungrow.cpp @@ -52,12 +52,15 @@ void IntegrationPluginSungrow::discoverThings(ThingDiscoveryInfo *info) SungrowDiscovery *discovery = new SungrowDiscovery(hardwareManager()->networkDeviceDiscovery(), m_modbusTcpPort, m_modbusSlaveAddress, info); connect(discovery, &SungrowDiscovery::discoveryFinished, info, [=](){ foreach (const SungrowDiscovery::SungrowDiscoveryResult &result, discovery->discoveryResults()) { - QString title = "Sungrow " + QString::number(result.nominalOutputPower) + "kW Inverter"; + QString title = "Sungrow " + result.model; if (!result.serialNumber.isEmpty()) - title.append(" " + result.serialNumber); + title.append(" - " + result.serialNumber); - ThingDescriptor descriptor(sungrowInverterTcpThingClassId, title, result.networkDeviceInfo.address().toString()); + QString description(QString::number(result.nominalOutputPower)+ "kW Inverter - " + result.networkDeviceInfo.address().toString()); + + + ThingDescriptor descriptor(sungrowInverterTcpThingClassId, title, description); qCInfo(dcSungrow()) << "Discovered:" << descriptor.title() << descriptor.description(); ParamList params; @@ -158,6 +161,9 @@ void IntegrationPluginSungrow::setupThing(ThingSetupInfo *info) child->setStateValue(sungrowMeterCurrentPhaseAStateTypeId, 0); child->setStateValue(sungrowMeterCurrentPhaseBStateTypeId, 0); child->setStateValue(sungrowMeterCurrentPhaseCStateTypeId, 0); + child->setStateValue(sungrowMeterVoltagePhaseAStateTypeId, 0); + child->setStateValue(sungrowMeterVoltagePhaseBStateTypeId, 0); + child->setStateValue(sungrowMeterVoltagePhaseCStateTypeId, 0); child->setStateValue(sungrowMeterApparentPowerPhaseAStateTypeId, 0); child->setStateValue(sungrowMeterApparentPowerPhaseBStateTypeId, 0); child->setStateValue(sungrowMeterApparentPowerPhaseCStateTypeId, 0); @@ -214,7 +220,7 @@ void IntegrationPluginSungrow::setupThing(ThingSetupInfo *info) // Update the meter if available Thing *meterThing = getMeterThing(thing); if (meterThing) { - auto runningState = sungrowConnection->runningState(); + quint16 runningState = sungrowConnection->runningState(); qCDebug(dcSungrow()) << "Power generated from PV:" << (runningState & (0x1 << 0) ? "true" : "false"); qCDebug(dcSungrow()) << "Battery charging:" << (runningState & (0x1 << 1) ? "true" : "false"); qCDebug(dcSungrow()) << "Battery discharging:" << (runningState & (0x1 << 2) ? "true" : "false"); @@ -245,7 +251,14 @@ void IntegrationPluginSungrow::setupThing(ThingSetupInfo *info) batteryThing->setStateValue(sungrowBatteryBatteryLevelStateTypeId, sungrowConnection->batteryLevel()); batteryThing->setStateValue(sungrowBatteryBatteryCriticalStateTypeId, sungrowConnection->batteryLevel() < 5); - batteryThing->setStateValue(sungrowBatteryCurrentPowerStateTypeId, sungrowConnection->batteryPower()); + // Note: since firmware 2024 this is a int16 value, and we can use the value directly without convertion + if (sungrowConnection->batteryPower() < 0) { + batteryThing->setStateValue(sungrowBatteryCurrentPowerStateTypeId, sungrowConnection->batteryPower()); + } else { + qint16 batteryPower = (sungrowConnection->runningState() & (0x1 << 1) ? sungrowConnection->batteryPower() : sungrowConnection->batteryPower() * -1); + batteryThing->setStateValue(sungrowBatteryCurrentPowerStateTypeId, batteryPower); + } + quint16 runningState = sungrowConnection->runningState(); if (runningState & (0x1 << 1)) { //Bit 1: Battery charging bit batteryThing->setStateValue(sungrowBatteryChargingStateStateTypeId, "charging"); diff --git a/sungrow/integrationpluginsungrow.h b/sungrow/integrationpluginsungrow.h index dc0bede..706b9de 100644 --- a/sungrow/integrationpluginsungrow.h +++ b/sungrow/integrationpluginsungrow.h @@ -66,6 +66,7 @@ private: Thing *getMeterThing(Thing *parentThing); Thing *getBatteryThing(Thing *parentThing); + }; #endif // INTEGRATIONPLUGINSUNGROW_H diff --git a/sungrow/sungrow-registers.json b/sungrow/sungrow-registers.json index b69d9c9..4b0f776 100644 --- a/sungrow/sungrow-registers.json +++ b/sungrow/sungrow-registers.json @@ -310,7 +310,109 @@ ] }, { - "id": "energyValues2", + "id": "energyValues3", + "readSchedule": "update", + "registers": [ + { + "id": "meterVoltagePhaseA", + "address": 5740, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter voltage phase A", + "defaultValue": "0", + "staticScaleFactor": -1, + "unit": "Volt", + "access": "RO" + }, + { + "id": "meterVoltagePhaseB", + "address": 5741, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter voltage phase B", + "defaultValue": "0", + "staticScaleFactor": -1, + "unit": "Volt", + "access": "RO" + }, + { + "id": "meterVoltagePhaseC", + "address": 5742, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter voltage phase C", + "defaultValue": "0", + "staticScaleFactor": -1, + "unit": "Volt", + "access": "RO" + }, + { + "id": "meterCurrentPhaseA", + "address": 5743, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter current phase A", + "defaultValue": "0", + "staticScaleFactor": -2, + "unit": "Amper", + "access": "RO" + }, + { + "id": "meterCurrentPhaseB", + "address": 5744, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter current phase B", + "defaultValue": "0", + "staticScaleFactor": -2, + "unit": "Amper", + "access": "RO" + }, + { + "id": "meterCurrentPhaseC", + "address": 5745, + "size": 1, + "type": "uint16", + "registerType": "inputRegister", + "description": "Meter current phase C", + "defaultValue": "0", + "staticScaleFactor": -2, + "unit": "Amper", + "access": "RO" + }, + { + "id": "meterTotalEnergyImported", + "address": 5746, + "size": 2, + "type": "uint32", + "registerType": "inputRegister", + "description": "Meter totoal energy imported", + "unit": "kWh", + "defaultValue": "0", + "staticScaleFactor": -2, + "access": "RO" + }, + { + "id": "meterTotalEnergyExported", + "address": 5748, + "size": 2, + "type": "uint32", + "registerType": "inputRegister", + "description": "Meter totoal energy exported", + "unit": "kWh", + "defaultValue": "0", + "staticScaleFactor": -2, + "access": "RO" + } + ] + }, + { + "id": "energyValues4", "readSchedule": "update", "registers": [ { @@ -465,7 +567,7 @@ "id": "batteryPower", "address": 13021, "size": 1, - "type": "uint16", + "type": "int16", "registerType": "inputRegister", "description": "Battery power", "unit": "W", diff --git a/sungrow/sungrowdiscovery.cpp b/sungrow/sungrowdiscovery.cpp index d4ee9d2..0371fcc 100644 --- a/sungrow/sungrowdiscovery.cpp +++ b/sungrow/sungrowdiscovery.cpp @@ -60,6 +60,115 @@ void SungrowDiscovery::startDiscovery() }); } +QString SungrowDiscovery::deviceCodeToString(quint16 deviceTypeCode) +{ + QString deviceType; + switch (deviceTypeCode) { + // SH3.0-6.0RS + case 0xD17: + deviceType = "SH3.0RS"; + break; + case 0xD0D: + deviceType = "SH3.6RS"; + break; + case 0xD18: + deviceType = "SH4.0RS"; + break; + case 0xD0F: + deviceType = "SH5.0RS"; + break; + case 0xD10: + deviceType = "SH5.0RS"; + break; + + // SH8.0-10RS + case 0xD1A: + deviceType = "SH8.0RS"; + break; + case 0xD1B: + deviceType = "SH10RS"; + break; + + // SH5.0-10RT + case 0xE00: + deviceType = "SH5.0RT"; + break; + case 0xE01: + deviceType = "SH6.0RT"; + break; + case 0xE02: + deviceType = "SH8.0RT"; + break; + case 0xE03: + deviceType = "SH10RT"; + break; + case 0xE10: + deviceType = "SH5.0RT-20"; + break; + case 0xE11: + deviceType = "SH6.0RT-20"; + break; + case 0xE12: + deviceType = "SH8.0RT-20"; + break; + case 0xE13: + deviceType = "SH10RT-20"; + break; + case 0xE0C: + deviceType = "SH5.0RT-V112"; + break; + case 0xE0D: + deviceType = "SH6.0RT-V112"; + break; + case 0xE0E: + deviceType = "SH8.0RT-V112"; + break; + case 0xE0F: + deviceType = "SH10RT-V112"; + break; + case 0xE08: + deviceType = "SH5.0RT-V122"; + break; + case 0xE09: + deviceType = "SH6.0RT-V122"; + break; + case 0xE0A: + deviceType = "SH8.0RT-V122"; + break; + case 0xE0B: + deviceType = "SH10RT-V122"; + break; + + // SH5-25T + case 0xE20: + deviceType = "SH5T-V11"; + break; + case 0xE21: + deviceType = "SH6T-V11"; + break; + case 0xE22: + deviceType = "SH8T-V11"; + break; + case 0xE23: + deviceType = "SH10T-V11"; + break; + case 0xE24: + deviceType = "SH12T-V11"; + break; + case 0xE25: + deviceType = "SH15T-V11"; + break; + case 0xE26: + deviceType = "SH20T-V11"; + break; + case 0xE28: + deviceType = "SH25T-V11"; + break; + } + + return deviceType; +} + QList SungrowDiscovery::discoveryResults() const { return m_discoveryResults; @@ -93,14 +202,19 @@ void SungrowDiscovery::checkNetworkDevice(const QHostAddress &address) return; } - qCDebug(dcSungrow()) << "Discovery: Initialized successfully" << address.toString() << connection->serialNumber(); - qCDebug(dcSungrow()) << " - Protocol number:" << connection->protocolNumber(); - qCDebug(dcSungrow()) << " - Protocol version:" << connection->protocolVersion(); - qCDebug(dcSungrow()) << " - ARM software version:" << connection->armSoftwareVersion(); - qCDebug(dcSungrow()) << " - DSP software version:" << connection->dspSoftwareVersion(); if (connection->deviceTypeCode() >= 0xd00 && connection->deviceTypeCode() <= 0xeff) { + + qCDebug(dcSungrow()) << "Discovery: Initialized successfully" << address.toString() << connection->serialNumber(); + qCDebug(dcSungrow()) << " - Model:" << deviceCodeToString(connection->deviceTypeCode()); + qCDebug(dcSungrow()) << " - Protocol number:" << connection->protocolNumber(); + qCDebug(dcSungrow()) << " - Protocol version:" << connection->protocolVersion(); + qCDebug(dcSungrow()) << " - ARM software version:" << connection->armSoftwareVersion(); + qCDebug(dcSungrow()) << " - DSP software version:" << connection->dspSoftwareVersion(); + + SungrowDiscoveryResult result; + result.model = deviceCodeToString(connection->deviceTypeCode()); result.address = address; result.serialNumber = connection->serialNumber(); result.nominalOutputPower = connection->nominalOutputPower(); diff --git a/sungrow/sungrowdiscovery.h b/sungrow/sungrowdiscovery.h index 6cdf2ca..3ae4dee 100644 --- a/sungrow/sungrowdiscovery.h +++ b/sungrow/sungrowdiscovery.h @@ -44,6 +44,7 @@ class SungrowDiscovery : public QObject public: explicit SungrowDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port = 502, quint16 modbusAddress = 1, QObject *parent = nullptr); typedef struct SungrowDiscoveryResult { + QString model; QString serialNumber; QHostAddress address; NetworkDeviceInfo networkDeviceInfo; @@ -55,6 +56,8 @@ public: QList discoveryResults() const; + static QString deviceCodeToString(quint16 deviceTypeCode); + signals: void discoveryFinished();