diff --git a/pcelectric/integrationpluginpcelectric.cpp b/pcelectric/integrationpluginpcelectric.cpp index 43426bb..5ea4c6b 100644 --- a/pcelectric/integrationpluginpcelectric.cpp +++ b/pcelectric/integrationpluginpcelectric.cpp @@ -3,7 +3,7 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. * @@ -26,13 +26,10 @@ #include "pcelectricdiscovery.h" #include "plugininfo.h" -#include #include +#include -IntegrationPluginPcElectric::IntegrationPluginPcElectric() -{ - -} +IntegrationPluginPcElectric::IntegrationPluginPcElectric() {} 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 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()) { - - ThingDescriptor descriptor(ev11ThingClassId, "PCE EV11.3 (" + result.serialNumber + ")", "Version: " + result.firmwareRevision + " - " + result.networkDeviceInfo.address().toString()); + ThingDescriptor descriptor(ev11ThingClassId, + "PCE EV11.3 (" + result.serialNumber + ")", + "Version: " + result.firmwareRevision + " - " + result.networkDeviceInfo.address().toString()); qCDebug(dcPcElectric()) << "Discovered:" << descriptor.title() << descriptor.description(); // Check if we already have set up this device @@ -102,7 +100,7 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info) m_monitors.insert(thing, monitor); - connect(info, &ThingSetupInfo::aborted, monitor, [=](){ + connect(info, &ThingSetupInfo::aborted, monitor, [=]() { if (m_monitors.contains(thing)) { qCDebug(dcPcElectric()) << "Unregistering monitor because setup has been aborted."; hardwareManager()->networkDeviceDiscovery()->unregisterMonitor(m_monitors.take(thing)); @@ -117,7 +115,7 @@ void IntegrationPluginPcElectric::setupThing(ThingSetupInfo *info) } else { // 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."; - connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable){ + connect(monitor, &NetworkDeviceMonitor::reachableChanged, info, [=](bool reachable) { if (reachable) { qCDebug(dcPcElectric()) << "Network device" << thing->name() << "is now reachable. Continue with the setup..."; setupConnection(info); @@ -149,7 +147,6 @@ void IntegrationPluginPcElectric::postSetupThing(Thing *thing) m_refreshTimer->start(); } - PceWallbox::ChargingCurrentState chargingCurrentState; chargingCurrentState.power = thing->stateValue(ev11PowerStateTypeId).toBool(); chargingCurrentState.maxChargingCurrent = thing->stateValue(ev11MaxChargingCurrentStateTypeId).toDouble(); @@ -197,7 +194,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info) } if (info->action().actionTypeId() == ev11PowerActionTypeId) { - bool power = info->action().paramValue(ev11PowerActionPowerParamTypeId).toBool(); qCDebug(dcPcElectric()) << "Set charging enabled to" << power; @@ -207,7 +203,7 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info) quint16 registerValue = PceWallbox::deriveRegisterFromStates(m_chargingCurrentStateBuffer.value(thing)); qCDebug(dcPcElectric()) << "Writing charging current register" << 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) { qCWarning(dcPcElectric()) << "Could not set power state to" << power << "(" << registerValue << ")" << reply->errorString(); info->finish(Thing::ThingErrorHardwareFailure); @@ -222,7 +218,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info) return; } else if (info->action().actionTypeId() == ev11MaxChargingCurrentActionTypeId) { - double desiredChargingCurrent = info->action().paramValue(ev11MaxChargingCurrentActionMaxChargingCurrentParamTypeId).toDouble(); 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)); qCDebug(dcPcElectric()) << "Writing charging current register" << 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) { qCWarning(dcPcElectric()) << "Could not set charging current to" << desiredChargingCurrent << reply->errorString(); info->finish(Thing::ThingErrorHardwareFailure); @@ -247,7 +242,6 @@ void IntegrationPluginPcElectric::executeAction(ThingActionInfo *info) return; } else if (info->action().actionTypeId() == ev11DesiredPhaseCountActionTypeId) { - uint desiredPhaseCount = info->action().paramValue(ev11DesiredPhaseCountActionDesiredPhaseCountParamTypeId).toUInt(); 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)); qCDebug(dcPcElectric()) << "Writing charging current register" << 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) { qCWarning(dcPcElectric()) << "Could not set desired phase count to" << desiredPhaseCount << reply->errorString(); info->finish(Thing::ThingErrorHardwareFailure); @@ -289,11 +283,11 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address()); // Monitor reachability - connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable){ + connect(monitor, &NetworkDeviceMonitor::reachableChanged, thing, [=](bool reachable) { if (!thing->setupComplete()) 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()) { connection->modbusTcpMaster()->setHostAddress(monitor->networkDeviceInfo().address()); connection->connectDevice(); @@ -305,22 +299,22 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) }); // 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; m_initialUpdate[thing] = true; 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()) << connection; if (!connection->phaseAutoSwitch()) { // 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(ev11PhaseCountStateTypeId, 3); } else { - thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, { 1, 3 }); // Enable phase switching + thing->setStatePossibleValues(ev11DesiredPhaseCountStateTypeId, {1, 3}); // Enable phase switching } if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) { @@ -332,8 +326,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) } thing->setStateMaxValue(ev11MaxChargingCurrentStateTypeId, connection->maxChargingCurrentDip() / 1000); - thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 && - connection->chargingState() < PceWallbox::ChargingStateError); + thing->setStateValue(ev11PluggedInStateTypeId, connection->chargingState() >= PceWallbox::ChargingStateB1 && connection->chargingState() < PceWallbox::ChargingStateError); thing->setStateValue(ev11ChargingStateTypeId, connection->chargingState() == PceWallbox::ChargingStateC2); if (connection->chargingRelayState() != EV11ModbusTcpConnection::ChargingRelayStateNoCharging) { @@ -405,7 +398,6 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) } if (m_initialUpdate.value(thing)) { - m_initialUpdate[thing] = false; qCDebug(dcPcElectric()) << "Update initial charger states from charging current register..."; @@ -440,7 +432,6 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) } thing->setStateValue(ev11DigitalInputModeStateTypeId, connection->digitalInputMode()); - if (connection->firmwareRevision() >= "0022") { thing->setSettingValue(ev11SettingsPhaseAutoSwitchPauseParamTypeId, connection->phaseAutoSwitchPause()); thing->setStateValue(ev11SettingsPhaseAutoSwitchMinChargingTimeParamTypeId, connection->phaseAutoSwitchMinChargingTime()); @@ -451,18 +442,29 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) if (connection->firmwareRevision() >= "0022") { thing->setStateValue(ev11CurrentPowerStateTypeId, connection->currentPower()); 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) { quint16 percentage = value.toUInt(); qCDebug(dcPcElectric()) << "Setting LED brightness to" << 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) { qCWarning(dcPcElectric()) << "Could not set led brightness to" << percentage << "%" << reply->errorString(); return; @@ -489,7 +491,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) } 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) { qCWarning(dcPcElectric()) << "Could not set digital input mode to" << modeValue << reply->errorString(); return; @@ -503,7 +505,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) qCDebug(dcPcElectric()) << "Setting phase auto switch pause to" << registerValue << "s"; QueuedModbusReply *reply = connection->setPhaseAutoSwitchPauseAsync(registerValue); - connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue](){ + connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue]() { if (reply->error() != QModbusDevice::NoError) { qCWarning(dcPcElectric()) << "Could not set phase auto switch pause to" << registerValue << "s" << reply->errorString(); return; @@ -516,7 +518,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) qCDebug(dcPcElectric()) << "Setting phase auto switch min charging current" << registerValue << "s"; QueuedModbusReply *reply = connection->setPhaseAutoSwitchMinChargingTimeAsync(registerValue); - connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue](){ + connect(reply, &QueuedModbusReply::finished, thing, [reply, registerValue]() { if (reply->error() != QModbusDevice::NoError) { qCWarning(dcPcElectric()) << "Could not set phase auto switch min charging current to" << registerValue << "s" << reply->errorString(); return; @@ -529,7 +531,7 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) qCDebug(dcPcElectric()) << "Setting force charging resume to" << 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) { qCWarning(dcPcElectric()) << "Could not set force charging resume to" << registerValue << reply->errorString(); return; @@ -547,4 +549,3 @@ void IntegrationPluginPcElectric::setupConnection(ThingSetupInfo *info) if (monitor->reachable()) connection->connectDevice(); } - diff --git a/pcelectric/integrationpluginpcelectric.h b/pcelectric/integrationpluginpcelectric.h index a2a9388..cb7a265 100644 --- a/pcelectric/integrationpluginpcelectric.h +++ b/pcelectric/integrationpluginpcelectric.h @@ -3,7 +3,7 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. * @@ -25,15 +25,15 @@ #ifndef INTEGRATIONPLUGINPCELECTRIC_H #define INTEGRATIONPLUGINPCELECTRIC_H -#include #include +#include #include #include #include -#include "pcewallbox.h" #include "extern-plugininfo.h" +#include "pcewallbox.h" class IntegrationPluginPcElectric : public IntegrationPlugin { @@ -67,9 +67,6 @@ private: QHash m_chargingCurrentStateBuffer; void setupConnection(ThingSetupInfo *info); - }; - - #endif // INTEGRATIONPLUGINPCELECTRIC_H diff --git a/pcelectric/pcelectricdiscovery.cpp b/pcelectric/pcelectricdiscovery.cpp index e59e6f5..76eb9e6 100644 --- a/pcelectric/pcelectricdiscovery.cpp +++ b/pcelectric/pcelectricdiscovery.cpp @@ -26,20 +26,17 @@ #include "extern-plugininfo.h" PcElectricDiscovery::PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent) - : QObject{parent}, - m_networkDeviceDiscovery{networkDeviceDiscovery}, - m_port{port}, - m_modbusAddress{modbusAddress} -{ - -} + : QObject{parent} + , m_networkDeviceDiscovery{networkDeviceDiscovery} + , m_port{port} + , m_modbusAddress{modbusAddress} +{} QList PcElectricDiscovery::results() const { return m_results; } - void PcElectricDiscovery::startDiscovery() { qCInfo(dcPcElectric()) << "Discovery: Start searching for PCE wallboxes in the network..."; @@ -48,12 +45,11 @@ void PcElectricDiscovery::startDiscovery() NetworkDeviceDiscoveryReply *discoveryReply = m_networkDeviceDiscovery->discover(); connect(discoveryReply, &NetworkDeviceDiscoveryReply::hostAddressDiscovered, this, &PcElectricDiscovery::checkNetworkDevice); connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, discoveryReply, &NetworkDeviceDiscoveryReply::deleteLater); - connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=](){ - + connect(discoveryReply, &NetworkDeviceDiscoveryReply::finished, this, [=]() { m_networkDeviceInfos = discoveryReply->networkDeviceInfos(); // 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."; finishDiscovery(); }); @@ -65,7 +61,7 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address) EV11ModbusTcpConnection *connection = new EV11ModbusTcpConnection(address, m_port, m_modbusAddress, this); m_connections.append(connection); - connect(connection, &EV11ModbusTcpConnection::reachableChanged, this, [=](bool reachable){ + connect(connection, &EV11ModbusTcpConnection::reachableChanged, this, [=](bool reachable) { if (!reachable) { // Disconnected ... done with this connection cleanupConnection(connection); @@ -73,9 +69,10 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address) } // 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) { - qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << address.toString() << "Continue...";; + qCDebug(dcPcElectric()) << "Discovery: Initialization failed on" << address.toString() << "Continue..."; + ; cleanupConnection(connection); return; } @@ -93,7 +90,6 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address) // According to PCE the HW revision must be 0 if (!registerMacAddress.isNull() && connection->hardwareRevision() == 0) { - // Parse the serial number QByteArray serialRawData; QDataStream stream(&serialRawData, QIODevice::ReadWrite); @@ -118,22 +114,25 @@ void PcElectricDiscovery::checkNetworkDevice(const QHostAddress &address) // Initializing... 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); } }); // 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) { - qCDebug(dcPcElectric()) << "Discovery: Connection error on" << address.toString() << "Continue...";; + qCDebug(dcPcElectric()) << "Discovery: Connection error on" << address.toString() << "Continue..."; + ; cleanupConnection(connection); } }); // If check reachability failed...skip this host... - connect(connection, &EV11ModbusTcpConnection::checkReachabilityFailed, this, [=](){ - qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << address.toString() << "Continue...";; + connect(connection, &EV11ModbusTcpConnection::checkReachabilityFailed, this, [=]() { + qCDebug(dcPcElectric()) << "Discovery: Check reachability failed on" << address.toString() << "Continue..."; + ; cleanupConnection(connection); }); @@ -158,16 +157,22 @@ void PcElectricDiscovery::finishDiscovery() Result result = m_potentialResults.at(i); if (networkDeviceInfo.macAddressInfos().hasMacAddress(result.registerMacAddress)) { - qCInfo(dcPcElectric()) << "Discovery: --> Found EV11.3" - << "Serial number:" << result.serialNumber - << "Firmware revision:" << result.firmwareRevision - << result.networkDeviceInfo; + qCInfo(dcPcElectric()) + << "Discovery: --> Found EV11.3" + << "Serial number:" + << result.serialNumber + << "Firmware revision:" + << result.firmwareRevision + << result.networkDeviceInfo; m_results.append(result); } else { - qCWarning(dcPcElectric()) << "Discovery: --> Found potential EV11.3, but not adding to the results due to imcomplete MAC address check:" - << "Serial number:" << result.serialNumber - << "Firmware revision:" << result.firmwareRevision - << result.networkDeviceInfo; + qCWarning(dcPcElectric()) + << "Discovery: --> Found potential EV11.3, but not adding to the results due to imcomplete MAC address check:" + << "Serial number:" + << result.serialNumber + << "Firmware revision:" + << result.firmwareRevision + << result.networkDeviceInfo; } } @@ -178,7 +183,10 @@ void PcElectricDiscovery::finishDiscovery() foreach (EV11ModbusTcpConnection *connection, m_connections) cleanupConnection(connection); - qCInfo(dcPcElectric()) << "Discovery: Finished the discovery process. Found" << m_results.length() - << "PCE wallboxes in" << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz"); + qCInfo(dcPcElectric()) + << "Discovery: Finished the discovery process. Found" + << m_results.length() + << "PCE wallboxes in" + << QTime::fromMSecsSinceStartOfDay(durationMilliSeconds).toString("mm:ss.zzz"); emit discoveryFinished(); } diff --git a/pcelectric/pcelectricdiscovery.h b/pcelectric/pcelectricdiscovery.h index 742c893..62fd40c 100644 --- a/pcelectric/pcelectricdiscovery.h +++ b/pcelectric/pcelectricdiscovery.h @@ -37,7 +37,8 @@ class PcElectricDiscovery : public QObject public: explicit PcElectricDiscovery(NetworkDeviceDiscovery *networkDeviceDiscovery, quint16 port, quint16 modbusAddress, QObject *parent = nullptr); - typedef struct Result { + typedef struct Result + { QString serialNumber; QString firmwareRevision; QHostAddress address; diff --git a/pcelectric/pcewallbox.cpp b/pcelectric/pcewallbox.cpp index dee7eac..f44267d 100644 --- a/pcelectric/pcewallbox.cpp +++ b/pcelectric/pcewallbox.cpp @@ -35,7 +35,7 @@ PceWallbox::PceWallbox(const QHostAddress &hostAddress, uint port, quint16 slave m_timer.setSingleShot(false); 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) { 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) { qCDebug(dcPcElectric()) << "Connection initialized successfully" << m_modbusTcpMaster->hostAddress().toString(); m_timer.start(); @@ -81,8 +81,7 @@ bool PceWallbox::update() QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockStatusDataUnit(), this); 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) m_currentReply = nullptr; @@ -100,7 +99,6 @@ bool PceWallbox::update() enqueueRequest(reply); - // charging current register. Contains // - power state // - chargingcurrent (if power is true) @@ -116,8 +114,7 @@ bool PceWallbox::update() if (!chargingCurrentQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, chargingCurrentDataUnit(), this); 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) m_currentReply = nullptr; @@ -148,8 +145,7 @@ bool PceWallbox::update() if (!digitalInputAlreadyQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, digitalInputModeDataUnit(), this); 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) m_currentReply = nullptr; @@ -168,7 +164,6 @@ bool PceWallbox::update() enqueueRequest(reply); } - // Led brightness bool ledBrightnessAlreadyQueued = false; foreach (QueuedModbusReply *r, m_readQueue) { @@ -181,8 +176,7 @@ bool PceWallbox::update() if (!ledBrightnessAlreadyQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, ledBrightnessDataUnit(), this); 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) m_currentReply = nullptr; @@ -204,11 +198,9 @@ bool PceWallbox::update() enqueueRequest(reply); } - if (firmwareRevision() < "0022") return true; - // --------------------------------------------------------------------------------------- // Registers since 0022 (V 0.22) @@ -224,8 +216,7 @@ bool PceWallbox::update() if (!update2Queued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, readBlockUpdate2DataUnit(), this); 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) m_currentReply = nullptr; @@ -245,7 +236,6 @@ bool PceWallbox::update() enqueueRequest(reply); } - bool phaseAutoSwitchPauseQueued = false; foreach (QueuedModbusReply *r, m_readQueue) { if (r->dataUnit().startAddress() == phaseAutoSwitchPauseDataUnit().startAddress()) { @@ -257,8 +247,7 @@ bool PceWallbox::update() if (!phaseAutoSwitchPauseQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchPauseDataUnit(), this); 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) m_currentReply = nullptr; @@ -289,8 +278,7 @@ bool PceWallbox::update() if (!phaseAutoSwitchMinChargingTimeQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, phaseAutoSwitchMinChargingTimeDataUnit(), this); 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) m_currentReply = nullptr; @@ -321,8 +309,7 @@ bool PceWallbox::update() if (!forceChargingResumeQueued) { reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeRead, forceChargingResumeDataUnit(), this); 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) m_currentReply = nullptr; @@ -354,7 +341,7 @@ QueuedModbusReply *PceWallbox::setChargingCurrentAsync(quint16 chargingCurrent) QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setChargingCurrentDataUnit(chargingCurrent), this); 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) m_currentReply = nullptr; @@ -374,7 +361,7 @@ QueuedModbusReply *PceWallbox::setLedBrightnessAsync(quint16 percentage) QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setLedBrightnessDataUnit(percentage), this); 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) m_currentReply = nullptr; @@ -394,7 +381,7 @@ QueuedModbusReply *PceWallbox::setPhaseAutoSwitchPauseAsync(quint16 seconds) QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchPauseDataUnit(seconds), this); 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) m_currentReply = nullptr; @@ -414,7 +401,7 @@ QueuedModbusReply *PceWallbox::setPhaseAutoSwitchMinChargingTimeAsync(quint16 se QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setPhaseAutoSwitchMinChargingTimeDataUnit(seconds), this); 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) m_currentReply = nullptr; @@ -434,7 +421,7 @@ QueuedModbusReply *PceWallbox::setForceChargingResumeAsync(quint16 value) QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setForceChargingResumeDataUnit(value), this); 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) m_currentReply = nullptr; @@ -454,7 +441,7 @@ QueuedModbusReply *PceWallbox::setDigitalInputModeAsync(DigitalInputMode digital QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setDigitalInputModeDataUnit(digitalInputMode), this); 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) 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 if (chargingCurrentState.power) { - bool threePhaseCharging = (registerValue & (1 << 15)); chargingCurrentState.desiredPhaseCount = (threePhaseCharging ? 3 : 1); @@ -516,7 +502,6 @@ PceWallbox::ChargingCurrentState PceWallbox::deriveStatesFromRegister(quint16 re return chargingCurrentState; } - void PceWallbox::sendHeartbeat() { if (m_aboutToDelete) @@ -525,7 +510,7 @@ void PceWallbox::sendHeartbeat() QueuedModbusReply *reply = new QueuedModbusReply(QueuedModbusReply::RequestTypeWrite, setHeartbeatDataUnit(m_heartbeat++), this); 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) 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(); } - switch(m_currentReply->requestType()) { + switch (m_currentReply->requestType()) { case QueuedModbusReply::RequestTypeRead: - qCDebug(dcPcElectric()) << "--> Reading" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType()) - << "register:" << m_currentReply->dataUnit().startAddress() - << "length" << m_currentReply->dataUnit().valueCount(); + qCDebug(dcPcElectric()) + << "--> Reading" + << 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)); break; case QueuedModbusReply::RequestTypeWrite: - qCDebug(dcPcElectric()) << "--> Writing" << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType()) - << "register:" << m_currentReply->dataUnit().startAddress() - << "length:" << m_currentReply->dataUnit().valueCount() - << "values:" << m_currentReply->dataUnit().values(); + qCDebug(dcPcElectric()) + << "--> Writing" + << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType()) + << "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)); break; } if (!m_currentReply->reply()) { - qCWarning(dcPcElectric()) << "Error occurred while sending" << m_currentReply->requestType() - << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType()) - << "register:" << m_currentReply->dataUnit().startAddress() - << "length:" << m_currentReply->dataUnit().valueCount() - << "to" << m_modbusTcpMaster->hostAddress().toString() << m_modbusTcpMaster->errorString(); + qCWarning(dcPcElectric()) + << "Error occurred while sending" + << m_currentReply->requestType() + << ModbusDataUtils::registerTypeToString(m_currentReply->dataUnit().registerType()) + << "register:" + << m_currentReply->dataUnit().startAddress() + << "length:" + << m_currentReply->dataUnit().valueCount() + << "to" + << m_modbusTcpMaster->hostAddress().toString() + << m_modbusTcpMaster->errorString(); m_currentReply->deleteLater(); m_currentReply = nullptr; QTimer::singleShot(0, this, &PceWallbox::sendNextRequest); @@ -634,6 +634,13 @@ void PceWallbox::cleanupQueues() QDebug operator<<(QDebug debug, const PceWallbox::ChargingCurrentState &chargingCurrentState) { 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; } diff --git a/pcelectric/pcewallbox.h b/pcelectric/pcewallbox.h index 3bf51a6..87164b6 100644 --- a/pcelectric/pcewallbox.h +++ b/pcelectric/pcewallbox.h @@ -25,10 +25,10 @@ #ifndef PCEWALLBOX_H #define PCEWALLBOX_H -#include -#include #include #include +#include +#include #include @@ -38,7 +38,8 @@ class PceWallbox : public EV11ModbusTcpConnection { Q_OBJECT public: - typedef struct ChargingCurrentState { + typedef struct ChargingCurrentState + { bool power = false; double maxChargingCurrent = 6; uint desiredPhaseCount = 3; @@ -57,7 +58,6 @@ public: QueuedModbusReply *setDigitalInputModeAsync(DigitalInputMode digitalInputMode); - // 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 // 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); - #endif // PCEWALLBOX_H