diff --git a/energyplugin/evcharger.cpp b/energyplugin/evcharger.cpp index 5329e18..f5c0649 100644 --- a/energyplugin/evcharger.cpp +++ b/energyplugin/evcharger.cpp @@ -168,13 +168,13 @@ Electricity::Phases EvCharger::phases() const } } - // TODO: Can we figure out from the root meter on which phase we're attached? - // One idea would be to sign up on root meter changes. When chargingEnabled is set or unset, - // memorize root meter values and compare the next (or some more) cycles if a phase changed - // by a similar value as we'd expect - - // Until we have this detection, we must ask the user how many phases will be used while charging + // For single-phase chargers, detect the actual connected phase from per-phase metering + Electricity::Phases metered = meteredPhases(); + if (metered != Electricity::PhaseNone) { + return metered; + } + // Phase unknown — charger has no per-phase metering or is not currently charging return Electricity::PhaseNone; } diff --git a/energyplugin/smartchargingmanager.cpp b/energyplugin/smartchargingmanager.cpp index 20fccc4..14dbdb7 100644 --- a/energyplugin/smartchargingmanager.cpp +++ b/energyplugin/smartchargingmanager.cpp @@ -391,9 +391,9 @@ void SmartChargingManager::verifyOverloadProtection(const QDateTime ¤tDate if (evCharger->phaseCount() == 1) { - // FIXME: get the actual phase, not assume it is phase A in single phase charging - if (requiredThrottlePower.value("A") > 0) { - int throttleAmpere = qCeil(requiredThrottlePower.value("A") / 230); + const QString phase = chargerPhaseKey(evCharger); + if (requiredThrottlePower.value(phase) > 0) { + int throttleAmpere = qCeil(requiredThrottlePower.value(phase) / 230); int desiredFallbackAmpere = evCharger->maxChargingCurrent() - throttleAmpere; if (desiredFallbackAmpere < static_cast(m_processInfos[evCharger].minimalChargingCurrent)) { @@ -474,8 +474,7 @@ void SmartChargingManager::verifyOverloadProtectionRecovery(const QDateTime &cur bool restoreCharger = false; if (evCharger->phaseCount() == 1) { - // FIXME: get the actual phase, not assume it is phase A in single phase charging - if (availablePhasePower.value("A") >= requiredRestorePhasePower) { + if (availablePhasePower.value(chargerPhaseKey(evCharger)) >= requiredRestorePhasePower) { qCDebug(dcNymeaEnergy()) << "Overload protection: Enought power available to restore the original configuration" << manualMaxChargingCurrent(evCharger->id()) << "[A]"; restoreCharger = true; @@ -514,8 +513,7 @@ void SmartChargingManager::verifyOverloadProtectionRecovery(const QDateTime &cur bool restoreChargerPower = false; if (evCharger->phaseCount() == 1) { - // FIXME: get the actual phase, not assume it is phase A in single phase charging - if (availablePhasePower.value("A") >= requiredRestorePhasePower) { + if (availablePhasePower.value(chargerPhaseKey(evCharger)) >= requiredRestorePhasePower) { qCDebug(dcNymeaEnergy()) << "Overload protection: Enought power available to start charging using the minimal charging current of" << m_processInfos.value(evCharger).minimalChargingCurrent << "[A]"; restoreChargerPower = true; @@ -1770,6 +1768,28 @@ Electricity::Phases SmartChargingManager::getAscendingPhasesForCount(uint phaseC return phases; } +QString SmartChargingManager::chargerPhaseKey(EvCharger *evCharger) const +{ + // Use live metering first — reliable when charger is actively charging + Electricity::Phases metered = evCharger->meteredPhases(); + if (metered.testFlag(Electricity::PhaseA)) return QStringLiteral("A"); + if (metered.testFlag(Electricity::PhaseB)) return QStringLiteral("B"); + if (metered.testFlag(Electricity::PhaseC)) return QStringLiteral("C"); + + // Charger may be off — fall back to last known phase stored by prepareInformation() + if (m_processInfos.contains(evCharger)) { + Electricity::Phases known = m_processInfos.value(evCharger).effectivePhases; + if (known.testFlag(Electricity::PhaseA)) return QStringLiteral("A"); + if (known.testFlag(Electricity::PhaseB)) return QStringLiteral("B"); + if (known.testFlag(Electricity::PhaseC)) return QStringLiteral("C"); + } + + // Phase unknown — conservative fallback (unchanged previous behavior) + qCWarning(dcNymeaEnergy()) << "Cannot determine connected phase for" + << evCharger->name() << "— defaulting to phase A"; + return QStringLiteral("A"); +} + uint SmartChargingManager::getBestPhaseCount(EvCharger *evCharger, double surplusAmpere) { uint desiredPhaseCount = 1; diff --git a/energyplugin/smartchargingmanager.h b/energyplugin/smartchargingmanager.h index 833bcaa..1099c34 100644 --- a/energyplugin/smartchargingmanager.h +++ b/energyplugin/smartchargingmanager.h @@ -123,6 +123,7 @@ private: Electricity::Phases getAscendingPhasesForCount(uint phaseCount); uint getBestPhaseCount(EvCharger *evCharger, double surplusAmpere); + QString chargerPhaseKey(EvCharger *evCharger) const; EnergyManager *m_energyManager = nullptr; ThingManager *m_thingManager = nullptr;