Finish first implementation of inverter, meter and battery
parent
89f152060f
commit
cb8fdb0105
|
|
@ -1,3 +1,11 @@
|
|||
nymea-plugins-modbus (0.30.0+202201281421~c194a9f~buster+202201281425~2c664e6~buster) UNRELEASED; urgency=medium
|
||||
|
||||
|
||||
[ ]
|
||||
* New Package build
|
||||
|
||||
-- <timon@base-nymea-builder-buster-amd64-armhf> Fri, 28 Jan 2022 14:25:13 +0000
|
||||
|
||||
nymea-plugins-modbus (0.30.0) xenial; urgency=medium
|
||||
|
||||
[ Michael Zanetti ]
|
||||
|
|
|
|||
|
|
@ -118,24 +118,36 @@
|
|||
"value": 40960
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "BatteryDeviceStatus",
|
||||
"values": [
|
||||
{
|
||||
"key": "Offline",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "Standby",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "Running",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "Fault",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "SleepMode",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"blocks": [
|
||||
],
|
||||
"registers": [
|
||||
{
|
||||
"id": "inverterDCPower",
|
||||
"address": 32064,
|
||||
"size": 2,
|
||||
"type": "int32",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Inverter DC power",
|
||||
"unit": "kW",
|
||||
"staticScaleFactor": -3,
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "inverterActivePower",
|
||||
"address": 32080,
|
||||
|
|
@ -149,6 +161,31 @@
|
|||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "inverterDeviceStatus",
|
||||
"address": 32089,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Inverter device status",
|
||||
"enum": "InverterDeviceStatus",
|
||||
"defaultValue": "InverterDeviceStatusStandbyInitializing",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "inverterEnergyProduced",
|
||||
"address": 32106,
|
||||
"size": 2,
|
||||
"type": "uint32",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Inverter energy produced",
|
||||
"unit": "kWh",
|
||||
"staticScaleFactor": -2,
|
||||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "powerMeterActivePower",
|
||||
"address": 37113,
|
||||
|
|
@ -161,6 +198,18 @@
|
|||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "lunaBattery1Status",
|
||||
"address": 37000,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Luna 2000 Battery 1 status",
|
||||
"enum": "BatteryDeviceStatus",
|
||||
"defaultValue": "BatteryDeviceStatusOffline",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "lunaBattery1Power",
|
||||
"address": 37001,
|
||||
|
|
@ -186,6 +235,18 @@
|
|||
"defaultValue": "0",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "lunaBattery2Status",
|
||||
"address": 37741,
|
||||
"size": 1,
|
||||
"type": "uint16",
|
||||
"registerType": "holdingRegister",
|
||||
"readSchedule": "update",
|
||||
"description": "Luna 2000 Battery 2 status",
|
||||
"enum": "BatteryDeviceStatus",
|
||||
"defaultValue": "BatteryDeviceStatusOffline",
|
||||
"access": "RO"
|
||||
},
|
||||
{
|
||||
"id": "lunaBattery2Power",
|
||||
"address": 37743,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#include "huaweifusionsolar.h"
|
||||
#include "extern-plugininfo.h"
|
||||
#include "loggingcategories.h"
|
||||
|
||||
NYMEA_LOGGING_CATEGORY(dcHuaweiFusionSolar, "HuaweiFusionSolar")
|
||||
|
||||
HuaweiFusionSolar::HuaweiFusionSolar(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent) :
|
||||
HuaweiModbusTcpConnection(hostAddress, port, slaveId, parent)
|
||||
|
|
@ -20,16 +23,24 @@ void HuaweiFusionSolar::update()
|
|||
return;
|
||||
|
||||
// Add the requests
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterInverterDCPower);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterInverterActivePower);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery1Power);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery1Soc);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterInverterDeviceStatus);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterInverterEnergyProduced);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery1Status);
|
||||
if (m_battery1Available) {
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery1Power);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery1Soc);
|
||||
}
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterPowerMeterActivePower);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery2Soc);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery2Power);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery2Status);
|
||||
if (m_battery2Available) {
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery2Power);
|
||||
m_registersQueue.enqueue(HuaweiModbusTcpConnection::RegisterLunaBattery2Soc);
|
||||
}
|
||||
|
||||
// Note: since huawei can only process one request at the time, we need to queue the requests
|
||||
|
||||
m_currentRegisterRequest = -1;
|
||||
readNextRegister();
|
||||
}
|
||||
|
||||
|
|
@ -39,11 +50,16 @@ void HuaweiFusionSolar::readNextRegister()
|
|||
if (m_currentRegisterRequest >= 0)
|
||||
return;
|
||||
|
||||
// Check if there is still a register to read
|
||||
if (m_registersQueue.isEmpty())
|
||||
return;
|
||||
|
||||
m_currentRegisterRequest = m_registersQueue.dequeue();
|
||||
|
||||
switch (m_currentRegisterRequest) {
|
||||
case HuaweiModbusTcpConnection::RegisterInverterDCPower:
|
||||
// Update registers from Inverter DC power
|
||||
qCDebug(dcHuawei()) << "--> Read \"Inverter DC power\" register:" << 32064 << "size:" << 2;
|
||||
QModbusReply *reply = readInverterDCPower();
|
||||
case HuaweiModbusTcpConnection::RegisterInverterActivePower: {
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Inverter active power\" register:" << 32080 << "size:" << 2;
|
||||
QModbusReply *reply = readInverterActivePower();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
|
|
@ -51,27 +67,364 @@ void HuaweiFusionSolar::readNextRegister()
|
|||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuawei()) << "<-- Response from \"Inverter DC power\" register" << 32064 << "size:" << 2 << values;
|
||||
float receivedInverterDCPower = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian) * 1.0 * pow(10, -3);
|
||||
if (m_inverterDCPower != receivedInverterDCPower) {
|
||||
m_inverterDCPower = receivedInverterDCPower;
|
||||
emit inverterDCPowerChanged(m_inverterDCPower);
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter active power\" register" << 32080 << "size:" << 2 << values;
|
||||
float receivedInverterActivePower = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian) * 1.0 * pow(10, -3);
|
||||
if (m_inverterActivePower != receivedInverterActivePower) {
|
||||
m_inverterActivePower = receivedInverterActivePower;
|
||||
emit inverterActivePowerChanged(m_inverterActivePower);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuawei()) << "Modbus reply error occurred while updating \"Inverter DC power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Inverter active power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuawei()) << "Error occurred while reading \"Inverter DC power\" registers from" << hostAddress().toString() << errorString();
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Inverter active power\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterInverterDeviceStatus: {
|
||||
// Update registers from Inverter device status
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Inverter device status\" register:" << 32089 << "size:" << 1;
|
||||
QModbusReply *reply = readInverterDeviceStatus();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter device status\" register" << 32089 << "size:" << 1 << values;
|
||||
InverterDeviceStatus receivedInverterDeviceStatus = static_cast<InverterDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
qCDebug(dcHuaweiFusionSolar()) << "Inverter status" << receivedInverterDeviceStatus;
|
||||
if (m_inverterDeviceStatus != receivedInverterDeviceStatus) {
|
||||
m_inverterDeviceStatus = receivedInverterDeviceStatus;
|
||||
emit inverterDeviceStatusChanged(m_inverterDeviceStatus);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Inverter device status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Inverter device status\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterInverterEnergyProduced: {
|
||||
// Update registers from Inverter energy produced
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Inverter energy produced\" register:" << 32106 << "size:" << 2;
|
||||
QModbusReply *reply = readInverterEnergyProduced();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Inverter energy produced\" register" << 32106 << "size:" << 2 << values;
|
||||
float receivedInverterEnergyProduced = ModbusDataUtils::convertToUInt32(values, ModbusDataUtils::ByteOrderBigEndian) * 1.0 * pow(10, -2);
|
||||
if (m_inverterEnergyProduced != receivedInverterEnergyProduced) {
|
||||
m_inverterEnergyProduced = receivedInverterEnergyProduced;
|
||||
emit inverterEnergyProducedChanged(m_inverterEnergyProduced);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Inverter energy produced\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Inverter energy produced\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery1Status: {
|
||||
// Update registers from Luna 2000 Battery 1 status
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 1 status\" register:" << 37000 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery1Status();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 status\" register" << 37000 << "size:" << 1 << values;
|
||||
BatteryDeviceStatus receivedLunaBattery1Status = static_cast<BatteryDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
qCDebug(dcHuaweiFusionSolar()) << "Battery 1 status" << receivedLunaBattery1Status;
|
||||
if (receivedLunaBattery1Status == BatteryDeviceStatusOffline) {
|
||||
m_battery1Available = false;
|
||||
} else {
|
||||
m_battery1Available = true;
|
||||
}
|
||||
|
||||
if (m_lunaBattery1Status != receivedLunaBattery1Status) {
|
||||
m_lunaBattery1Status = receivedLunaBattery1Status;
|
||||
emit lunaBattery1StatusChanged(m_lunaBattery1Status);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 1 status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 1 status\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery1Power: {
|
||||
// Update registers from Luna 2000 Battery 1 power
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 1 power\" register:" << 37001 << "size:" << 2;
|
||||
QModbusReply *reply = readLunaBattery1Power();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 power\" register" << 37001 << "size:" << 2 << values;
|
||||
qint32 receivedLunaBattery1Power = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian);
|
||||
if (m_lunaBattery1Power != receivedLunaBattery1Power) {
|
||||
m_lunaBattery1Power = receivedLunaBattery1Power;
|
||||
emit lunaBattery1PowerChanged(m_lunaBattery1Power);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 1 power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 1 power\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery1Soc: {
|
||||
// Update registers from Luna 2000 Battery 1 state of charge
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 1 state of charge\" register:" << 37004 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery1Soc();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 1 state of charge\" register" << 37004 << "size:" << 1 << values;
|
||||
float receivedLunaBattery1Soc = ModbusDataUtils::convertToUInt16(values) * 1.0 * pow(10, -1);
|
||||
if (m_lunaBattery1Soc != receivedLunaBattery1Soc) {
|
||||
m_lunaBattery1Soc = receivedLunaBattery1Soc;
|
||||
emit lunaBattery1SocChanged(m_lunaBattery1Soc);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 1 state of charge\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 1 state of charge\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterPowerMeterActivePower: {
|
||||
// Update registers from Power meter active power
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Power meter active power\" register:" << 37113 << "size:" << 2;
|
||||
QModbusReply *reply = readPowerMeterActivePower();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Power meter active power\" register" << 37113 << "size:" << 2 << values;
|
||||
qint32 receivedPowerMeterActivePower = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian);
|
||||
if (m_powerMeterActivePower != receivedPowerMeterActivePower) {
|
||||
m_powerMeterActivePower = receivedPowerMeterActivePower;
|
||||
emit powerMeterActivePowerChanged(m_powerMeterActivePower);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Power meter active power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Power meter active power\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery2Status: {
|
||||
// Update registers from Luna 2000 Battery 2 status
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 2 status\" register:" << 37741 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery2Status();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 status\" register" << 37741 << "size:" << 1 << values;
|
||||
BatteryDeviceStatus receivedLunaBattery2Status = static_cast<BatteryDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
qCDebug(dcHuaweiFusionSolar()) << "Battery 2 status" << receivedLunaBattery2Status;
|
||||
if (receivedLunaBattery2Status == BatteryDeviceStatusOffline) {
|
||||
m_battery2Available = false;
|
||||
} else {
|
||||
m_battery2Available = true;
|
||||
}
|
||||
if (m_lunaBattery2Status != receivedLunaBattery2Status) {
|
||||
m_lunaBattery2Status = receivedLunaBattery2Status;
|
||||
emit lunaBattery2StatusChanged(m_lunaBattery2Status);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 2 status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 2 status\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery2Power: {
|
||||
// Update registers from Luna 2000 Battery 2 power
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 2 power\" register:" << 37743 << "size:" << 2;
|
||||
QModbusReply *reply = readLunaBattery2Power();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 power\" register" << 37743 << "size:" << 2 << values;
|
||||
qint32 receivedLunaBattery2Power = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian);
|
||||
if (m_lunaBattery2Power != receivedLunaBattery2Power) {
|
||||
m_lunaBattery2Power = receivedLunaBattery2Power;
|
||||
emit lunaBattery2PowerChanged(m_lunaBattery2Power);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 2 power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 2 power\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HuaweiModbusTcpConnection::RegisterLunaBattery2Soc: {
|
||||
// Update registers from Luna 2000 Battery 2 state of charge
|
||||
qCDebug(dcHuaweiFusionSolar()) << "--> Read \"Luna 2000 Battery 2 state of charge\" register:" << 37738 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery2Soc();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 state of charge\" register" << 37738 << "size:" << 1 << values;
|
||||
float receivedLunaBattery2Soc = ModbusDataUtils::convertToUInt16(values) * 1.0 * pow(10, -1);
|
||||
if (m_lunaBattery2Soc != receivedLunaBattery2Soc) {
|
||||
m_lunaBattery2Soc = receivedLunaBattery2Soc;
|
||||
emit lunaBattery2SocChanged(m_lunaBattery2Soc);
|
||||
}
|
||||
}
|
||||
finishRequest();
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 2 state of charge\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
finishRequest();
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiFusionSolar()) << "Error occurred while reading \"Luna 2000 Battery 2 state of charge\" registers from" << hostAddress().toString() << errorString();
|
||||
finishRequest();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiFusionSolar::finishRequest()
|
||||
{
|
||||
m_currentRegisterRequest = -1;
|
||||
QTimer::singleShot(1000, this, &HuaweiFusionSolar::readNextRegister);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,12 +15,19 @@ public:
|
|||
virtual void initialize() override;
|
||||
virtual void update() override;
|
||||
|
||||
|
||||
private:
|
||||
QQueue<HuaweiModbusTcpConnection::Registers> m_registersQueue;
|
||||
|
||||
int m_currentRegisterRequest = -1;
|
||||
void finishRequest();
|
||||
|
||||
bool m_battery1Available = true;
|
||||
bool m_battery2Available = true;
|
||||
|
||||
private slots:
|
||||
void readNextRegister();
|
||||
|
||||
};
|
||||
|
||||
#endif // HUAWEIFUSIONSOLAR_H
|
||||
|
|
|
|||
|
|
@ -41,21 +41,31 @@ HuaweiModbusTcpConnection::HuaweiModbusTcpConnection(const QHostAddress &hostAdd
|
|||
|
||||
}
|
||||
|
||||
float HuaweiModbusTcpConnection::inverterDCPower() const
|
||||
{
|
||||
return m_inverterDCPower;
|
||||
}
|
||||
|
||||
float HuaweiModbusTcpConnection::inverterActivePower() const
|
||||
{
|
||||
return m_inverterActivePower;
|
||||
}
|
||||
|
||||
HuaweiModbusTcpConnection::InverterDeviceStatus HuaweiModbusTcpConnection::inverterDeviceStatus() const
|
||||
{
|
||||
return m_inverterDeviceStatus;
|
||||
}
|
||||
|
||||
float HuaweiModbusTcpConnection::inverterEnergyProduced() const
|
||||
{
|
||||
return m_inverterEnergyProduced;
|
||||
}
|
||||
|
||||
qint32 HuaweiModbusTcpConnection::powerMeterActivePower() const
|
||||
{
|
||||
return m_powerMeterActivePower;
|
||||
}
|
||||
|
||||
HuaweiModbusTcpConnection::BatteryDeviceStatus HuaweiModbusTcpConnection::lunaBattery1Status() const
|
||||
{
|
||||
return m_lunaBattery1Status;
|
||||
}
|
||||
|
||||
qint32 HuaweiModbusTcpConnection::lunaBattery1Power() const
|
||||
{
|
||||
return m_lunaBattery1Power;
|
||||
|
|
@ -66,6 +76,11 @@ float HuaweiModbusTcpConnection::lunaBattery1Soc() const
|
|||
return m_lunaBattery1Soc;
|
||||
}
|
||||
|
||||
HuaweiModbusTcpConnection::BatteryDeviceStatus HuaweiModbusTcpConnection::lunaBattery2Status() const
|
||||
{
|
||||
return m_lunaBattery2Status;
|
||||
}
|
||||
|
||||
qint32 HuaweiModbusTcpConnection::lunaBattery2Power() const
|
||||
{
|
||||
return m_lunaBattery2Power;
|
||||
|
|
@ -84,48 +99,18 @@ void HuaweiModbusTcpConnection::initialize()
|
|||
|
||||
void HuaweiModbusTcpConnection::update()
|
||||
{
|
||||
updateInverterDCPower();
|
||||
updateInverterActivePower();
|
||||
updateInverterDeviceStatus();
|
||||
updateInverterEnergyProduced();
|
||||
updatePowerMeterActivePower();
|
||||
updateLunaBattery1Status();
|
||||
updateLunaBattery1Power();
|
||||
updateLunaBattery1Soc();
|
||||
updateLunaBattery2Status();
|
||||
updateLunaBattery2Power();
|
||||
updateLunaBattery2Soc();
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateInverterDCPower()
|
||||
{
|
||||
// Update registers from Inverter DC power
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "--> Read \"Inverter DC power\" register:" << 32064 << "size:" << 2;
|
||||
QModbusReply *reply = readInverterDCPower();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "<-- Response from \"Inverter DC power\" register" << 32064 << "size:" << 2 << values;
|
||||
float receivedInverterDCPower = ModbusDataUtils::convertToInt32(values, ModbusDataUtils::ByteOrderBigEndian) * 1.0 * pow(10, -3);
|
||||
if (m_inverterDCPower != receivedInverterDCPower) {
|
||||
m_inverterDCPower = receivedInverterDCPower;
|
||||
emit inverterDCPowerChanged(m_inverterDCPower);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Modbus reply error occurred while updating \"Inverter DC power\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Error occurred while reading \"Inverter DC power\" registers from" << hostAddress().toString() << errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateInverterActivePower()
|
||||
{
|
||||
// Update registers from Inverter active power
|
||||
|
|
@ -159,6 +144,72 @@ void HuaweiModbusTcpConnection::updateInverterActivePower()
|
|||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateInverterDeviceStatus()
|
||||
{
|
||||
// Update registers from Inverter device status
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "--> Read \"Inverter device status\" register:" << 32089 << "size:" << 1;
|
||||
QModbusReply *reply = readInverterDeviceStatus();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "<-- Response from \"Inverter device status\" register" << 32089 << "size:" << 1 << values;
|
||||
InverterDeviceStatus receivedInverterDeviceStatus = static_cast<InverterDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
if (m_inverterDeviceStatus != receivedInverterDeviceStatus) {
|
||||
m_inverterDeviceStatus = receivedInverterDeviceStatus;
|
||||
emit inverterDeviceStatusChanged(m_inverterDeviceStatus);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Modbus reply error occurred while updating \"Inverter device status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Error occurred while reading \"Inverter device status\" registers from" << hostAddress().toString() << errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateInverterEnergyProduced()
|
||||
{
|
||||
// Update registers from Inverter energy produced
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "--> Read \"Inverter energy produced\" register:" << 32106 << "size:" << 2;
|
||||
QModbusReply *reply = readInverterEnergyProduced();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "<-- Response from \"Inverter energy produced\" register" << 32106 << "size:" << 2 << values;
|
||||
float receivedInverterEnergyProduced = ModbusDataUtils::convertToUInt32(values, ModbusDataUtils::ByteOrderBigEndian) * 1.0 * pow(10, -2);
|
||||
if (m_inverterEnergyProduced != receivedInverterEnergyProduced) {
|
||||
m_inverterEnergyProduced = receivedInverterEnergyProduced;
|
||||
emit inverterEnergyProducedChanged(m_inverterEnergyProduced);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Modbus reply error occurred while updating \"Inverter energy produced\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Error occurred while reading \"Inverter energy produced\" registers from" << hostAddress().toString() << errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updatePowerMeterActivePower()
|
||||
{
|
||||
// Update registers from Power meter active power
|
||||
|
|
@ -192,6 +243,37 @@ void HuaweiModbusTcpConnection::updatePowerMeterActivePower()
|
|||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateLunaBattery1Status()
|
||||
{
|
||||
// Update registers from Luna 2000 Battery 1 status
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "--> Read \"Luna 2000 Battery 1 status\" register:" << 37000 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery1Status();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "<-- Response from \"Luna 2000 Battery 1 status\" register" << 37000 << "size:" << 1 << values;
|
||||
BatteryDeviceStatus receivedLunaBattery1Status = static_cast<BatteryDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
m_lunaBattery1Status = receivedLunaBattery1Status;
|
||||
emit lunaBattery1StatusChanged(m_lunaBattery1Status);
|
||||
}
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 1 status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Error occurred while reading \"Luna 2000 Battery 1 status\" registers from" << hostAddress().toString() << errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateLunaBattery1Power()
|
||||
{
|
||||
// Update registers from Luna 2000 Battery 1 power
|
||||
|
|
@ -258,6 +340,37 @@ void HuaweiModbusTcpConnection::updateLunaBattery1Soc()
|
|||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateLunaBattery2Status()
|
||||
{
|
||||
// Update registers from Luna 2000 Battery 2 status
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "--> Read \"Luna 2000 Battery 2 status\" register:" << 37741 << "size:" << 1;
|
||||
QModbusReply *reply = readLunaBattery2Status();
|
||||
if (reply) {
|
||||
if (!reply->isFinished()) {
|
||||
connect(reply, &QModbusReply::finished, reply, &QModbusReply::deleteLater);
|
||||
connect(reply, &QModbusReply::finished, this, [this, reply](){
|
||||
if (reply->error() == QModbusDevice::NoError) {
|
||||
const QModbusDataUnit unit = reply->result();
|
||||
const QVector<quint16> values = unit.values();
|
||||
qCDebug(dcHuaweiModbusTcpConnection()) << "<-- Response from \"Luna 2000 Battery 2 status\" register" << 37741 << "size:" << 1 << values;
|
||||
BatteryDeviceStatus receivedLunaBattery2Status = static_cast<BatteryDeviceStatus>(ModbusDataUtils::convertToUInt16(values));
|
||||
m_lunaBattery2Status = receivedLunaBattery2Status;
|
||||
emit lunaBattery2StatusChanged(m_lunaBattery2Status);
|
||||
}
|
||||
});
|
||||
|
||||
connect(reply, &QModbusReply::errorOccurred, this, [this, reply] (QModbusDevice::Error error){
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Modbus reply error occurred while updating \"Luna 2000 Battery 2 status\" registers from" << hostAddress().toString() << error << reply->errorString();
|
||||
emit reply->finished(); // To make sure it will be deleted
|
||||
});
|
||||
} else {
|
||||
delete reply; // Broadcast reply returns immediatly
|
||||
}
|
||||
} else {
|
||||
qCWarning(dcHuaweiModbusTcpConnection()) << "Error occurred while reading \"Luna 2000 Battery 2 status\" registers from" << hostAddress().toString() << errorString();
|
||||
}
|
||||
}
|
||||
|
||||
void HuaweiModbusTcpConnection::updateLunaBattery2Power()
|
||||
{
|
||||
// Update registers from Luna 2000 Battery 2 power
|
||||
|
|
@ -324,24 +437,36 @@ void HuaweiModbusTcpConnection::updateLunaBattery2Soc()
|
|||
}
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readInverterDCPower()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 32064, 2);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readInverterActivePower()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 32080, 2);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readInverterDeviceStatus()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 32089, 1);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readInverterEnergyProduced()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 32106, 2);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readPowerMeterActivePower()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 37113, 2);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readLunaBattery1Status()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 37000, 1);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readLunaBattery1Power()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 37001, 2);
|
||||
|
|
@ -354,6 +479,12 @@ QModbusReply *HuaweiModbusTcpConnection::readLunaBattery1Soc()
|
|||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readLunaBattery2Status()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 37741, 1);
|
||||
return sendReadRequest(request, m_slaveId);
|
||||
}
|
||||
|
||||
QModbusReply *HuaweiModbusTcpConnection::readLunaBattery2Power()
|
||||
{
|
||||
QModbusDataUnit request = QModbusDataUnit(QModbusDataUnit::RegisterType::HoldingRegisters, 37743, 2);
|
||||
|
|
@ -377,11 +508,14 @@ void HuaweiModbusTcpConnection::verifyInitFinished()
|
|||
QDebug operator<<(QDebug debug, HuaweiModbusTcpConnection *huaweiModbusTcpConnection)
|
||||
{
|
||||
debug.nospace().noquote() << "HuaweiModbusTcpConnection(" << huaweiModbusTcpConnection->hostAddress().toString() << ":" << huaweiModbusTcpConnection->port() << ")" << "\n";
|
||||
debug.nospace().noquote() << " - Inverter DC power:" << huaweiModbusTcpConnection->inverterDCPower() << " [kW]" << "\n";
|
||||
debug.nospace().noquote() << " - Inverter active power:" << huaweiModbusTcpConnection->inverterActivePower() << " [kW]" << "\n";
|
||||
debug.nospace().noquote() << " - Inverter device status:" << huaweiModbusTcpConnection->inverterDeviceStatus() << "\n";
|
||||
debug.nospace().noquote() << " - Inverter energy produced:" << huaweiModbusTcpConnection->inverterEnergyProduced() << " [kWh]" << "\n";
|
||||
debug.nospace().noquote() << " - Power meter active power:" << huaweiModbusTcpConnection->powerMeterActivePower() << " [W]" << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 1 status:" << huaweiModbusTcpConnection->lunaBattery1Status() << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 1 power:" << huaweiModbusTcpConnection->lunaBattery1Power() << " [W]" << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 1 state of charge:" << huaweiModbusTcpConnection->lunaBattery1Soc() << " [%]" << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 2 status:" << huaweiModbusTcpConnection->lunaBattery2Status() << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 2 power:" << huaweiModbusTcpConnection->lunaBattery2Power() << " [W]" << "\n";
|
||||
debug.nospace().noquote() << " - Luna 2000 Battery 2 state of charge:" << huaweiModbusTcpConnection->lunaBattery2Soc() << " [%]" << "\n";
|
||||
return debug.quote().space();
|
||||
|
|
|
|||
|
|
@ -41,12 +41,15 @@ class HuaweiModbusTcpConnection : public ModbusTCPMaster
|
|||
Q_OBJECT
|
||||
public:
|
||||
enum Registers {
|
||||
RegisterInverterDCPower = 32064,
|
||||
RegisterInverterActivePower = 32080,
|
||||
RegisterInverterDeviceStatus = 32089,
|
||||
RegisterInverterEnergyProduced = 32106,
|
||||
RegisterLunaBattery1Status = 37000,
|
||||
RegisterLunaBattery1Power = 37001,
|
||||
RegisterLunaBattery1Soc = 37004,
|
||||
RegisterPowerMeterActivePower = 37113,
|
||||
RegisterLunaBattery2Soc = 37738,
|
||||
RegisterLunaBattery2Status = 37741,
|
||||
RegisterLunaBattery2Power = 37743
|
||||
};
|
||||
Q_ENUM(Registers)
|
||||
|
|
@ -83,24 +86,42 @@ public:
|
|||
};
|
||||
Q_ENUM(InverterDeviceStatus)
|
||||
|
||||
enum BatteryDeviceStatus {
|
||||
BatteryDeviceStatusOffline = 0,
|
||||
BatteryDeviceStatusStandby = 1,
|
||||
BatteryDeviceStatusRunning = 1,
|
||||
BatteryDeviceStatusFault = 1,
|
||||
BatteryDeviceStatusSleepMode = 1
|
||||
};
|
||||
Q_ENUM(BatteryDeviceStatus)
|
||||
|
||||
explicit HuaweiModbusTcpConnection(const QHostAddress &hostAddress, uint port, quint16 slaveId, QObject *parent = nullptr);
|
||||
~HuaweiModbusTcpConnection() = default;
|
||||
|
||||
/* Inverter DC power [kW] - Address: 32064, Size: 2 */
|
||||
float inverterDCPower() const;
|
||||
|
||||
/* Inverter active power [kW] - Address: 32080, Size: 2 */
|
||||
float inverterActivePower() const;
|
||||
|
||||
/* Inverter device status - Address: 32089, Size: 1 */
|
||||
InverterDeviceStatus inverterDeviceStatus() const;
|
||||
|
||||
/* Inverter energy produced [kWh] - Address: 32106, Size: 2 */
|
||||
float inverterEnergyProduced() const;
|
||||
|
||||
/* Power meter active power [W] - Address: 37113, Size: 2 */
|
||||
qint32 powerMeterActivePower() const;
|
||||
|
||||
/* Luna 2000 Battery 1 status - Address: 37000, Size: 1 */
|
||||
BatteryDeviceStatus lunaBattery1Status() const;
|
||||
|
||||
/* Luna 2000 Battery 1 power [W] - Address: 37001, Size: 2 */
|
||||
qint32 lunaBattery1Power() const;
|
||||
|
||||
/* Luna 2000 Battery 1 state of charge [%] - Address: 37004, Size: 1 */
|
||||
float lunaBattery1Soc() const;
|
||||
|
||||
/* Luna 2000 Battery 2 status - Address: 37741, Size: 1 */
|
||||
BatteryDeviceStatus lunaBattery2Status() const;
|
||||
|
||||
/* Luna 2000 Battery 2 power [W] - Address: 37743, Size: 2 */
|
||||
qint32 lunaBattery2Power() const;
|
||||
|
||||
|
|
@ -111,46 +132,58 @@ public:
|
|||
virtual void initialize();
|
||||
virtual void update();
|
||||
|
||||
void updateInverterDCPower();
|
||||
void updateInverterActivePower();
|
||||
void updateInverterDeviceStatus();
|
||||
void updateInverterEnergyProduced();
|
||||
void updatePowerMeterActivePower();
|
||||
void updateLunaBattery1Status();
|
||||
void updateLunaBattery1Power();
|
||||
void updateLunaBattery1Soc();
|
||||
void updateLunaBattery2Status();
|
||||
void updateLunaBattery2Power();
|
||||
void updateLunaBattery2Soc();
|
||||
|
||||
signals:
|
||||
void initializationFinished();
|
||||
|
||||
void inverterDCPowerChanged(float inverterDCPower);
|
||||
void inverterActivePowerChanged(float inverterActivePower);
|
||||
void inverterDeviceStatusChanged(InverterDeviceStatus inverterDeviceStatus);
|
||||
void inverterEnergyProducedChanged(float inverterEnergyProduced);
|
||||
void powerMeterActivePowerChanged(qint32 powerMeterActivePower);
|
||||
void lunaBattery1StatusChanged(BatteryDeviceStatus lunaBattery1Status);
|
||||
void lunaBattery1PowerChanged(qint32 lunaBattery1Power);
|
||||
void lunaBattery1SocChanged(float lunaBattery1Soc);
|
||||
void lunaBattery2StatusChanged(BatteryDeviceStatus lunaBattery2Status);
|
||||
void lunaBattery2PowerChanged(qint32 lunaBattery2Power);
|
||||
void lunaBattery2SocChanged(float lunaBattery2Soc);
|
||||
|
||||
protected:
|
||||
QModbusReply *readInverterDCPower();
|
||||
QModbusReply *readInverterActivePower();
|
||||
QModbusReply *readInverterDeviceStatus();
|
||||
QModbusReply *readInverterEnergyProduced();
|
||||
QModbusReply *readPowerMeterActivePower();
|
||||
QModbusReply *readLunaBattery1Status();
|
||||
QModbusReply *readLunaBattery1Power();
|
||||
QModbusReply *readLunaBattery1Soc();
|
||||
QModbusReply *readLunaBattery2Status();
|
||||
QModbusReply *readLunaBattery2Power();
|
||||
QModbusReply *readLunaBattery2Soc();
|
||||
|
||||
float m_inverterActivePower = 0;
|
||||
InverterDeviceStatus m_inverterDeviceStatus = InverterDeviceStatusStandbyInitializing;
|
||||
float m_inverterEnergyProduced = 0;
|
||||
qint32 m_powerMeterActivePower = 0;
|
||||
BatteryDeviceStatus m_lunaBattery1Status = BatteryDeviceStatusOffline;
|
||||
qint32 m_lunaBattery1Power = 0;
|
||||
float m_lunaBattery1Soc = 0;
|
||||
BatteryDeviceStatus m_lunaBattery2Status = BatteryDeviceStatusOffline;
|
||||
qint32 m_lunaBattery2Power = 0;
|
||||
float m_lunaBattery2Soc = 0;
|
||||
|
||||
private:
|
||||
quint16 m_slaveId = 1;
|
||||
QVector<QModbusReply *> m_pendingInitReplies;
|
||||
|
||||
float m_inverterDCPower = 0;
|
||||
float m_inverterActivePower = 0;
|
||||
qint32 m_powerMeterActivePower = 0;
|
||||
qint32 m_lunaBattery1Power = 0;
|
||||
float m_lunaBattery1Soc = 0;
|
||||
qint32 m_lunaBattery2Power = 0;
|
||||
float m_lunaBattery2Soc = 0;
|
||||
|
||||
void verifyInitFinished();
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void IntegrationPluginHuawei::discoverThings(ThingDiscoveryInfo *info)
|
|||
|
||||
QString title;
|
||||
if (networkDeviceInfo.hostName().isEmpty()) {
|
||||
title = networkDeviceInfo.address().toString();
|
||||
title = "Huawei FusionSolar";
|
||||
} else {
|
||||
title = networkDeviceInfo.hostName() + " (" + networkDeviceInfo.address().toString() + ")";
|
||||
}
|
||||
|
|
@ -111,54 +111,193 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
|
|||
uint port = thing->paramValue(huaweiInverterThingPortParamTypeId).toUInt();
|
||||
quint16 slaveId = thing->paramValue(huaweiInverterThingSlaveIdParamTypeId).toUInt();
|
||||
|
||||
HuaweiModbusTcpConnection *connection = new HuaweiModbusTcpConnection(hostAddress, port, slaveId, this);
|
||||
connect(connection, &HuaweiModbusTcpConnection::initializationFinished, this, [this, thing, connection, info]{
|
||||
qCDebug(dcHuawei()) << "Connection init" << connection;
|
||||
HuaweiFusionSolar *connection = new HuaweiFusionSolar(hostAddress, port, slaveId, this);
|
||||
|
||||
// FIXME: check if success
|
||||
|
||||
m_connections.insert(thing, connection);
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
|
||||
// Set connected true
|
||||
thing->setStateValue(huaweiInverterConnectedStateTypeId, true);
|
||||
|
||||
// Update registers
|
||||
connection->update();
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiModbusTcpConnection::connectionStateChanged, this, [thing, connection](bool status){
|
||||
connect(connection, &HuaweiFusionSolar::connectionStateChanged, this, [this, thing, connection](bool status){
|
||||
qCDebug(dcHuawei()) << "Connected changed to" << status << "for" << thing;
|
||||
if (status) {
|
||||
// Connected true will be set after successfull init
|
||||
connection->initialize();
|
||||
thing->setStateValue(huaweiInverterConnectedStateTypeId, true);
|
||||
} else {
|
||||
thing->setStateValue(huaweiInverterConnectedStateTypeId, false);
|
||||
}
|
||||
|
||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
||||
childThing->setStateValue("connected", status);
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::inverterActivePowerChanged, this, [thing](float inverterActivePower){
|
||||
qCDebug(dcHuawei()) << "Inverter power changed" << inverterActivePower * -1000.0 << "W";
|
||||
thing->setStateValue(huaweiInverterCurrentPowerStateTypeId, inverterActivePower * -1000.0);
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::inverterDeviceStatusChanged, this, [thing](HuaweiFusionSolar::InverterDeviceStatus inverterDeviceStatus){
|
||||
qCDebug(dcHuawei()) << "Inverter device status changed" << inverterDeviceStatus;
|
||||
Q_UNUSED(thing)
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::inverterEnergyProducedChanged, this, [thing](float inverterEnergyProduced){
|
||||
qCDebug(dcHuawei()) << "Inverter total energy produced changed" << inverterEnergyProduced << "kWh";
|
||||
thing->setStateValue(huaweiInverterTotalEnergyProducedStateTypeId, inverterEnergyProduced);
|
||||
});
|
||||
|
||||
// Meter
|
||||
connect(connection, &HuaweiFusionSolar::powerMeterActivePowerChanged, this, [this, thing](qint32 powerMeterActivePower){
|
||||
Things meterThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiMeterThingClassId);
|
||||
if (!meterThings.isEmpty()) {
|
||||
qCDebug(dcHuawei()) << "Meter power changed" << powerMeterActivePower << "W";
|
||||
// Note: > 0 -> return, < 0 consume
|
||||
meterThings.first()->setStateValue(huaweiMeterCurrentPowerStateTypeId, -powerMeterActivePower);
|
||||
}
|
||||
});
|
||||
|
||||
// Battery 1
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery1StatusChanged, this, [this, thing](HuaweiFusionSolar::BatteryDeviceStatus lunaBattery1Status){
|
||||
qCDebug(dcHuawei()) << "Battery 1 status changed" << lunaBattery1Status;
|
||||
if (lunaBattery1Status != HuaweiFusionSolar::BatteryDeviceStatusOffline) {
|
||||
// Check if w have to create the energy storage
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId);
|
||||
bool alreadySetUp = false;
|
||||
foreach (Thing *batteryThing, batteryThings) {
|
||||
if (batteryThing->paramValue(huaweiBatteryThingUnitParamTypeId).toUInt() == 1) {
|
||||
alreadySetUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadySetUp) {
|
||||
qCDebug(dcHuawei()) << "Set up huawei energy storage 1 for" << thing;
|
||||
ThingDescriptor descriptor(huaweiBatteryThingClassId, "Luna 2000 Battery", QString(), thing->id());
|
||||
ParamList params;
|
||||
params.append(Param(huaweiBatteryThingUnitParamTypeId, 1));
|
||||
descriptor.setParams(params);
|
||||
emit autoThingsAppeared(ThingDescriptors() << descriptor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery1PowerChanged, this, [this, thing](qint32 lunaBattery1Power){
|
||||
qCDebug(dcHuawei()) << "Battery 1 power changed" << lunaBattery1Power << "W";
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId).filterByParam(huaweiBatteryThingUnitParamTypeId, 1);
|
||||
if (!batteryThings.isEmpty()) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryCurrentPowerStateTypeId, lunaBattery1Power);
|
||||
if (lunaBattery1Power < 0) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "discharging");
|
||||
} else if (lunaBattery1Power > 0) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "charging");
|
||||
} else {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "idle");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery1SocChanged, this, [this, thing](float lunaBattery1Soc){
|
||||
qCDebug(dcHuawei()) << "Battery 1 SOC changed" << lunaBattery1Soc << "%";
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId).filterByParam(huaweiBatteryThingUnitParamTypeId, 1);
|
||||
if (!batteryThings.isEmpty()) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryBatteryLevelStateTypeId, lunaBattery1Soc);
|
||||
batteryThings.first()->setStateValue(huaweiBatteryBatteryCriticalStateTypeId, lunaBattery1Soc < 10);
|
||||
}
|
||||
});
|
||||
|
||||
// Battery 2
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery2StatusChanged, this, [this, thing](HuaweiFusionSolar::BatteryDeviceStatus lunaBattery1Status){
|
||||
qCDebug(dcHuawei()) << "Battery 2 status changed" << lunaBattery1Status;
|
||||
if (lunaBattery1Status != HuaweiFusionSolar::BatteryDeviceStatusOffline) {
|
||||
// Check if w have to create the energy storage
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId);
|
||||
bool alreadySetUp = false;
|
||||
foreach (Thing *batteryThing, batteryThings) {
|
||||
if (batteryThing->paramValue(huaweiBatteryThingUnitParamTypeId).toUInt() == 2) {
|
||||
alreadySetUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!alreadySetUp) {
|
||||
qCDebug(dcHuawei()) << "Set up huawei energy storage 2 for" << thing;
|
||||
ThingDescriptor descriptor(huaweiBatteryThingClassId, "Luna 2000 Battery", QString(), thing->id());
|
||||
ParamList params;
|
||||
params.append(Param(huaweiBatteryThingUnitParamTypeId, 2));
|
||||
descriptor.setParams(params);
|
||||
emit autoThingsAppeared(ThingDescriptors() << descriptor);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery2PowerChanged, this, [this, thing](qint32 lunaBattery2Power){
|
||||
qCDebug(dcHuawei()) << "Battery 2 power changed" << lunaBattery2Power << "W";
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId).filterByParam(huaweiBatteryThingUnitParamTypeId, 2);
|
||||
if (!batteryThings.isEmpty()) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryCurrentPowerStateTypeId, lunaBattery2Power);
|
||||
|
||||
if (lunaBattery2Power < 0) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "discharging");
|
||||
} else if (lunaBattery2Power > 0) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "charging");
|
||||
} else {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryChargingStateStateTypeId, "idle");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
connect(connection, &HuaweiFusionSolar::lunaBattery2SocChanged, this, [this, thing](float lunaBattery2Soc){
|
||||
qCDebug(dcHuawei()) << "Battery 2 SOC changed" << lunaBattery2Soc << "%";
|
||||
Things batteryThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiBatteryThingClassId).filterByParam(huaweiBatteryThingUnitParamTypeId, 2);
|
||||
if (!batteryThings.isEmpty()) {
|
||||
batteryThings.first()->setStateValue(huaweiBatteryBatteryLevelStateTypeId, lunaBattery2Soc);
|
||||
batteryThings.first()->setStateValue(huaweiBatteryBatteryCriticalStateTypeId, lunaBattery2Soc < 10);
|
||||
}
|
||||
});
|
||||
|
||||
m_connections.insert(thing, connection);
|
||||
connection->connectDevice();
|
||||
|
||||
// FIXME: make async and check if this is really a huawei
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == huaweiMeterThingClassId) {
|
||||
// Nothing to do here, we get all information from the inverter connection
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
if (parentThing) {
|
||||
thing->setStateValue("connected", parentThing->stateValue("connected").toBool());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (thing->thingClassId() == huaweiBatteryThingClassId) {
|
||||
// Nothing to do here, we get all information from the inverter connection
|
||||
info->finish(Thing::ThingErrorNoError);
|
||||
Thing *parentThing = myThings().findById(thing->parentId());
|
||||
if (parentThing) {
|
||||
thing->setStateValue("connected", parentThing->stateValue("connected").toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IntegrationPluginHuawei::postSetupThing(Thing *thing)
|
||||
{
|
||||
Q_UNUSED(thing)
|
||||
if (thing->thingClassId() == huaweiInverterThingClassId) {
|
||||
if (!m_pluginTimer) {
|
||||
qCDebug(dcHuawei()) << "Starting plugin timer...";
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(10);
|
||||
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
|
||||
connect(m_pluginTimer, &PluginTimer::timeout, this, [this] {
|
||||
foreach(HuaweiModbusTcpConnection *connection, m_connections) {
|
||||
foreach(HuaweiFusionSolar *connection, m_connections) {
|
||||
if (connection->connected()) {
|
||||
connection->update();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
m_pluginTimer->start();
|
||||
}
|
||||
|
||||
// Check if w have to set up a child meter for this inverter connection
|
||||
if (myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiMeterThingClassId).isEmpty()) {
|
||||
qCDebug(dcHuawei()) << "Set up huawei meter for" << thing;
|
||||
emit autoThingsAppeared(ThingDescriptors() << ThingDescriptor(huaweiMeterThingClassId, "Huawei Power Meter", QString(), thing->id()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -166,8 +305,7 @@ void IntegrationPluginHuawei::postSetupThing(Thing *thing)
|
|||
void IntegrationPluginHuawei::thingRemoved(Thing *thing)
|
||||
{
|
||||
if (thing->thingClassId() == huaweiInverterThingClassId && m_connections.contains(thing)) {
|
||||
HuaweiModbusTcpConnection *connection = m_connections.take(thing);
|
||||
delete connection;
|
||||
m_connections.take(thing)->deleteLater();
|
||||
}
|
||||
|
||||
if (myThings().isEmpty() && m_pluginTimer) {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
#include "plugintimer.h"
|
||||
#include "integrations/integrationplugin.h"
|
||||
#include "huaweimodbustcpconnection.h"
|
||||
#include "huaweifusionsolar.h"
|
||||
|
||||
class IntegrationPluginHuawei: public IntegrationPlugin
|
||||
{
|
||||
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
private:
|
||||
PluginTimer *m_pluginTimer = nullptr;
|
||||
QHash<Thing *, HuaweiModbusTcpConnection *> m_connections;
|
||||
QHash<Thing *, HuaweiFusionSolar *> m_connections;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
"id": "87e75ee0-d544-457b-add3-bd4e58160fcd",
|
||||
"createMethods": ["discovery", "user"],
|
||||
"interfaces": ["solarinverter", "connectable"],
|
||||
"providedInterfaces": [ "solarinverter", "energymeter", "energystorage"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "d93371db-0954-4dcd-a1a5-6881b78cb0ea",
|
||||
|
|
@ -73,87 +74,6 @@
|
|||
"type": "double",
|
||||
"unit": "KiloWattHour",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "6609a589-8f0f-4747-9240-c0d0e0d87f29",
|
||||
"name": "phaseACurrent",
|
||||
"displayName": "Phase A current",
|
||||
"displayNameEvent": "Phase A current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "1bff8853-ec1e-4fe8-b148-c04d1db67e74",
|
||||
"name": "phaseBCurrent",
|
||||
"displayName": "Phase B current",
|
||||
"displayNameEvent": "Phase B current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "0977c3bc-7798-4161-a75f-19858d44c463",
|
||||
"name": "phaseCCurrent",
|
||||
"displayName": "Phase C current",
|
||||
"displayNameEvent": "Phase C current changed",
|
||||
"type": "double",
|
||||
"unit": "Ampere",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "e91281b3-d89f-4d3e-b81e-96645a8de63f",
|
||||
"name": "voltagePhaseA",
|
||||
"displayName": "Voltage phase A",
|
||||
"displayNameEvent": "Voltage phase A changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "ee921f23-ceeb-4818-adca-8c2fa1e75b17",
|
||||
"name": "voltagePhaseB",
|
||||
"displayName": "Voltage phase B",
|
||||
"displayNameEvent": "Voltage phase B changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "5613cea9-11cb-4b81-9b61-0e9a7ec737a3",
|
||||
"name": "voltagePhaseC",
|
||||
"displayName": "Voltage phase C",
|
||||
"displayNameEvent": "Voltage phase C changed",
|
||||
"type": "double",
|
||||
"unit": "Volt",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "4db7c66c-7676-449d-94c5-1b8c0ddf368a",
|
||||
"name": "currentPowerPhaseA",
|
||||
"displayName": "Current power phase A",
|
||||
"displayNameEvent": "Current power phase A changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "59026351-1cea-45e8-bffe-9ab65b44ddb2",
|
||||
"name": "currentPowerPhaseB",
|
||||
"displayName": "Current power phase B",
|
||||
"displayNameEvent": "Current power phase B changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00
|
||||
},
|
||||
{
|
||||
"id": "89ccd9d7-fd26-431a-b198-5001564373dc",
|
||||
"name": "currentPowerPhaseC",
|
||||
"displayName": "Current power phase C",
|
||||
"displayNameEvent": "Current power phase C changed",
|
||||
"type": "double",
|
||||
"unit": "Watt",
|
||||
"defaultValue": 0.00
|
||||
}
|
||||
],
|
||||
"actionTypes": [ ]
|
||||
|
|
@ -303,6 +223,13 @@
|
|||
"createMethods": ["auto"],
|
||||
"interfaces": [ "energystorage", "connectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "019287a6-c593-45a8-9695-2e1ad8e81c32",
|
||||
"name":"unit",
|
||||
"displayName": "Unit",
|
||||
"type": "uint",
|
||||
"defaultValue": 0
|
||||
}
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue