PCE: Assume current power for firmware version 0.19
This commit is contained in:
parent
431dc43776
commit
02149aeb2d
@ -3,7 +3,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 - 2024, nymea GmbH
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
* Copyright (C) 2024 - 2026, chargebyte austria GmbH
|
||||||
*
|
*
|
||||||
* This file is part of nymea-plugins-modbus.
|
* This file is part of nymea-plugins-modbus.
|
||||||
*
|
*
|
||||||
@ -26,13 +26,10 @@
|
|||||||
#include "pcelectricdiscovery.h"
|
#include "pcelectricdiscovery.h"
|
||||||
#include "plugininfo.h"
|
#include "plugininfo.h"
|
||||||
|
|
||||||
#include <hardwaremanager.h>
|
|
||||||
#include <hardware/electricity.h>
|
#include <hardware/electricity.h>
|
||||||
|
#include <hardwaremanager.h>
|
||||||
|
|
||||||
IntegrationPluginPcElectric::IntegrationPluginPcElectric()
|
IntegrationPluginPcElectric::IntegrationPluginPcElectric() {}
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void IntegrationPluginPcElectric::init()
|
void IntegrationPluginPcElectric::init()
|
||||||
{
|
{
|
||||||
@ -49,10 +46,11 @@ void IntegrationPluginPcElectric::discoverThings(ThingDiscoveryInfo *info)
|
|||||||
|
|
||||||
// Create a discovery with the info as parent for auto deleting the object once the discovery info is done
|
// Create a discovery with the info as parent for auto deleting the object once the discovery info is done
|
||||||
PcElectricDiscovery *discovery = new PcElectricDiscovery(hardwareManager()->networkDeviceDiscovery(), 502, 1, info);
|
PcElectricDiscovery *discovery = new PcElectricDiscovery(hardwareManager()->networkDeviceDiscovery(), 502, 1, info);
|
||||||
connect(discovery, &PcElectricDiscovery::discoveryFinished, info, [=](){
|
connect(discovery, &PcElectricDiscovery::discoveryFinished, info, [=]() {
|
||||||
foreach (const PcElectricDiscovery::Result &result, discovery->results()) {
|
foreach (const PcElectricDiscovery::Result &result, discovery->results()) {
|
||||||
|
ThingDescriptor descriptor(ev11ThingClassId,
|
||||||
ThingDescriptor descriptor(ev11ThingClassId, "PCE EV11.3 (" + result.serialNumber + ")", "Version: " + result.firmwareRevision + " - " + result.networkDeviceInfo.address().toString());
|
"PCE EV11.3 (" + result.serialNumber + ")",
|
||||||
|
"Version: " + result.firmwareRevision + " - " + result.networkDeviceInfo.address().toString());
|
||||||
qCDebug(dcPcElectric()) << "Discovered:" << descriptor.title() << descriptor.description();
|
qCDebug(dcPcElectric()) << "Discovered:" << descriptor.title() << descriptor.description();
|
||||||
|
|
||||||
// Check if we already have set up this device
|
// Check if we already have set up this device
|
||||||
@ -102,7 +100,7 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info)
|
|||||||
|
|
||||||
m_monitors.insert(thing, monitor);
|
m_monitors.insert(thing, monitor);
|
||||||
|
|
||||||
connect(info, &ThingSetupInfo::aborted, monitor, [=](){
|
connect(info, &ThingSetupInfo::aborted, monitor, [=]() {
|
||||||
if (m_monitors.contains(thing)) {
|
if (m_monitors.contains(thing)) {
|
||||||
qCDebug(dcPcElectric()) << "Unregistering monitor because setup has been aborted.";
|
qCDebug(dcPcElectric()) << "Unregistering monitor because setup has been aborted.";
|
||||||
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing));
|
||||||
@ -117,7 +115,7 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info)
|
|||||||
} else {
|
} else {
|
||||||
// otherwise wait until we reach the networkdevice before setting up the device
|
// otherwise wait until we reach the networkdevice before setting up the device
|
||||||
qCDebug(dcPcElectric()) << "Network device" << thing->name() << "is not reachable yet. Continue with the setup once reachable.";
|
qCDebug(dcPcElectric()) << "Network device" << thing->name() << "is not reachable yet. Continue with the setup once reachable.";
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable) {
|
||||||
if (reachable) {
|
if (reachable) {
|
||||||
qCDebug(dcPcElectric()) << "Network device" << thing->name() << "is now reachable. Continue with the setup...";
|
qCDebug(dcPcElectric()) << "Network device" << thing->name() << "is now reachable. Continue with the setup...";
|
||||||
setupConnection(info);
|
setupConnection(info);
|
||||||
@ -149,7 +147,6 @@ void IntegrationPluginPcElectric::postSetupThing(Thing *thing)
|
|||||||
m_refreshTimer->start();
|
m_refreshTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PceWallbox::ChargingCurrentState chargingCurrentState;
|
PceWallbox::ChargingCurrentState chargingCurrentState;
|
||||||
chargingCurrentState.power = thing->stateValue(ev11PowerStateTypeId).toBool();
|
chargingCurrentState.power = thing->stateValue(ev11PowerStateTypeId).toBool();
|
||||||
chargingCurrentState.maxChargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble();
|
chargingCurrentState.maxChargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble();
|
||||||
@ -197,7 +194,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (info->action().actionTypeId() == ev11PowerActionTypeId) {
|
if (info->action().actionTypeId() == ev11PowerActionTypeId) {
|
||||||
|
|
||||||
bool power = info->action().paramValue(ev11PowerActionPowerParamTypeId).toBool();
|
bool power = info->action().paramValue(ev11PowerActionPowerParamTypeId).toBool();
|
||||||
qCDebug(dcPcElectric()) << "Set charging enabled to" << power;
|
qCDebug(dcPcElectric()) << "Set charging enabled to" << power;
|
||||||
|
|
||||||
@ -207,7 +203,7 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, power, registerValue](){
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, power, registerValue]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set power state to" << power << "(" << registerValue << ")" << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set power state to" << power << "(" << registerValue << ")" << reply->errorString();
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
@ -222,7 +218,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (info->action().actionTypeId() == ev11MaxChargingCurrentActionTypeId) {
|
} else if (info->action().actionTypeId() == ev11MaxChargingCurrentActionTypeId) {
|
||||||
|
|
||||||
double desiredChargingCurrent = info->action().paramValue(ev11MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble();
|
double desiredChargingCurrent = info->action().paramValue(ev11MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble();
|
||||||
qCDebug(dcPcElectric()) << "Set max charging current to" << desiredChargingCurrent << "A";
|
qCDebug(dcPcElectric()) << "Set max charging current to" << desiredChargingCurrent << "A";
|
||||||
|
|
||||||
@ -232,7 +227,7 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredChargingCurrent](){
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredChargingCurrent]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set charging current to" << desiredChargingCurrent << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set charging current to" << desiredChargingCurrent << reply->errorString();
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
@ -247,7 +242,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
} else if (info->action().actionTypeId() == ev11DesiredPhaseCountActionTypeId) {
|
} else if (info->action().actionTypeId() == ev11DesiredPhaseCountActionTypeId) {
|
||||||
|
|
||||||
uint desiredPhaseCount = info->action().paramValue(ev11DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt();
|
uint desiredPhaseCount = info->action().paramValue(ev11DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt();
|
||||||
qCDebug(dcPcElectric()) << "Set desried phase count to" << desiredPhaseCount;
|
qCDebug(dcPcElectric()) << "Set desried phase count to" << desiredPhaseCount;
|
||||||
|
|
||||||
@ -257,7 +251,7 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info)
|
|||||||
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing));
|
||||||
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
qCDebug(dcPcElectric()) << "Writing charging current register" << registerValue;
|
||||||
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
QueuedModbusReply *reply = connection->setChargingCurrentAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredPhaseCount](){
|
connect(reply, &QueuedModbusReply::finished, info, [reply, info, thing, desiredPhaseCount]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set desired phase count to" << desiredPhaseCount << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set desired phase count to" << desiredPhaseCount << reply->errorString();
|
||||||
info->finish(Thing::ThingErrorHardwareFailure);
|
info->finish(Thing::ThingErrorHardwareFailure);
|
||||||
@ -289,11 +283,11 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address());
|
connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address());
|
||||||
|
|
||||||
// Monitor reachability
|
// Monitor reachability
|
||||||
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){
|
connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable) {
|
||||||
if (!thing->setupComplete())
|
if (!thing->setupComplete())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Network device monitor for" << thing->name() << (reachable ? "is now reachable" : "is not reachable any more" );
|
qCDebug(dcPcElectric()) << "Network device monitor for" << thing->name() << (reachable ? "is now reachable" : "is not reachable any more");
|
||||||
if (reachable && !thing->stateValue("connected").toBool()) {
|
if (reachable && !thing->stateValue("connected").toBool()) {
|
||||||
connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address());
|
connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address());
|
||||||
connection->connectDevice();
|
connection->connectDevice();
|
||||||
@ -305,22 +299,22 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Connection reachability
|
// Connection reachability
|
||||||
connect(connection, &PceWallbox::reachableChanged, thing, [this, thing](bool reachable){
|
connect(connection, &PceWallbox::reachableChanged, thing, [this, thing](bool reachable) {
|
||||||
qCInfo(dcPcElectric()) << "Reachable changed to" << reachable << "for" << thing;
|
qCInfo(dcPcElectric()) << "Reachable changed to" << reachable << "for" << thing;
|
||||||
m_initialUpdate[thing] = true;
|
m_initialUpdate[thing] = true;
|
||||||
thing->setStateValue("connected", reachable);
|
thing->setStateValue("connected", reachable);
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(connection, &PceWallbox::updateFinished, thing, [this, thing, connection](){
|
connect(connection, &PceWallbox::updateFinished, thing, [this, thing, connection]() {
|
||||||
qCDebug(dcPcElectric()) << "Update finished for" << thing;
|
qCDebug(dcPcElectric()) << "Update finished for" << thing;
|
||||||
qCDebug(dcPcElectric()) << connection;
|
qCDebug(dcPcElectric()) << connection;
|
||||||
if (!connection->phaseAutoSwitch()) {
|
if (!connection->phaseAutoSwitch()) {
|
||||||
// Note: if auto phase switching is disabled, the wallbox forces 3 phase charging
|
// Note: if auto phase switching is disabled, the wallbox forces 3 phase charging
|
||||||
thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, { 3 }); // Disable phase switching (default 3)
|
thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, {3}); // Disable phase switching (default 3)
|
||||||
thing->setStateValue(ev11DesiredPhaseCountStateTypeId, 3);
|
thing->setStateValue(ev11DesiredPhaseCountStateTypeId, 3);
|
||||||
thing->setStateValue(ev11PhaseCountStateTypeId, 3);
|
thing->setStateValue(ev11PhaseCountStateTypeId, 3);
|
||||||
} else {
|
} else {
|
||||||
thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, { 1, 3 }); // Enable phase switching
|
thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, {1, 3}); // Enable phase switching
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
||||||
@ -332,8 +326,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000);
|
thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000);
|
||||||
thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 &&
|
thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 && connection->chargingState() < PceWallbox::ChargingStateError);
|
||||||
connection->chargingState() < PceWallbox::ChargingStateError);
|
|
||||||
|
|
||||||
thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2);
|
thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2);
|
||||||
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) {
|
||||||
@ -405,7 +398,6 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_initialUpdate.value(thing)) {
|
if (m_initialUpdate.value(thing)) {
|
||||||
|
|
||||||
m_initialUpdate[thing] = false;
|
m_initialUpdate[thing] = false;
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Update initial charger states from charging current register...";
|
qCDebug(dcPcElectric()) << "Update initial charger states from charging current register...";
|
||||||
@ -440,7 +432,6 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
thing->setStateValue(ev11DigitalInputModeStateTypeId, connection->digitalInputMode());
|
thing->setStateValue(ev11DigitalInputModeStateTypeId, connection->digitalInputMode());
|
||||||
|
|
||||||
|
|
||||||
if (connection->firmwareRevision() >= "0022") {
|
if (connection->firmwareRevision() >= "0022") {
|
||||||
thing->setSettingValue(ev11SettingsPhaseAutoSwitchPauseParamTypeId, connection->phaseAutoSwitchPause());
|
thing->setSettingValue(ev11SettingsPhaseAutoSwitchPauseParamTypeId, connection->phaseAutoSwitchPause());
|
||||||
thing->setStateValue(ev11SettingsPhaseAutoSwitchMinChargingTimeParamTypeId, connection->phaseAutoSwitchMinChargingTime());
|
thing->setStateValue(ev11SettingsPhaseAutoSwitchMinChargingTimeParamTypeId, connection->phaseAutoSwitchMinChargingTime());
|
||||||
@ -451,18 +442,29 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
if (connection->firmwareRevision() >= "0022") {
|
if (connection->firmwareRevision() >= "0022") {
|
||||||
thing->setStateValue(ev11CurrentPowerStateTypeId, connection->currentPower());
|
thing->setStateValue(ev11CurrentPowerStateTypeId, connection->currentPower());
|
||||||
thing->setStateValue(ev11DigitalInputFlagStateTypeId, QString("0b%1").arg(connection->digitalInputFlag(), 16, 2, QLatin1Char('0')));
|
thing->setStateValue(ev11DigitalInputFlagStateTypeId, QString("0b%1").arg(connection->digitalInputFlag(), 16, 2, QLatin1Char('0')));
|
||||||
}
|
} else {
|
||||||
|
// In firmware 0019 there is no current power register, depending on the CP state we can assume the car is consuming the amount
|
||||||
|
// we adjusted, if the car is full, the CP state will change back to B2
|
||||||
|
|
||||||
|
if (connection->chargingState() == PceWallbox::ChargingStateC2 && connection->currentPower() == 0) {
|
||||||
|
// We are currently chargin, but the wallbox reports 0 W (which is expected), let's calculate the theoretical power...
|
||||||
|
double assumedCurrentPower = thing->stateValue(ev11PhaseCountStateTypeId).toInt() * 230 * thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble();
|
||||||
|
qCDebug(dcPcElectric()) << "Assuming current power" << assumedCurrentPower << "W (" << thing->stateValue(ev11PhaseCountStateTypeId).toInt() << "phases * 230 V *"
|
||||||
|
<< thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble() << "A )";
|
||||||
|
thing->setStateValue(ev11CurrentPowerStateTypeId, assumedCurrentPower);
|
||||||
|
} else {
|
||||||
|
thing->setStateValue(ev11CurrentPowerStateTypeId, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(thing, &Thing::settingChanged, connection, [thing, connection](const ParamTypeId ¶mTypeId, const QVariant &value){
|
connect(thing, &Thing::settingChanged, connection, [thing, connection](const ParamTypeId ¶mTypeId, const QVariant &value) {
|
||||||
|
|
||||||
if (paramTypeId == ev11SettingsLedBrightnessParamTypeId) {
|
if (paramTypeId == ev11SettingsLedBrightnessParamTypeId) {
|
||||||
quint16 percentage = value.toUInt();
|
quint16 percentage = value.toUInt();
|
||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Setting LED brightness to" << percentage << "%";
|
qCDebug(dcPcElectric()) << "Setting LED brightness to" << percentage << "%";
|
||||||
QueuedModbusReply *reply = connection->setLedBrightnessAsync(percentage);
|
QueuedModbusReply *reply = connection->setLedBrightnessAsync(percentage);
|
||||||
connect(reply, &QueuedModbusReply::finished, thing, [reply, percentage](){
|
connect(reply, &QueuedModbusReply::finished, thing, [reply, percentage]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set led brightness to" << percentage << "%" << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set led brightness to" << percentage << "%" << reply->errorString();
|
||||||
return;
|
return;
|
||||||
@ -489,7 +491,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QueuedModbusReply *reply = connection->setDigitalInputModeAsync(modeValue);
|
QueuedModbusReply *reply = connection->setDigitalInputModeAsync(modeValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, thing, [thing, reply, modeValue](){
|
connect(reply, &QueuedModbusReply::finished, thing, [thing, reply, modeValue]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set digital input mode to" << modeValue << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set digital input mode to" << modeValue << reply->errorString();
|
||||||
return;
|
return;
|
||||||
@ -503,7 +505,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Setting phase auto switch pause to" << registerValue << "s";
|
qCDebug(dcPcElectric()) << "Setting phase auto switch pause to" << registerValue << "s";
|
||||||
QueuedModbusReply *reply = connection->setPhaseAutoSwitchPauseAsync(registerValue);
|
QueuedModbusReply *reply = connection->setPhaseAutoSwitchPauseAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue](){
|
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set phase auto switch pause to" << registerValue << "s" << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set phase auto switch pause to" << registerValue << "s" << reply->errorString();
|
||||||
return;
|
return;
|
||||||
@ -516,7 +518,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Setting phase auto switch min charging current" << registerValue << "s";
|
qCDebug(dcPcElectric()) << "Setting phase auto switch min charging current" << registerValue << "s";
|
||||||
QueuedModbusReply *reply = connection->setPhaseAutoSwitchMinChargingTimeAsync(registerValue);
|
QueuedModbusReply *reply = connection->setPhaseAutoSwitchMinChargingTimeAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue](){
|
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set phase auto switch min charging current to" << registerValue << "s" << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set phase auto switch min charging current to" << registerValue << "s" << reply->errorString();
|
||||||
return;
|
return;
|
||||||
@ -529,7 +531,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
|
|
||||||
qCDebug(dcPcElectric()) << "Setting force charging resume to" << registerValue;
|
qCDebug(dcPcElectric()) << "Setting force charging resume to" << registerValue;
|
||||||
QueuedModbusReply *reply = connection->setForceChargingResumeAsync(registerValue);
|
QueuedModbusReply *reply = connection->setForceChargingResumeAsync(registerValue);
|
||||||
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue](){
|
connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue]() {
|
||||||
if (reply->error() != QModbusDevice::NoError) {
|
if (reply->error() != QModbusDevice::NoError) {
|
||||||
qCWarning(dcPcElectric()) << "Could not set force charging resume to" << registerValue << reply->errorString();
|
qCWarning(dcPcElectric()) << "Could not set force charging resume to" << registerValue << reply->errorString();
|
||||||
return;
|
return;
|
||||||
@ -547,4 +549,3 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info)
|
|||||||
if (monitor->reachable())
|
if (monitor->reachable())
|
||||||
connection->connectDevice();
|
connection->connectDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Copyright (C) 2013 - 2024, nymea GmbH
|
* Copyright (C) 2013 - 2024, nymea GmbH
|
||||||
* Copyright (C) 2024 - 2025, chargebyte austria GmbH
|
* Copyright (C) 2024 - 2026, chargebyte austria GmbH
|
||||||
*
|
*
|
||||||
* This file is part of nymea-plugins-modbus.
|
* This file is part of nymea-plugins-modbus.
|
||||||
*
|
*
|
||||||
@ -25,15 +25,15 @@
|
|||||||
#ifndef INTEGRATIONPLUGINPCELECTRIC_H
|
#ifndef INTEGRATIONPLUGINPCELECTRIC_H
|
||||||
#define INTEGRATIONPLUGINPCELECTRIC_H
|
#define INTEGRATIONPLUGINPCELECTRIC_H
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include <integrations/integrationplugin.h>
|
#include <integrations/integrationplugin.h>
|
||||||
#include <network/networkdevicediscovery.h>
|
#include <network/networkdevicediscovery.h>
|
||||||
#include <plugintimer.h>
|
#include <plugintimer.h>
|
||||||
|
|
||||||
#include "pcewallbox.h"
|
|
||||||
#include "extern-plugininfo.h"
|
#include "extern-plugininfo.h"
|
||||||
|
#include "pcewallbox.h"
|
||||||
|
|
||||||
class IntegrationPluginPcElectric : public IntegrationPlugin
|
class IntegrationPluginPcElectric : public IntegrationPlugin
|
||||||
{
|
{
|
||||||
@ -67,9 +67,6 @@ private:
|
|||||||
QHash<Thing *, PceWallbox::ChargingCurrentState> m_chargingCurrentStateBuffer;
|
QHash<Thing *, PceWallbox::ChargingCurrentState> m_chargingCurrentStateBuffer;
|
||||||
|
|
||||||
void setupConnection(ThingSetupInfo *info);
|
void setupConnection(ThingSetupInfo *info);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // INTEGRATIONPLUGINPCELECTRIC_H
|
#endif // INTEGRATIONPLUGINPCELECTRIC_H
|
||||||
|
|||||||
@ -26,20 +26,17 @@
|
|||||||
#include "extern-plugininfo.h"
|
#include "extern-plugininfo.h"
|
||||||
|
|
||||||
PcElectricDiscovery::PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent)
|
PcElectricDiscovery::PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent)
|
||||||
: QObject{parent},
|
: QObject{parent}
|
||||||
m_networkDeviceDiscovery{networkDeviceDiscovery},
|
, m_networkDeviceDiscovery{networkDeviceDiscovery}
|
||||||
m_port{port},
|
, m_port{port}
|
||||||
m_modbusAddress{modbusAddress}
|
, m_modbusAddress{modbusAddress}
|
||||||
{
|
{}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<PcElectricDiscovery::Result> PcElectricDiscovery::results() const
|
QList<PcElectricDiscovery::Result> PcElectricDiscovery::results() const
|
||||||
{
|
{
|
||||||
return m_results;
|
return m_results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PcElectricDiscovery::startDiscovery()
|
void PcElectricDiscovery::startDiscovery()
|
||||||
{
|
{
|
||||||
qCInfo(dcPcElectric()) << "Discovery: Start searching for PCE wallboxes in the network...";
|
qCInfo(dcPcElectric()) << "Discovery: Start searching for PCE wallboxes in the network...";
|
||||||
@ -48,12 +45,11 @@ void PcElectricDiscovery::startDiscovery()
|
|||||||
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover();
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &PcElectricDiscovery::checkNetworkDevice);
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &PcElectricDiscovery::checkNetworkDevice);
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater);
|
||||||
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){
|
connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=]() {
|
||||||
|
|
||||||
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
m_networkDeviceInfos = discoveryReply->networkDeviceInfos();
|
||||||
|
|
||||||
// Finish with some delay so the last added network device information objects still can be checked.
|
// Finish with some delay so the last added network device information objects still can be checked.
|
||||||
QTimer::singleShot(3000, this, [this](){
|
QTimer::singleShot(3000, this, [this]() {
|
||||||
qCDebug(dcPcElectric()) << "Discovery: Grace period timer triggered.";
|
qCDebug(dcPcElectric()) << "Discovery: Grace period timer triggered.";
|
||||||
finishDiscovery();
|
finishDiscovery();
|
||||||
});
|
});
|
||||||
@ -65,7 +61,7 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||||||
EV11ModbusTcpConnection *connection = new EV11ModbusTcpConnection(address, m_port, m_modbusAddress, this);
|
EV11ModbusTcpConnection *connection = new EV11ModbusTcpConnection(address, m_port, m_modbusAddress, this);
|
||||||
m_connections.append(connection);
|
m_connections.append(connection);
|
||||||
|
|
||||||
connect(connection, &EV11ModbusTcpConnection::reachableChanged, this, [=](bool reachable){
|
connect(connection, &EV11ModbusTcpConnection::reachableChanged, this, [=](bool reachable) {
|
||||||
if (!reachable) {
|
if (!reachable) {
|
||||||
// Disconnected ... done with this connection
|
// Disconnected ... done with this connection
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
@ -73,9 +69,10 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Modbus TCP connected...ok, let's try to initialize it!
|
// Modbus TCP connected...ok, let's try to initialize it!
|
||||||
connect(connection, &EV11ModbusTcpConnection::initializationFinished, this, [=](bool success){
|
connect(connection, &EV11ModbusTcpConnection::initializationFinished, this, [=](bool success) {
|
||||||
if (!success) {
|
if (!success) {
|
||||||
qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << address.toString() << "Continue...";;
|
qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << address.toString() << "Continue...";
|
||||||
|
;
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -93,7 +90,6 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||||||
|
|
||||||
// According to PCE the HW revision must be 0
|
// According to PCE the HW revision must be 0
|
||||||
if (!registerMacAddress.isNull() && connection->hardwareRevision() == 0) {
|
if (!registerMacAddress.isNull() && connection->hardwareRevision() == 0) {
|
||||||
|
|
||||||
// Parse the serial number
|
// Parse the serial number
|
||||||
QByteArray serialRawData;
|
QByteArray serialRawData;
|
||||||
QDataStream stream(&serialRawData, QIODevice::ReadWrite);
|
QDataStream stream(&serialRawData, QIODevice::ReadWrite);
|
||||||
@ -118,22 +114,25 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address)
|
|||||||
|
|
||||||
// Initializing...
|
// Initializing...
|
||||||
if (!connection->initialize()) {
|
if (!connection->initialize()) {
|
||||||
qCDebug(dcPcElectric()) << "Discovery: Unable to initialize connection on" << address.toString() << "Continue...";;
|
qCDebug(dcPcElectric()) << "Discovery: Unable to initialize connection on" << address.toString() << "Continue...";
|
||||||
|
;
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// If we get any error...skip this host...
|
// If we get any error...skip this host...
|
||||||
connect(connection->modbusTcpMaster(), &ModbusTcpMaster::connectionErrorOccurred, this, [=](QModbusDevice::Error error){
|
connect(connection->modbusTcpMaster(), &ModbusTcpMaster::connectionErrorOccurred, this, [=](QModbusDevice::Error error) {
|
||||||
if (error != QModbusDevice::NoError) {
|
if (error != QModbusDevice::NoError) {
|
||||||
qCDebug(dcPcElectric()) << "Discovery: Connection error on" << address.toString() << "Continue...";;
|
qCDebug(dcPcElectric()) << "Discovery: Connection error on" << address.toString() << "Continue...";
|
||||||
|
;
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// If check reachability failed...skip this host...
|
// If check reachability failed...skip this host...
|
||||||
connect(connection, &EV11ModbusTcpConnection::checkReachabilityFailed, this, [=](){
|
connect(connection, &EV11ModbusTcpConnection::checkReachabilityFailed, this, [=]() {
|
||||||
qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << address.toString() << "Continue...";;
|
qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << address.toString() << "Continue...";
|
||||||
|
;
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -158,16 +157,22 @@ void PcElectricDiscovery::finishDiscovery()
|
|||||||
|
|
||||||
Result result = m_potentialResults.at(i);
|
Result result = m_potentialResults.at(i);
|
||||||
if (networkDeviceInfo.macAddressInfos().hasMacAddress(result.registerMacAddress)) {
|
if (networkDeviceInfo.macAddressInfos().hasMacAddress(result.registerMacAddress)) {
|
||||||
qCInfo(dcPcElectric()) << "Discovery: --> Found EV11.3"
|
qCInfo(dcPcElectric())
|
||||||
<< "Serial number:" << result.serialNumber
|
<< "Discovery: --> Found EV11.3"
|
||||||
<< "Firmware revision:" << result.firmwareRevision
|
<< "Serial number:"
|
||||||
<< result.networkDeviceInfo;
|
<< result.serialNumber
|
||||||
|
<< "Firmware revision:"
|
||||||
|
<< result.firmwareRevision
|
||||||
|
<< result.networkDeviceInfo;
|
||||||
m_results.append(result);
|
m_results.append(result);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(dcPcElectric()) << "Discovery: --> Found potential EV11.3, but not adding to the results due to imcomplete MAC address check:"
|
qCWarning(dcPcElectric())
|
||||||
<< "Serial number:" << result.serialNumber
|
<< "Discovery: --> Found potential EV11.3, but not adding to the results due to imcomplete MAC address check:"
|
||||||
<< "Firmware revision:" << result.firmwareRevision
|
<< "Serial number:"
|
||||||
<< result.networkDeviceInfo;
|
<< result.serialNumber
|
||||||
|
<< "Firmware revision:"
|
||||||
|
<< result.firmwareRevision
|
||||||
|
<< result.networkDeviceInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +183,10 @@ void PcElectricDiscovery::finishDiscovery()
|
|||||||
foreach (EV11ModbusTcpConnection *connection, m_connections)
|
foreach (EV11ModbusTcpConnection *connection, m_connections)
|
||||||
cleanupConnection(connection);
|
cleanupConnection(connection);
|
||||||
|
|
||||||
qCInfo(dcPcElectric()) << "Discovery: Finished the discovery process. Found" << m_results.length()
|
qCInfo(dcPcElectric())
|
||||||
<< "PCE wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
<< "Discovery: Finished the discovery process. Found"
|
||||||
|
<< m_results.length()
|
||||||
|
<< "PCE wallboxes in"
|
||||||
|
<< QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz");
|
||||||
emit discoveryFinished();
|
emit discoveryFinished();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,8 @@ class PcElectricDiscovery : public QObject
|
|||||||
public:
|
public:
|
||||||
explicit PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent = nullptr);
|
explicit PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent = nullptr);
|
||||||
|
|
||||||
typedef struct Result {
|
typedef struct Result
|
||||||
|
{
|
||||||
QString serialNumber;
|
QString serialNumber;
|
||||||
QString firmwareRevision;
|
QString firmwareRevision;
|
||||||
QHostAddress address;
|
QHostAddress address;
|
||||||
|
|||||||
@ -35,7 +35,7 @@ PceWallbox::PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slave
|
|||||||
m_timer.setSingleShot(false);
|
m_timer.setSingleShot(false);
|
||||||
connect(&m_timer, &QTimer::timeout, this, &PceWallbox::sendHeartbeat);
|
connect(&m_timer, &QTimer::timeout, this, &PceWallbox::sendHeartbeat);
|
||||||
|
|
||||||
connect(this, &EV11ModbusTcpConnection::reachableChanged, this, [this](bool reachable){
|
connect(this, &EV11ModbusTcpConnection::reachableChanged, this, [this](bool reachable) {
|
||||||
if (!reachable) {
|
if (!reachable) {
|
||||||
m_timer.stop();
|
m_timer.stop();
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ PceWallbox::PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slave
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(this, &EV11ModbusTcpConnection::initializationFinished, this, [this](bool success){
|
connect(this, &EV11ModbusTcpConnection::initializationFinished, this, [this](bool success) {
|
||||||
if (success) {
|
if (success) {
|
||||||
qCDebug(dcPcElectric()) << "Connection initialized successfully" << m_modbusTcpMaster->hostAddress().toString();
|
qCDebug(dcPcElectric()) << "Connection initialized successfully" << m_modbusTcpMaster->hostAddress().toString();
|
||||||
m_timer.start();
|
m_timer.start();
|
||||||
@ -81,8 +81,7 @@ bool PceWallbox::update()
|
|||||||
|
|
||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockStatusDataUnit(), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockStatusDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -100,7 +99,6 @@ bool PceWallbox::update()
|
|||||||
|
|
||||||
enqueueRequest(reply);
|
enqueueRequest(reply);
|
||||||
|
|
||||||
|
|
||||||
// charging current register. Contains
|
// charging current register. Contains
|
||||||
// - power state
|
// - power state
|
||||||
// - chargingcurrent (if power is true)
|
// - chargingcurrent (if power is true)
|
||||||
@ -116,8 +114,7 @@ bool PceWallbox::update()
|
|||||||
if (!chargingCurrentQueued) {
|
if (!chargingCurrentQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, chargingCurrentDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, chargingCurrentDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -148,8 +145,7 @@ bool PceWallbox::update()
|
|||||||
if (!digitalInputAlreadyQueued) {
|
if (!digitalInputAlreadyQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, digitalInputModeDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, digitalInputModeDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -168,7 +164,6 @@ bool PceWallbox::update()
|
|||||||
enqueueRequest(reply);
|
enqueueRequest(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Led brightness
|
// Led brightness
|
||||||
bool ledBrightnessAlreadyQueued = false;
|
bool ledBrightnessAlreadyQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_readQueue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
@ -181,8 +176,7 @@ bool PceWallbox::update()
|
|||||||
if (!ledBrightnessAlreadyQueued) {
|
if (!ledBrightnessAlreadyQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, ledBrightnessDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, ledBrightnessDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -204,11 +198,9 @@ bool PceWallbox::update()
|
|||||||
enqueueRequest(reply);
|
enqueueRequest(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (firmwareRevision() < "0022")
|
if (firmwareRevision() < "0022")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// Registers since 0022 (V 0.22)
|
// Registers since 0022 (V 0.22)
|
||||||
|
|
||||||
@ -224,8 +216,7 @@ bool PceWallbox::update()
|
|||||||
if (!update2Queued) {
|
if (!update2Queued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockUpdate2DataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockUpdate2DataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -245,7 +236,6 @@ bool PceWallbox::update()
|
|||||||
enqueueRequest(reply);
|
enqueueRequest(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool phaseAutoSwitchPauseQueued = false;
|
bool phaseAutoSwitchPauseQueued = false;
|
||||||
foreach (QueuedModbusReply *r, m_readQueue) {
|
foreach (QueuedModbusReply *r, m_readQueue) {
|
||||||
if (r->dataUnit().startAddress() == phaseAutoSwitchPauseDataUnit().startAddress()) {
|
if (r->dataUnit().startAddress() == phaseAutoSwitchPauseDataUnit().startAddress()) {
|
||||||
@ -257,8 +247,7 @@ bool PceWallbox::update()
|
|||||||
if (!phaseAutoSwitchPauseQueued) {
|
if (!phaseAutoSwitchPauseQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchPauseDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchPauseDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -289,8 +278,7 @@ bool PceWallbox::update()
|
|||||||
if (!phaseAutoSwitchMinChargingTimeQueued) {
|
if (!phaseAutoSwitchMinChargingTimeQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchMinChargingTimeDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchMinChargingTimeDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -321,8 +309,7 @@ bool PceWallbox::update()
|
|||||||
if (!forceChargingResumeQueued) {
|
if (!forceChargingResumeQueued) {
|
||||||
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, forceChargingResumeDataUnit(), this);
|
reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, forceChargingResumeDataUnit(), this);
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
|
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -354,7 +341,7 @@ QueuedModbusReply *PceWallbox::setChargingCurrentAsync(quint16 chargingCurrent)
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setChargingCurrentDataUnit(chargingCurrent), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setChargingCurrentDataUnit(chargingCurrent), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -374,7 +361,7 @@ QueuedModbusReply *PceWallbox::setLedBrightnessAsync(quint16 percentage)
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setLedBrightnessDataUnit(percentage), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setLedBrightnessDataUnit(percentage), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -394,7 +381,7 @@ QueuedModbusReply *PceWallbox::setPhaseAutoSwitchPauseAsync(quint16 seconds)
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchPauseDataUnit(seconds), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchPauseDataUnit(seconds), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -414,7 +401,7 @@ QueuedModbusReply *PceWallbox::setPhaseAutoSwitchMinChargingTimeAsync(quint16 se
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchMinChargingTimeDataUnit(seconds), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchMinChargingTimeDataUnit(seconds), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -434,7 +421,7 @@ QueuedModbusReply *PceWallbox::setForceChargingResumeAsync(quint16 value)
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setForceChargingResumeDataUnit(value), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setForceChargingResumeDataUnit(value), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -454,7 +441,7 @@ QueuedModbusReply *PceWallbox::setDigitalInputModeAsync(DigitalInputMode digital
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setDigitalInputModeDataUnit(digitalInputMode), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setDigitalInputModeDataUnit(digitalInputMode), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -506,7 +493,6 @@ PceWallbox::ChargingCurrentState PceWallbox::deriveStatesFromRegister(quint16 re
|
|||||||
|
|
||||||
// Only set max charging current if power, otherwise we use default 6A
|
// Only set max charging current if power, otherwise we use default 6A
|
||||||
if (chargingCurrentState.power) {
|
if (chargingCurrentState.power) {
|
||||||
|
|
||||||
bool threePhaseCharging = (registerValue & (1 << 15));
|
bool threePhaseCharging = (registerValue & (1 << 15));
|
||||||
chargingCurrentState.desiredPhaseCount = (threePhaseCharging ? 3 : 1);
|
chargingCurrentState.desiredPhaseCount = (threePhaseCharging ? 3 : 1);
|
||||||
|
|
||||||
@ -516,7 +502,6 @@ PceWallbox::ChargingCurrentState PceWallbox::deriveStatesFromRegister(quint16 re
|
|||||||
return chargingCurrentState;
|
return chargingCurrentState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PceWallbox::sendHeartbeat()
|
void PceWallbox::sendHeartbeat()
|
||||||
{
|
{
|
||||||
if (m_aboutToDelete)
|
if (m_aboutToDelete)
|
||||||
@ -525,7 +510,7 @@ void PceWallbox::sendHeartbeat()
|
|||||||
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setHeartbeatDataUnit(m_heartbeat++), this);
|
QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setHeartbeatDataUnit(m_heartbeat++), this);
|
||||||
|
|
||||||
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
connect(reply, &QueuedModbusReply::finished, reply, &QueuedModbusReply::deleteLater);
|
||||||
connect(reply, &QueuedModbusReply::finished, this, [this, reply](){
|
connect(reply, &QueuedModbusReply::finished, this, [this, reply]() {
|
||||||
if (m_currentReply == reply)
|
if (m_currentReply == reply)
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
|
|
||||||
@ -571,28 +556,43 @@ void PceWallbox::sendNextRequest()
|
|||||||
qCDebug(dcPcElectric()) << "Dequeued read request. Queue count: W" << m_writeQueue.length() << "| R:" << m_readQueue.length();
|
qCDebug(dcPcElectric()) << "Dequeued read request. Queue count: W" << m_writeQueue.length() << "| R:" << m_readQueue.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(m_currentReply->requestType()) {
|
switch (m_currentReply->requestType()) {
|
||||||
case QueuedModbusReply::RequestTypeRead:
|
case QueuedModbusReply::RequestTypeRead:
|
||||||
qCDebug(dcPcElectric()) << "--> Reading" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
qCDebug(dcPcElectric())
|
||||||
<< "register:" << m_currentReply->dataUnit().startAddress()
|
<< "--> Reading"
|
||||||
<< "length" << m_currentReply->dataUnit().valueCount();
|
<< ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
||||||
|
<< "register:"
|
||||||
|
<< m_currentReply->dataUnit().startAddress()
|
||||||
|
<< "length"
|
||||||
|
<< m_currentReply->dataUnit().valueCount();
|
||||||
m_currentReply->setReply(m_modbusTcpMaster->sendReadRequest(m_currentReply->dataUnit(), m_slaveId));
|
m_currentReply->setReply(m_modbusTcpMaster->sendReadRequest(m_currentReply->dataUnit(), m_slaveId));
|
||||||
break;
|
break;
|
||||||
case QueuedModbusReply::RequestTypeWrite:
|
case QueuedModbusReply::RequestTypeWrite:
|
||||||
qCDebug(dcPcElectric()) << "--> Writing" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
qCDebug(dcPcElectric())
|
||||||
<< "register:" << m_currentReply->dataUnit().startAddress()
|
<< "--> Writing"
|
||||||
<< "length:" << m_currentReply->dataUnit().valueCount()
|
<< ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
||||||
<< "values:" << m_currentReply->dataUnit().values();
|
<< "register:"
|
||||||
|
<< m_currentReply->dataUnit().startAddress()
|
||||||
|
<< "length:"
|
||||||
|
<< m_currentReply->dataUnit().valueCount()
|
||||||
|
<< "values:"
|
||||||
|
<< m_currentReply->dataUnit().values();
|
||||||
m_currentReply->setReply(m_modbusTcpMaster->sendWriteRequest(m_currentReply->dataUnit(), m_slaveId));
|
m_currentReply->setReply(m_modbusTcpMaster->sendWriteRequest(m_currentReply->dataUnit(), m_slaveId));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_currentReply->reply()) {
|
if (!m_currentReply->reply()) {
|
||||||
qCWarning(dcPcElectric()) << "Error occurred while sending" << m_currentReply->requestType()
|
qCWarning(dcPcElectric())
|
||||||
<< ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
<< "Error occurred while sending"
|
||||||
<< "register:" << m_currentReply->dataUnit().startAddress()
|
<< m_currentReply->requestType()
|
||||||
<< "length:" << m_currentReply->dataUnit().valueCount()
|
<< ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType())
|
||||||
<< "to" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString();
|
<< "register:"
|
||||||
|
<< m_currentReply->dataUnit().startAddress()
|
||||||
|
<< "length:"
|
||||||
|
<< m_currentReply->dataUnit().valueCount()
|
||||||
|
<< "to"
|
||||||
|
<< m_modbusTcpMaster->hostAddress().toString()
|
||||||
|
<< m_modbusTcpMaster->errorString();
|
||||||
m_currentReply->deleteLater();
|
m_currentReply->deleteLater();
|
||||||
m_currentReply = nullptr;
|
m_currentReply = nullptr;
|
||||||
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
QTimer::singleShot(0, this, &PceWallbox::sendNextRequest);
|
||||||
@ -634,6 +634,13 @@ void PceWallbox::cleanupQueues()
|
|||||||
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState)
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState)
|
||||||
{
|
{
|
||||||
QDebugStateSaver saver(debug);
|
QDebugStateSaver saver(debug);
|
||||||
debug.nospace() << "ChargingCurrentState(" << chargingCurrentState.power << ", " << chargingCurrentState.maxChargingCurrent << " [A], " << chargingCurrentState.desiredPhaseCount << ')';
|
debug.nospace()
|
||||||
|
<< "ChargingCurrentState("
|
||||||
|
<< chargingCurrentState.power
|
||||||
|
<< ", "
|
||||||
|
<< chargingCurrentState.maxChargingCurrent
|
||||||
|
<< " [A], "
|
||||||
|
<< chargingCurrentState.desiredPhaseCount
|
||||||
|
<< ')';
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,10 @@
|
|||||||
#ifndef PCEWALLBOX_H
|
#ifndef PCEWALLBOX_H
|
||||||
#define PCEWALLBOX_H
|
#define PCEWALLBOX_H
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QQueue>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QQueue>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include <queuedmodbusreply.h>
|
#include <queuedmodbusreply.h>
|
||||||
|
|
||||||
@ -38,7 +38,8 @@ class PceWallbox : public EV11ModbusTcpConnection
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
typedef struct ChargingCurrentState {
|
typedef struct ChargingCurrentState
|
||||||
|
{
|
||||||
bool power = false;
|
bool power = false;
|
||||||
double maxChargingCurrent = 6;
|
double maxChargingCurrent = 6;
|
||||||
uint desiredPhaseCount = 3;
|
uint desiredPhaseCount = 3;
|
||||||
@ -57,7 +58,6 @@ public:
|
|||||||
|
|
||||||
QueuedModbusReply *setDigitalInputModeAsync(DigitalInputMode digitalInputMode);
|
QueuedModbusReply *setDigitalInputModeAsync(DigitalInputMode digitalInputMode);
|
||||||
|
|
||||||
|
|
||||||
// Note: the modbus implementation of the wallbox gets stuck if a Modbus request has been sent
|
// Note: the modbus implementation of the wallbox gets stuck if a Modbus request has been sent
|
||||||
// and we disconnect the socket before the response has arrived. Only a reboot of the wallbox
|
// and we disconnect the socket before the response has arrived. Only a reboot of the wallbox
|
||||||
// fixes the broken communication afterwards. This method waits for the current request before closing the
|
// fixes the broken communication afterwards. This method waits for the current request before closing the
|
||||||
@ -87,5 +87,4 @@ private:
|
|||||||
|
|
||||||
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState);
|
QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState);
|
||||||
|
|
||||||
|
|
||||||
#endif // PCEWALLBOX_H
|
#endif // PCEWALLBOX_H
|
||||||
|
|||||||
Reference in New Issue
Block a user