Update huawei and make it working

This commit is contained in:
Simon Stürz 2022-08-09 13:01:18 +02:00
parent 225fa3ed84
commit 33a32169f1
3 changed files with 70 additions and 59 deletions

View File

@ -518,7 +518,7 @@ void HuaweiFusionSolar::readNextRegister()
if (reply->error() == QModbusDevice::NoError) {
const QModbusDataUnit unit = reply->result();
qCDebug(dcHuaweiFusionSolar()) << "<-- Response from \"Luna 2000 Battery 2 power\" register" << 37743 << "size:" << 2 << "valueCount:" << unit.valueCount() << unit.values() << unit.values().count();
if (!valuesAreVaild(unit.values(), 1)) {
if (!valuesAreVaild(unit.values(), 2)) {
qCWarning(dcHuaweiFusionSolar()) << "<-- Received invalid values count. Requested" << 2 << "but received" << unit.values();
} else {
processLunaBattery2PowerRegisterValues(unit.values());
@ -588,8 +588,10 @@ void HuaweiFusionSolar::readNextRegister()
bool HuaweiFusionSolar::valuesAreVaild(const QVector<quint16> &values, int readSize)
{
if (values.count() != readSize)
if (values.count() != readSize) {
qCDebug(dcHuaweiFusionSolar()) << "Invalid values. The received values count does not match the requested" << readSize << "registers.";
return false;
}
// According to the documentation:
// 0x7FFF: invalid value of the floating point type returned by one register
@ -598,7 +600,13 @@ bool HuaweiFusionSolar::valuesAreVaild(const QVector<quint16> &values, int readS
if (values.count() == 2) {
bool floatingPointValid = (values.at(0) != 0x7fff && values.at(1) != 0xffff);
if (!floatingPointValid)
qCDebug(dcHuaweiFusionSolar()) << "Invalid values. The received values match the invalid for floating pointer:" << values;
bool otherTypesValid = (values.at(0) != 0xffff && values.at(1) != 0xffff);
if (!otherTypesValid)
qCDebug(dcHuaweiFusionSolar()) << "Invalid values. The received values match the invalid registers values:" << values;
return floatingPointValid && otherTypesValid;
}
@ -618,7 +626,7 @@ void HuaweiFusionSolar::calculatActualInverterPower()
actualPower += m_lunaBattery2Power;
qCDebug(dcHuaweiFusionSolar()) << "Inverter power:" << m_inverterActivePower << "W Battery 1:" << m_lunaBattery1Power << "W Battery 2:" << m_lunaBattery2Power << "W -->" << "Actual inverter power:" << actualPower << "W";
if (m_actualInverterPower != actualPower)
if (m_actualInverterPower == actualPower)
return;
m_actualInverterPower = actualPower;

View File

@ -134,6 +134,9 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
// Create a monitor so we always get the correct IP in the network and see if the device is reachable without polling on our own
NetworkDeviceMonitor *monitor = hardwareManager()->networkDeviceDiscovery()->registerMonitor(macAddress);
m_monitors.insert(thing, monitor);
connect(info, &ThingSetupInfo::aborted, monitor, [=](){
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
});
// Continue with setup only if we know that the network device is reachable
if (monitor->reachable()) {
@ -176,7 +179,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
ModbusRtuMaster *rtuMaster = hardwareManager()->modbusRtuResource()->getModbusRtuMaster(uuid);
HuaweiModbusRtuConnection *connection = new HuaweiModbusRtuConnection(rtuMaster, address, this);
connect(connection, &HuaweiModbusRtuConnection::reachableChanged, this, [this, thing, connection](bool reachable){
connect(connection, &HuaweiModbusRtuConnection::reachableChanged, thing, [this, thing, connection](bool reachable){
qCDebug(dcHuawei()) << thing->name() << "reachable changed" << reachable;
if (reachable) {
// Connected true will be set after successfull init
@ -189,7 +192,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::initializationFinished, this, [this, thing, connection](bool success){
connect(connection, &HuaweiModbusRtuConnection::initializationFinished, thing, [this, thing, connection](bool success){
if (success) {
thing->setStateValue("connected", true);
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
@ -200,23 +203,23 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::inverterActivePowerChanged, this, [thing](float inverterActivePower){
connect(connection, &HuaweiModbusRtuConnection::inverterActivePowerChanged, thing, [thing](float inverterActivePower){
qCDebug(dcHuawei()) << "Inverter power changed" << inverterActivePower * -1000.0 << "W";
thing->setStateValue(huaweiRtuInverterCurrentPowerStateTypeId, inverterActivePower * -1000.0);
});
connect(connection, &HuaweiModbusRtuConnection::inverterDeviceStatusChanged, this, [thing](HuaweiModbusRtuConnection::InverterDeviceStatus inverterDeviceStatus){
connect(connection, &HuaweiModbusRtuConnection::inverterDeviceStatusChanged, thing, [thing](HuaweiModbusRtuConnection::InverterDeviceStatus inverterDeviceStatus){
qCDebug(dcHuawei()) << "Inverter device status changed" << inverterDeviceStatus;
Q_UNUSED(thing)
});
connect(connection, &HuaweiModbusRtuConnection::inverterEnergyProducedChanged, this, [thing](float inverterEnergyProduced){
connect(connection, &HuaweiModbusRtuConnection::inverterEnergyProducedChanged, thing, [thing](float inverterEnergyProduced){
qCDebug(dcHuawei()) << "Inverter total energy produced changed" << inverterEnergyProduced << "kWh";
thing->setStateValue(huaweiRtuInverterTotalEnergyProducedStateTypeId, inverterEnergyProduced);
});
// Meter
connect(connection, &HuaweiModbusRtuConnection::powerMeterActivePowerChanged, this, [this, thing](qint32 powerMeterActivePower){
connect(connection, &HuaweiModbusRtuConnection::powerMeterActivePowerChanged, thing, [this, thing](qint32 powerMeterActivePower){
Things meterThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiMeterThingClassId);
if (!meterThings.isEmpty()) {
qCDebug(dcHuawei()) << "Meter power changed" << powerMeterActivePower << "W";
@ -226,7 +229,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
});
// Battery 1
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1StatusChanged, this, [this, thing](HuaweiModbusRtuConnection::BatteryDeviceStatus lunaBattery1Status){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1StatusChanged, thing, [this, thing](HuaweiModbusRtuConnection::BatteryDeviceStatus lunaBattery1Status){
qCDebug(dcHuawei()) << "Battery 1 status changed" << lunaBattery1Status;
if (lunaBattery1Status != HuaweiModbusRtuConnection::BatteryDeviceStatusOffline) {
// Check if w have to create the energy storage
@ -249,7 +252,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1PowerChanged, this, [this, thing](qint32 lunaBattery1Power){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1PowerChanged, thing, [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()) {
@ -264,7 +267,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1SocChanged, this, [this, thing](float lunaBattery1Soc){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery1SocChanged, thing, [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()) {
@ -274,7 +277,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
});
// Battery 2
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2StatusChanged, this, [this, thing](HuaweiModbusRtuConnection::BatteryDeviceStatus lunaBattery1Status){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2StatusChanged, thing, [this, thing](HuaweiModbusRtuConnection::BatteryDeviceStatus lunaBattery1Status){
qCDebug(dcHuawei()) << "Battery 2 status changed" << lunaBattery1Status;
if (lunaBattery1Status != HuaweiModbusRtuConnection::BatteryDeviceStatusOffline) {
// Check if w have to create the energy storage
@ -297,7 +300,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2PowerChanged, this, [this, thing](qint32 lunaBattery2Power){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2PowerChanged, thing, [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()) {
@ -313,7 +316,7 @@ void IntegrationPluginHuawei::setupThing(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2SocChanged, this, [this, thing](float lunaBattery2Soc){
connect(connection, &HuaweiModbusRtuConnection::lunaBattery2SocChanged, thing, [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()) {
@ -356,7 +359,7 @@ void IntegrationPluginHuawei::postSetupThing(Thing *thing)
if (thing->thingClassId() == huaweiFusionSolarInverterThingClassId || thing->thingClassId() == huaweiRtuInverterThingClassId) {
if (!m_pluginTimer) {
qCDebug(dcHuawei()) << "Starting plugin timer...";
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(5);
m_pluginTimer = hardwareManager()->pluginTimerManager()->registerTimer(2);
connect(m_pluginTimer, &PluginTimer::timeout, this, [this] {
foreach(HuaweiFusionSolar *connection, m_connections) {
if (connection->connected()) {
@ -411,55 +414,52 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
qCDebug(dcHuawei()) << "Finish setup huawei fusion solar dongle" << monitor->networkDeviceInfo().address().toString() << port << slaveId;
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
if (!thing->setupComplete())
return;
qCDebug(dcHuawei()) << "Network device monitor for" << thing->name() << (reachable ? "is now reachable" : "is not reachable any more" );
if (reachable) {
// Update address and refresh
thing->setStateValue("hostAddress", monitor->networkDeviceInfo().address().toString());
connection->setHostAddress(monitor->networkDeviceInfo().address());
connection->update();
}
});
connect(connection, &HuaweiFusionSolar::reachableChanged, this, [this, thing, connection](bool reachable){
connect(connection, &HuaweiFusionSolar::reachableChanged, thing, [=](bool reachable){
qCDebug(dcHuawei()) << "Reachable changed to" << reachable << "for" << thing;
if (reachable) {
// Connected true will be set after successfull init
connection->initialize();
thing->setStateValue("connected", true);
} else {
thing->setStateValue("connected", false);
}
thing->setStateValue("connected", reachable);
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
childThing->setStateValue("connected", reachable);
}
});
connect(connection, &HuaweiFusionSolar::inverterActivePowerChanged, this, [](float inverterActivePower){
qCDebug(dcHuawei()) << "Inverter power changed" << inverterActivePower * -1000.0 << "W";
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
if (!thing->setupComplete())
return;
qCDebug(dcHuawei()) << "Network device monitor for" << thing->name() << (reachable ? "is now reachable" : "is not reachable any more" );
if (reachable && !thing->stateValue("connected").toBool()) {
connection->setHostAddress(monitor->networkDeviceInfo().address());
connection->connectDevice();
} else if (!reachable) {
// Note: We disable autoreconnect explicitly and we will
// connect the device once the monitor says it is reachable again
connection->disconnectDevice();
}
});
connect(connection, &HuaweiFusionSolar::actualInverterPowerChanged, this, [thing](float actualInverterPower){
connect(connection, &HuaweiFusionSolar::inverterActivePowerChanged, thing, [](float inverterActivePower){
qCDebug(dcHuawei()) << "Inverter power changed" << inverterActivePower * -1000.0 << "W";
//thing->setStateValue(huaweiFusionSolarInverterCurrentPowerStateTypeId, inverterActivePower * -1000.0);
});
connect(connection, &HuaweiFusionSolar::actualInverterPowerChanged, thing, [thing](float actualInverterPower){
qCDebug(dcHuawei()) << "Inverter actual power changed" << actualInverterPower << "W";
thing->setStateValue(huaweiFusionSolarInverterCurrentPowerStateTypeId, actualInverterPower);
});
connect(connection, &HuaweiFusionSolar::inverterDeviceStatusChanged, this, [thing](HuaweiFusionSolar::InverterDeviceStatus inverterDeviceStatus){
connect(connection, &HuaweiFusionSolar::inverterDeviceStatusChanged, thing, [thing](HuaweiFusionSolar::InverterDeviceStatus inverterDeviceStatus){
qCDebug(dcHuawei()) << "Inverter device status changed" << inverterDeviceStatus;
Q_UNUSED(thing)
});
connect(connection, &HuaweiFusionSolar::inverterEnergyProducedChanged, this, [thing](float inverterEnergyProduced){
connect(connection, &HuaweiFusionSolar::inverterEnergyProducedChanged, thing, [thing](float inverterEnergyProduced){
qCDebug(dcHuawei()) << "Inverter total energy produced changed" << inverterEnergyProduced << "kWh";
thing->setStateValue(huaweiFusionSolarInverterTotalEnergyProducedStateTypeId, inverterEnergyProduced);
});
// Meter
connect(connection, &HuaweiFusionSolar::powerMeterActivePowerChanged, this, [this, thing](qint32 powerMeterActivePower){
connect(connection, &HuaweiFusionSolar::powerMeterActivePowerChanged, thing, [this, thing](qint32 powerMeterActivePower){
Things meterThings = myThings().filterByParentId(thing->id()).filterByThingClassId(huaweiMeterThingClassId);
if (!meterThings.isEmpty()) {
qCDebug(dcHuawei()) << "Meter power changed" << powerMeterActivePower << "W";
@ -469,7 +469,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
});
// Battery 1
connect(connection, &HuaweiFusionSolar::lunaBattery1StatusChanged, this, [this, thing](HuaweiFusionSolar::BatteryDeviceStatus lunaBattery1Status){
connect(connection, &HuaweiFusionSolar::lunaBattery1StatusChanged, thing, [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
@ -492,7 +492,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiFusionSolar::lunaBattery1PowerChanged, this, [this, thing](qint32 lunaBattery1Power){
connect(connection, &HuaweiFusionSolar::lunaBattery1PowerChanged, thing, [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()) {
@ -507,7 +507,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiFusionSolar::lunaBattery1SocChanged, this, [this, thing](float lunaBattery1Soc){
connect(connection, &HuaweiFusionSolar::lunaBattery1SocChanged, thing, [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()) {
@ -517,7 +517,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
});
// Battery 2
connect(connection, &HuaweiFusionSolar::lunaBattery2StatusChanged, this, [this, thing](HuaweiFusionSolar::BatteryDeviceStatus lunaBattery1Status){
connect(connection, &HuaweiFusionSolar::lunaBattery2StatusChanged, thing, [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
@ -540,7 +540,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiFusionSolar::lunaBattery2PowerChanged, this, [this, thing](qint32 lunaBattery2Power){
connect(connection, &HuaweiFusionSolar::lunaBattery2PowerChanged, thing, [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()) {
@ -556,7 +556,7 @@ void IntegrationPluginHuawei::setupFusionSolar(ThingSetupInfo *info)
}
});
connect(connection, &HuaweiFusionSolar::lunaBattery2SocChanged, this, [this, thing](float lunaBattery2Soc){
connect(connection, &HuaweiFusionSolar::lunaBattery2SocChanged, thing, [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()) {

View File

@ -10,7 +10,7 @@
"thingClasses": [
{
"name": "huaweiFusionSolarInverter",
"displayName": "Huawei FusionSolar Inverter",
"displayName": "Huawei FusionSolar Inverter (SmartDongle)",
"id": "87e75ee0-d544-457b-add3-bd4e58160fcd",
"createMethods": ["discovery", "user"],
"interfaces": ["solarinverter", "connectable"],
@ -57,7 +57,7 @@
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
"cached": true
},
{
"id": "e97fe328-6ca4-4fe4-86f7-fee6e9e406a5",
@ -66,14 +66,15 @@
"displayNameEvent": "AC energy changed",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0.00
"defaultValue": 0.00,
"cached": true
}
],
"actionTypes": [ ]
},
{
"name": "huaweiRtuInverter",
"displayName": "Huawei Inverter",
"displayName": "Huawei FusionSolar Inverter ((Modbus RTU)",
"id": "77558007-5076-4ca6-bd46-169f215c3e29",
"createMethods": ["discovery"],
"interfaces": ["solarinverter", "connectable"],
@ -122,7 +123,7 @@
"type": "double",
"unit": "Watt",
"defaultValue": 0,
"cached": false
"cached": true
},
{
"id": "49b92919-301c-4ff7-ae63-0c1a2184e3f4",
@ -131,7 +132,8 @@
"displayNameEvent": "AC energy changed",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0.00
"defaultValue": 0.00,
"cached": true
}
],
"actionTypes": [ ]
@ -162,7 +164,7 @@
"type": "double",
"unit": "Watt",
"defaultValue": 0.00,
"cached": false
"cached": true
},
{
"id": "759554dd-74c5-4836-9792-96e02eb816f0",
@ -171,7 +173,8 @@
"displayNameEvent": "AC energy changed",
"type": "double",
"unit": "KiloWattHour",
"defaultValue": 0.00
"defaultValue": 0.00,
"cached": true
},
{
"id": "2cf8d885-37f7-478f-819e-c4e20f2dbe01",
@ -337,7 +340,7 @@
"type": "double",
"unit": "Watt",
"defaultValue": 0.00,
"cached": false
"cached": true
},
{
"id": "3eed974a-0acb-4e38-bcb8-0e3f6fbfd51a",