Sma: Fix setup of monitor based sma devices
parent
8f47c12b23
commit
59f15b8fdb
|
|
@ -73,7 +73,7 @@ void IntegrationPluginSma::discoverThings(ThingDiscoveryInfo *info)
|
||||||
description = networkDeviceInfo.address().toString();
|
description = networkDeviceInfo.address().toString();
|
||||||
if (!macInfo.vendorName().isEmpty())
|
if (!macInfo.vendorName().isEmpty())
|
||||||
description += " - " + networkDeviceInfo.macAddressInfos().constFirst().vendorName();
|
description += " - " + networkDeviceInfo.macAddressInfos().constFirst().vendorName();
|
||||||
break;
|
break;
|
||||||
case NetworkDeviceInfo::MonitorModeHostName:
|
case NetworkDeviceInfo::MonitorModeHostName:
|
||||||
description = networkDeviceInfo.address().toString();
|
description = networkDeviceInfo.address().toString();
|
||||||
break;
|
break;
|
||||||
|
|
@ -594,18 +594,26 @@ void IntegrationPluginSma::setupThing(ThingSetupInfo *info)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for the monitor to be ready
|
|
||||||
if (monitor->reachable()) {
|
// If this is the initial setup, wait for the monitor to be reachable and make sure
|
||||||
// Thing already reachable...let's continue with the setup
|
// we have an IP address, otherwise let the monitor do his work
|
||||||
setupModbusSolarInverterConnection(info);
|
if (info->isInitialSetup()) {
|
||||||
|
// Continue with setup only if we know that the network device is reachable
|
||||||
|
if (monitor->reachable()) {
|
||||||
|
setupModbusSolarInverterConnection(info);
|
||||||
|
} else {
|
||||||
|
// otherwise wait until we reach the networkdevice before setting up the device
|
||||||
|
qCDebug(dcSma()) << "Network device" << thing->name() << "is not reachable yet. Continue with the setup once reachable.";
|
||||||
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
||||||
|
if (reachable) {
|
||||||
|
qCDebug(dcSma()) << "Network device" << thing->name() << "is now reachable. Continue with the setup...";
|
||||||
|
setupModbusSolarInverterConnection(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcSma()) << "Waiting for the network monitor to get reachable before continue to set up the connection" << thing->name() << address.toString() << "...";
|
// Continue setup with monitor...
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
setupModbusSolarInverterConnection(info);
|
||||||
if (reachable) {
|
|
||||||
qCDebug(dcSma()) << "The monitor for thing setup" << thing->name() << "is now reachable. Continue setup...";
|
|
||||||
setupModbusSolarInverterConnection(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (thing->thingClassId() == modbusBatteryInverterThingClassId) {
|
} else if (thing->thingClassId() == modbusBatteryInverterThingClassId) {
|
||||||
|
|
@ -645,18 +653,25 @@ void IntegrationPluginSma::setupThing(ThingSetupInfo *info)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for the monitor to be ready
|
// If this is the initial setup, wait for the monitor to be reachable and make sure
|
||||||
if (monitor->reachable()) {
|
// we have an IP address, otherwise let the monitor do his work
|
||||||
// Thing already reachable...let's continue with the setup
|
if (info->isInitialSetup()) {
|
||||||
setupModbusBatteryInverterConnection(info);
|
// Continue with setup only if we know that the network device is reachable
|
||||||
|
if (monitor->reachable()) {
|
||||||
|
setupModbusBatteryInverterConnection(info);
|
||||||
|
} else {
|
||||||
|
// otherwise wait until we reach the networkdevice before setting up the device
|
||||||
|
qCDebug(dcSma()) << "Network device" << thing->name() << "is not reachable yet. Continue with the setup once reachable.";
|
||||||
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
||||||
|
if (reachable) {
|
||||||
|
qCDebug(dcSma()) << "Network device" << thing->name() << "is now reachable. Continue with the setup...";
|
||||||
|
setupModbusBatteryInverterConnection(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(dcSma()) << "Waiting for the network monitor to become reachable before continue to set up the connection" << thing->name() << address.toString() << "...";
|
// Continue setup with monitor...
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
setupModbusBatteryInverterConnection(info);
|
||||||
if (reachable) {
|
|
||||||
qCDebug(dcSma()) << "The monitor for thing setup" << thing->name() << "is now reachable. Continuing with setup...";
|
|
||||||
setupModbusBatteryInverterConnection(info);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -748,8 +763,8 @@ void IntegrationPluginSma::thingRemoved(Thing *thing)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myThings().filterByThingClassId(speedwireMeterThingClassId).isEmpty()
|
if (myThings().filterByThingClassId(speedwireMeterThingClassId).isEmpty()
|
||||||
&& myThings().filterByThingClassId(speedwireInverterThingClassId).isEmpty()
|
&& myThings().filterByThingClassId(speedwireInverterThingClassId).isEmpty()
|
||||||
&& myThings().filterByThingClassId(speedwireBatteryThingClassId).isEmpty()) {
|
&& myThings().filterByThingClassId(speedwireBatteryThingClassId).isEmpty()) {
|
||||||
// Delete shared multicast socket...
|
// Delete shared multicast socket...
|
||||||
m_speedwireInterface->deleteLater();
|
m_speedwireInterface->deleteLater();
|
||||||
m_speedwireInterface = nullptr;
|
m_speedwireInterface = nullptr;
|
||||||
|
|
@ -810,12 +825,12 @@ void IntegrationPluginSma::setupRefreshTimer()
|
||||||
inverter->refresh();
|
inverter->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (SmaSolarInverterModbusTcpConnection *connection, m_modbusSolarInverters) {
|
foreach (SmaSolarInverterModbusTcpConnection *connection, m_modbusSolarInverters)
|
||||||
connection->update();
|
connection->update();
|
||||||
}
|
|
||||||
foreach (SmaBatteryInverterModbusTcpConnection *connection, m_modbusBatteryInverters) {
|
foreach (SmaBatteryInverterModbusTcpConnection *connection, m_modbusBatteryInverters)
|
||||||
connection->update();
|
connection->update();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
m_refreshTimer->start();
|
m_refreshTimer->start();
|
||||||
|
|
@ -881,78 +896,59 @@ void IntegrationPluginSma::setupModbusSolarInverterConnection(ThingSetupInfo *in
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(connection, &SmaSolarInverterModbusTcpConnection::initializationFinished, info, [=](bool success){
|
connect(connection, &SmaSolarInverterModbusTcpConnection::updateFinished, thing, [=](){
|
||||||
if (!success) {
|
qCDebug(dcSma()) << "Updated" << connection;
|
||||||
qCWarning(dcSma()) << "Connection init finished with errors" << thing->name() << connection->modbusTcpMaster()->hostAddress().toString();
|
|
||||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(monitor);
|
|
||||||
connection->deleteLater();
|
|
||||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Could not initialize the communication with the inverter."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcSma()) << "Connection init finished successfully" << connection;
|
// Grid voltage
|
||||||
m_modbusSolarInverters.insert(thing, connection);
|
if (isModbusValueValid(connection->gridVoltagePhaseA()))
|
||||||
info->finish(Thing::ThingErrorNoError);
|
thing->setStateValue(modbusSolarInverterVoltagePhaseAStateTypeId, connection->gridVoltagePhaseA() / 100.0);
|
||||||
|
|
||||||
// Set connected true
|
if (isModbusValueValid(connection->gridVoltagePhaseB()))
|
||||||
thing->setStateValue("connected", true);
|
thing->setStateValue(modbusSolarInverterVoltagePhaseBStateTypeId, connection->gridVoltagePhaseB() / 100.0);
|
||||||
foreach (Thing *childThing, myThings().filterByParentId(thing->id())) {
|
|
||||||
childThing->setStateValue("connected", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(connection, &SmaSolarInverterModbusTcpConnection::updateFinished, thing, [=](){
|
if (isModbusValueValid(connection->gridVoltagePhaseC()))
|
||||||
qCDebug(dcSma()) << "Updated" << connection;
|
thing->setStateValue(modbusSolarInverterVoltagePhaseCStateTypeId, connection->gridVoltagePhaseC() / 100.0);
|
||||||
|
|
||||||
// Grid voltage
|
// Grid current
|
||||||
if (isModbusValueValid(connection->gridVoltagePhaseA()))
|
if (isModbusValueValid(connection->gridCurrentPhaseA()))
|
||||||
thing->setStateValue(modbusSolarInverterVoltagePhaseAStateTypeId, connection->gridVoltagePhaseA() / 100.0);
|
thing->setStateValue(modbusSolarInverterCurrentPhaseAStateTypeId, connection->gridCurrentPhaseA() / 1000.0);
|
||||||
|
|
||||||
if (isModbusValueValid(connection->gridVoltagePhaseB()))
|
if (isModbusValueValid(connection->gridCurrentPhaseB()))
|
||||||
thing->setStateValue(modbusSolarInverterVoltagePhaseBStateTypeId, connection->gridVoltagePhaseB() / 100.0);
|
thing->setStateValue(modbusSolarInverterCurrentPhaseBStateTypeId, connection->gridCurrentPhaseB() / 1000.0);
|
||||||
|
|
||||||
if (isModbusValueValid(connection->gridVoltagePhaseC()))
|
if (isModbusValueValid(connection->gridCurrentPhaseC()))
|
||||||
thing->setStateValue(modbusSolarInverterVoltagePhaseCStateTypeId, connection->gridVoltagePhaseC() / 100.0);
|
thing->setStateValue(modbusSolarInverterCurrentPhaseCStateTypeId, connection->gridCurrentPhaseC() / 1000.0);
|
||||||
|
|
||||||
// Grid current
|
// Phase power
|
||||||
if (isModbusValueValid(connection->gridCurrentPhaseA()))
|
if (isModbusValueValid(connection->currentPowerPhaseA()))
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPhaseAStateTypeId, connection->gridCurrentPhaseA() / 1000.0);
|
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseAStateTypeId, connection->currentPowerPhaseA());
|
||||||
|
|
||||||
if (isModbusValueValid(connection->gridCurrentPhaseB()))
|
if (isModbusValueValid(connection->currentPowerPhaseB()))
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPhaseBStateTypeId, connection->gridCurrentPhaseB() / 1000.0);
|
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseBStateTypeId, connection->currentPowerPhaseB());
|
||||||
|
|
||||||
if (isModbusValueValid(connection->gridCurrentPhaseC()))
|
if (isModbusValueValid(connection->currentPowerPhaseC()))
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPhaseCStateTypeId, connection->gridCurrentPhaseC() / 1000.0);
|
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseCStateTypeId, connection->currentPowerPhaseC());
|
||||||
|
|
||||||
// Phase power
|
// Others
|
||||||
if (isModbusValueValid(connection->currentPowerPhaseA()))
|
if (isModbusValueValid(connection->totalYield()))
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseAStateTypeId, connection->currentPowerPhaseA());
|
thing->setStateValue(modbusSolarInverterTotalEnergyProducedStateTypeId, connection->totalYield() / 1000.0); // kWh
|
||||||
|
|
||||||
if (isModbusValueValid(connection->currentPowerPhaseB()))
|
if (isModbusValueValid(connection->dailyYield()))
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseBStateTypeId, connection->currentPowerPhaseB());
|
thing->setStateValue(modbusSolarInverterEnergyProducedTodayStateTypeId, connection->dailyYield() / 1000.0); // kWh
|
||||||
|
|
||||||
if (isModbusValueValid(connection->currentPowerPhaseC()))
|
// Power
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPowerPhaseCStateTypeId, connection->currentPowerPhaseC());
|
if (isModbusValueValid(connection->currentPower()))
|
||||||
|
thing->setStateValue(modbusSolarInverterCurrentPowerStateTypeId, -connection->currentPower());
|
||||||
|
|
||||||
// Others
|
// Version
|
||||||
if (isModbusValueValid(connection->totalYield()))
|
thing->setStateValue(modbusSolarInverterFirmwareVersionStateTypeId, Sma::buildSoftwareVersionString(connection->softwarePackage()));
|
||||||
thing->setStateValue(modbusSolarInverterTotalEnergyProducedStateTypeId, connection->totalYield() / 1000.0); // kWh
|
|
||||||
|
|
||||||
if (isModbusValueValid(connection->dailyYield()))
|
|
||||||
thing->setStateValue(modbusSolarInverterEnergyProducedTodayStateTypeId, connection->dailyYield() / 1000.0); // kWh
|
|
||||||
|
|
||||||
// Power
|
|
||||||
if (isModbusValueValid(connection->currentPower()))
|
|
||||||
thing->setStateValue(modbusSolarInverterCurrentPowerStateTypeId, -connection->currentPower());
|
|
||||||
|
|
||||||
// Version
|
|
||||||
thing->setStateValue(modbusSolarInverterFirmwareVersionStateTypeId, Sma::buildSoftwareVersionString(connection->softwarePackage()));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update registers
|
|
||||||
connection->update();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connection->connectDevice();
|
m_modbusSolarInverters.insert(thing, connection);
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
|
||||||
|
if (monitor->reachable())
|
||||||
|
connection->connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntegrationPluginSma::setupModbusBatteryInverterConnection(ThingSetupInfo *info)
|
void IntegrationPluginSma::setupModbusBatteryInverterConnection(ThingSetupInfo *info)
|
||||||
|
|
@ -1012,37 +1008,22 @@ void IntegrationPluginSma::setupModbusBatteryInverterConnection(ThingSetupInfo *
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(connection, &SmaBatteryInverterModbusTcpConnection::initializationFinished, info, [=](bool success){
|
connect(connection, &SmaBatteryInverterModbusTcpConnection::updateFinished, thing, [=](){
|
||||||
if (!success) {
|
qCDebug(dcSma()) << "Updated" << connection;
|
||||||
qCWarning(dcSma()) << "Connection init finished with errors" << thing->name() << connection->modbusTcpMaster()->hostAddress().toString();
|
thing->setStateValue(modbusBatteryInverterFirmwareVersionStateTypeId, Sma::buildSoftwareVersionString(connection->softwarePackage()));
|
||||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(monitor);
|
|
||||||
connection->deleteLater();
|
|
||||||
info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Could not initialize the communication with the battery inverter."));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qCDebug(dcSma()) << "Connection init finished successfully" << connection;
|
thing->setStateValue(modbusBatteryInverterBatteryLevelStateTypeId, connection->batterySOC());
|
||||||
m_modbusBatteryInverters.insert(thing, connection);
|
thing->setStateValue(modbusBatteryInverterBatteryCriticalStateTypeId, connection->batterySOC() <= 5);
|
||||||
info->finish(Thing::ThingErrorNoError);
|
thing->setStateValue(modbusBatteryInverterCurrentPowerStateTypeId, -connection->currentPower());
|
||||||
|
thing->setStateValue(modbusBatteryInverterChargingStateStateTypeId, connection->currentPower() == 0 ? "idle" : (connection->currentPower() > 0 ? "charging" : "discharging"));
|
||||||
|
|
||||||
thing->setStateValue("connected", true);
|
|
||||||
|
|
||||||
connect(connection, &SmaBatteryInverterModbusTcpConnection::updateFinished, thing, [=](){
|
|
||||||
qCDebug(dcSma()) << "Updated" << connection;
|
|
||||||
thing->setStateValue(modbusBatteryInverterFirmwareVersionStateTypeId, Sma::buildSoftwareVersionString(connection->softwarePackage()));
|
|
||||||
|
|
||||||
thing->setStateValue(modbusBatteryInverterBatteryLevelStateTypeId, connection->batterySOC());
|
|
||||||
thing->setStateValue(modbusBatteryInverterBatteryCriticalStateTypeId, connection->batterySOC() <= 5);
|
|
||||||
thing->setStateValue(modbusBatteryInverterCurrentPowerStateTypeId, -connection->currentPower());
|
|
||||||
thing->setStateValue(modbusBatteryInverterChargingStateStateTypeId, connection->currentPower() == 0 ? "idle" : (connection->currentPower() > 0 ? "charging" : "discharging"));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update registers
|
|
||||||
connection->update();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connection->connectDevice();
|
m_modbusBatteryInverters.insert(thing, connection);
|
||||||
|
info->finish(Thing::ThingErrorNoError);
|
||||||
|
|
||||||
|
if (monitor->reachable())
|
||||||
|
connection->connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
SpeedwireInterface *IntegrationPluginSma::getSpeedwireInterface()
|
SpeedwireInterface *IntegrationPluginSma::getSpeedwireInterface()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue